Annotation of uae/src/os.c, revision 1.1.1.2

1.1       root        1:  /* 
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   * 
                      4:   * OS specific functions
                      5:   * 
                      6:   * (c) 1995 Bernd Schmidt
                      7:   * (c) 1996 Marcus Sundberg
                      8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include "config.h"
                     14: #include "options.h"
                     15: #include "memory.h"
                     16: #include "custom.h"
                     17: #include "os.h"
                     18: #include "events.h"
                     19: 
                     20: #ifndef DONT_WANT_SOUND
1.1.1.2 ! root       21: static void sample_ulaw_handler(void);
1.1       root       22: #endif
                     23: 
                     24: int joystickpresent = 0;
                     25: 
                     26: #ifdef HAVE_LINUX_JOYSTICK_H
                     27: 
                     28: static int js0;
                     29: 
                     30: struct JS_DATA_TYPE jscal;
                     31: 
                     32: void read_joystick(UWORD *dir, int *button)
                     33: {
                     34:     static int minx = MAXINT, maxx = MININT,
                     35:                miny = MAXINT, maxy = MININT;
                     36:     int left = 0, right = 0, top = 0, bot = 0;
                     37:     struct JS_DATA_TYPE buffer;
                     38:     int len;
                     39:     
                     40:     *dir = 0;
                     41:     *button = 0;
                     42:     if (!joystickpresent)
                     43:        return;
                     44:     
                     45:     len = read(js0, &buffer, sizeof(buffer));
                     46:     if (len != sizeof(buffer)) 
                     47:        return;
                     48:     
                     49:     if (buffer.x < minx) minx = buffer.x;
                     50:     if (buffer.y < miny) miny = buffer.y;
                     51:     if (buffer.x > maxx) maxx = buffer.x;
                     52:     if (buffer.y > maxy) maxy = buffer.y;
                     53:     
                     54:     if (buffer.x < (minx + (maxx-minx)/3))
                     55:        left = 1;
                     56:     else if (buffer.x > (minx + 2*(maxx-minx)/3))
                     57:        right = 1;
                     58: 
                     59:     if (buffer.y < (miny + (maxy-miny)/3))
                     60:        top = 1;
                     61:     else if (buffer.y > (miny + 2*(maxy-miny)/3))
                     62:        bot = 1;
                     63:        
                     64:     if (left) top = !top;
                     65:     if (right) bot = !bot;
                     66:     *dir = bot | (right << 1) | (top << 8) | (left << 9);
                     67:     *button = (buffer.buttons & 3) != 0;
                     68: }
                     69: 
                     70: void init_joystick(void)
                     71: {
                     72:     js0 = open("/dev/js0", O_RDONLY);
                     73:     if (js0 < 0)
                     74:        return;
                     75:     joystickpresent = 1;
                     76: }
                     77: 
                     78: void close_joystick(void)
                     79: {
                     80:     if (joystickpresent)
                     81:        close(js0);
                     82: }
                     83: 
                     84: #elif defined(__DOS__)
                     85: 
                     86: void read_joystick(UWORD *dir, int *button)
                     87: {
                     88:     static int minx = MAXINT, maxx = MININT,
                     89:               miny = MAXINT, maxy = MININT;
                     90:     int left = 0, right = 0, top = 0, bot = 0;
                     91:     char JoyPort;
                     92:     int laps, JoyX, JoyY;
                     93: 
                     94:     *dir = 0;
                     95:     *button = 0;
                     96:     if (!joystickpresent)
                     97:        return;
                     98: 
                     99:     JoyX = 0;
                    100:     JoyY = 0;
                    101:     laps = 0;
                    102:     __asm__ __volatile__("cli");
                    103:     outportb(0x201, 0xff);
                    104:     do {
                    105:        JoyPort = inportb(0x201);
                    106:        JoyX = JoyX + (JoyPort & 1);
                    107:        JoyY = JoyY + ((JoyPort & 2) >> 1);
                    108:        laps++;
                    109:     } while(((JoyPort & 3) != 0) && (laps != 65535));
                    110:     __asm__ __volatile__("sti");
                    111: 
                    112:     if (JoyX < minx) minx = JoyX;
                    113:     if (JoyY < miny) miny = JoyY;
                    114:     if (JoyX > maxx) maxx = JoyX;
                    115:     if (JoyY > maxy) maxy = JoyY;
                    116: 
                    117:     if (JoyX < (minx + (maxx-minx)/3))
                    118:        left = 1;
                    119:     else if (JoyX > (minx + 2*(maxx-minx)/3))
                    120:        right = 1;
                    121: 
                    122:     if (JoyY < (miny + (maxy-miny)/3))
                    123:        top = 1;
                    124:     else if (JoyY > (miny + 2*(maxy-miny)/3))
                    125:        bot = 1;
                    126: 
                    127:     if (left) top = !top;
                    128:     if (right) bot = !bot;
                    129:     *dir = bot | (right << 1) | (top << 8) | (left << 9);
                    130:     *button = ((~JoyPort) & 48) != 0;
                    131: }
                    132: 
                    133: void init_joystick(void)
                    134: {
                    135:     int laps = 0;
                    136:     char JoyPort;
                    137:     __asm__ __volatile__("cli");
                    138:     outportb(0x201, 0xff);
                    139:     do {
                    140:        JoyPort = inportb(0x201);
                    141:        laps++;
                    142:     } while(((JoyPort & 3) != 0) && (laps != 65535));
                    143:     __asm__ __volatile__("sti");
                    144:     if (laps != 65535)
                    145:        joystickpresent = 1;
                    146: }
                    147: 
                    148: void close_joystick(void)
                    149: {
                    150: }
                    151: 
1.1.1.2 ! root      152: #elif defined(AMIGA)
        !           153: 
        !           154: #define EXEC_TYPES_H /* exec/types.h has trouble as LONG, ULONG, etc. */
        !           155: typedef void *APTR;  /* are already defined. This avoid the trouble.  */
        !           156: typedef char *STRPTR;
        !           157: typedef float *FLOAT;
        !           158: typedef int BOOL;
        !           159: #define VOID void
        !           160: 
        !           161: #include <hardware/custom.h>
        !           162: #include <hardware/cia.h>
        !           163: 
        !           164: #define CIAAPRA 0xBFE001 
        !           165: #define CUSTOM  0xDFF000
        !           166: 
        !           167: static struct Custom *custom= (struct Custom*) CUSTOM;
        !           168: static struct CIA *cia = (struct CIA *) CIAAPRA;
        !           169: 
        !           170: void read_joystick(UWORD *dir, int *button)
        !           171: {
        !           172:     int bot, right, top, left, joy,fire;
        !           173:     
        !           174:     joy   = custom->joy1dat;
        !           175:     fire  = !( cia->ciapra & 0x0080 ) ? 1 : 0;
        !           176: 
        !           177:     right = (joy & 0x0002) ? 1 : 0;
        !           178:     left  = (joy & 0x0200) ? 1 : 0;
        !           179:     bot   = (joy & 0x0001) ? 1 : 0;
        !           180:     top   = (joy & 0x0100) ? 1 : 0;
        !           181:     
        !           182:     *button = fire;
        !           183:     *dir = bot | (right << 1) | (top << 8) | (left << 9);
        !           184: }
        !           185: 
        !           186: void init_joystick(void)
        !           187: {
        !           188: }
        !           189: 
        !           190: void close_joystick(void)
        !           191: {
        !           192: }
        !           193: 
        !           194: #elif !defined(__BEOS__)
        !           195: 
