Annotation of uae/amiga/source/uae.audio.asm, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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