|
|
1.1 ! root 1: ;*** ScR *** *** NOTESff *** ! 2: ! 3: ;* There is still room For improvements in the softint's. For example, ! 4: ;* try If reducing Chip memory accesses increases speed. NOT high priority, though. ! 5: ;* This driver should probably have a DMA play mode For 1-4 stereo channels. ! 6: ;* ! 7: ;* The sampler routines are just For fun. Since interrupts must NOT be disabled, ! 8: ;* there are lots of clicks. But still, I have tried To sample at 22kHz While down- ! 9: ;* loading files from a BBS On my A4000/040, AND it worked without any serial errors. ! 10: MC68020 ! 11: ;------------ ! 12: ! 13: VERSION EQU 4 ! 14: REVISION EQU 2 ! 15: DATE Macro ! 16: Dc.b "17.4.97" ! 17: ENDM ! 18: VERS Macro ! 19: Dc.b "uae 4.2" ! 20: ENDM ! 21: VSTRING Macro ! 22: VERS ! 23: Dc.b " (" ! 24: DATE ! 25: Dc.b ")",13,10,0 ! 26: ENDM ! 27: VERSTAG Macro ! 28: Dc.b 0,"$VER: " ! 29: VERS ! 30: Dc.b " (" ! 31: DATE ! 32: Dc.b ")",0 ! 33: ENDM ! 34: ! 35: incdir include: ! 36: ! 37: include hardware/all.i ! 38: ! 39: include exec/initializers.i ! 40: include exec/resident.i ! 41: include exec/alerts.i ! 42: include exec/memory.i ! 43: include graphics/gfxbase.i ! 44: include utility/utility.i ! 45: include utility/hooks.i ! 46: include devices/audio.i ! 47: include dos/dos.i ! 48: ! 49: ! 50: include lvos/exec_lib.i ! 51: include lvos/utility_lib.i ! 52: include lvos/dos_lib.i ! 53: include lvos/cardres_lib.i ! 54: ! 55: include devices/ahi.i ! 56: include libraries/ahi_sub.i ! 57: include lvos/ahi_sub_lib.i ! 58: ! 59: include resources/misc.i ! 60: include resources/card.i ! 61: include macros.i ! 62: ! 63: _ciaa EQU $bfe001 ! 64: _ciab EQU $bfd000 ! 65: ! 66: PALFREQ EQU 3546895 ! 67: NTSCFREQ EQU 3579545 ! 68: MINPER EQU 62 ! 69: ! 70: RECORDSAMPLES EQU 1024 ! 71: ! 72: ! 73: ! 74: ;* paula.audio extra tags ! 75: AHIDB_Paula14Bit EQU AHIDB_UserBase+0 * Boolean ! 76: AHIDB_PaulaTable EQU AHIDB_UserBase+1 * Boolean ! 77: ! 78: ;* paulaBase (private) ! 79: STRUCTURE paulaBase,LIB_SIZE ! 80: UBYTE pb_Flags ! 81: UBYTE pb_Pad1 ! 82: UWORD pb_Pad2 ! 83: APTR pb_SysLib ! 84: ULONG pb_SegList ! 85: APTR pb_GfxLib ! 86: APTR pb_UtilLib ! 87: APTR pb_DosLib ! 88: APTR pb_MiscResource ! 89: APTR pb_CardResource ! 90: LABEL paulaBase_SIZEOF ! 91: ! 92: ;* paula (private) ahiac_DriverData points to this structure. ! 93: STRUCTURE paula,0 ! 94: UBYTE p_Flags ! 95: UBYTE p_Parallel ;TRUE if pport allocated ! 96: UWORD p_DisableCount ! 97: APTR p_audioport ! 98: APTR p_audioreq ! 99: ULONG p_audiodev ! 100: APTR p_DMAbuffer ! 101: APTR p_ParBitsUser ! 102: APTR p_ParPortUser ! 103: APTR p_CardHandle ! 104: ! 105: STRUCT p_PlayInt,IS_SIZE ! 106: STRUCT p_PlaySoftInt,IS_SIZE ! 107: STRUCT p_RecInt,IS_SIZE ! 108: STRUCT p_RecSoftInt,IS_SIZE ! 109: ! 110: UWORD p_MonitorVolume ! 111: UWORD p_Input ! 112: ! 113: ;*** IS_DATA for Play Interrupt (do not change order!) ! 114: LABEL p_PlayIntData ! 115: APTR p_PlaySoftIntPtr ! 116: UWORD p_AudLen ;don't change order ! 117: ULONG p_AudPer ; ! 118: UWORD p_DoubleBufferFlag ! 119: APTR p_AudPtr1A ! 120: APTR p_AudPtr2A ! 121: APTR p_AudPtr3A ! 122: APTR p_AudPtr4A ! 123: APTR p_AudPtr1B ! 124: APTR p_AudPtr2B ! 125: APTR p_AudPtr3B ! 126: APTR p_AudPtr4B ! 127: ! 128: ;*** IS_DATA for Play Software Interrupt (do not change order!) ! 129: LABEL p_PlaySoftIntData ! 130: APTR p_PlayerHook ! 131: ULONG p_Reserved ! 132: APTR p_AudioCtrlP ! 133: FPTR p_PlayerEntry ;p_PlayerHook->h_Entry ! 134: FPTR p_PreTimer ! 135: FPTR p_PostTimer ! 136: ULONG p_LoopTimes ! 137: APTR p_MixHook ! 138: APTR p_Mixbuffer ! 139: APTR p_AudioCtrlM ! 140: FPTR p_MixEntry ;p_MixHook->h_Entry ! 141: APTR p_AudPtrs ! 142: APTR p_CalibrationTable ! 143: ! 144: ;*** IS_DATA for Aura Record Interrupt (do not change order!) ! 145: LABEL p_RecIntDataAura ! 146: APTR p_AuraAddress ! 147: ;*** IS_DATA for Paula Record Interrupt (do not change order!) ! 148: LABEL p_RecIntData ! 149: APTR p_RecFillPtr ! 150: UWORD p_RecFillCount ! 151: UWORD p_Pad3 ! 152: APTR p_RecBuffer1 ! 153: APTR p_RecBuffer2 ! 154: APTR p_RecSoftIntPtr ! 155: ! 156: LABEL p_RecordMessage ! 157: ULONG p_rmType ! 158: APTR p_rmBuffer ! 159: ULONG p_rmLength ! 160: ! 161: STRUCT p_CalibrationArray,256 ! 162: LABEL paula_SIZEOF ! 163: ! 164: ;* p_Flags ! 165: BITDEF P,14BIT,0 ! 166: PB_STEREO EQU AHIACB_STEREO ;=2 ! 167: PF_STEREO EQU AHIACF_STEREO ! 168: ! 169: Start: ! 170: MOVEQ #-1,d0 ! 171: RTS ! 172: ! 173: RomTag: ! 174: Dc.W RTC_MATCHWORD ! 175: Dc.L RomTag ! 176: Dc.L EndCode ! 177: Dc.B RTF_AUTOINIT ! 178: Dc.B VERSION ;version ! 179: Dc.B NT_LIBRARY ! 180: Dc.B 0 ;pri ! 181: Dc.L LibName ! 182: Dc.L IDString ! 183: Dc.L InitTable ! 184: ! 185: LibName: Dc.b "uae.audio",0 ! 186: IDString: VSTRING ! 187: gfxName: GRAPHICSNAME ! 188: utilName: UTILITYNAME ! 189: dosName: DOSNAME ! 190: miscName: MISCNAME ! 191: cardName: Dc.b "card.resource",0 ! 192: envVar: Dc.b "AHIpaulaFilterFreq",0 ! 193: cnop 0,2 ! 194: ! 195: InitTable: ! 196: Dc.L paulaBase_SIZEOF ! 197: Dc.L funcTable ! 198: Dc.L dataTable ! 199: Dc.L initRoutine ! 200: ! 201: funcTable: ! 202: Dc.l Open ! 203: Dc.l Close ! 204: Dc.l Expunge ! 205: Dc.l Null ! 206: ;* ! 207: Dc.l AHIsub_AllocAudio ! 208: Dc.l AHIsub_FreeAudio ! 209: Dc.l AHIsub_Disable ! 210: Dc.l AHIsub_Enable ! 211: Dc.l AHIsub_Start ! 212: Dc.l AHIsub_Update ! 213: Dc.l AHIsub_Stop ! 214: Dc.l AHIsub_SetVol ! 215: Dc.l AHIsub_SetFreq ! 216: Dc.l AHIsub_SetSound ! 217: Dc.l AHIsub_SetEffect ! 218: Dc.l AHIsub_LoadSound ! 219: Dc.l AHIsub_UnloadSound ! 220: Dc.l AHIsub_GetAttr ! 221: Dc.l AHIsub_HardwareControl ! 222: Dc.l -1 ! 223: ! 224: dataTable: ! 225: INITBYTE LN_TYPE,NT_LIBRARY ! 226: INITLONG LN_NAME,LibName ! 227: INITBYTE LIB_FLAGS,LIBF_SUMUSED!LIBF_CHANGED ! 228: INITWORD LIB_VERSION,VERSION ! 229: INITWORD LIB_REVISION,REVISION ! 230: INITLONG LIB_IDSTRING,IDString ! 231: Dc.L 0 ! 232: ! 233: initRoutine: ! 234: MOVEM.l d1/a0/a1/a5/a6,-(sp) ! 235: MOVE.l d0,a5 ! 236: MOVE.l a6,pb_SysLib(a5) ! 237: MOVE.l a0,pb_SegList(a5) ! 238: LEA gfxName(pc),a1 ! 239: MOVEQ #0,d0 ! 240: call OpenLibrary ! 241: MOVE.l d0,pb_GfxLib(a5) ! 242: BNE.b .gfxOK ! 243: ALERT AG_OpenLib!AO_GraphicsLib ! 244: MOVEQ #0,d0 ! 245: BRA .exit ! 246: .gfxOK ! 247: LEA utilName(pc),a1 ! 248: MOVEQ #0,d0 ! 249: call OpenLibrary ! 250: MOVE.l d0,pb_UtilLib(a5) ! 251: BNE.b .utilOK ! 252: ALERT AG_OpenLib!AO_UtilityLib ! 253: MOVEQ #0,d0 ! 254: BRA .exit ! 255: .utilOK ! 256: LEA dosName(pc),a1 ! 257: MOVEQ #0,d0 ! 258: call OpenLibrary ! 259: MOVE.l d0,pb_DosLib(a5) ! 260: BNE.b .dosOK ! 261: ALERT AG_OpenLib!AO_DOSLib ! 262: MOVEQ #0,d0 ! 263: BRA .exit ! 264: .dosOK ! 265: LEA miscName(pc),a1 ! 266: call OpenResource ! 267: MOVE.l d0,pb_MiscResource(a5) ! 268: BNE.b .miscOK ! 269: ALERT AG_OpenRes!AO_MiscRsrc ! 270: MOVEQ #0,d0 ! 271: BRA .exit ! 272: .miscOK ! 273: LEA cardName(pc),a1 ! 274: call OpenResource ! 275: MOVE.l d0,pb_CardResource(a5) ;Don't fail on error ! 276: ! 277: MOVE.l a5,d0 ! 278: .exit ! 279: MOVEM.l (sp)+,d1/a0/a1/a5/a6 ! 280: RTS ! 281: ! 282: Open: ! 283: MOVEQ #0,d0 ! 284: ADDQ.w #1,LIB_OPENCNT(a6) ! 285: BCLR.b #LIBB_DELEXP,pb_Flags(a6) ! 286: MOVE.l a6,d0 ! 287: .exit ! 288: RTS ! 289: ! 290: Close: ! 291: MOVEQ #0,d0 ! 292: SUBQ.w #1,LIB_OPENCNT(a6) ! 293: BNE.b .exit ! 294: BTST.b #LIBB_DELEXP,pb_Flags(a6) ! 295: BEQ.b .exit ! 296: BSR Expunge ! 297: .exit ! 298: RTS ! 299: ! 300: Expunge: ! 301: MOVEM.l d1/d2/a0/a1/a5/a6,-(sp) ! 302: MOVE.l a6,a5 ! 303: MOVE.l pb_SysLib(a5),a6 ! 304: TST.w LIB_OPENCNT(a5) ! 305: BEQ.b .notopen ! 306: BSET.b #LIBB_DELEXP,pb_Flags(a5) ! 307: MOVEQ #0,d0 ! 308: BRA.b .Expunge_end ! 309: .notopen ! 310: MOVE.l pb_GfxLib(a5),a1 ! 311: call CloseLibrary ! 312: ! 313: MOVE.l pb_UtilLib(a5),a1 ! 314: call CloseLibrary ! 315: ! 316: MOVE.l pb_DosLib(a5),a1 ! 317: call CloseLibrary ! 318: ! 319: MOVE.l pb_SegList(a5),d2 ! 320: MOVE.l a5,a1 ! 321: call Remove ! 322: ! 323: MOVEQ #0,d0 ! 324: MOVE.l a5,a1 ! 325: MOVE.w LIB_NEGSIZE(a5),d0 ! 326: SUB.l d0,a1 ! 327: ADD.w LIB_POSSIZE(a5),d0 ! 328: call FreeMem ! 329: MOVE.l d2,d0 ! 330: .Expunge_end ! 331: MOVEM.l (sp)+,d1/d2/a0/a1/a5/a6 ! 332: RTS ! 333: ! 334: Null: ! 335: MOVEQ #0,d0 ! 336: RTS ! 337: ! 338: ;* BeginIO(ioRequest)(a1) (From amiga.lib) ! 339: BeginIO: ! 340: MOVE.l a1,a0 ;probably not neccesary ! 341: push a6 ! 342: MOVE.l IO_DEVICE(a1),a6 ! 343: JSR -30(a6) ! 344: pop a6 ! 345: RTS ! 346: ! 347: ;****** [driver].audio/--background-- **************************************** ! 348: ;* ! 349: ;* OVERVIEW ! 350: ;* ! 351: ;* AUDIO ID NUMBERS ! 352: ;* ! 353: ;* Just some notes about selecting ID numbers for different modes: ! 354: ;* It is up to the driver programmer to chose which modes should be ! 355: ;* available to the user. Take care when selecting. ! 356: ;* The upper word is the hardware ID, and can only be allocated by ! 357: ;* Martin Blom <[email protected]>. The lower word is free, but in ! 358: ;* order to allow enhancements, please only use bit 0 to 3 for modes! ! 359: ;* Set the remaining bits to zero. ! 360: ;* The ID is currently used by AHI_BestAudioIDA() to select a mode. ! 361: ;* In order for this to work, you have to follow some rules. ! 362: ;* 7 Modes using tables should have higher IDs than modes that uses more ! 363: ;* CPU power. ! 364: ;* 7 Mono modes should have higher IDs than stereo modes ! 365: ;* 7 Stereo modes should have higher IDs than stereo modes with panning. ! 366: ;* Use AHI:Developer/Support/ScanAudioModes to have a look at the modes ! 367: ;* currently available. ! 368: ;* ! 369: ;* I do reserve the right to change the rules if I find them incorrect! ! 370: ;* ! 371: ;***************************************************************************** ! 372: ;* ! 373: ;* ! 374: ! 375: ;****** [driver].audio/AHIsub_AllocAudio ************************************* ! 376: ;* ! 377: ;* NAME ! 378: ;* AHIsub_AllocAudio -- Allocates and initializes the audio hardware. ! 379: ;* ! 380: ;* SYNOPSIS ! 381: ;* result = AHIsub_AllocAudio( tags, audioctrl); ! 382: ;* D0 A1 A2 ! 383: ;* ! 384: ;* ULONG AHIsub_AllocAudio( struct TagItem *, struct AHIAudioCtrlDrv * ); ! 385: ;* ! 386: ;* IMPLEMENTATION ! 387: ;* Allocate and initialize the audio hardware. Decide if and how you ! 388: ;* wish to use the mixing routines provided by 'ahi.device', by looking ! 389: ;* in the AHIAudioCtrlDrv structure and parsing the tag list for tags ! 390: ;* you support. ! 391: ;* ! 392: ;* 1) Use mixing routines with timing: ! 393: ;* You will need to be able to play any number of samples from ! 394: ;* about 80 up to 65535 with low overhead. ! 395: ;* 7 Update AudioCtrl->ahiac_MixFreq to nearest value that your ! 396: ;* hardware supports. ! 397: ;* 7 Return AHISF_MIXING|AHISF_TIMING. ! 398: ;* 2) Use mixing routines without timing: ! 399: ;* If the hardware can't play samples with any length, use this ! 400: ;* alternative and provide timing yourself. The buffer must ! 401: ;* take less than about 20 ms to play, preferable less than 10! ! 402: ;* 7 Update AudioCtrl->ahiac_MixFreq to nearest value that your ! 403: ;* hardware supports. ! 404: ;* 7 Store the number of samples to mix each pass in ! 405: ;* AudioCtrl->ahiac_BuffSamples. ! 406: ;* 7 Return AHISF_MIXING ! 407: ;* Alternatively, you can use the first method and call the ! 408: ;* mixing hook several times in a row to fill up a buffer. ! 409: ;* In that case, AHIsub_GetAttr(AHIDB_MaxPlaySamples) should ! 410: ;* return the size of the buffer plus AudioCtrl->ahiac_MaxBuffSamples. ! 411: ;* If the buffer is so large that it takes more than (approx.) 10 ms to ! 412: ;* play it for high sample frequencies, AHIsub_GetAttr(AHIDB_Realtime) ! 413: ;* should return FALSE. ! 414: ;* 3) Don't use mixing routines: ! 415: ;* If your hardware can handle everything without using the CPU to ! 416: ;* mix the channels, you tell 'ahi.device' this by not setting ! 417: ;* neither the AHISB_MIXING nor the AHISB_TIMING bit. ! 418: ;* ! 419: ;* If you can handle stereo output from the mixing routines, also set ! 420: ;* bit AHISB_KNOWSTEREO. ! 421: ;* ! 422: ;* If you can handle hifi (32 bit) output from the mixing routines, ! 423: ;* set bit AHISB_KNOWHIFI. ! 424: ;* ! 425: ;* If this driver can be used to record samples, set bit AHISB_CANRECORD, ! 426: ;* too (regardless if you use the mixing routines in AHI or not). ! 427: ;* ! 428: ;* If the sound card has hardware to do DSP effects, you can set the ! 429: ;* AHISB_CANPOSTPROCESS bit. The output from the mixing routines will ! 430: ;* then be two separate buffers, one wet and one dry. You should then ! 431: ;* apply the Fx on the wet buffer, and post-mix the two buffers before ! 432: ;* you send the samples to the DAC. (V4) ! 433: ;* ! 434: ;* INPUTS ! 435: ;* tags - pointer to a taglist. ! 436: ;* audioctrl - pointer to an AHIAudioCtrlDrv structure. ! 437: ;* ! 438: ;* TAGS ! 439: ;* The tags are from the audio database (AHIDB_#? in <devices/ahi.h>), ! 440: ;* NOT the tag list the user called ahi.device/AHI_AllocAudio() with. ! 441: ;* ! 442: ;* RESULT ! 443: ;* Flags, defined in <libraries/ahi_sub.h>. ! 444: ;* ! 445: ;* EXAMPLE ! 446: ;* ! 447: ;* NOTES ! 448: ;* You don't have to clean up on failure, AHIsub_FreeAudio() will ! 449: ;* always be called. ! 450: ;* ! 451: ;* BUGS ! 452: ;* ! 453: ;* SEE ALSO ! 454: ;* AHIsub_FreeAudio(), AHIsub_Start() ! 455: ;* ! 456: ;***************************************************************************** ! 457: ;* ! 458: ;* ! 459: ! 460: AHIsub_AllocAudio: ! 461: pushm d2-d7/a2-a6 ! 462: MOVE.l a6,a5 ! 463: ! 464: MOVE.l a1,d3 ! 465: ! 466: * Allocate the 'paula' structure (our variables) ! 467: MOVE.l pb_SysLib(a5),a6 ! 468: MOVE.l #paula_SIZEOF,d0 ! 469: MOVE.l #MEMF_PUBLIC|MEMF_CLEAR,d1 ! 470: call AllocVec ! 471: MOVE.l d0,ahiac_DriverData(a2) ! 472: BEQ .error_nopaula ! 473: MOVE.l d0,a3 ! 474: ! 475: * Initialize some Fields... ! 476: MOVE.l #-1,p_audiodev(a3) ! 477: MOVE.l #-1,p_ParBitsUser(a3) ! 478: MOVE.l #-1,p_ParPortUser(a3) ! 479: MOVE.l a2,p_AudioCtrlP(a3) ;player Hook ! 480: MOVE.l a2,p_AudioCtrlM(a3) ;mixer Hook ! 481: LEA p_PlaySoftInt(a3),a0 ! 482: MOVE.l a0,p_PlaySoftIntPtr(a3) ! 483: LEA p_RecSoftInt(a3),a0 ! 484: MOVE.l a0,p_RecSoftIntPtr(a3) ! 485: MOVE.l #AHIST_S16S,p_rmType(a3) ! 486: MOVE.l #RECORDSAMPLES,p_rmLength(a3) ! 487: ! 488: * Translate Tags To flags ! 489: MOVEQ #0,d2 ! 490: MOVE.l pb_UtilLib(a5),a6 ! 491: MOVE.l #AHIDB_Paula14Bit,d0 ! 492: MOVEQ #0,d1 ! 493: MOVE.l d3,a0 ;tag list ! 494: call GetTagData ! 495: TST.l d0 ! 496: BEQ.b .no14bit ! 497: MOVEQ #PF_14BIT,d2 ! 498: .no14bit ! 499: MOVE.l ahiac_Flags(a2),d0 ! 500: AND.b #PF_STEREO,d0 ;same as AHIACF_STEREO ! 501: OR.b d2,d0 ! 502: MOVE.b p_Flags(a3),d1 ! 503: AND.b #~(PF_STEREO|PF_14BIT),d1 ! 504: OR.b d0,d1 ! 505: MOVE.b d1,p_Flags(a3) ! 506: ! 507: * Check If a table should be Used (14 bit calibration) ! 508: MOVE.l #AHIDB_PaulaTable,d0 ! 509: MOVEQ #0,d1 ! 510: MOVE.l d3,a0 ;tag list ! 511: call GetTagData ! 512: TST.l d0 ! 513: BEQ .notable ! 514: ! 515: * Load 'ENV:CyberSound/SoundDrivers/14Bit_Calibration', allocate ! 516: * AND initialize the table. ! 517: * FIXIT: The calibration File should MOVE To a special chunk in ! 518: * 'DEVS:AudioModes/PAULA'. ! 519: MOVE.l pb_DosLib(a5),a6 ! 520: LEA .calibname(pc),a0 ! 521: MOVE.l a0,d1 ! 522: MOVE.l #MODE_OLDFILE,d2 ! 523: call Open ! 524: MOVE.l d0,d4 ! 525: BEQ .nocalib ! 526: MOVE.l d0,d1 ! 527: LEA p_CalibrationArray(a3),a0 ! 528: MOVE.l a0,d2 ! 529: MOVE.l #256,d3 ! 530: call Read ! 531: CMP.l d0,d3 ! 532: BEQ .tableloaded ! 533: .nocalib ! 534: ; Fill defaults ! 535: LEA p_CalibrationArray(a3),a0 ! 536: MOVE.w #254-1,d0 ! 537: .initcalib ! 538: MOVE.b #$55,(a0)+ ! 539: DBF d0,.initcalib ! 540: MOVE.b #$7f,(a0)+ ! 541: .tableloaded ! 542: MOVE.l d4,d1 ! 543: BEQ.b .nofile ! 544: call Close ! 545: .nofile ! 546: MOVE.l pb_SysLib(a5),a6 ! 547: MOVE.l #65536*2,d0 ! 548: MOVE.l #MEMF_PUBLIC,d1 ! 549: call AllocVec ! 550: MOVE.l d0,p_CalibrationTable(a3) ! 551: BEQ.b .notable ! 552: MOVE.l d0,a0 ;table ! 553: LEA p_CalibrationArray(a3),a1 ! 554: BSR.w _CreateTable ! 555: .notable ! 556: ! 557: ! 558: * allocate audio.device ! 559: MOVE.l pb_SysLib(a5),a6 ! 560: call CreateMsgPort ! 561: MOVE.l d0,p_audioport(a3) ! 562: BEQ .error_noport ! 563: MOVEQ #ioa_SIZEOF,d0 ! 564: MOVE.l #MEMF_PUBLIC!MEMF_CLEAR,d1 ! 565: call AllocVec ! 566: MOVE.l d0,p_audioreq(a3) ! 567: BEQ .error_noreqmem ! 568: MOVE.l d0,a0 ! 569: MOVE.l p_audioport(a3),MN_REPLYPORT(a0) ! 570: CLR.w ioa_AllocKey(a0) ! 571: MOVE.b #127,LN_PRI(a0) ;steal it! ! 572: LEA .audiochannelarray(pc),a1 ! 573: MOVE.l a1,ioa_Data(a0) ! 574: MOVE.l #1,ioa_Length(a0) ! 575: LEA .audioname(pc),a0 ! 576: MOVEQ #0,d0 ! 577: MOVE.l p_audioreq(a3),a1 ! 578: MOVEQ #0,d1 ! 579: call OpenDevice ! 580: MOVE.l d0,p_audiodev(a3) ! 581: BNE .error_noaudiodev ;somebody already owns the hardware (could be us!) ! 582: MOVE.l p_audioreq(a3),a1 ;bernd#1 ! 583: MOVE.w #CMD_RESET,IO_COMMAND(a1) ! 584: BSR.w BeginIO ;clear attach, stop sound. ! 585: MOVE.l p_audioport(a3),a0 ! 586: call WaitPort ! 587: MOVE.l p_audioport(a3),a0 ! 588: call GetMsg ! 589: ! 590: MOVE.l pb_DosLib(a5),a6 ! 591: MOVEQ #1,d1 ! 592: call Delay ! 593: ! 594: * test If mode supports recording ! 595: BTST #PB_14BIT,p_Flags(a3) ! 596: BNE .dontgetsampler ;no record if 14 bit mode ! 597: ! 598: * try To allocate parallel port ! 599: CLR.b p_Parallel(a3) ! 600: MOVE.l pb_MiscResource(a5),a6 ! 601: MOVEQ #MR_PARALLELBITS,d0 ! 602: LEA IDString(pc),a1 ! 603: JSR MR_ALLOCMISCRESOURCE(a6) ! 604: MOVE.l d0,p_ParBitsUser(a3) ! 605: BNE .no_parrallel ! 606: MOVEQ #MR_PARALLELPORT,d0 ! 607: LEA IDString(pc),a1 ! 608: JSR MR_ALLOCMISCRESOURCE(a6) ! 609: MOVE.l d0,p_ParPortUser(a3) ! 610: BNE .no_parrallel ! 611: ! 612: MOVE.b #TRUE,p_Parallel(a3) ! 613: ;move.b #0,_ciaa+ciaddrb ;make PB0-PB7 inputs ! 614: .no_parrallel ! 615: ! 616: ;* allocate Aura sampler ! 617: CLR.l p_AuraAddress(a3) ! 618: MOVE.l pb_CardResource(a5),d0 ! 619: BEQ .no_aura ! 620: MOVE.l d0,a6 ! 621: call GetCardMap ! 622: TST.l d0 ! 623: BEQ .no_aura ! 624: MOVE.l d0,a0 ! 625: MOVE.l cmm_IOMemory(a0),d2 ! 626: BEQ .no_aura ! 627: ! 628: base exec ! 629: MOVEQ #CardHandle_SIZEOF,d0 ! 630: MOVE.l #MEMF_PUBLIC|MEMF_CLEAR,d1 ! 631: call AllocVec ! 632: MOVE.l d0,p_CardHandle(a3) ! 633: BEQ .no_aura ! 634: ! 635: MOVE.l pb_CardResource(a5),a6 ! 636: MOVE.l d0,a1 ! 637: MOVE.l #IDString,LN_NAME(a1) ! 638: MOVE.b #CARDF_RESETREMOVE|CARDF_IFAVAILABLE,cah_CardFlags(a1) ! 639: call OwnCard ! 640: TST.l d0 ! 641: BNE .no_aura ! 642: ! 643: MOVE.l p_CardHandle(a3),a1 ! 644: call BeginCardAccess ! 645: TST.l d0 ! 646: BEQ .no_aura ! 647: ! 648: MOVE.l d2,p_AuraAddress(a3) ! 649: .no_aura ! 650: .dontgetsampler ! 651: ! 652: ! 653: ;* initialize interrupts (Only dummy function pointers at this time) ! 654: ! 655: ;* p_PlayInt (the main playback interrupt) ! 656: MOVE.b #NT_INTERRUPT,LN_TYPE+p_PlayInt(a3) ! 657: MOVE.l #LibName,LN_NAME+p_PlayInt(a3) ! 658: MOVE.l #Interrupt_Dummy,IS_CODE+p_PlayInt(a3) ! 659: LEA p_PlayIntData(a3),a1 ! 660: MOVE.l a1,IS_DATA+p_PlayInt(a3) ! 661: ! 662: ;* p_PlaySoftInt (caused by p_PlayInt, here are the mixing and conversion done) ! 663: MOVE.b #NT_INTERRUPT,LN_TYPE+p_PlaySoftInt(a3) ! 664: MOVE.l #LibName,LN_NAME+p_PlaySoftInt(a3) ! 665: MOVE.l #SoftInt_Dummy,IS_CODE+p_PlaySoftInt(a3) ! 666: LEA p_PlaySoftIntData(a3),a1 ! 667: MOVE.l a1,IS_DATA+p_PlaySoftInt(a3) ! 668: ! 669: ;* p_RecInt (the interrupt used for recording) ! 670: MOVE.b #NT_INTERRUPT,LN_TYPE+p_RecInt(a3) ! 671: MOVE.l #LibName,LN_NAME+p_RecInt(a3) ! 672: MOVE.l #Interrupt_Dummy,IS_CODE+p_RecInt(a3) ! 673: CLR.l IS_DATA+p_RecInt(a3) ! 674: ! 675: ;* p_RecSoftInt (caused by p_RecInt when the record buffer has been filled) ! 676: MOVE.b #32,LN_PRI+p_RecSoftInt(a3) ! 677: MOVE.b #NT_INTERRUPT,LN_TYPE+p_RecSoftInt(a3) ! 678: MOVE.l #LibName,LN_NAME+p_RecSoftInt(a3) ! 679: MOVE.l #RecordSoftInt,IS_CODE+p_RecSoftInt(a3) ! 680: MOVE.l a3,IS_DATA+p_RecSoftInt(a3) ! 681: ! 682: ;* Make sure no interrupts occur until AHIsub_Start() is called ! 683: MOVE.w #INTF_AUD0!INTF_AUD1!INTF_AUD2!INTF_AUD3,CUSTOM+INTENA ! 684: ! 685: ;* Update ahiac_MixFreq to what the mixing/sampling frequency really is ! 686: MOVE.l ahiac_MixFreq(a2),d1 ! 687: BSR calcperiod ! 688: MOVE.l d0,ahiac_MixFreq(a2) ;store actual freq ! 689: ! 690: MOVEQ #AHISB_KNOWHIFI|AHISF_KNOWSTEREO|AHISF_CANRECORD|AHISF_MIXING|AHISF_TIMING,d0 ! 691: .exit ! 692: popm d2-d7/a2-a6 ! 693: RTS ! 694: ! 695: .error_noaudiodev ! 696: .error_noreqmem ! 697: .error_noport ! 698: .error_nopaula ! 699: MOVEQ #AHISF_ERROR,d0 ! 700: BRA.b .exit ! 701: ! 702: .audiochannelarray ! 703: Dc.b 1+2+4+8 ! 704: .audioname ! 705: AUDIONAME ! 706: .calibname ! 707: Dc.b "ENV:CyberSound/SoundDrivers/14Bit_Calibration",0 ! 708: Even ! 709: .cardhandle: ! 710: Dc.l 0,0 ;ln_Succ, ln_Pred ! 711: Dc.b 0 ;ln_Type ! 712: Dc.b 0 ;ln_Pri ! 713: Dc.l IDString ;ln_Name ! 714: Dc.l 0,0,0 ;cah_CardRemoved, cah_CardInserted, cah_CardStatus ! 715: Dc.b (CARDF_RESETREMOVE|CARDF_IFAVAILABLE) ! 716: Even ! 717: ! 718: ;in: ! 719: ;* d1 MixFreq ! 720: ;* a5 paulaBase ! 721: ;out: ! 722: ;* d0 New MixFreq ! 723: ;* d1.w Period ! 724: ;description: ! 725: ;* Calculate and return the best period and the actual frequency. ! 726: calcperiod: ! 727: pushm d2-d5 ! 728: move.l d1,d5 ! 729: MOVE.l #0,d0 ! 730: jsr $F0FFB0 ! 731: MOVE.l d0,d1 ! 732: MOVE.l #1,d0 ! 733: jsr $F0FFB0 ! 734: ; now, d0 contains the divisor UAE uses for its output frequency. ! 735: ; d1 contains the nominal output frequency of UAE. ! 736: ; Multiply the two and divide by desired frequency (which we'll ! 737: ; assume to be 44100 Hz), and we get the necessary divider ! 738: MOVE.l pb_UtilLib(a5),a1 ! 739: jsr _LVOUMult32(a1) ! 740: MOVE.l #44100,d5 ; @@@ potentially change this ! 741: MOVE.l d5,d1 ! 742: jsr _LVOUDivMod32(a1) ! 743: MOVE.l d0,d1 ! 744: MOVE.l d5,d0 ! 745: popm d2-d5 ! 746: RTS ! 747: ! 748: ;in: ! 749: * d0 Frequency ! 750: ;out: ! 751: * d0 Closest frequency ! 752: * d1 Index ! 753: findfreq: ! 754: LEA uae(pc),a0 ! 755: CMP.l (a0),d0 ! 756: BLS.b .2 ! 757: .findfreq ! 758: CMP.l (a0)+,d0 ! 759: BHI.b .findfreq ! 760: MOVE.l -4(a0),d1 ! 761: SUB.l d0,d1 ! 762: SUB.l -8(a0),d0 ! 763: CMP.l d1,d0 ! 764: bhs.b .1 ! 765: SUBQ.l #4,a0 ! 766: .1 ! 767: SUBQ.l #4,a0 ! 768: .2 ! 769: MOVE.l (a0),d0 ! 770: MOVE.l a0,d1 ! 771: SUB.l #uae,d1 ! 772: LSR.l #2,d1 ! 773: RTS ! 774: ! 775: freqlist: ! 776: Dc.l 4410 ; CD/10 ! 777: Dc.l 4800 ; DAT/10 ! 778: Dc.l 5513 ; CD/8 ! 779: Dc.l 6000 ; DAT/8 ! 780: Dc.l 7350 ; CD/6 ! 781: Dc.l 8000 ; 5- and A-Law, DAT/6 ! 782: Dc.l 9600 ; DAT/5 ! 783: Dc.l 11025 ; CD/4 ! 784: Dc.l 12000 ; DAT/4 ! 785: Dc.l 14700 ; CD/3 ! 786: Dc.l 16000 ; DAT/3 ! 787: Dc.l 17640 ; CD/2.5 ! 788: Dc.l 18900 ! 789: Dc.l 19200 ; DAT/2.5 ! 790: Dc.l 22050 ; CD/2 ! 791: Dc.l 24000 ; DAT/2 ! 792: Dc.l 27429 ! 793: FREQUENCIES_OCS EQU (*-freqlist) ! 794: Dc.l 29400 ; CD/1.5 ! 795: uae Dc.l 32000 ; DAT/1.5 ! 796: ;dc.l 33075 ! 797: ;dc.l 37800 ! 798: Dc.l 44100 ; CD ! 799: ;dc.l 48000 ; DAT ! 800: FREQUENCIES EQU (*-uae) ! 801: Dc.l -1 ! 802: ! 803: * _CreateTable directly stolen from Christian Buchner's CyberSound ! 804: * audio SUB system (with permission). ! 805: ! 806: * _CreateTable ************************************************************** ! 807: ! 808: ; Parameters ! 809: ! 810: ; a0 = Table address ! 811: ; (MUST have enough space for 65536 UWORDS) ! 812: ; a1 = Additive Array ! 813: ; 256 UBYTEs ! 814: ; ! 815: ; the table is organized as follows: ! 816: ; 32768 UWORDS positive range, ascending order ! 817: ; 32768 UWORDS negative range, ascending order ! 818: ; access: (a0,d0.l*2) ! 819: ; where d0.w is signed word sample data ! 820: ; and the upper word of d0.l is *cleared!* ! 821: ! 822: ! 823: _CreateTable MOVEM.l a2/d2-d6,-(sp) ! 824: ! 825: LEA 128(a1),a2 ! 826: ! 827: MOVE.l a2,a1 ; count the number of steps ! 828: MOVEQ #128-1,d0 ; in the positive range ! 829: MOVEQ #0,d5 ! 830: .countpositive MOVE.b (a1)+,d1 ! 831: EXT.w d1 ! 832: EXT.l d1 ! 833: ADD.l d1,d5 ! 834: DBRA d0,.countpositive ; d5=number of steps ! 835: MOVE.l #32768,d6 ; reset stretch counter ! 836: ! 837: MOVE.l a2,a1 ; middle value in calibdata ! 838: MOVE.w #32768-1,d0 ; number of positive values -1 ! 839: MOVEQ #0,d1 ; HI value ! 840: MOVEQ #0,d2 ; LO value ! 841: MOVEQ #0,d3 ; counter ! 842: .fetchnext2 MOVE.b (a1)+,d4 ; add calibtable to counter ! 843: EXT.w d4 ! 844: ADD.w d4,d3 ! 845: .outerloop2 TST.w d3 ! 846: BGT.s .positive2 ! 847: .negative2 ADDQ.w #1,d1 ; increment HI value ! 848: SUB.w d4,d2 ; reset LO value ! 849: BRA.s .fetchnext2 ! 850: .positive2 MOVE.b d1,(a0)+ ; store HI and LO value ! 851: MOVE.b d2,(a0)+ ! 852: SUB.l d5,d6 ; stretch the table ! 853: BPL.s .repeat2 ; to 32768 entries ! 854: ADD.l #32768,d6 ! 855: ADDQ.w #1,d2 ; increment LO value ! 856: SUBQ.w #1,d3 ; decrement counter ! 857: .repeat2 DBRA d0,.outerloop2 ! 858: ! 859: MOVE.l a2,a1 ; count the number of steps ! 860: MOVEQ #128-1,d0 ; in the negative range ! 861: MOVEQ #0,d5 ! 862: .countnegative MOVE.b -(a1),d1 ! 863: EXT.w d1 ! 864: EXT.l d1 ! 865: ADD.l d1,d5 ! 866: DBRA d0,.countnegative ; d5=number of steps ! 867: MOVE.l #32768,d6 ; reset stretch counter ! 868: ! 869: ADD.l #2*32768,a0 ; place at the end of the table ! 870: MOVE.l a2,a1 ; middle value in calibdata ! 871: MOVE.w #32768-1,d0 ; number of negative values -1 ! 872: MOVEQ #-1,d1 ; HI value ! 873: MOVEQ #-1,d2 ; LO value ! 874: MOVEQ #0,d3 ; counter ! 875: .fetchnext1 MOVE.b -(a1),d4 ; add calibtable to counter ! 876: EXT.w d4 ! 877: ADD.w d4,d3 ! 878: ADD.w d4,d2 ; maximize LO value ! 879: .outerloop1 TST.w d3 ! 880: BGT.s .positive1 ! 881: .negative1 SUBQ.w #1,d1 ! 882: BRA.s .fetchnext1 ! 883: .positive1 MOVE.b d2,-(a0) ; store LO and HI value ! 884: MOVE.b d1,-(a0) ! 885: SUB.l d5,d6 ; stretch the table ! 886: BPL.s .repeat1 ; to 32768 entries ! 887: ADD.l #32768,d6 ! 888: SUBQ.w #1,d2 ; decrement lo value ! 889: SUBQ.w #1,d3 ; decrement counter ! 890: .repeat1 DBRA d0,.outerloop1 ! 891: ! 892: MOVEM.l (sp)+,a2/d2-d6 ! 893: RTS ! 894: ! 895: ! 896: ****** [driver].audio/AHIsub_FreeAudio ************************************** ! 897: * ! 898: * NAME ! 899: * AHIsub_FreeAudio -- Deallocates the audio hardware. ! 900: * ! 901: * SYNOPSIS ! 902: * AHIsub_FreeAudio( audioctrl ); ! 903: * A2 ! 904: * ! 905: * void AHIsub_FreeAudio( struct AHIAudioCtrlDrv * ); ! 906: * ! 907: * IMPLEMENTATION ! 908: * Deallocate the audio hardware AND other resources allocated in ! 909: * AHIsub_AllocAudio(). AHIsub_Stop() will always be called by ! 910: * 'ahi.device' before this Call is made. ! 911: * ! 912: * INPUTS ! 913: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 914: * ! 915: * NOTES ! 916: * It must be safe To Call this routine Even If AHIsub_AllocAudio() ! 917: * was never called, failed OR called more than once. ! 918: * ! 919: * SEE ALSO ! 920: * AHIsub_AllocAudio() ! 921: * ! 922: ***************************************************************************** ! 923: * ! 924: * ! 925: ! 926: AHIsub_FreeAudio: ! 927: pushm d2-d7/a2-a6 ! 928: ! 929: MOVE.l a6,a5 ! 930: MOVE.l pb_SysLib(a5),a6 ! 931: ! 932: MOVE.l ahiac_DriverData(a2),d0 ! 933: BEQ .nopaula ! 934: MOVE.l d0,a3 ! 935: ! 936: MOVE.l p_CalibrationTable(a3),d0 ! 937: BEQ.b .notable ! 938: MOVE.l d0,a1 ! 939: call FreeVec ! 940: .notable ! 941: TST.l p_audiodev(a3) ! 942: BNE.b .noaudiodev ! 943: MOVE.l p_audioreq(a3),a1 ;bernd#1 ! 944: MOVE.w #CMD_RESET,IO_COMMAND(a1) ;Restore audio interrupts ! 945: BSR.w BeginIO ! 946: MOVE.l p_audioport(a3),a0 ! 947: call WaitPort ! 948: MOVE.l p_audioport(a3),a0 ! 949: call GetMsg ! 950: MOVE.l p_audioreq(a3),a1 ! 951: SUBQ.l #1,p_audiodev(a3) ! 952: call CloseDevice ! 953: .noaudiodev ! 954: MOVE.l p_audioreq(a3),d0 ! 955: BEQ.b .noaudioreq ! 956: MOVE.l d0,a1 ! 957: call FreeVec ! 958: .noaudioreq ! 959: MOVE.l p_audioport(a3),d0 ! 960: BEQ.b .noaudioport ! 961: MOVE.l d0,a0 ! 962: call DeleteMsgPort ! 963: .noaudioport ! 964: MOVE.l pb_CardResource(a5),d0 ! 965: BEQ .noaura ! 966: MOVE.l d0,a6 ! 967: MOVE.l p_CardHandle(a3),d0 ! 968: BEQ .noaura ! 969: MOVE.l d0,a1 ! 970: call EndCardAccess ! 971: MOVE.l p_CardHandle(a3),a1 ! 972: MOVEQ #CARDF_REMOVEHANDLE,d0 ! 973: call ReleaseCard ! 974: .noaura ! 975: MOVE.l pb_SysLib(a5),a6 ! 976: MOVE.l p_CardHandle(a3),d0 ! 977: BEQ .nocardhandle ! 978: MOVE.l d0,a1 ! 979: call FreeVec ! 980: .nocardhandle ! 981: MOVE.l pb_MiscResource(a5),a6 ! 982: TST.l p_ParPortUser(a3) ! 983: BNE.b .noparport ! 984: MOVEQ #MR_PARALLELPORT,d0 ! 985: JSR MR_FREEMISCRESOURCE(a6) ! 986: .noparport ! 987: TST.l p_ParBitsUser(a3) ! 988: BNE.b .noparbits ! 989: MOVEQ #MR_PARALLELBITS,d0 ! 990: JSR MR_FREEMISCRESOURCE(a6) ! 991: .noparbits ! 992: MOVE.l pb_SysLib(a5),a6 ! 993: MOVE.l a3,a1 ! 994: CLR.l ahiac_DriverData(a2) ! 995: call FreeVec ! 996: .nopaula ! 997: MOVEQ #0,d0 ! 998: popm d2-d7/a2-a6 ! 999: RTS ! 1000: ! 1001: ! 1002: ****** [driver].audio/AHIsub_Disable **************************************** ! 1003: * ! 1004: * NAME ! 1005: * AHIsub_Disable -- Temporary turn Off audio interrupt/task ! 1006: * ! 1007: * SYNOPSIS ! 1008: * AHIsub_Disable( audioctrl ); ! 1009: * A2 ! 1010: * ! 1011: * void AHIsub_Disable( struct AHIAudioCtrlDrv * ); ! 1012: * ! 1013: * IMPLEMENTATION ! 1014: * If you are lazy, Then Call exec.library/Disable(). ! 1015: * If you are smart, only Disable your own interrupt OR task. ! 1016: * ! 1017: * INPUTS ! 1018: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 1019: * ! 1020: * NOTES ! 1021: * This Call should be guaranteed To preserve all registers. ! 1022: * This Call nests. ! 1023: * ! 1024: * SEE ALSO ! 1025: * AHIsub_Enable(), exec.library/Disable() ! 1026: * ! 1027: ***************************************************************************** ! 1028: * ! 1029: * ! 1030: ! 1031: AHIsub_Disable: ! 1032: push a3 ! 1033: MOVE.l ahiac_DriverData(a2),a3 ! 1034: ADDQ.w #1,p_DisableCount(a3) ! 1035: MOVE.w #INTF_AUD0,CUSTOM+INTENA ! 1036: ; moveq #2,d0 ! 1037: ; moveq #0,d1 ! 1038: ; jsr.l $f0ffb0 ! 1039: pop a3 ! 1040: RTS ! 1041: ! 1042: ****** [driver].audio/AHIsub_Enable ***************************************** ! 1043: * ! 1044: * NAME ! 1045: * AHIsub_Enable -- Turn On audio interrupt/task ! 1046: * ! 1047: * SYNOPSIS ! 1048: * AHIsub_Enable( audioctrl ); ! 1049: * A2 ! 1050: * ! 1051: * void AHIsub_Enable( struct AHIAudioCtrlDrv * ); ! 1052: * ! 1053: * IMPLEMENTATION ! 1054: * If you are lazy, Then Call exec.library/Enable(). ! 1055: * If you are smart, only Enable your own interrupt OR task. ! 1056: * ! 1057: * INPUTS ! 1058: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 1059: * ! 1060: * NOTES ! 1061: * This Call should be guaranteed To preserve all registers. ! 1062: * This Call nests. ! 1063: * ! 1064: * SEE ALSO ! 1065: * AHIsub_Disable(), exec.library/Enable() ! 1066: * ! 1067: ***************************************************************************** ! 1068: * ! 1069: * ! 1070: ! 1071: AHIsub_Enable: ! 1072: push a3 ! 1073: MOVE.l ahiac_DriverData(a2),a3 ! 1074: SUBQ.w #1,p_DisableCount(a3) ! 1075: BNE.b .exit ! 1076: MOVE.w #INTF_SETCLR!INTF_AUD0,CUSTOM+INTENA ! 1077: ; moveq #2,d0 ! 1078: ; moveq #1,d1 ! 1079: ; jsr.l $f0ffb0 ! 1080: .exit ! 1081: pop a3 ! 1082: RTS ! 1083: ! 1084: ****** [driver].audio/AHIsub_Start ****************************************** ! 1085: * ! 1086: * NAME ! 1087: * AHIsub_Start -- Starts PlayBack OR recording ! 1088: * ! 1089: * SYNOPSIS ! 1090: * error = AHIsub_Start( flags, audioctrl ); ! 1091: * D0 D0 A2 ! 1092: * ! 1093: * ULONG AHIsub_Start(ULONG, struct AHIAudioCtrlDrv * ); ! 1094: * ! 1095: * IMPLEMENTATION ! 1096: * What To do depends what you returned in AHIsub_AllocAudio(). ! 1097: * ! 1098: * * First, assume bit AHISB_PLAY in flags is set. This means that you ! 1099: * should begin PlayBack. ! 1100: * ! 1101: * - AHIsub_AllocAudio() returned AHISF_MIXING|AHISF_TIMING: ! 1102: * ! 1103: * A) Allocate a mixing Buffer of ahiac_BuffSize bytes. The Buffer must ! 1104: * be long aligned! ! 1105: * B) Create/Start an interrupt OR task that will do 1-6 over AND over ! 1106: * again Until AHIsub_Stop() is called. Note that it is NOT a good ! 1107: * idea To do the actual mixing AND conversion in a real hardware ! 1108: * interrupt. Signal a task OR create a Software Interrupt To do ! 1109: * the number crunching. ! 1110: * ! 1111: * 1) Call the user Hook ahiac_PlayerFunc with the following parameters: ! 1112: * A0 - (struct Hook *) ! 1113: * A2 - (struct AHIAudioCtrlDrv *) ! 1114: * A1 - Set To Null. ! 1115: * ! 1116: * 2) [Call the ahiac_PreTimer Function. If it returns True (Z will be ! 1117: * cleared so you don't have To test d0), skip Step 3 AND 4. This ! 1118: * is Used To avoid overloading the CPU. This Step is optional. ! 1119: * A2 is assumed To Point To struct AHIAudioCtrlDrv. All registers ! 1120: * except d0 are preserved. (V4)] ! 1121: * ! 1122: * 3) Call the mixing Hook (ahiac_MixerFunc) with the following ! 1123: * parameters: ! 1124: * A0 - (struct Hook *) - The Hook itself ! 1125: * A2 - (struct AHIAudioCtrlDrv *) ! 1126: * A1 - (WORD *[]) - The mixing Buffer. ! 1127: * Note that ahiac_MixerFunc preserves ALL registers. ! 1128: * The user Hook ahiac_SoundFunc will be called by the mixing ! 1129: * routine when a sample have been processed, so you don't have To ! 1130: * worry about that. ! 1131: * How the Buffer will be filled is indicated by ahiac_Flags. ! 1132: * It is always filled with signed 16-bit (32 bit If AHIDBB_HIFI in ! 1133: * in ahiac_Flags is set) words, Even If PlayBack is 8 bit. If ! 1134: * AHIDBB_STEREO is set (in ahiac_Flags), Data For left AND right ! 1135: * channel are interleaved: ! 1136: * 1st sample left channel, ! 1137: * 1st sample right channel, ! 1138: * 2nd sample left channel, ! 1139: * ..., ! 1140: * ahiac_BuffSamples:th sample left channel, ! 1141: * ahiac_BuffSamples:th sample right channel. ! 1142: * If AHIDBB_STEREO is cleared, the mono Data is stored: ! 1143: * 1st sample, ! 1144: * 2nd sample, ! 1145: * ..., ! 1146: * ahiac_BuffSamples:th sample. ! 1147: * Note that neither AHIDBB_STEREO nor AHIDBB_HIFI will be set If ! 1148: * you didn't report that you understand these flags when ! 1149: * AHI_AllocAudio() was called. ! 1150: * ! 1151: * For AHI V2, the Type of Buffer is also available in ahiac_BuffType. ! 1152: * It is suggested that you Use this value instead. ahiac_BuffType ! 1153: * can be one of AHIST_M16S, AHIST_S16S, AHIST_M32S AND AHIST_S32S. ! 1154: * ! 1155: * 4) Convert the Buffer If needed AND feed it To the audio hardware. ! 1156: * Note that you may have To clear CPU caches If you are using DMA ! 1157: * To play the Buffer, AND the Buffer is NOT allocated in non- ! 1158: * cachable RAM. ! 1159: * ! 1160: * 5) [Call the ahiac_PostTimer Function. A2 is assumed To Point To ! 1161: * struct AHIAudioCtrlDrv. All registers are preserved. (V4)] ! 1162: * ! 1163: * 6) Wait Until the whole Buffer has been played, Then Repeat. ! 1164: * ! 1165: * Use double buffering If possible! ! 1166: * ! 1167: * You may DECREASE ahiac_BuffSamples slightly, For example To force an ! 1168: * Even number of samples To be mixed. By doing this you will make ! 1169: * ahiac_PlayerFunc To be called at wrong frequency so be careful! ! 1170: * Even If ahiac_BuffSamples is defined ULONG, it will never be greater ! 1171: * than 65535. ! 1172: * ! 1173: * ahiac_BuffSize is the Largest size of the mixing Buffer that will be ! 1174: * needed Until AHIsub_Stop() is called. ! 1175: * ! 1176: * ahiac_MaxBuffSamples is the Maximum number of samples that will be ! 1177: * mixed (Until AHIsub_Stop() is called). You can Use this value If you ! 1178: * need To allocate DMA buffers. ! 1179: * ! 1180: * ahiac_MinBuffSamples is the minimum number of samples that will be ! 1181: * mixed. Most drivers will ignore it. ! 1182: * ! 1183: * If AHIsub_AllocAudio() returned with the AHISB_CANPOSTPROCESS bit set, ! 1184: * ahiac_BuffSize is large enough To hold two buffers. The mixing Buffer ! 1185: * will be filled with the wet Buffer first, immediately followed by the ! 1186: * dry Buffer. I.e., ahiac_BuffSamples sample Frames wet Data, Then ! 1187: * ahiac_BuffSamples sample Frames dry Data. The DSP fx should only be ! 1188: * applied To the wet Buffer, AND the two buffers should Then be added ! 1189: * together. (V4) ! 1190: * ! 1191: * - If AHIsub_AllocAudio() returned AHISF_MIXING, do as described above, ! 1192: * except calling ahiac_PlayerFunc. ahiac_PlayerFunc should be called ! 1193: * ahiac_PlayerFreq times per second, clocked by timers On your Sound ! 1194: * card OR by using 'realtime.library'. No other AMIGA resources may ! 1195: * be Used For timing (like direct CIA timers). ! 1196: * ahiac_MinBuffSamples AND ahiac_MaxBuffSamples are undefined If ! 1197: * AHIsub_AllocAudio() returned AHISF_MIXING (AHISB_TIMING bit NOT set). ! 1198: * ! 1199: * - If AHIsub_AllocAudio() returned with neither the AHISB_MIXING nor ! 1200: * the AHISB_TIMING bit set, Then just Start PlayBack. Don't forget To ! 1201: * Call ahiac_PlayerFunc ahiac_PlayerFreq times per second. Only your ! 1202: * own timing hardware OR 'realtime.library' may be Used. Note that ! 1203: * ahiac_MixerFunc, ahiac_BuffSamples, ahiac_MinBuffSamples, ! 1204: * ahiac_MaxBuffSamples AND ahiac_BuffSize are undefined. ahiac_MixFreq ! 1205: * is the frequency the user wants To Use For recording, If you support ! 1206: * that. ! 1207: * ! 1208: * * Second, assume bit AHISB_RECORD in flags is set. This means that you ! 1209: * should Start To sample. Create a interrupt OR task that does the ! 1210: * following: ! 1211: * ! 1212: * Allocate a Buffer (you chose size, but try To keep it reasonable ! 1213: * small To avoid delays - it is suggested that RecordFunc is called ! 1214: * at least 4 times/second For the lowers sampling rate, AND more often ! 1215: * For higher rates), AND fill it with the sampled Data. The Buffer must ! 1216: * be long aligned, AND it's size must be evenly divisible by four. ! 1217: * The Format should always be AHIST_S16S (Even with 8 bit mono samplers), ! 1218: * which means: ! 1219: * 1st sample left channel, ! 1220: * 1st sample right channel (same as prev. If mono), ! 1221: * 2nd sample left channel, ! 1222: * ... etc. ! 1223: * Each sample is a signed word (WORD). The sample rate should be equal ! 1224: * To the mixing rate. ! 1225: * ! 1226: * Call the ahiac_SamplerFunc Hook with the following parameters: ! 1227: * A0 - (struct Hook *) - The Hook itself ! 1228: * A2 - (struct AHIAudioCtrlDrv *) ! 1229: * A1 - (struct AHIRecordMessage *) ! 1230: * The message should be filled as follows: ! 1231: * ahirm_Type - Set To AHIST_S16S. ! 1232: * ahirm_Buffer - A Pointer To the filled Buffer. ! 1233: * ahirm_Samples - How many sample Frames stored. ! 1234: * You must NOT destroy the Buffer Until Next time the Hook is called. ! 1235: * ! 1236: * Repeat Until AHIsub_Stop() is called. ! 1237: * ! 1238: * * Note that both bits may be set when this Function is called. ! 1239: * ! 1240: * INPUTS ! 1241: * flags - See <libraries/ahi_sub.h>. ! 1242: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 1243: * ! 1244: * RESULT ! 1245: * Returns AHIE_OK If successful, Else an error code as defined ! 1246: * in <devices/ahi.h>. AHIsub_Stop() will always be called, Even ! 1247: * If this Call failed. ! 1248: * ! 1249: * NOTES ! 1250: * The driver must be able To Handle multiple calls To this routine ! 1251: * without preceding calls To AHIsub_Stop(). ! 1252: * ! 1253: * SEE ALSO ! 1254: * AHIsub_Update(), AHIsub_Stop() ! 1255: * ! 1256: ***************************************************************************** ! 1257: * ! 1258: * ! 1259: * ! 1260: ! 1261: AHIsub_Start: ! 1262: pushm d2-d7/a2-a6 ! 1263: ! 1264: MOVE.l d0,d7 ! 1265: LEA CUSTOM,a4 ! 1266: MOVE.l ahiac_DriverData(a2),a3 ! 1267: ! 1268: BTST #AHISB_PLAY,d0 ! 1269: BEQ .dont_play ! 1270: ! 1271: ** ! 1272: *** AHISB_PLAY ! 1273: ** ! 1274: MOVEQ #AHISF_PLAY,d0 ! 1275: call AHIsub_Stop ;Stop current playback if any. ! 1276: call AHIsub_Update ;fill variables ! 1277: ! 1278: MOVE.l a6,a5 ! 1279: MOVE.l pb_SysLib(a5),a6 ! 1280: ! 1281: MOVE.l ahiac_BuffSize(a2),d0 ! 1282: MOVE.l #MEMF_PUBLIC|MEMF_CLEAR,d1 ! 1283: call AllocVec ! 1284: MOVE.l d0,p_Mixbuffer(a3) ! 1285: BEQ .error_nomem ! 1286: ! 1287: MOVE.l ahiac_MixFreq(a2),d1 ! 1288: BSR.w calcperiod ! 1289: MOVE.l d1,p_AudPer(a3) ! 1290: MOVE.l #0,flag ! 1291: CMP.w #$7f,d1 ;use old routines ! 1292: BGE .10 ! 1293: MOVE.l #1,flag ! 1294: .10 ! 1295: * The init*bit? routines allocates p_DMAbuffer, sets up p_AudPtr, sets the Volume, ! 1296: * stores the correct interrupt routines in p_PlayInt's AND p_PlaySoftInt's IS_CODE. ! 1297: ! 1298: PEA .1(pc) ! 1299: MOVE.b p_Flags(a3),d0 ! 1300: AND.b #PF_STEREO!PF_14BIT,d0 ! 1301: BEQ.w init16bitM ! 1302: CMP.b #PF_STEREO,d0 ! 1303: BEQ.w init16bitS ! 1304: CMP.b #PF_14BIT,d0 ! 1305: BEQ.w init14bitM ! 1306: BRA.w init14bitS ! 1307: .1 ! 1308: TST.l d0 ! 1309: BNE .exit ! 1310: ! 1311: * Install play interrupt ! 1312: LEA p_PlayInt(a3),a1 ! 1313: MOVEQ #INTB_AUD0,d0 ! 1314: call SetIntVector ! 1315: CLR.w p_DisableCount(a3) ! 1316: ! 1317: MOVE.w #INTF_SETCLR!INTF_AUD0,INTENA(a4) ;enable ! 1318: MOVE.w #INTF_SETCLR!INTF_AUD0,INTREQ(a4) ;start ! 1319: MOVE.l a5,a6 ! 1320: ! 1321: ! 1322: .dont_play ! 1323: BTST #AHISB_RECORD,d7 ! 1324: BEQ .dont_record ! 1325: ** ! 1326: *** AHISB_RECORD ! 1327: ** ! 1328: BTST #PB_14BIT,p_Flags(a3) ;Sanity check... ! 1329: BNE .error_unknown ! 1330: ! 1331: MOVEQ #AHISF_RECORD,d0 ! 1332: call AHIsub_Stop ;Stop current recording if any. ! 1333: ! 1334: MOVE.l a6,a5 ! 1335: MOVE.l pb_SysLib(a5),a6 ! 1336: ! 1337: MOVE.l #RECORDSAMPLES*4,d0 ! 1338: MOVE.l #MEMF_PUBLIC,d1 ! 1339: call AllocVec ! 1340: MOVE.l d0,p_RecBuffer1(a3) ! 1341: BEQ .error_nomem ! 1342: ! 1343: MOVE.l d0,p_RecFillPtr(a3) ! 1344: MOVE.w #RECORDSAMPLES,p_RecFillCount(a3) ! 1345: ! 1346: MOVE.l #RECORDSAMPLES*4,d0 ! 1347: MOVE.l #MEMF_PUBLIC,d1 ! 1348: call AllocVec ! 1349: MOVE.l d0,p_RecBuffer2(a3) ! 1350: BEQ .error_nomem ! 1351: ! 1352: MOVE.l ahiac_MixFreq(a2),d1 ! 1353: BSR.w calcperiod ! 1354: LSR.w #1,d1 ;Period/2 => Frequency72 ! 1355: MOVE.w d1,AUD2PER(a4) ! 1356: MOVE.w d1,AUD3PER(a4) ! 1357: MOVE.w p_MonitorVolume(a3),AUD2VOL(a4) ! 1358: MOVE.w p_MonitorVolume(a3),AUD3VOL(a4) ! 1359: ! 1360: * Install Record interrupt ! 1361: MOVE.w p_Input(a3),d0 ! 1362: BEQ .parsampler ! 1363: CMP.w #1,d0 ! 1364: BEQ .aurasampler ! 1365: BRA .error_unknown ! 1366: .parsampler ! 1367: TST.b p_Parallel(a3) ;Parrallel port allocated? ! 1368: BEQ .error_unknown ! 1369: LEA p_RecIntData(a3),a1 ! 1370: MOVE.l a1,IS_DATA+p_RecInt(a3) ! 1371: MOVE.l #RecordInterrupt,IS_CODE+p_RecInt(a3) ! 1372: BRA .setrecint ! 1373: .aurasampler ! 1374: TST.l p_AuraAddress(a3) ;Aura sampler allocated? ! 1375: BEQ .error_unknown ! 1376: LEA p_RecIntDataAura(a3),a1 ! 1377: MOVE.l a1,IS_DATA+p_RecInt(a3) ! 1378: MOVE.l #RecordInterruptAura,IS_CODE+p_RecInt(a3) ! 1379: .setrecint ! 1380: LEA p_RecInt(a3),a1 ! 1381: MOVEQ #INTB_AUD3,d0 ! 1382: call SetIntVector ! 1383: ! 1384: MOVE.w #DMAF_AUD2!DMAF_AUD3,DMACON(a4) ;disable DMA ! 1385: MOVE.w #INTF_SETCLR!INTF_AUD3,INTENA(a4) ;enable ! 1386: MOVE.w #INTF_SETCLR!INTF_AUD3,INTREQ(a4) ;start ! 1387: ! 1388: .dont_record ! 1389: .return ! 1390: ! 1391: ! 1392: MOVEQ #AHIE_OK,d0 ! 1393: .exit ! 1394: popm d2-d7/a2-a6 ! 1395: RTS ! 1396: .error_nomem ! 1397: MOVEQ #AHIE_NOMEM,d0 ! 1398: BRA.b .exit ! 1399: .error_unknown ! 1400: MOVEQ #AHIE_UNKNOWN,d0 ! 1401: BRA.b .exit ! 1402: ! 1403: ! 1404: ;in: ! 1405: * a2 AudioCtrl ! 1406: * a3 paula ! 1407: * a4 CUSTOM ! 1408: * a5 paulaBase ! 1409: * a6 ExecBase ! 1410: ! 1411: init16bitM: ! 1412: MOVE.l #AudioInterrupt2,IS_CODE+p_PlayInt(a3) ! 1413: MOVE.l #SoftInt_16bitM,IS_CODE+p_PlaySoftInt(a3) ! 1414: ! 1415: MOVE.l ahiac_MaxBuffSamples(a2),d0 ;Max. # of 8 bit samples ! 1416: ! 1417: ADDQ.l #1,d0 ! 1418: BCLR #0,d0 ;force even ! 1419: MOVE.l d0,d2 ;d2 = channel size ! 1420: LSL #1,d2 ! 1421: ; move.l d0,ahiac_BuffSamples(a2) ! 1422: LSL.l #1,d0 ;Double buffer ! 1423: LSL.l #1,d0 ;it's actually 16 bits ! 1424: MOVE.l #MEMF_CHIP!MEMF_PUBLIC|MEMF_CLEAR,d1 ! 1425: call AllocVec ! 1426: MOVE.l d0,p_DMAbuffer(a3) ! 1427: BEQ .nomem ! 1428: ! 1429: MOVE.l d0,p_AudPtr1A(a3) ! 1430: MOVE.l d0,p_AudPtr2A(a3) ! 1431: ADD.l d2,d0 ! 1432: MOVE.l d0,p_AudPtr1B(a3) ! 1433: MOVE.l d0,p_AudPtr2B(a3) ! 1434: ! 1435: MOVEQ #0,d0 ! 1436: RTS ! 1437: .nomem ! 1438: MOVEQ #AHIE_NOMEM,d0 ! 1439: RTS ! 1440: ! 1441: ;in: ! 1442: * a2 AudioCtrl ! 1443: * a3 paula ! 1444: * a5 paulaBase ! 1445: * a6 ExecBase ! 1446: init16bitS: ! 1447: MOVE.l #AudioInterrupt2,IS_CODE+p_PlayInt(a3) ! 1448: MOVE.l #SoftInt_16bitS,IS_CODE+p_PlaySoftInt(a3) ! 1449: ! 1450: MOVE.l ahiac_MaxBuffSamples(a2),d0 ;Max. # of 8 bit samples ! 1451: ADDQ.l #1,d0 ! 1452: BCLR #0,d0 ;force even ! 1453: MOVE.l d0,d2 ;d2 = channel size ! 1454: LSL #1,d2 ! 1455: ; move.l d0,ahiac_BuffSamples(a2) ! 1456: ! 1457: LSL.l #2,d0 ;Double buffer + Stereo ! 1458: LSL.l #1,d0 ;it's actually 16 bits ! 1459: MOVE.l #MEMF_CHIP!MEMF_PUBLIC|MEMF_CLEAR,d1 ! 1460: call AllocVec ! 1461: MOVE.l d0,p_DMAbuffer(a3) ! 1462: BEQ .nomem ! 1463: ! 1464: MOVE.l d0,p_AudPtr1A(a3) ! 1465: ADD.l d2,d0 ! 1466: MOVE.l d0,p_AudPtr2A(a3) ! 1467: ADD.l d2,d0 ! 1468: MOVE.l d0,p_AudPtr1B(a3) ! 1469: ADD.l d2,d0 ! 1470: MOVE.l d0,p_AudPtr2B(a3) ! 1471: ! 1472: MOVEQ #0,d0 ! 1473: RTS ! 1474: .nomem ! 1475: MOVEQ #AHIE_NOMEM,d0 ! 1476: RTS ! 1477: ! 1478: ;in: ! 1479: * a2 AudioCtrl ! 1480: * a3 paula ! 1481: * a5 paulaBase ! 1482: * a6 ExecBase ! 1483: init14bitM: ! 1484: MOVE.l #AudioInterrupt4,IS_CODE+p_PlayInt(a3) ! 1485: LEA SoftInt_14bitM(pc),a0 ! 1486: TST.l p_CalibrationTable(a3) ! 1487: BEQ.b .nocalib ! 1488: LEA SoftInt_14CbitM(pc),a0 ! 1489: .nocalib ! 1490: MOVE.l a0,IS_CODE+p_PlaySoftInt(a3) ! 1491: ! 1492: MOVE.l ahiac_MaxBuffSamples(a2),d0 ;Max. # of 16 bit samples ! 1493: ADDQ.l #1,d0 ! 1494: BCLR #0,d0 ;force even ! 1495: MOVE.l d0,d2 ;d2 = channel size ! 1496: ! 1497: LSL.l #2,d0 ;Double buffer + 2W8 bit ! 1498: MOVE.l #MEMF_CHIP!MEMF_PUBLIC|MEMF_CLEAR,d1 ! 1499: call AllocVec ! 1500: MOVE.l d0,p_DMAbuffer(a3) ! 1501: BEQ .nomem ! 1502: ! 1503: MOVE.l d0,p_AudPtr1A(a3) ! 1504: MOVE.l d0,p_AudPtr2A(a3) ! 1505: ADD.l d2,d0 ! 1506: MOVE.l d0,p_AudPtr4A(a3) ! 1507: MOVE.l d0,p_AudPtr3A(a3) ! 1508: ADD.l d2,d0 ! 1509: MOVE.l d0,p_AudPtr1B(a3) ! 1510: MOVE.l d0,p_AudPtr2B(a3) ! 1511: ADD.l d2,d0 ! 1512: MOVE.l d0,p_AudPtr4B(a3) ! 1513: MOVE.l d0,p_AudPtr3B(a3) ! 1514: ! 1515: MOVE.w #64,AUD0VOL(a4) ! 1516: MOVE.w #64,AUD1VOL(a4) ! 1517: MOVE.w #1,AUD2VOL(a4) ! 1518: MOVE.w #1,AUD3VOL(a4) ! 1519: ! 1520: MOVEQ #0,d0 ! 1521: RTS ! 1522: .nomem ! 1523: MOVEQ #AHIE_NOMEM,d0 ! 1524: RTS ! 1525: ! 1526: ;in: ! 1527: * a2 AudioCtrl ! 1528: * a3 paula ! 1529: * a5 paulaBase ! 1530: * a6 ExecBase ! 1531: init14bitS: ! 1532: MOVE.l #AudioInterrupt4,IS_CODE+p_PlayInt(a3) ! 1533: LEA SoftInt_14bitS(pc),a0 ! 1534: TST.l p_CalibrationTable(a3) ! 1535: BEQ .nocalib ! 1536: ;lea SoftInt_14CbitS(pc),a0 changed for uae ! 1537: .nocalib ! 1538: MOVE.l a0,IS_CODE+p_PlaySoftInt(a3) ! 1539: ! 1540: ! 1541: MOVE.l ahiac_MaxBuffSamples(a2),d0 ;Max. # of 16 bit samples ! 1542: ASL.l #2,d0 ! 1543: MOVE.l d0,ahiac_MaxBuffSamples(a2) ! 1544: ADDQ.l #1,d0 ! 1545: BCLR #0,d0 ;force even ! 1546: MOVE.l d0,d2 ;d2 = channel size ! 1547: ! 1548: LSL.l #3,d0 ;Double buffer + 2W8 bit + Stereo ! 1549: MOVE.l #MEMF_CHIP!MEMF_PUBLIC|MEMF_CLEAR,d1 ! 1550: call AllocVec ! 1551: MOVE.l d0,p_DMAbuffer(a3) ! 1552: BEQ .nomem ! 1553: ! 1554: MOVE.l d0,p_AudPtr1A(a3) ! 1555: ADD.l d2,d0 ! 1556: MOVE.l d0,p_AudPtr2A(a3) ! 1557: ADD.l d2,d0 ! 1558: MOVE.l d0,p_AudPtr3A(a3) ! 1559: ADD.l d2,d0 ! 1560: MOVE.l d0,p_AudPtr4A(a3) ! 1561: ADD.l d2,d0 ! 1562: MOVE.l d0,p_AudPtr1B(a3) ! 1563: ADD.l d2,d0 ! 1564: MOVE.l d0,p_AudPtr2B(a3) ! 1565: ADD.l d2,d0 ! 1566: MOVE.l d0,p_AudPtr3B(a3) ! 1567: ADD.l d2,d0 ! 1568: MOVE.l d0,p_AudPtr4B(a3) ! 1569: ! 1570: MOVE.w #$4849,AUD0VOL(a4) ;changed for uae ! 1571: MOVE.w #64,AUD1VOL(a4) ! 1572: MOVE.w #1,AUD2VOL(a4) ! 1573: MOVE.w #1,AUD3VOL(a4) ! 1574: ! 1575: MOVEQ #0,d0 ! 1576: RTS ! 1577: .nomem ! 1578: MOVEQ #AHIE_NOMEM,d0 ! 1579: RTS ! 1580: ! 1581: ****** [driver].audio/AHIsub_Update ***************************************** ! 1582: * ! 1583: * NAME ! 1584: * AHIsub_Update -- Update some variables ! 1585: * ! 1586: * SYNOPSIS ! 1587: * AHIsub_Update( flags, audioctrl ); ! 1588: * D0 A2 ! 1589: * ! 1590: * void AHIsub_Update(ULONG, struct AHIAudioCtrlDrv * ); ! 1591: * ! 1592: * IMPLEMENTATION ! 1593: * All you have To do is To update some variables: ! 1594: * Mixing & timing: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc, ! 1595: * ahiac_BuffSamples (AND perhaps ahiac_PlayerFreq If you Use it). ! 1596: * Mixing only: ahiac_PlayerFunc, ahiac_MixerFunc, ahiac_SamplerFunc AND ! 1597: * ahiac_PlayerFreq. ! 1598: * Nothing: ahiac_PlayerFunc, ahiac_SamplerFunc AND ahiac_PlayerFreq. ! 1599: * ! 1600: * INPUTS ! 1601: * flags - Currently no flags defined. ! 1602: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 1603: * ! 1604: * RESULT ! 1605: * ! 1606: * NOTES ! 1607: * This Call must be safe from interrupts. ! 1608: * ! 1609: * SEE ALSO ! 1610: * AHIsub_Start() ! 1611: * ! 1612: ***************************************************************************** ! 1613: * ! 1614: * ! 1615: * ! 1616: ! 1617: AHIsub_Update: ! 1618: pushm d2-d7/a2-a6 ! 1619: ! 1620: call AHIsub_Disable ;make sure we don't get an interrupt ! 1621: ;while updating our local variables ! 1622: MOVE.l ahiac_DriverData(a2),a3 ! 1623: ! 1624: MOVE.l ahiac_PlayerFunc(a2),a0 ! 1625: MOVE.l a0,p_PlayerHook(a3) ! 1626: MOVE.l h_Entry(a0),p_PlayerEntry(a3) ! 1627: ! 1628: MOVE.l ahiac_BuffSamples(a2),d0 ! 1629: MOVE.w d0,p_AudLen(a3) ! 1630: SUBQ.l #1,d0 ! 1631: MOVE.l d0,p_LoopTimes(a3) ;See softints. (Unrolled) ! 1632: ! 1633: MOVE.l ahiac_MixerFunc(a2),a0 ! 1634: MOVE.l a0,p_MixHook(a3) ! 1635: MOVE.l h_Entry(a0),p_MixEntry(a3) ! 1636: ! 1637: MOVE.l ahiac_PreTimer(a2),p_PreTimer(a3) ! 1638: MOVE.l ahiac_PostTimer(a2),p_PostTimer(a3) ! 1639: ! 1640: call AHIsub_Enable ! 1641: MOVEQ #0,d0 ! 1642: popm d2-d7/a2-a6 ! 1643: RTS ! 1644: ! 1645: ! 1646: ****** [driver].audio/AHIsub_Stop ******************************************* ! 1647: * ! 1648: * NAME ! 1649: * AHIsub_Stop -- Stops PlayBack. ! 1650: * ! 1651: * SYNOPSIS ! 1652: * AHIsub_Stop( flags, audioctrl ); ! 1653: * D0 A2 ! 1654: * ! 1655: * void AHIsub_Stop( ULONG, struct AHIAudioCtrlDrv * ); ! 1656: * ! 1657: * IMPLEMENTATION ! 1658: * Stop PlayBack AND/OR recording, remove all resources allocated by ! 1659: * AHIsub_Start(). ! 1660: * ! 1661: * INPUTS ! 1662: * flags - See <libraries/ahi_sub.h>. ! 1663: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 1664: * ! 1665: * NOTES ! 1666: * It must be safe To Call this routine Even If AHIsub_Start() was never ! 1667: * called, failed OR called more than once. ! 1668: * ! 1669: * SEE ALSO ! 1670: * AHIsub_Start() ! 1671: * ! 1672: ***************************************************************************** ! 1673: * ! 1674: * ! 1675: ! 1676: AHIsub_Stop: ! 1677: pushm d2-d7/a2-a6 ! 1678: ! 1679: LEA CUSTOM,a4 ! 1680: MOVE.l a6,a5 ! 1681: MOVE.l pb_SysLib(a5),a6 ! 1682: MOVE.l ahiac_DriverData(a2),a3 ! 1683: ! 1684: push d0 ! 1685: BTST #AHISB_PLAY,d0 ! 1686: BEQ .dontplay ! 1687: ! 1688: ** ! 1689: *** AHISB_PLAY ! 1690: ** ! 1691: MOVEQ #2,d0 ! 1692: MOVEQ #0,d1 ! 1693: jsr.l $F0FFB0 ! 1694: MOVEQ #3,d0 ! 1695: MOVEQ #0,d3 ! 1696: jsr.l $F0FFB0 ! 1697: MOVEQ #4,d0 ! 1698: MOVEQ #0,d3 ! 1699: jsr.l $F0FFB0 ! 1700: ! 1701: MOVEQ #0,d0 ! 1702: MOVE.w d0,AUD0VOL(a4) ! 1703: MOVE.w d0,AUD1VOL(a4) ! 1704: MOVE.w d0,AUD2VOL(a4) ! 1705: MOVE.w d0,AUD3VOL(a4) ! 1706: MOVE.w #DMAF_AUDIO,DMACON(a4) ;disable audio DMA ! 1707: ! 1708: MOVE.w #INTF_AUD0,INTENA(a4) ! 1709: MOVE.w #INTF_AUD0,INTREQ(a4) ;Clear any waiting interrupts ! 1710: MOVE.l #Interrupt_Dummy,IS_CODE+p_PlayInt(a3) ! 1711: LEA p_PlayInt(a3),a1 ! 1712: MOVEQ #INTB_AUD0,d0 ! 1713: call SetIntVector ! 1714: ! 1715: MOVE.l p_DMAbuffer(a3),d0 ! 1716: BEQ.b .nodmamem ! 1717: MOVE.l d0,a1 ! 1718: CLR.l p_DMAbuffer(a3) ! 1719: call FreeVec ! 1720: .nodmamem ! 1721: MOVE.l p_Mixbuffer(a3),d0 ! 1722: BEQ.b .nomixmem ! 1723: MOVE.l d0,a1 ! 1724: CLR.l p_Mixbuffer(a3) ! 1725: call FreeVec ! 1726: .nomixmem ! 1727: ! 1728: .dontplay ! 1729: pop d0 ! 1730: BTST #AHISB_RECORD,d0 ! 1731: BEQ .dontrecord ! 1732: ! 1733: ** ! 1734: *** AHISB_RECORD ! 1735: ** ! 1736: BTST #PB_14BIT,p_Flags(a3) ;Sanity check... ! 1737: BNE .dontrecord ! 1738: ! 1739: MOVE.w #INTF_AUD3,INTENA(a4) ! 1740: MOVE.w #INTF_AUD3,INTREQ(a4) ;Clear any waiting interrupts ! 1741: ! 1742: MOVE.l #Interrupt_Dummy,IS_CODE+p_RecInt(a3) ! 1743: LEA p_RecInt(a3),a1 ! 1744: MOVEQ #INTB_AUD3,d0 ! 1745: call SetIntVector ! 1746: ! 1747: MOVE.w #0,AUD2VOL(a4) ! 1748: MOVE.w #0,AUD3VOL(a4) ! 1749: ! 1750: MOVE.l p_RecBuffer1(a3),d0 ! 1751: BEQ.b .norecmem1 ! 1752: MOVE.l d0,a1 ! 1753: CLR.l p_RecBuffer1(a3) ! 1754: call FreeVec ! 1755: .norecmem1 ! 1756: MOVE.l p_RecBuffer2(a3),d0 ! 1757: BEQ.b .norecmem2 ! 1758: MOVE.l d0,a1 ! 1759: CLR.l p_RecBuffer2(a3) ! 1760: call FreeVec ! 1761: .norecmem2 ! 1762: .dontrecord ! 1763: .return ! 1764: MOVEQ #0,d0 ! 1765: popm d2-d7/a2-a6 ! 1766: RTS ! 1767: ! 1768: ****** [driver].audio/AHIsub_#? ********************************************* ! 1769: * ! 1770: * NAME ! 1771: * AHIsub_SetEffect -- Set effect. ! 1772: * AHIsub_SetFreq -- Set frequency. ! 1773: * AHIsub_SetSound -- Set Sound. ! 1774: * AHIsub_SetVol -- Set Volume AND stereo panning. ! 1775: * AHIsub_LoadSound -- Prepare a Sound For PlayBack. ! 1776: * AHIsub_UnloadSound -- Discard a Sound. ! 1777: * ! 1778: * SYNOPSIS ! 1779: * See functions in 'ahi.device'. ! 1780: * ! 1781: * IMPLEMENTATION ! 1782: * If AHIsub_AllocAudio() did NOT Return with bit AHISB_MIXING set, ! 1783: * all user calls To these Function will be routed To the driver. ! 1784: * ! 1785: * If AHIsub_AllocAudio() did Return with bit AHISB_MIXING set, the ! 1786: * calls will first be routed To the driver, AND only handled by ! 1787: * 'ahi.device' If the driver returned AHIS_UNKNOWN. This way it is ! 1788: * possible To ADD effects that the Sound card handles On its own, like ! 1789: * Filter AND echo effects. ! 1790: * ! 1791: * For what each Function does, see the autodocs For 'ahi.device'. ! 1792: * ! 1793: * INPUTS ! 1794: * See functions in 'ahi.device'. ! 1795: * ! 1796: * NOTES ! 1797: * See functions in 'ahi.device'. ! 1798: * ! 1799: * SEE ALSO ! 1800: * ahi.device/AHI_SetEffect(), ahi.device/AHI_SetFreq(), ! 1801: * ahi.device/AHI_SetSound(), ahi.device/AHI_SetVol(), ! 1802: * ahi.device/AHI_LoadSound(), ahi.device/AHI_UnloadSound() ! 1803: * ! 1804: * ! 1805: ***************************************************************************** ! 1806: * ! 1807: * ! 1808: ! 1809: AHIsub_SetVol: ! 1810: AHIsub_SetFreq: ! 1811: AHIsub_SetSound: ! 1812: AHIsub_SetEffect: ! 1813: AHIsub_LoadSound: ! 1814: AHIsub_UnloadSound: ! 1815: MOVEQ #AHIS_UNKNOWN,d0 ! 1816: RTS ! 1817: ! 1818: ****** [driver].audio/AHIsub_GetAttr **************************************** ! 1819: * ! 1820: * NAME ! 1821: * AHIsub_GetAttr -- Returns information about audio modes OR driver ! 1822: * ! 1823: * SYNOPSIS ! 1824: * AHIsub_GetAttr( attribute, argument, Default, taglist, audioctrl ); ! 1825: * D0 D0 D1 D2 A1 A2 ! 1826: * ! 1827: * LONG AHIsub_GetAttr( ULONG, LONG, LONG, struct TagItem *, ! 1828: * struct AHIAudioCtrlDrv * ); ! 1829: * ! 1830: * IMPLEMENTATION ! 1831: * Return the attribute based On a tag List AND an AHIAudioCtrlDrv ! 1832: * structure, which are the same that will be passed To ! 1833: * AHIsub_AllocAudio() by 'ahi.device'. If the attribute is ! 1834: * unknown To you, Return the Default. ! 1835: * ! 1836: * INPUTS ! 1837: * attribute - Is really a Tag AND can be one of the following: ! 1838: * AHIDB_Bits - Return how many output bits the tag List will ! 1839: * result in. ! 1840: * AHIDB_MaxChannels - Return the resulting number of channels. ! 1841: * AHIDB_Frequencies - Return how many mixing/sampling frequencies ! 1842: * you support ! 1843: * AHIDB_Frequency - Return the argument:th frequency ! 1844: * Example: You support 3 frequencies 32, 44.1 AND 48 kHz. ! 1845: * If argument is 1, Return 44100. ! 1846: * AHIDB_Index - Return the Index which gives the frequency closest ! 1847: * To argument. ! 1848: * Example: You support 3 frequencies 32, 44.1 AND 48 kHz. ! 1849: * If argument is 40000, Return 1 (=> 44100). ! 1850: * AHIDB_Author - Return Pointer To name of driver author: ! 1851: * "Martin 'Leviticus' Blom" ! 1852: * AHIDB_Copyright - Return Pointer To copyright notice, including ! 1853: * the ')' character: "?????1996 Martin Blom" OR "Public Domain" ! 1854: * AHIDB_Version - Return Pointer version string, normal AMIGA ! 1855: * Format: "paula 1.5 (18.2.96)\r\n" ! 1856: * AHIDB_Annotation - Return Pointer To an annotation string, which ! 1857: * can be several lines. ! 1858: * AHIDB_Record - Are you a sampler, too? Return True OR False. ! 1859: * AHIDB_FullDuplex - Return True OR False. ! 1860: * AHIDB_Realtime - Return True OR False. ! 1861: * AHIDB_MaxPlaySamples - Normally, Return the Default. See ! 1862: * AHIsub_AllocAudio(), section 2. ! 1863: * AHIDB_MaxRecordSamples - Return the size of the Buffer you fill ! 1864: * when recording. ! 1865: * ! 1866: * The following are associated with AHIsub_HardwareControl() AND are ! 1867: * new For V2. ! 1868: * AHIDB_MinMonitorVolume ! 1869: * AHIDB_MaxMonitorVolume - Return the lower/upper limit For ! 1870: * AHIC_MonitorVolume. If unsupported but always 1.0, Return ! 1871: * 1.0 For both. ! 1872: * AHIDB_MinInputGain ! 1873: * AHIDB_MaxInputGain - Return the lower/upper limit For ! 1874: * AHIC_InputGain. If unsupported but always 1.0, Return 1.0 For ! 1875: * both. ! 1876: * AHIDB_MinOutputVolume ! 1877: * AHIDB_MaxOutputVolume - Return the lower/upper limit For ! 1878: * AHIC_OutputVolume. ! 1879: * AHIDB_Inputs - Return how many inputs you have. ! 1880: * AHIDB_Input - Return a short string describing the argument:th ! 1881: * input. Number 0 should be the Default one. Example strings ! 1882: * can be "Line 1", "Mic", "Optical" OR whatever. ! 1883: * AHIDB_Outputs - Return how many outputs you have. ! 1884: * AHIDB_Output - Return a short string describing the argument:th ! 1885: * output. Number 0 should be the Default one. Example strings ! 1886: * can be "Line 1", "Headphone", "Optical" OR whatever. ! 1887: * argument - extra info For some attributes. ! 1888: * Default - What you should Return For unknown attributes. ! 1889: * taglist - Pointer To a tag List that eventually will be fed To ! 1890: * AHIsub_AllocAudio(), OR Null. ! 1891: * audioctrl - Pointer To an AHIAudioCtrlDrv structure that eventually ! 1892: * will be fed To AHIsub_AllocAudio(), OR Null. ! 1893: * ! 1894: * NOTES ! 1895: * ! 1896: * SEE ALSO ! 1897: * AHIsub_AllocAudio(), AHIsub_HardwareControl(), ! 1898: * ahi.device/AHI_GetAudioAttrsA() ! 1899: * ! 1900: ***************************************************************************** ! 1901: * ! 1902: * ! 1903: ! 1904: AHIsub_GetAttr: ! 1905: pushm a3/a5-a6 ! 1906: MOVE.l a6,a5 ! 1907: MOVE.l pb_UtilLib(a5),a6 ! 1908: ! 1909: IFD MC020 ! 1910: TST.l a1 ! 1911: Else ! 1912: CMP.l #0,a1 ! 1913: ENDC ! 1914: BEQ .notaglist ;no tag list! ! 1915: ! 1916: MOVE.l a1,a3 ! 1917: ! 1918: pushm d0-d1 ! 1919: ! 1920: MOVE.l #AHIDB_Paula14Bit,d0 ! 1921: MOVEQ #FALSE,d1 ! 1922: MOVE.l a3,a0 ! 1923: call GetTagData ! 1924: TST.l d0 ! 1925: BNE .2 ! 1926: ! 1927: * Only For AHIDB_Paula14Bit False (== recording available) ! 1928: popm d0-d1 ! 1929: ! 1930: CMP.l #AHIDB_Record,d0 ! 1931: BNE.b .not_record1 ! 1932: MOVEQ #TRUE,d0 ! 1933: BRA .exit ! 1934: .not_record1 ! 1935: CMP.l #AHIDB_FullDuplex,d0 ! 1936: BNE.b .not_fullduplex1 ! 1937: MOVEQ #TRUE,d0 ! 1938: BRA .exit ! 1939: .not_fullduplex1 ! 1940: CMP.l #AHIDB_MaxRecordSamples,d0 ! 1941: BNE.b .not_mrs1 ! 1942: MOVE.l #RECORDSAMPLES,d0 ! 1943: BRA .exit ! 1944: .not_mrs1 ! 1945: CMP.l #AHIDB_MinMonitorVolume,d0 ! 1946: BNE.b .not_minmonvol1 ! 1947: MOVEQ #0,d0 ! 1948: BRA .exit ! 1949: .not_minmonvol1 ! 1950: CMP.l #AHIDB_MaxMonitorVolume,d0 ! 1951: BNE.b .not_maxmonvol1 ! 1952: MOVE.l #$10000,d0 ! 1953: BRA .exit ! 1954: .not_maxmonvol1 ! 1955: CMP.l #AHIDB_MinInputGain,d0 ! 1956: BNE.b .not_mingain1 ! 1957: MOVE.l #$10000,d0 ! 1958: BRA .exit ! 1959: .not_mingain1 ! 1960: CMP.l #AHIDB_MaxInputGain,d0 ! 1961: BNE.b .not_maxgain1 ! 1962: MOVE.l #$10000,d0 ! 1963: BRA .exit ! 1964: .not_maxgain1 ! 1965: CMP.l #AHIDB_Inputs,d0 ! 1966: BNE.b .not_inputs ! 1967: MOVEQ #2,d0 ! 1968: BRA .exit ! 1969: .not_inputs ! 1970: CMP.l #AHIDB_Input,d0 ! 1971: BNE.b .not_input ! 1972: LSL.l #2,d1 ! 1973: MOVE.l .inputs(pc,d1.w),d0 ! 1974: BRA .exit ! 1975: .not_input ! 1976: BRA .3 ! 1977: .inputs: ! 1978: Dc.l .input0 ! 1979: Dc.l .input1 ! 1980: ! 1981: .2 ! 1982: * Only For AHIDB_Paula14Bit True (== no recording) ! 1983: popm d0-d1 ! 1984: CMP.l #AHIDB_Record,d0 ! 1985: BNE.b .not_record2 ! 1986: MOVEQ #FALSE,d0 ! 1987: BRA .exit ! 1988: .not_record2 ! 1989: CMP.l #AHIDB_FullDuplex,d0 ! 1990: BNE.b .not_fullduplex2 ! 1991: MOVEQ #FALSE,d0 ! 1992: BRA .exit ! 1993: .not_fullduplex2 ! 1994: ! 1995: .3 ! 1996: * Common Tags (AHIDB_14bit) ! 1997: ! 1998: CMP.l #AHIDB_Bits,d0 ! 1999: BNE.b .not_bits ! 2000: MOVE.l #AHIDB_Paula14Bit,d0 ! 2001: MOVEQ #FALSE,d1 ! 2002: MOVE.l a3,a0 ! 2003: call GetTagData ! 2004: TST.l d0 ! 2005: BEQ.b .no14bit ! 2006: MOVEQ #14,d0 ! 2007: skipw ! 2008: .no14bit ! 2009: MOVEQ #8,d0 ! 2010: BRA .exit ! 2011: .not_bits ! 2012: .notaglist ! 2013: CMP.l #AHIDB_Frequencies,d0 ! 2014: BNE.b .not_freqs ! 2015: MOVE.l #FREQUENCIES,d0 ! 2016: lsr.l #2,d0 ! 2017: BRA .exit ! 2018: .not_freqs ! 2019: ! 2020: CMP.l #AHIDB_Frequency,d0 ! 2021: BNE.b .not_freq ! 2022: ADD.w d1,d1 ! 2023: ADD.w d1,d1 ! 2024: LEA uae(pc),a0 ! 2025: ; move.l (a0,d1.w),d1 ! 2026: ; bsr calcperiod ! 2027: MOVE.l (a0,d1.w),d0 ! 2028: BRA .exit ! 2029: .not_freq ! 2030: CMP.l #AHIDB_Index,d0 ! 2031: BNE.b .not_index ! 2032: MOVE.l d1,d0 ! 2033: BSR findfreq ! 2034: MOVE.l d1,d0 ! 2035: BRA .exit ! 2036: .not_index ! 2037: CMP.l #AHIDB_Author,d0 ! 2038: BNE.b .not_author ! 2039: LEA .author(pc),a0 ! 2040: MOVE.l a0,d0 ! 2041: BRA .exit ! 2042: .not_author ! 2043: CMP.l #AHIDB_Copyright,d0 ! 2044: BNE.b .not_copyright ! 2045: LEA .copyright(pc),a0 ! 2046: MOVE.l a0,d0 ! 2047: BRA .exit ! 2048: .not_copyright ! 2049: CMP.l #AHIDB_Version,d0 ! 2050: BNE.b .not_version ! 2051: LEA IDString(pc),a0 ! 2052: MOVE.l a0,d0 ! 2053: BRA .exit ! 2054: .not_version ! 2055: CMP.l #AHIDB_Annotation,d0 ! 2056: BNE.b .not_anno ! 2057: LEA .anno(pc),a0 ! 2058: MOVE.l a0,d0 ! 2059: BRA .exit ! 2060: .not_anno ! 2061: CMP.l #AHIDB_Realtime,d0 ! 2062: BNE.b .not_realtime ! 2063: MOVEQ #TRUE,d0 ! 2064: BRA .exit ! 2065: .not_realtime ! 2066: CMP.l #AHIDB_Outputs,d0 ! 2067: BNE.b .not_outputs ! 2068: MOVEQ #1,d0 ! 2069: BRA .exit ! 2070: .not_outputs ! 2071: CMP.l #AHIDB_Output,d0 ! 2072: BNE.b .not_output ! 2073: LEA .output(pc),a0 ! 2074: MOVE.l a0,d0 ! 2075: BRA .exit ! 2076: .not_output ! 2077: ! 2078: * Unknown attribute, Return Default. ! 2079: MOVE.l d2,d0 ! 2080: .exit ! 2081: popm a3/a5-a6 ! 2082: RTS ! 2083: .author Dc.b "Martin 'Leviticus' Blom",0 ! 2084: .copyright Dc.b "Public Domain",0 ! 2085: .anno Dc.b "14 bit routines by Christian Buchner.",0 ! 2086: .input0 Dc.b "Parallel port sampler",0 ! 2087: .input1 Dc.b "Aura sampler",0 ! 2088: .output Dc.b "Line",0 ! 2089: Even ! 2090: ! 2091: ! 2092: ****** [driver].audio/AHIsub_HardwareControl ******************************** ! 2093: * ! 2094: * NAME ! 2095: * AHIsub_HardwareControl -- Modify Sound card settings ! 2096: * ! 2097: * SYNOPSIS ! 2098: * AHIsub_HardwareControl( attribute, argument, audioctrl ); ! 2099: * D0 D0 D1 A2 ! 2100: * ! 2101: * LONG AHIsub_HardwareControl( ULONG, LONG, struct AHIAudioCtrlDrv * ); ! 2102: * ! 2103: * IMPLEMENTATION ! 2104: * Set OR Return the state of a particular hardware component. AHI uses ! 2105: * AHIsub_GetAttr() To supply the user with limits AND what Tags are ! 2106: * available. ! 2107: * ! 2108: * INPUTS ! 2109: * attribute - Is really a Tag AND can be one of the following: ! 2110: * AHIC_MonitorVolume - Set the input monitor Volume To argument. ! 2111: * AHIC_MonitorVolume_Query - Return the current input monitor ! 2112: * Volume (argument is ignored). ! 2113: * ! 2114: * AHIC_InputGain - Set the input gain To argument. (V2) ! 2115: * AHIC_InputGain_Query (V2) ! 2116: * ! 2117: * AHIC_OutputVolume - Set the output Volume To argument. (V2) ! 2118: * AHIC_OutputVolume_Query (V2) ! 2119: * ! 2120: * AHIC_Input - Use the argument:th input source (Default is 0). (V2) ! 2121: * AHIC_Input_Query (V2) ! 2122: * ! 2123: * AHIC_Output - Use the argument:th output destination (Default ! 2124: * is 0). (V2) ! 2125: * AHIC_Output_Query (V2) ! 2126: * ! 2127: * argument - What value attribute should be set To. ! 2128: * audioctrl - Pointer To an AHIAudioCtrlDrv structure. ! 2129: * ! 2130: * RESULT ! 2131: * Return the state of selected attribute. If you were asked To set ! 2132: * something, Return True. If attribute is unknown To you OR unsupported, ! 2133: * Return False. ! 2134: * ! 2135: * NOTES ! 2136: * This Call must be safe from interrupts. ! 2137: * ! 2138: * SEE ALSO ! 2139: * ahi.device/AHI_ControlAudioA(), AHIsub_GetAttr() ! 2140: * ! 2141: ***************************************************************************** ! 2142: * ! 2143: * ! 2144: ! 2145: AHIsub_HardwareControl: ! 2146: CMP.l #AHIC_MonitorVolume,d0 ! 2147: BNE.b .dontsetmonvol ! 2148: MOVE.l ahiac_DriverData(a2),a1 ! 2149: LSR.l #8,d1 ! 2150: LSR.l #2,d1 ! 2151: MOVE.w d1,p_MonitorVolume(a1) ! 2152: BRA.b .exit ! 2153: .dontsetmonvol ! 2154: CMP.l #AHIC_MonitorVolume_Query,d0 ! 2155: BNE.b .dontgetmonvol ! 2156: MOVE.l ahiac_DriverData(a2),a1 ! 2157: MOVEQ #0,d0 ! 2158: MOVE.w p_MonitorVolume(a1),d0 ! 2159: LSL.l #8,d0 ! 2160: LSL.l #2,d0 ! 2161: BRA.b .quit ! 2162: .dontgetmonvol ! 2163: CMP.l #AHIC_Input,d0 ! 2164: BNE.b .dontsetinput ! 2165: MOVE.l ahiac_DriverData(a2),a1 ! 2166: MOVE.w d1,p_Input(a1) ! 2167: BRA.b .exit ! 2168: .dontsetinput ! 2169: CMP.l #AHIC_Input_Query,d0 ! 2170: BNE.b .dontgetinput ! 2171: MOVE.l ahiac_DriverData(a2),a1 ! 2172: MOVEQ #0,d0 ! 2173: MOVE.w p_Input(a1),d0 ! 2174: BRA.b .quit ! 2175: .dontgetinput ! 2176: MOVEQ #FALSE,d0 ! 2177: .quit ! 2178: RTS ! 2179: .exit ! 2180: MOVEQ #TRUE,d0 ! 2181: RTS ! 2182: ! 2183: ! 2184: ! 2185: ! 2186: ! 2187: ! 2188: ! 2189: ;---------------------------------------------------------------------------- ! 2190: ! 2191: Interrupt_Dummy: ! 2192: MOVE.w #INTF_AUD0!INTF_AUD1!INTF_AUD2!INTF_AUD3,INTREQ(a0) ! 2193: SoftInt_Dummy: ! 2194: RTS ! 2195: ! 2196: ;in: ! 2197: * d0 scratch ! 2198: * d1 INTENAR && INTREQR ! 2199: * a0 CUSTOM ! 2200: * a1 &(paulaBase->p_RecIntData) ! 2201: * a5 &RecordInterrupt ! 2202: * a6 ExecBase ! 2203: RecordInterrupt: ! 2204: ! 2205: * This Function will be executed up To 28000 times per second - that's once per ! 2206: * rasterline! It has To be as fast as possible. ! 2207: ! 2208: MOVE.w #INTF_AUD2!INTF_AUD3,INTREQ(a0) ;Clear the interrupt flags ! 2209: MOVEQ #0,d0 ! 2210: ;move.b _ciaa+ciaprb,d0 ;read parallel port ! 2211: IFD MC020 ! 2212: ;move.l convtable(pc,d0.w*4),d0 ;1 unsigned byte -> 2 signed words ! 2213: Else ! 2214: ADD.w d0,d0 ! 2215: ADD.w d0,d0 ! 2216: ;move.l convtable(pc,d0.w),d0 ! 2217: ENDC ! 2218: MOVE.w d0,AUD2DAT(a0) ;right ! 2219: MOVE.w d0,AUD3DAT(a0) ;left ! 2220: ! 2221: MOVE.l (a1),a5 ;p_RecFillPtr ! 2222: MOVE.l d0,(a5)+ ;store sample in buffer ! 2223: MOVE.l a5,(a1)+ ;update pointer ! 2224: SUBQ.w #1,(a1) ;p_ReqFillCount ! 2225: BEQ ri_Filled ;branch if buffer filled ! 2226: RTS ! 2227: ! 2228: ;convtable ! 2229: ;CNT SET 0 ! 2230: ; REPT 256 ! 2231: ; dc.b CNT-128,CNT-128,CNT-128,CNT-128 ! 2232: ; SET CNT+1 ! 2233: ; ENDR ! 2234: ! 2235: ;in: ! 2236: * d0 scratch ! 2237: * d1 INTENAR && INTREQR ! 2238: * a0 CUSTOM ! 2239: * a1 &(paulaBase->p_RecIntDataAura) ! 2240: * a5 &RecordInterrupt ! 2241: * a6 ExecBase ! 2242: RecordInterruptAura: ! 2243: MOVE.w #INTF_AUD2!INTF_AUD3,INTREQ(a0) ;Clear the interrupt flags ! 2244: MOVE.l (a1)+,a5 ! 2245: MOVE.l (a5),d0 ;read aura sampler ! 2246: EOR.l #$80008000,d0 ! 2247: MOVE.l (a1),a5 ;p_RecFillPtr ! 2248: MOVE.l d0,(a5)+ ;store sample in buffer ! 2249: MOVE.l a5,(a1)+ ;update pointer ! 2250: ! 2251: MOVE.w d0,d1 ! 2252: LSR.w #8,d0 ! 2253: MOVE.b d0,d1 ! 2254: ! 2255: MOVE.w d1,AUD2DAT(a0) ;right ! 2256: MOVE.w d1,AUD3DAT(a0) ;left ! 2257: ! 2258: SUBQ.w #1,(a1) ;p_ReqFillCount ! 2259: BEQ ri_Filled ;branch if buffer filled ! 2260: RTS ! 2261: ! 2262: ri_Filled: ! 2263: ! 2264: * This part is only executed every RECORDSAMPLES:th time... No need To hurry. ! 2265: ! 2266: MOVE.l 8(a1),d0 ;p_RecBuffer2-> ! 2267: MOVE.l 4(a1),8(a1) ;p_RecBuffer1->p_RecBuffer2 ! 2268: MOVE.l d0,4(a1) ; ->p_RecBuffer1 ! 2269: MOVE.l d0,-4(a1) ;p_RecFillPtr ! 2270: MOVE.w #RECORDSAMPLES,(a1) ;p_ReqFillCount ! 2271: MOVE.l 12(a1),a1 ;p_RecSoftIntPtr ! 2272: JMP _LVOCause(a6) ! 2273: ! 2274: ! 2275: ;in: ! 2276: * d0 scratch ! 2277: * d1 scratch ! 2278: * a0 scratch ! 2279: * a1 paulaBase ! 2280: * a5 scratch ! 2281: RecordSoftInt: ! 2282: ! 2283: * This Function is NOT executed many times per second AND is therefore NOT ! 2284: * fully optimized... ;) ! 2285: push a2 ! 2286: MOVE.w p_MonitorVolume(a1),CUSTOM+AUD2VOL ! 2287: MOVE.w p_MonitorVolume(a1),CUSTOM+AUD3VOL ! 2288: MOVE.l p_RecBuffer2(a1),p_rmBuffer(a1) ! 2289: MOVE.l p_AudioCtrlP(a1),a2 ! 2290: LEA p_RecordMessage(a1),a1 ! 2291: MOVE.l ahiac_SamplerFunc(a2),a0 ! 2292: MOVE.l h_Entry(a0),a5 ! 2293: JSR (a5) ! 2294: pop a2 ! 2295: RTS ! 2296: ! 2297: ;in: ! 2298: * d0 scratch ! 2299: * d1 INTENAR && INTREQR ! 2300: * a0 CUSTOM ! 2301: * a1 &(paulaBase->p_PlayIntData) ! 2302: * a5 &AudioInterrupt ! 2303: * a6 ExecBase ! 2304: ! 2305: AudioInterrupt2: ;Two hardware channels used ! 2306: MOVEM.l a2/d2/d3,-(sp) ! 2307: MOVEQ #1,d3 ; Enable UAE-side AHI ! 2308: moveq #0,d2 ! 2309: MOVE.w 4(a1),d2 ; Length ! 2310: MOVE.l 6(a1),d1 ; Period ! 2311: LEA.l 12(a1),a2 ! 2312: NOT.w 10(a1) ;double buffering ! 2313: BEQ.b .1 ! 2314: ADD.w #4*4,a2 ! 2315: .1 ! 2316: LEA p_AudPtrs-p_PlaySoftIntPtr(a1),a5; ! 2317: ! 2318: MOVE.l a2,(a5) ! 2319: MOVE.l (a2)+,a0 ! 2320: MOVEQ #3,d0 ! 2321: jsr $F0FFB0 ; Left channel ! 2322: MOVE.l (a2)+,a0 ! 2323: MOVEQ #4,d0 ! 2324: jsr $F0FFB0 ; Right channel ! 2325: ! 2326: moveq #2,d0 ! 2327: moveq #1,d1 ! 2328: jsr $F0FFB0 ; Enable AHI. ! 2329: ! 2330: MOVE.l (a1),a1 ;p_PlaySoftInt ! 2331: MOVEM.l (sp)+,a2/d2/d3 ! 2332: MOVE.w #INTF_AUD0,$DFF09C ;Clear the interrupt ! 2333: JMP _LVOCause(a6) ;start PlaySoftInt ! 2334: ! 2335: AudioInterrupt4: ;Four hardware channels used ! 2336: ! 2337: MOVEM.l (a1)+,d0/d1 ;p_PlaySoftIntPtr,p_AudLen/p_AudPer ! 2338: ! 2339: ! 2340: ! 2341: MOVE.l d1,AUD1LEN(a0) ! 2342: MOVE.l d1,AUD2LEN(a0) ! 2343: MOVE.l d1,AUD3LEN(a0) ! 2344: ! 2345: MOVE.l d1,AUD0LEN(a0) ! 2346: NOT.l (a1)+ ;double buffering ! 2347: ! 2348: LEA p_AudPtrs-p_AudPtr1A(a1),a5 ! 2349: BEQ.b .1 ! 2350: ! 2351: ADD.w #4*4,a1 ! 2352: ! 2353: .1 ! 2354: ! 2355: ! 2356: MOVE.l a1,(a5) ! 2357: MOVE.l (a1)+,AUD0LC(a0) ! 2358: MOVE.l (a1)+,AUD1LC(a0) ! 2359: MOVE.l (a1)+,AUD2LC(a0) ! 2360: MOVE.l (a1)+,AUD3LC(a0) ! 2361: MOVE.l d0,a1 ;p_PlaySoftInt ! 2362: MOVE.w #INTF_AUD0,INTREQ(a0) ;Clear the interrupt ! 2363: ! 2364: JMP _LVOCause(a6) ;start PlaySoftInt ! 2365: ! 2366: ;in: ! 2367: * d0 scratch ! 2368: * d1 scratch ! 2369: * a0 scratch ! 2370: * a1 &(paulaBase->p_PlaySoftIntData) ! 2371: * a5 scratch ! 2372: ! 2373: SoftInt_16bitM: ! 2374: pushm a2/a3/a4/a6 ! 2375: MOVE.l a1,a5 ! 2376: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2377: JSR (a3) ;call Player Hook ! 2378: JSR (a4) ;call PreTimer ! 2379: BNE .exit ! 2380: MOVEM.l (a5),d0/a0/a1/a2/a3/a5 ! 2381: JSR (a3) ;call Mixer Hook ! 2382: ! 2383: * convert AND transfer Buffer ! 2384: MOVE.l (a5),a0 ! 2385: .loop ! 2386: MOVE.w (a1)+,(a0)+ ! 2387: ! 2388: ; MOVE.w (a1)+,(a0)+ ! 2389: DBF d0,.loop ! 2390: .exit ! 2391: JSR (a6) ;call PostTimer, a2 ok ! 2392: popm a2/a3/a4/a6 ! 2393: MOVE.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,CUSTOM+DMACON ! 2394: RTS ! 2395: ! 2396: ;in: ! 2397: * d0 scratch ! 2398: * d1 scratch ! 2399: * a0 scratch ! 2400: * a1 &(paulaBase->p_PlaySoftIntData) ! 2401: * a5 scratch ! 2402: ! 2403: SoftInt_16bitS: ! 2404: pushm a2/a3/a4/a6 ! 2405: MOVE.l a1,a5 ! 2406: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2407: JSR (a3) ;call Player Hook ! 2408: JSR (a4) ;call PreTimer ! 2409: BNE .exit ! 2410: MOVEM.l (a5),d0/a0/a1/a2/a3/a5 ! 2411: JSR (a3) ;call Mixer Hook ! 2412: ! 2413: * convert AND transfer Buffer ! 2414: MOVEM.l (a5),a0/a3 ! 2415: .loop ! 2416: ; REPT 2 ! 2417: ;left ! 2418: MOVE.w (a1)+,(a3)+ ! 2419: ;right ! 2420: MOVE.w (a1)+,(a0)+ ! 2421: ; ENDR ! 2422: DBF d0,.loop ! 2423: .exit ! 2424: JSR (a6) ;call PostTimer, a2 ok ! 2425: popm a2/a3/a4/a6 ! 2426: MOVE.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1,CUSTOM+DMACON ! 2427: RTS ! 2428: ! 2429: ;in: ! 2430: * d0 scratch ! 2431: * d1 scratch ! 2432: * a0 scratch ! 2433: * a1 &(paulaBase->p_PlaySoftIntData) ! 2434: * a5 scratch ! 2435: ! 2436: SoftInt_14bitM: ! 2437: pushm a2/a3/a4/a6 ! 2438: MOVE.l a1,a5 ! 2439: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2440: JSR (a3) ;call Player Hook ! 2441: JSR (a4) ;call PreTimer ! 2442: BNE .exit ! 2443: MOVEM.l (a5),d0/a0/a1/a2/a3/a5 ! 2444: JSR (a3) ;call Mixer Hook ! 2445: ! 2446: * convert AND transfer Buffer ! 2447: MOVEM.l (a5),a0/a3/a4/a5 ;a3/a4 unused ! 2448: .loop ! 2449: REPT 2 ! 2450: MOVE.b (a1)+,(a0)+ ! 2451: MOVE.b (a1)+,d1 ! 2452: LSR.b #2,d1 ! 2453: MOVE.b d1,(a5)+ ! 2454: ENDR ! 2455: DBF d0,.loop ! 2456: .exit ! 2457: JSR (a6) ;call PostTimer, a2 ok ! 2458: popm a2/a3/a4/a6 ! 2459: MOVE.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,CUSTOM+DMACON ! 2460: RTS ! 2461: ! 2462: ;in: ! 2463: * d0 scratch ! 2464: * d1 scratch ! 2465: * a0 scratch ! 2466: * a1 &(paulaBase->p_PlaySoftIntData) ! 2467: * a5 scratch ! 2468: ! 2469: SoftInt_14CbitM: ! 2470: pushm a2/a3/a4/a6 ! 2471: MOVE.l a1,a5 ! 2472: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2473: JSR (a3) ;call Player Hook ! 2474: JSR (a4) ;call PreTimer ! 2475: BNE .exit ! 2476: MOVEM.l (a5),d0/a0/a1/a2/a3/a4/a5 ! 2477: JSR (a3) ;call Mixer Hook ! 2478: ! 2479: * convert AND transfer Buffer, using the table ! 2480: MOVE.l (a4),a0 ! 2481: MOVE.l 12(a4),a4 ! 2482: MOVEQ #0,d1 ! 2483: .loop ! 2484: ! 2485: REPT 2 ! 2486: IFD MC020 ! 2487: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2488: MOVE.w (a5,d1.l*2),d1 ! 2489: Else ! 2490: MOVEQ #0,d1 ! 2491: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2492: ADD.w d1,d1 ! 2493: MOVE.w (a5,d1.l),d1 ! 2494: ENDC ! 2495: MOVE.b d1,(a4)+ ;low byte ! 2496: LSR.w #8,d1 ! 2497: MOVE.b d1,(a0)+ ;high byte ! 2498: ENDR ! 2499: DBF d0,.loop ! 2500: .exit ! 2501: JSR (a6) ;call PostTimer, a2 ok ! 2502: popm a2/a3/a4/a6 ! 2503: MOVE.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,CUSTOM+DMACON ! 2504: RTS ! 2505: ! 2506: ;in: ! 2507: * d0 scratch ! 2508: * d1 scratch ! 2509: * a0 scratch ! 2510: * a1 &(paulaBase->p_PlaySoftIntData) ! 2511: * a5 scratch ! 2512: ! 2513: SoftInt_14bitS: ! 2514: pushm a2/a3/a4/a6 ! 2515: MOVE.l a1,a5 ! 2516: ! 2517: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2518: JSR (a3) ;call Player Hook ! 2519: JSR (a4) ;call PreTimer ! 2520: BNE .exit ! 2521: MOVEM.l (a5),d0/a0/a1/a2/a3/a5 ! 2522: JSR (a3) ;call Mixer Hook ! 2523: push a2 ! 2524: * convert AND transfer Buffer ! 2525: * TODO: Use a table! ! 2526: ! 2527: MOVEM.l (a5),a0/a2/a3/a5 ! 2528: ;move.l d2,-(a7) ! 2529: ! 2530: .loop ! 2531: REPT 2 ! 2532: ;left ! 2533: ! 2534: ;add.b #1,check ! 2535: MOVE.b (a1)+,(a2)+ ;used for uae ! 2536: MOVE.b (a1)+,(a3)+ ! 2537: ;move.b check,(a2)+ ! 2538: ;right ! 2539: MOVE.b (a1)+,(a0)+ ! 2540: MOVE.b (a1)+,(a5)+ ! 2541: ENDR ! 2542: DBF d0,.loop ! 2543: ;movem.l (a7)+,d2 ! 2544: pop a2 ! 2545: .exit ! 2546: JSR (a6) ;call PostTimer, a2 ok ! 2547: popm a2/a3/a4/a6 ! 2548: ;move.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,CUSTOM+DMACON ! 2549: RTS ! 2550: ! 2551: ;in: ! 2552: * d0 scratch ! 2553: * d1 scratch ! 2554: * a0 scratch ! 2555: * a1 &(paulaBase->p_PlaySoftIntData) ! 2556: * a5 scratch ! 2557: ! 2558: SoftInt_14CbitS: ! 2559: pushm a2/a3/a4/a6 ! 2560: MOVE.l a1,a5 ! 2561: MOVEM.l (a5)+,a0/a1/a2/a3/a4/a6 ! 2562: JSR (a3) ;call Player Hook ! 2563: JSR (a4) ;call PreTimer ! 2564: BNE .exit ! 2565: MOVEM.l (a5),d0/a0/a1/a2/a3/a4/a5 ! 2566: JSR (a3) ;call Mixer Hook ! 2567: push a2 ! 2568: * convert AND transfer Buffer, using the table ! 2569: MOVEM.l (a4),a0/a2/a3/a4 ! 2570: MOVEQ #0,d1 ! 2571: .loop ! 2572: REPT 2 ! 2573: ! 2574: ;left ! 2575: IFD MC020 ! 2576: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2577: MOVE.w (a5,d1.l*2),d1 ! 2578: Else ! 2579: MOVEQ #0,d1 ! 2580: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2581: ADD.w d1,d1 ! 2582: MOVE.w (a5,d1.l),d1 ! 2583: ENDC ! 2584: MOVE.b d1,(a3)+ ;low byte ! 2585: LSR.w #8,d1 ! 2586: MOVE.b d1,(a2)+ ;high byte ! 2587: ! 2588: ;right ! 2589: IFD MC020 ! 2590: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2591: MOVE.w (a5,d1.l*2),d1 ! 2592: Else ! 2593: MOVEQ #0,d1 ! 2594: MOVE.w (a1)+,d1 ;fetch 16 bit sample ! 2595: ADD.w d1,d1 ! 2596: MOVE.w (a5,d1.l),d1 ! 2597: ENDC ! 2598: MOVE.b d1,(a4)+ ;low byte ! 2599: LSR.w #8,d1 ! 2600: MOVE.b d1,(a0)+ ;high byte ! 2601: ENDR ! 2602: ! 2603: DBF d0,.loop ! 2604: pop a2 ! 2605: .exit ! 2606: JSR (a6) ;call PostTimer ! 2607: popm a2/a3/a4/a6 ! 2608: ;move.w #DMAF_SETCLR|DMAF_AUD0|DMAF_AUD1|DMAF_AUD2|DMAF_AUD3,CUSTOM+DMACON ! 2609: RTS ! 2610: flag Dc.l 0 ! 2611: EndCode: ! 2612: check Dc.b 0 ! 2613: END
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.