1.1       root      196: void read_joystick(UWORD *dir, int *button)
                    197: {
                    198:     *dir = 0;
                    199:     *button = 0;
                    200: }
                    201: 
                    202: void init_joystick(void)
                    203: {
                    204: }
                    205: 
                    206: void close_joystick(void)
                    207: {
                    208: }
                    209: 
                    210: #endif
                    211: 
                    212: int sound_available = 0;
                    213: 
                    214: struct audio_channel_data audio_channel[4];
                    215: 
1.1.1.2 ! root      216: #ifdef __BEOS__
        !           217: UWORD *sndbuffer;
        !           218: #elif !defined(AMIGA)
1.1       root      219: /* The buffer is too large... */
1.1.1.2 ! root      220: static UWORD sndbuffer[44100];
        !           221: #endif
        !           222: UWORD *sndbufpt;
1.1       root      223: 
                    224: static ULONG data;
                    225: 
                    226: int sound_table[256][64];
1.1.1.2 ! root      227: static int dspbits = 16;
        !           228: int sndbufsize;
1.1       root      229: 
1.1.1.2 ! root      230: void init_sound_table16(void)
1.1       root      231: {
                    232:     int i,j;
                    233:     
                    234:     for (i = 0; i < 256; i++)
                    235:        for (j = 0; j < 64; j++)
                    236:            sound_table[i][j] = j * (BYTE)i;
                    237: }
                    238: 
1.1.1.2 ! root      239: void init_sound_table8 (void)
1.1       root      240: {
                    241:     int i,j;
                    242:     
                    243:     for (i = 0; i < 256; i++)
                    244:        for (j = 0; j < 64; j++)
                    245:            sound_table[i][j] = (j * (BYTE)i) / 256;
                    246: }
                    247: 
                    248: static int exact_log2(int v)
                    249: {
                    250:     int l = 0;
                    251:     while ((v >>= 1) != 0)
                    252:        l++;
                    253:     return l;
                    254: }
                    255: 
                    256: #ifdef LINUX_SOUND
                    257: 
                    258: #include <sys/ioctl.h>
                    259: #include <sys/soundcard.h>
                    260: 
                    261: static int sfd;
                    262: static int have_sound;
                    263: 
1.1.1.2 ! root      264: void close_sound(void)
        !           265: {
        !           266:     if (have_sound)
        !           267:        close(sfd);
        !           268: }
        !           269: 
