|
|
1.1 root 1: /*
2: * UAE - The Un*x Amiga Emulator
3: *
1.1.1.2 ! root 4: * Support for Amiga audio.device and AHI.device sound.
1.1 root 5: *
1.1.1.2 ! root 6: * Copyright 1996, 1997, 1998 Samuel Devulder, Holger Jakob (AHI)
1.1 root 7: */
8:
1.1.1.2 ! root 9: #ifdef HAVE_DEVICES_AHI_H
! 10: #define USE_AHIDEVICE
! 11: #ifdef FRAME_RATE_HACK
! 12: /* holger:In this mode emulation speed is adjusted with sound dma
! 13: and sound output delay does not depend on sndbufsize
! 14: #define AHI_DMA_MODE
! 15: */
1.1 root 16: #endif
1.1.1.2 ! root 17: #endif
1.1 root 18:
19: #include <exec/memory.h>
20: #include <exec/devices.h>
21: #include <exec/io.h>
22:
23: #include <graphics/gfxbase.h>
24: #include <devices/timer.h>
25: #include <devices/audio.h>
26:
1.1.1.2 ! root 27: #if defined(POWERUP)
! 28: #ifndef USE_CLIB
! 29: #include <powerup/ppcproto/exec.h>
! 30: #include <powerup/ppcproto/dos.h>
! 31: /* sam: no inline/alib.h on powerup, so use this instead :( */
! 32: static void BeginIO(struct IORequest *iorequest)
! 33: {
! 34: struct Caos MyCaos;
! 35: MyCaos.a1 = (ULONG) iorequest;
! 36: MyCaos.M68kCacheMode = IF_CACHEFLUSHALL;
! 37: MyCaos.PPCCacheMode = IF_CACHEFLUSHALL;
! 38: MyCaos.caos_Un.Offset = (-0x1e);
! 39: MyCaos.a6 = (ULONG) iorequest->io_Device;
! 40: PPCCallOS(&MyCaos);
! 41: }
! 42: #else
! 43: #include <clib/exec_protos.h>
! 44: #include <clib/alib_protos.h>
! 45: #endif
! 46: #else
! 47: #include <proto/exec.h>
! 48: #include <proto/dos.h>
! 49: #ifdef __GNUC__
! 50: #include <proto/alib.h>
! 51: #elif defined(__SASC)
! 52: #include <clib/alib_protos.h>
! 53: #endif
! 54: #endif
! 55:
! 56: #ifdef USE_AHIDEVICE
! 57: #include <devices/ahi.h>
! 58: extern struct AHIRequest *AHIio[];
! 59: extern struct AHIRequest *linkio;
! 60: #ifdef AHI_DMA_MODE
! 61: extern struct Library *AHIBase;
! 62: extern struct AHIAudioCtrl *actrl;
! 63: extern uae_u16 *sndbufptrmax;
! 64: #endif /* AHI_DMA_MODE */
! 65: #endif /* USE_AHI_DEVICE */
! 66:
1.1 root 67: extern char whichchannel[];
68: extern struct IOAudio *AudioIO;
69: extern struct MsgPort *AudioMP;
70: extern struct Message *AudioMSG;
71:
72: extern unsigned char *buffers[2];
73: extern uae_u16 *sndbuffer, *sndbufpt;
1.1.1.2 ! root 74: extern int bufidx, devopen,ahiopen;
1.1 root 75: extern int sndbufsize;
76:
77: extern int have_sound, clockval, oldledstate, period;
78:
79: extern ULONG AUDIO_FILE;
80:
81: static __inline__ void flush_sound_buffer(void)
82: {
83: if(AUDIO_FILE) {
1.1.1.2 ! root 84: Write(AUDIO_FILE,
! 85: sndbuffer = sndbufpt = (uae_u16*)buffers[bufidx],
! 86: sndbufsize);
! 87: } else if(ahiopen) {
! 88: #ifdef USE_AHIDEVICE
! 89: void *tmp;
! 90:
! 91: AHIio[bufidx]->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
! 92: AHIio[bufidx]->ahir_Std.io_Command = CMD_WRITE;
! 93: AHIio[bufidx]->ahir_Std.io_Data = buffers[bufidx];
! 94: AHIio[bufidx]->ahir_Std.io_Length = sndbufsize;
! 95: AHIio[bufidx]->ahir_Std.io_Offset = 0;
! 96: AHIio[bufidx]->ahir_Frequency = currprefs.sound_freq;
! 97: if( currprefs.stereo )
! 98: AHIio[bufidx]->ahir_Type = (currprefs.sound_bits==16) ?
! 99: AHIST_S16S : AHIST_S8S;
! 100: else
! 101: AHIio[bufidx]->ahir_Type = (currprefs.sound_bits==16) ?
! 102: AHIST_M16S : AHIST_M8S;
! 103: AHIio[bufidx]->ahir_Volume = 0x10000; /* Full volume */
! 104: AHIio[bufidx]->ahir_Position = 0x8000; /* Centered */
! 105: AHIio[bufidx]->ahir_Link = linkio;
! 106: SendIO((struct IORequest *) AHIio[bufidx]);
! 107:
! 108: if( linkio ) WaitIO((struct IORequest *) linkio);
! 109: linkio = AHIio[bufidx];
! 110: /* double buffering */
! 111: bufidx = 1 - bufidx;
! 112: sndbuffer = sndbufpt = (uae_u16*)buffers[bufidx];
! 113: #endif
! 114: } else {
1.1 root 115: static char IOSent = 0;
116:
117: AudioIO->ioa_Request.io_Command = CMD_WRITE;
118: AudioIO->ioa_Request.io_Flags = ADIOF_PERVOL|IOF_QUICK;
119: AudioIO->ioa_Data = (uae_s8 *)buffers[bufidx];
120: AudioIO->ioa_Length = sndbufsize;
121: AudioIO->ioa_Period = period;
122: AudioIO->ioa_Volume = 64;
123: AudioIO->ioa_Cycles = 1;
124:
125: if(IOSent) WaitIO((void*)AudioIO); else IOSent=1;
126: BeginIO((void*)AudioIO);
127:
128: /* double buffering */
129: bufidx = 1 - bufidx;
130: sndbuffer = sndbufpt = (uae_u16*)buffers[bufidx];
131: }
132: }
133:
134: static __inline__ void check_sound_buffers (void)
135: {
1.1.1.2 ! root 136: #ifndef AHI_DMA_MODE
1.1 root 137: if ((char *)sndbufpt - (char *)sndbuffer >= sndbufsize) {
138: flush_sound_buffer();
139: }
1.1.1.2 ! root 140: #endif
1.1 root 141: }
142:
1.1.1.2 ! root 143: #ifdef AHI_DMA_MODE
! 144: #define PUT_SOUND_BYTE(b) \
! 145: if (sndbufpt == sndbufptrmax) { \
! 146: sndbufpt = (uae_u16 *)buffers[0]; \
! 147: } \
! 148: *(uae_u8 *)sndbufpt = b; \
! 149: sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 1);
! 150:
! 151: #define PUT_SOUND_WORD(b) \
! 152: if (sndbufpt == sndbufptrmax) { \
! 153: sndbufpt = (uae_u16 *)buffers[0]; \
! 154: } \
! 155: *(uae_u16 *)sndbufpt = b; \
! 156: sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2);
! 157: #else
1.1 root 158: #define PUT_SOUND_BYTE(b) do { *(uae_u8 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 1); } while (0)
159: #define PUT_SOUND_WORD(b) do { *(uae_u16 *)sndbufpt = b; sndbufpt = (uae_u16 *)(((uae_u8 *)sndbufpt) + 2); } while (0)
1.1.1.2 ! root 160: #endif
! 161:
! 162: #ifdef USE_AHIDEVICE
! 163: #define HAVE_STEREO_SUPPORT
! 164: /* left and right channel on wrong side */
! 165: #define PUT_SOUND_BYTE_LEFT(b) PUT_SOUND_BYTE(b)
! 166: #define PUT_SOUND_WORD_LEFT(b) PUT_SOUND_WORD(b)
! 167: #define PUT_SOUND_BYTE_RIGHT(b) PUT_SOUND_BYTE(b)
! 168: #define PUT_SOUND_WORD_RIGHT(b) PUT_SOUND_WORD(b)
! 169: #endif
! 170:
1.1 root 171: #define SOUND16_BASE_VAL 0
172: #define SOUND8_BASE_VAL 0
173:
174: #define DEFAULT_SOUND_MAXB 8192
175: #define DEFAULT_SOUND_MINB 8192
176: #define DEFAULT_SOUND_BITS 16
177: #define DEFAULT_SOUND_FREQ 11025
178:
179: #undef DONT_WANT_SOUND
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.