|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.