1.1       root      270: int init_sound (void)
                    271: {
                    272:     int tmp;
                    273:     int rate;
                    274:     
                    275:     unsigned long formats;
                    276:     
                    277:     sfd = open ("/dev/dsp", O_WRONLY);
                    278:     have_sound = !(sfd < 0);
                    279:     if (!have_sound) {
                    280:        return 0;
                    281:     }
                    282:     
                    283:     ioctl (sfd, SNDCTL_DSP_GETFMTS, &formats);
                    284: 
                    285:     if (sound_desired_bsiz < 128 || sound_desired_bsiz > 16384) {
                    286:        fprintf(stderr, "Sound buffer size %d out of range.\n", sound_desired_bsiz);
                    287:        sound_desired_bsiz = 8192;
                    288:     }
                    289:     
                    290:     tmp = 0x00040000 + exact_log2(sound_desired_bsiz);
                    291:     ioctl (sfd, SNDCTL_DSP_SETFRAGMENT, &tmp);
                    292:     ioctl (sfd, SNDCTL_DSP_GETBLKSIZE, &sndbufsize);
                    293: 
                    294:     dspbits = sound_desired_bits;
                    295:     ioctl(sfd, SNDCTL_DSP_SAMPLESIZE, &dspbits);
                    296:     ioctl(sfd, SOUND_PCM_READ_BITS, &dspbits);
                    297:     if (dspbits != sound_desired_bits) {
                    298:        fprintf(stderr, "Can't use sound with %d bits\n", sound_desired_bits);
                    299:        return 0;
                    300:     }
                    301: 
                    302:     tmp = 0;
                    303:     ioctl(sfd, SNDCTL_DSP_STEREO, &tmp);
                    304:     
                    305:     rate = sound_desired_freq;
                    306:     ioctl(sfd, SNDCTL_DSP_SPEED, &rate);
                    307:     ioctl(sfd, SOUND_PCM_READ_RATE, &rate);
                    308:     /* Some soundcards have a bit of tolerance here. */
                    309:     if (rate < sound_desired_freq * 90 / 100 || rate > sound_desired_freq * 110 / 100) {
                    310:        fprintf(stderr, "Can't use sound with desired frequency %d\n", sound_desired_freq);
                    311:        return 0;
                    312:     }
                    313: 
                    314:     eventtab[ev_sample].evtime = (long)maxhpos * maxvpos * 50 / rate;
                    315: 
                    316:     if (dspbits == 16) {
                    317:        /* Will this break horribly on Linux/Alpha? Possible... */
                    318:        if (!(formats & AFMT_S16_LE))
                    319:            return 0;
                    320:        init_sound_table16 ();
                    321:        eventtab[ev_sample].handler = sample16_handler;
                    322:     } else {
                    323:        if (!(formats & AFMT_U8))
                    324:            return 0;
                    325:        init_sound_table8 ();
                    326:        eventtab[ev_sample].handler = sample8_handler;
                    327:     }
                    328:     sound_available = 1;
                    329:     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
                    330:            dspbits, rate, sndbufsize);
1.1.1.2 ! root      331:     sndbufpt = sndbuffer;
1.1       root      332:     return 1;
                    333: }
                    334: 
                    335: static void flush_sound_buffer(void)
                    336: {
1.1.1.2 ! root      337:     write(sfd, sndbuffer, sndbufsize);
        !           338:     sndbufpt = sndbuffer;
1.1       root      339: }
                    340: 
                    341: #elif defined(AF_SOUND)
                    342: 
                    343: #include <AF/AFlib.h>
                    344: 
                    345: static AFAudioConn  *aud;
                    346: static AC            ac;
                    347: static long          aftime;
                    348: static int           rate;
                    349: 
                    350: static int have_sound;
                    351: 
1.1.1.2 ! root      352: void close_sound(void)
        !           353: {
        !           354: }
        !           355: 
1.1       root      356: int init_sound (void)
                    357: {
                    358:     AFSetACAttributes   attributes;
                    359:     AFDeviceDescriptor *aDev;
                    360:     int                 device;
                    361:     
                    362:     aud = AFOpenAudioConn(NULL);
                    363:     have_sound = !(aud == NULL);
                    364:     if (!have_sound) {
                    365:        return 0;
                    366:     }
                    367:     
                    368:     for(device = 0; device < ANumberOfAudioDevices(aud); device++) {
                    369:        aDev = AAudioDeviceDescriptor(aud, device);
                    370:        rate = aDev->playSampleFreq;
                    371:        sndbufsize = (rate / 8) * 4;
                    372:        if(aDev->inputsFromPhone == 0
                    373:           && aDev->outputsToPhone == 0
                    374:           && aDev->playNchannels == 1)
                    375:            break;
                    376:     }
                    377:     if (device == ANumberOfAudioDevices(aud)) {
                    378:        return 0;
                    379:     }
                    380:     
                    381:     dspbits = 16;
                    382:     attributes.type = LIN16;
                    383:     ac = AFCreateAC(aud, device, ACEncodingType, &attributes);
                    384:     aftime = AFGetTime(ac);
                    385: 
                    386:     init_sound_table16 ();
                    387:     eventtab[ev_sample].handler = sample16_handler;
                    388:     eventtab[ev_sample].evtime = (long)maxhpos * maxvpos * 50 / rate;
                    389:     
1.1.1.2 ! root      390:     sndbufpt = sndbuffer;
1.1       root      391:     sound_available = 1;
                    392:     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n", dspbits, rate, sndbufsize);
                    393:     return 1;
                    394: }
                    395: 
                    396: static void flush_sound_buffer(void)
                    397: {
1.1.1.2 ! root      398:     long size = (char *)sndbufpt - (char *)sndbuffer;
1.1       root      399:     if (AFGetTime(ac) > aftime)
                    400:        aftime = AFGetTime(ac);
1.1.1.2 ! root      401:     AFPlaySamples(ac, aftime, size, (unsigned char*) sndbuffer);
1.1       root      402:     aftime += size / 2;
1.1.1.2 ! root      403:     sndbufpt = sndbuffer;
1.1       root      404: }
                    405: 
                    406: #elif defined(__mac__)
                    407: 
                    408: #include <Sound.h>
                    409: 
                    410: static SndChannelPtr newChannel;
                    411: static ExtSoundHeader theSndBuffer;
                    412: static SndCommand theCmd;
                    413: 
                    414: /* The buffer is too large... */
1.1.1.2 ! root      415: static UWORD buffer0[44100], buffer1[44100], *sndbufpt;
1.1       root      416: 
                    417: static int have_sound;
                    418: static int nextbuf=0;
                    419: static Boolean sFlag=true;
                    420: 
1.1.1.2 ! root      421: void close_sound(void)
        !           422: {
        !           423: }
        !           424: 
1.1       root      425: int init_sound (void)
                    426: {      
                    427:     if (SndNewChannel(&newChannel, sampledSynth, initMono, NULL)) 
                    428:        return 0;
                    429:     sndbufsize = 44100;
                    430:     init_sound_table8 ();
1.1.1.2 ! root      431: 
        !           432:     sndbufpt = buffer0;
1.1       root      433:     sound_available = 1;
                    434:     return 1;
                    435: }
                    436: 
                    437: static void flush_sound_buffer(void)
                    438: {
1.1.1.2 ! root      439:     sndbufpt = buffer0;
1.1       root      440:     
                    441:     theSndBuffer.samplePtr = (Ptr)buffer0;
                    442:     theSndBuffer.numChannels = 1;
                    443:     theSndBuffer.sampleRate = 0xac440000;
                    444:     theSndBuffer.encode = extSH;
                    445:     theSndBuffer.numFrames = sndbufsize;
                    446:     theSndBuffer.sampleSize = 8;
                    447:     theCmd.param1 = 0;
                    448:     theCmd.param2 = (long)&theSndBuffer;
                    449:     theCmd.cmd = bufferCmd;
                    450:     SndDoCommand(newChannel, &theCmd, false);    
                    451: }
                    452: 
                    453: #elif defined(__DOS__)
                    454: 
1.1.1.2 ! root      455: #include "sound/sb.h"
        !           456: #include "sound/gus.h"
1.1       root      457: 
                    458: void (*SND_Write)(void *buf, unsigned long size);  // Pointer to function that plays data on card
1.1.1.2 ! root      459: 
        !           460: void close_sound(void)
        !           461: {
        !           462: }
1.1       root      463: 
                    464: int init_sound (void)
                    465: {
                    466:     int rate;
                    467: 
                    468:     dspbits = sound_desired_bits;
                    469:     rate = sound_desired_freq;
1.1.1.2 ! root      470:     if ((rate != 22050) && (rate != 44100)) {
1.1       root      471:        fprintf(stderr, "Can't use sample rate %d!\n", rate);
                    472:        return 0;
                    473:     }
                    474:        
1.1.1.2 ! root      475:     if (GUS_Init(&dspbits, &rate, &sndbufsize));
        !           476:     else if (SB_DetectInitSound(&dspbits, &rate, &sndbufsize));
1.1       root      477:     else if (0/*OTHER_CARD_DETECT_ROUTINE*/);
                    478:     else
                    479:        return 0;
                    480:     
                    481:     eventtab[ev_sample].evtime = (long)maxhpos * maxvpos * 50 / rate;
                    482: 
                    483:     if (dspbits == 16) {
                    484:        init_sound_table16 ();
                    485:        eventtab[ev_sample].handler = sample16_handler;
                    486:     } else {
                    487:        init_sound_table8 ();
                    488:        eventtab[ev_sample].handler = sample8_handler;
                    489:     }
                    490:     sound_available = 1;
1.1.1.2 ! root      491:     fprintf(stderr, "Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
1.1       root      492:            dspbits, rate, sndbufsize);
1.1.1.2 ! root      493:     sndbufpt = sndbuffer;
1.1       root      494:     return 1;
                    495: }
                    496: 
                    497: static void flush_sound_buffer(void)
                    498: {
1.1.1.2 ! root      499:     SND_Write(sndbuffer, sndbufsize);
        !           500:     sndbufpt = sndbuffer;
1.1       root      501: }
                    502: 
                    503: #elif defined(SOLARIS_SOUND)
                    504: 
                    505: #include <sys/audioio.h>
                    506: 
                    507: static int sfd;
                    508: static int have_sound;
                    509: 
1.1.1.2 ! root      510: void close_sound(void)
        !           511: {
        !           512:     if (have_sound)
        !           513:        close(sfd);
        !           514: }
        !           515: 
1.1       root      516: int init_sound (void)
                    517: {
                    518:     int rate;
                    519: 
                    520:     struct audio_info sfd_info;
                    521: 
                    522:     sfd = open("/dev/audio", O_WRONLY);
                    523:     have_sound = !(sfd <0);
                    524:     if (!have_sound) {
                    525:         return 0;
                    526:     }
                    527:     
1.1.1.2 ! root      528:     if (sound_desired_bsiz < 128 || sound_desired_bsiz > 44100) {
        !           529:        fprintf(stderr, "Sound buffer size %d out of range.\n", sound_desired_bsiz);
        !           530:        sound_desired_bsiz = 8192;
        !           531:     }
        !           532: 
1.1       root      533:     rate = sound_desired_freq;
                    534:     dspbits = sound_desired_bits;
1.1.1.2 ! root      535:     AUDIO_INITINFO(&sfd_info);
1.1       root      536:     sfd_info.play.sample_rate = rate;
                    537:     sfd_info.play.channels = 1;
                    538:     sfd_info.play.precision = dspbits;
1.1.1.2 ! root      539:     sfd_info.play.encoding = (dspbits == 8 ) ? AUDIO_ENCODING_ULAW : AUDIO_ENCODING_LINEAR;
1.1       root      540:     if (ioctl(sfd, AUDIO_SETINFO, &sfd_info)) {
1.1.1.2 ! root      541:        fprintf(stderr, "Can't use sample rate %d with %d bits, %s!\n", rate, dspbits, (dspbits ==8) ? "ulaw" : "linear");
1.1       root      542:        return 0;
                    543:     }
                    544:     eventtab[ev_sample].evtime = (long)maxhpos * maxvpos * 50 / rate;
                    545: 
1.1.1.2 ! root      546:     init_sound_table16 ();
        !           547: 
        !           548:     if (dspbits == 8) {
        !           549:        eventtab[ev_sample].handler = sample_ulaw_handler;
1.1       root      550:     } else {
1.1.1.2 ! root      551:        eventtab[ev_sample].handler = sample16_handler;
1.1       root      552:     }
                    553: 
1.1.1.2 ! root      554:     sndbufpt = sndbuffer;
1.1       root      555:     smplcnt = 0;
                    556:     sound_available = 1;
1.1.1.2 ! root      557:     sndbufsize = sound_desired_bsiz;
        !           558:     printf ("Sound driver found and configured for %d bits, %s at %d Hz, buffer is %d bytes\n", dspbits, (dspbits ==8) ? "ulaw" : "linear", rate, sndbufsize);
1.1       root      559:     return 1;
                    560: }
                    561: 
                    562: static void flush_sound_buffer(void)
                    563: {
1.1.1.2 ! root      564:     write(sfd, sndbuffer, sndbufsize);
        !           565:     sndbufpt = sndbuffer;
1.1       root      566: }
                    567: 
                    568: 
1.1.1.2 ! root      569: #elif defined(AMIGA) && !defined(DONT_WANT_SOUND)
        !           570: /*
        !           571:  * Compared to Linux, AF_SOUND, and mac above, the AMIGA sound processing
        !           572:  * with OS routines is awfull. (sam)
        !           573:  */
        !           574: #define DEVICES_TIMER_H /* as there is a conflict on timeval */
        !           575: #include <proto/exec.h>
        !           576: #include <proto/alib.h>
        !           577: #include <proto/dos.h>
        !           578: 
        !           579: #include <exec/memory.h>
        !           580: #include <exec/devices.h>
        !           581: #include <exec/io.h>
        !           582: 
        !           583: #include <graphics/gfxbase.h>
        !           584: #include <devices/timer.h>
        !           585: #include <devices/audio.h>
        !           586: 
        !           587: static char whichchannel[]={1,2,4,8};
        !           588: static struct IOAudio *AudioIO;
        !           589: static struct MsgPort *AudioMP;
        !           590: static struct Message *AudioMSG;
        !           591: 
        !           592: static unsigned char *buffers[2];
        !           593: static UWORD *sndbuffer;
        !           594: static int bufidx, devopen;
        !           595: 
        !           596: static int have_sound, clockval, oldledstate, period;
        !           597: 
        !           598: int init_sound (void) 
        !           599: { /* too complex ? No it is only the allocation of a single channel ! */
        !           600:   /* it would have been far less painfull if AmigaOS provided a */
        !           601:   /* SOUND: device handler */
        !           602:     int rate;
        !           603: 
        !           604:     atexit(close_sound);
        !           605: 
        !           606:     if (sound_desired_bsiz < 2 || sound_desired_bsiz > (128*1024)) {
        !           607:        fprintf(stderr, "Sound buffer size %d out of range.\n", sound_desired_bsiz);
        !           608:        sound_desired_bsiz = 8192;
        !           609:     } 
        !           610:     sndbufsize = (sound_desired_bsiz + 1)&~1;
        !           611: 
        !           612:     /* get the buffers */
        !           613:     buffers[0] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR);
        !           614:     buffers[1] = (void*)AllocMem(sndbufsize,MEMF_CHIP|MEMF_CLEAR);
        !           615:     if(!buffers[0] || !buffers[1]) goto fail;
        !           616:     bufidx = 0;
        !           617:     sndbuffer = sndbufpt = (UWORD*)buffers[bufidx];
        !           618: 
        !           619:     /* determine the clock */
        !           620:     { 
        !           621:        struct GfxBase *GB;
        !           622:        GB = (void*)OpenLibrary("graphics.library",0L);
        !           623:        if(!GB) goto fail;
        !           624:        if (GB->DisplayFlags & PAL)
        !           625:            clockval = 3546895;        /* PAL clock */
        !           626:        else
        !           627:            clockval = 3579545;        /* NTSC clock */
        !           628:        CloseLibrary((void*)GB);
        !           629:     }
        !           630: 
        !           631:     if (!sound_desired_freq) sound_desired_freq = 1;
        !           632:     if (clockval/sound_desired_freq < 124 || clockval/sound_desired_freq > 65535) {
        !           633:        fprintf(stderr, "Can't use sound with desired frequency %d Hz\n", sound_desired_freq);
        !           634:         sound_desired_freq = 22000;
        !           635:     }
        !           636:     rate   = sound_desired_freq;
        !           637:     period = (UWORD)(clockval/rate);
        !           638: 
        !           639:     /* setup the stuff */
        !           640:     AudioMP = CreatePort(0,0);
        !           641:     if(!AudioMP) goto fail;
        !           642:     AudioIO = (struct IOAudio *)CreateExtIO(AudioMP, sizeof(struct IOAudio));
        !           643:     if(!AudioIO) goto fail;
        !           644: 
        !           645:     AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri /*pfew!!*/ = 85;
        !           646:     AudioIO->ioa_Data = whichchannel;
        !           647:     AudioIO->ioa_Length = sizeof(whichchannel);
        !           648:     AudioIO->ioa_AllocKey = 0;
        !           649:     if(OpenDevice(AUDIONAME, 0, (void*)AudioIO, 0)) goto fail;
        !           650:     devopen = 1;
        !           651: 
        !           652:     oldledstate = cia->ciapra & (1<<CIAB_LED);
        !           653:     cia->ciapra |= (1<<CIAB_LED);
        !           654: 
        !           655:     eventtab[ev_sample].evtime = (long)maxhpos * maxvpos * 50 / rate;
        !           656:     init_sound_table8 ();
        !           657:     eventtab[ev_sample].handler = sample8_handler;
        !           658: 
        !           659:     printf ("Sound driver found and configured for %d bits at %d Hz, buffer is %d bytes\n",
        !           660:             8, rate, sndbufsize);
        !           661: 
        !           662:     sound_available = 1;
        !           663:     return 1;
        !           664: fail:
        !           665:     sound_available = 0;
        !           666:     return 0;
        !           667: }
        !           668: 
        !           669: void close_sound(void)
        !           670: {
        !           671:     if(devopen) {CloseDevice((void*)AudioIO);devopen = 0;}
        !           672:     if(AudioIO) {DeleteExtIO((void*)AudioIO);AudioIO = NULL;}
        !           673:     if(AudioMP) {DeletePort((void*)AudioMP);AudioMP = NULL;}
        !           674:     if(buffers[0]) {FreeMem((APTR)buffers[0],sndbufsize);buffers[0] = 0;}
        !           675:     if(buffers[1]) {FreeMem((APTR)buffers[1],sndbufsize);buffers[1] = 0;}
        !           676:     if(sound_available) {
        !           677:        cia->ciapra = (cia->ciapra & ~(1<<CIAB_LED)) | oldledstate;
        !           678:        sound_available = 0;
        !           679:     }
        !           680: }
        !           681: 
        !           682: static void flush_sound_buffer(void)
        !           683: {
        !           684:     static char IOSent = 0;
        !           685:     AudioIO->ioa_Request.io_Command = CMD_WRITE;
        !           686:     AudioIO->ioa_Request.io_Flags   = ADIOF_PERVOL|IOF_QUICK;
        !           687:     AudioIO->ioa_Data               = (BYTE *)buffers[bufidx];
        !           688:     AudioIO->ioa_Length             = sndbufsize;
        !           689:     AudioIO->ioa_Period             = period;
        !           690:     AudioIO->ioa_Volume             = 64;
        !           691:     AudioIO->ioa_Cycles             = 1;
        !           692: 
        !           693:     if(IOSent) WaitIO((void*)AudioIO); else IOSent=1;
        !           694:     BeginIO((void*)AudioIO);
        !           695: 
        !           696:     /* double buffering */
        !           697:     bufidx = 1 - bufidx;
        !           698:     sndbuffer = sndbufpt = (UWORD*)buffers[bufidx];
        !           699: }
        !           700: 
        !           701: #elif !defined(__BEOS__)
1.1       root      702: 
                    703: int init_sound (void)
                    704: {
                    705:     produce_sound = 0;
                    706:     return 1;
                    707: }
                    708: 
1.1.1.2 ! root      709: void close_sound(void)
        !           710: {
        !           711: }
        !           712: 
1.1       root      713: static void flush_sound_buffer(void)
                    714: {
                    715: }
                    716: 
                    717: #endif
                    718: 
                    719: void AUDxDAT(int nr, UWORD v) 
                    720: {
                    721: #ifndef DONT_WANT_SOUND
                    722:     struct audio_channel_data *cdp = audio_channel + nr;
                    723:     cdp->dat = v;
                    724:     if (cdp->state == 0 && !(INTREQR() & (0x80 << nr))) {
                    725:        cdp->state = 2;
                    726:        INTREQ(0x8000 | (0x80 << nr));
                    727:        /* data_written = 2 ???? */
                    728:        eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
                    729:        eventtab[ev_aud0 + nr].oldcycles = cycles;
                    730:        eventtab[ev_aud0 + nr].active = 1;
                    731:        events_schedule();
                    732:     }
                    733: #endif
                    734: }
                    735: 
                    736: #ifndef DONT_WANT_SOUND
1.1.1.2 ! root      737: void sample16_handler(void)
1.1       root      738: {
                    739:     int nr;
                    740:     ULONG data = 0;
                    741: 
                    742:     eventtab[ev_sample].evtime += cycles - eventtab[ev_sample].oldcycles;
                    743:     eventtab[ev_sample].oldcycles = cycles;
                    744: 
                    745:     if (produce_sound < 2)
                    746:        return;
                    747: 
                    748:     for (nr = 0; nr < 4; nr++) {
                    749:        if (!(adkcon & (0x11 << nr)))
                    750:            data += sound_table[audio_channel[nr].current_sample][audio_channel[nr].vol];
                    751:     }
1.1.1.2 ! root      752:     *sndbufpt++ = data;
        !           753:     if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) {
1.1       root      754:        flush_sound_buffer();
                    755:     }
                    756: }
                    757: 
1.1.1.2 ! root      758: void sample8_handler(void)
1.1       root      759: {
                    760:     int nr;
                    761:     ULONG data = 0;
1.1.1.2 ! root      762:     unsigned char *bp = (unsigned char *)sndbufpt;
1.1       root      763:     
                    764:     eventtab[ev_sample].evtime += cycles - eventtab[ev_sample].oldcycles;
                    765:     eventtab[ev_sample].oldcycles = cycles;
                    766:     
                    767:     if (produce_sound < 2)
                    768:        return;
                    769: 
                    770:     for (nr = 0; nr < 4; nr++) {
                    771:        if (!(adkcon & (0x11 << nr)))
                    772:            data += sound_table[audio_channel[nr].current_sample][audio_channel[nr].vol];
                    773:     }
1.1.1.2 ! root      774: #ifdef AMIGA
        !           775:     *bp++ = (unsigned char) data;
        !           776: #else
1.1       root      777:     *bp++ = data + 128;
1.1.1.2 ! root      778: #endif
        !           779:     sndbufpt = (UWORD *)bp;
        !           780: 
        !           781:     if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) {
        !           782:        flush_sound_buffer();
        !           783:     }
        !           784: }
        !           785: 
        !           786: static char int2ulaw(int ch)
        !           787: {
        !           788:     int mask;
        !           789: 
        !           790:     if (ch < 0) {
        !           791:       ch = -ch;
        !           792:       mask = 0x7f;
        !           793:     }
        !           794:     else {
        !           795:       mask = 0xff;
        !           796:     }
        !           797: 
        !           798:     if (ch < 32) {
        !           799:        ch = 0xF0 | ( 15 - (ch/2) );
        !           800:     } else if (ch < 96) {
        !           801:         ch = 0xE0 | ( 15 - (ch-32)/4 );
        !           802:     } else if (ch < 224) {
        !           803:        ch = 0xD0 | ( 15 - (ch-96)/8 );
        !           804:     } else if (ch < 480) {
        !           805:        ch = 0xC0 | ( 15 - (ch-224)/16 );
        !           806:     } else if (ch < 992 ) {
        !           807:        ch = 0xB0 | ( 15 - (ch-480)/32 );
        !           808:     } else if (ch < 2016) {
        !           809:        ch = 0xA0 | ( 15 - (ch-992)/64 );
        !           810:     } else if (ch < 4064) {
        !           811:        ch = 0x90 | ( 15 - (ch-2016)/128 );
        !           812:     } else if (ch < 8160) {
        !           813:        ch = 0x80 | ( 15 - (ch-4064)/256 );
        !           814:     } else {
        !           815:        ch = 0x80;
        !           816:     }
        !           817:     return (char)(mask & ch);
        !           818: }
        !           819: 
        !           820: static void sample_ulaw_handler(void)
        !           821: {
        !           822:     int nr;
        !           823:     ULONG data = 0;
        !           824:     char *bp = (char *)sndbufpt;
        !           825: 
        !           826:     eventtab[ev_sample].evtime += cycles - eventtab[ev_sample].oldcycles;
        !           827:     eventtab[ev_sample].oldcycles = cycles;
        !           828: 
        !           829:     if (produce_sound < 2)
        !           830:        return;
        !           831: 
        !           832:     for (nr = 0; nr < 4; nr++) {
        !           833:        if (!(adkcon & (0x11 << nr)))
        !           834:            data += sound_table[audio_channel[nr].current_sample][audio_channel[nr].vol];
        !           835:     }
        !           836:     *bp++ = int2ulaw(data);
        !           837:     sndbufpt = (UWORD *)bp;
1.1       root      838: 
1.1.1.2 ! root      839:     if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) {
1.1       root      840:        flush_sound_buffer();
                    841:     }
                    842: }
                    843: 
                    844: static void audio_handler(int nr) 
                    845: {
                    846:     struct audio_channel_data *cdp = audio_channel + nr;
                    847: 
                    848:     switch (cdp->state) {
                    849:      case 0:
                    850:        fprintf(stderr, "Bug in sound code\n");
                    851:        break;
                    852: 
                    853:      case 1:
                    854:        /* We come here at the first hsync after DMA was turned on. */
                    855:        eventtab[ev_aud0 + nr].evtime += maxhpos;
                    856:        eventtab[ev_aud0 + nr].oldcycles += maxhpos;
                    857:        
                    858:        cdp->state = 5;
                    859:        INTREQ(0x8000 | (0x80 << nr));
                    860:        if (cdp->wlen != 1)
                    861:            cdp->wlen--;
                    862:        cdp->nextdat = chipmem_bank.wget(cdp->pt);
                    863:        cdp->pt += 2;
                    864:        break;
                    865: 
                    866:      case 5:
                    867:        /* We come here at the second hsync after DMA was turned on. */
                    868:        if (produce_sound == 0)
                    869:            cdp->per = 65535;
                    870: 
                    871:        eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
                    872:        eventtab[ev_aud0 + nr].oldcycles = cycles;
                    873:        cdp->dat = cdp->nextdat;
                    874:        cdp->current_sample = (UBYTE)(cdp->dat >> 8);
                    875:        cdp->state = 2;
                    876:        {
                    877:            int audav = adkcon & (1 << nr);
                    878:            int audap = adkcon & (16 << nr);
                    879:            int napnav = (!audav && !audap) || audav;
                    880:            if (napnav)
                    881:                cdp->data_written = 2;
                    882:        }
                    883:        break;
                    884:        
                    885:      case 2:
                    886:        /* We come here when a 2->3 transition occurs */
                    887:        if (produce_sound == 0)
                    888:            cdp->per = 65535;
                    889: 
                    890:        cdp->current_sample = (UBYTE)(cdp->dat & 0xFF);
                    891:        eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
                    892:        eventtab[ev_aud0 + nr].oldcycles = cycles;
                    893: 
                    894:        cdp->state = 3;
                    895: 
                    896:        /* Period attachment? */
                    897:        if (adkcon & (0x10 << nr)) {
                    898:            if (cdp->intreq2 && cdp->dmaen)
                    899:                INTREQ(0x8000 | (0x80 << nr));
                    900:            cdp->intreq2 = 0;
                    901: 
                    902:            cdp->dat = cdp->nextdat;
                    903:            if (cdp->dmaen)
                    904:                cdp->data_written = 2;
                    905:            if (nr < 3) {
                    906:                if (cdp->dat == 0)
                    907:                    (cdp+1)->per = 65535;
                    908: 
                    909:                else if (cdp->dat < maxhpos/2 && produce_sound < 3)
                    910:                    (cdp+1)->per = maxhpos/2;
                    911:                else
                    912:                    (cdp+1)->per = cdp->dat;
                    913:            }
                    914:        }
                    915:        break;
                    916:        
                    917:      case 3:
                    918:        /* We come here when a 3->2 transition occurs */
                    919:        if (produce_sound == 0)
                    920:            cdp->per = 65535;
                    921: 
                    922:        eventtab[ev_aud0 + nr].evtime = cycles + cdp->per;
                    923:        eventtab[ev_aud0 + nr].oldcycles = cycles;
                    924:        
                    925:        if ((INTREQR() & (0x80 << nr)) && !cdp->dmaen) {
                    926:            cdp->state = 0;
                    927:            cdp->current_sample = 0;
                    928:            eventtab[ev_aud0 + nr].active = 0;
                    929:            break;
                    930:        } else {
                    931:            int audav = adkcon & (1 << nr);
                    932:            int audap = adkcon & (16 << nr);
                    933:            int napnav = (!audav && !audap) || audav;
                    934:            cdp->state = 2;
                    935:            
                    936:            if ((cdp->intreq2 && cdp->dmaen && napnav)
                    937:                || (napnav && !cdp->dmaen))
                    938:                INTREQ(0x8000 | (0x80 << nr));
                    939:            cdp->intreq2 = 0;
                    940:            
                    941:            cdp->dat = cdp->nextdat;
                    942:            cdp->current_sample = (UBYTE)(cdp->dat >> 8);
                    943: 
                    944:            if (cdp->dmaen && napnav)
                    945:                cdp->data_written = 2;
                    946:            
                    947:            /* Volume attachment? */
                    948:            if (audav) {
                    949:                if (nr < 3)
                    950:                    (cdp+1)->vol = cdp->dat;
                    951:            }
                    952:        }
                    953:        break;
                    954:            
                    955:      default:
                    956:        cdp->state = 0;
                    957:        eventtab[ev_aud0 + nr].active = 0;
                    958:        break;
                    959:     }
                    960: }
                    961: 
                    962: void aud0_handler(void)
                    963: {
                    964:     audio_handler(0);
                    965: }
                    966: void aud1_handler(void)
                    967: {
                    968:     audio_handler(1);
                    969: }
                    970: void aud2_handler(void)
                    971: {
                    972:     audio_handler(2);
                    973: }
                    974: void aud3_handler(void)
                    975: {
                    976:     audio_handler(3);
                    977: }
                    978: #endif

unix.superglobalmegacorp.com

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