2 ** XModule replay routine 0.1
4 ** Copyright (C) 1995,96 Bernardo Innocenti
8 DEBUG_VERSION EQU 0 ; Debug Code On/Off
9 USE_CALIBRATION EQU 0 ; Calibration On/Off
10 STAND_ALONE EQU 0 ; Start without XModule
17 dc.b '$VER: XModule_Replay 0.1 (6.1.96) © 1995,96 by Bernardo Innocenti.',$a
29 include exec/execbase.i
30 include exec/funcdef.i
31 include hardware/intbits.i
32 include hardware/custom.i
33 include devices/audio.i
35 include dos/dosextens.i
36 include graphics/gfxbase.i
38 include libraries/songclass.i
54 move.l sp,a1 ; Arguments array
58 lea 4(sp),sp ; Fix stack
67 * An harmless Enforcer hit to help debugging operations :-)
75 ***************************************************************************
77 ***************************************************************************
83 lea _DATA_BAS_+32766,a4
90 * D3 is the return code for the startup message
93 * Find this task's process structure
100 move.l ex_EClockFrequency(a6),d0
102 lsl.l #2,d1 ; #3 for panning support
104 move.l d0,ClockBase ; Clock constant
106 * Open graphics.library
108 moveq.l #0,d0 ; Library version
110 move.l d0,_GFXBase(a4)
113 move.l #ERROR_INVALID_RESIDENT_LIBRARY,d3
118 * Wait for startup message
119 lea pr_MsgPort(a2),a2 ; a2 still contains our Process structure.
123 * Get startup message
128 * Get parent task address
129 move.l MN_REPLYPORT(a1),a0
130 move.l MP_SIGTASK(a0),ParentTask(a4)
132 * Reply startup message
133 move.l d3,pcmd_Err(a1) ; Put returncode
141 * Go ahead to MainLoop
144 ***************************************************************************
146 ***************************************************************************
154 move.b MP_SIGBIT(a2),d1
156 bset.l #SIGBREAKB_CTRL_C,d0
158 move.l d0,d2 ; Save signal bits
175 move.l pcmd_ID(a3),d0
176 cmp.l #PCMD_COUNT,d0 ; Check if command is supported
182 move.l .jumptable(pc,d0),a1
187 move.l d0,pcmd_Err(a3) ; Set returncode
189 JSRLIB ReplyMsg ; Return message to parent...
191 bra.s .checkmsg ; ...and check for more messages
197 moveq #PERR_UNKNOWN_COMMAND,d0
206 * Check for abort signal
207 btst.l #SIGBREAKB_CTRL_C,d2
210 * Note: I'm falling down to Exit.
214 ***************************************************************************
216 ***************************************************************************
220 * Close graphics.library
222 move.l _GFXBase(a4),d0
230 * This rts will remove our process and call UnLoadSeg() on us.
236 GFXName dc.b 'graphics.library',0
237 AudioDevName dc.b 'audio.device',0
243 ***************************************************************************
244 * LONG error = CmdInit (struct PlayerCmd *pcmd, struct ExecBase *SysBase)
246 ***************************************************************************
249 move.l a3,-(a7) ; Save a3
250 move.l pcmd_Data(a0),a3 ; get SongInfo
252 * Allocate audio channels
255 lea AudioDevName(pc),a0
256 lea AllocIORequest(a4),a1
259 bne .AllocFail ; Error
261 * Set audio interrupts
262 move.w AttnFlags(a6),d0
263 btst.l #AFB_68020,d0 ; >= 68020 CPU ?
264 bne.s .CPU68020 ; yes !
268 lea Audio0IRQ_000(a4),a1
269 JSRLIB SetIntVector ; set new Audio0-IRQ
270 move.l d0,_OldAudio0(a4)
273 lea Audio1IRQ_000(a4),a1
274 JSRLIB SetIntVector ; set new Audio1-IRQ
275 move.l d0,_OldAudio1(a4)
280 lea Audio0IRQ_020(a4),a1
281 JSRLIB SetIntVector ; set new Audio0-IRQ
282 move.l d0,_OldAudio0(a4)
285 lea Audio1IRQ_020(a4),a1
286 JSRLIB SetIntVector ; set new Audio1-IRQ
287 move.l d0,_OldAudio1(a4)
291 * Initialize ScaleFactor
292 move.w si_MaxTracks(a3),d1
293 move.w d1,ChannelNum(a4)
295 moveq #32,d0 ; max. channels (16 for no panning!)
297 move.w d0,ScaleFactor ; set ScaleFactor
299 * Initialize player. Warning: these calls will trash all registrers!
300 movem.l d2-d7/a2-a6,-(a7)
301 jsr InitSVolTable(pc)
302 jsr InitBoostTable(pc)
303 jsr InitTracksNChannels(pc)
304 bsr NewMixFreq ; MixPeriod berechnen
305 movem.l (sp)+,d2-d7/a2-a6
307 * Audio hardware twiddling
309 move.w #$000f,dmacon(a0) ; Audio-DMA aus
310 move.w #$00ff,adkcon(a0)
311 move.w #$0780,intreq(a0) ; Audio-Req. löschen
312 move.w #$0780,intena(a0) ; Audio-Int. aus
319 moveq #PERR_NO_AUDIO,d0
325 ***************************************************************************
326 * LONG error = CmdPlay (struct PlayerCmd *pcmd, struct ExecBase *SysBase)
328 ***************************************************************************
331 move.l pcmd_Data(a0),a0 ; get SongInfo
333 move.w si_MaxTracks(a0),mt_NumCh(a4) ; set channels
336 moveq #MAXCHANNELS-1,d0
361 ***************************************************************************
362 * void SetTimer (timeval)
364 ***************************************************************************
370 ***************************************************************************
371 * void SetTimer (void)
373 ***************************************************************************
379 *-----------------------------------------------------------------------*
384 ; move.l dtg_StopInt(a5),a0
385 ; jsr (a0) !!!!!!!!!!!!!!!!!!!
396 ; move.l dtg_StartInt(a5),a0
397 ; jsr (a0) !!!!!!!!!!!!!!!!!!!
400 *-----------------------------------------------------------------------*
405 ; move.l dtg_StopInt(a5),a0 !!!!!!!!!!!!!!!!!!!
417 ; move.l dtg_StartInt(a5),a0 !!!!!!!!!!!!!!!!!!
423 *-----------------------------------------------------------------------*
425 ; TakeTracker - Replay
427 ;********************************************
428 ;* ----- Protracker V1.1B Playroutine ----- *
429 ;* Lars "Zap" Hamre/Amiga Freelancers 1991 *
430 ;* Bekkeliveien 10, N-2010 STRØMMEN, Norway *
431 ;********************************************
437 move.l ex_EClockFrequency(a4),d1
440 add.l ex_EClockFrequency(a4),d1
450 ;---- Playroutine ----
464 UWORD pn_WantedPeriod
467 UBYTE pn_TonePortDirec
468 UBYTE pn_TonePortSpeed
475 UBYTE pn_SampleOffset
485 move.w si_Length(a0),mt_MaxPos
488 MOVE.W si_GlobalTempo(a0),d0
491 MOVE.W si_GlobalSpeed(a0),mt_speed
499 CLR.B mt_PattDelTime2
506 MOVEM.L D2-D7/A2-A6,-(SP)
521 TST.B mt_PattDelTime2
523 BSR.S mt_NoNewAllChannels
527 BSR.S mt_NoNewAllChannels
531 move.l NoteStructure,a5
537 lea NoteChannel_SIZE(a5),a5
544 move.l si_Patt(a0),a1
545 move.l si_Sequence(a0),a0
549 move.w (a0,d0.w),d0 ; Put current patt number in d0
551 move.l pa_Notes(a0,d0),a0 ; Get pointer to tracks array
553 move.l NoteStructure,a5
560 lea NoteChannel_SIZE(a5),a5
562 dbra d5,mt_GetNewLoop
566 CMP.W #NCHD_Ignore,nch_Stereo(a5)
577 move.l (a4,d0),a4 ; Pointer to channel
579 move.w mt_PatternPos,d0
582 move.l (a4,d0),(a6) ; Current note in (a6)
585 move.b note_Inst(a6),d2 ; Instrument number in d2
590 * Retrieve Instrument structure
596 move.l in_SampleData(a1),pn_Start(a6)
597 move.l in_Length(a1),pn_Length(a6)
598 move.l in_Length(a1),pn_RealLength(a6)
599 move.b in_FineTune+1(a1),pn_FineTune(a6)
600 move.b in_Volume(a1),pn_Volume(a6)
601 move.l in_Repeat(a1),d3 ; Get repeat
604 move.l pn_Start(a6),d2 ; Get start
605 add.l D3,D2 ; Add repeat
606 move.l D2,pn_LoopStart(a6)
607 move.l D2,pn_WaveStart(a6)
608 move.l in_Repeat(a1),d0 ; Get repeat
609 add.l in_Replen(a1),d0 ; Add replen
610 move.l d0,pn_Length(A6)
611 move.l in_Replen(a1),pn_Replen(a6) ; Save replen
613 MOVE.B pn_Volume(A6),D0
614 move.w d0,nch_Volume(a5)
615 bset.b #NCHB_Volume,nch_Changed(a5)
619 MOVE.L pn_Start(a6),d2
621 MOVE.L D2,pn_LoopStart(A6)
622 MOVE.L D2,pn_WaveStart(A6)
623 MOVE.L in_Replen(a1),pn_Replen(a6) ; Save replen
625 MOVE.B pn_Volume(A6),D0
626 move.w d0,nch_Volume(a5)
627 bset.b #NCHB_Volume,nch_Changed(a5)
630 move.b pn_Note(a6),d0
631 beq mt_CheckMoreEfx2 ; If no note
634 CMP.W #$0E50,D0 ; Check for E5
635 beq.s mt_DoSetFineTune
637 cmp.b #EFF_TONEPORTAMENTO,d0 ; TonePortamento
638 beq.s mt_ChkTonePorta
639 cmp.b #EFF_TONEPVOLSLIDE,d0
640 beq.s mt_ChkTonePorta
641 cmp.b #EFF_SAMPLEOFFSET,d0 ; Sample Offset
655 MOVEM.L D0-D1/A0-A1,-(SP)
657 move.b pn_Note(a6),d1 ; Find note period
658 sub.b #24,d1 ; Less octaves!!!
659 add.l d1,d1 ; Look up period table
661 lea mt_PeriodTable,a1
664 move.b pn_FineTune(a6),d1
667 move.w (a1,d0.w),pn_Period(a6)
668 movem.l (sp)+,d0-d1/a0-a1
672 CMP.W #$0ED0,D0 ; Notedelay
675 BTST #2,pn_WaveControl(A6)
677 CLR.B pn_VibratoPos(A6)
679 BTST #6,pn_WaveControl(A6)
681 CLR.B pn_TremoloPos(A6)
683 move.l pn_Start(a6),nch_SampleStart(a5)
684 move.l pn_Length(a6),d0
685 move.l d0,nch_SampleLength(a5)
686 bset.b #NCHB_Sample,nch_Changed(a5)
687 move.w pn_Period(A6),nch_Frequency(a5)
688 bset.b #NCHB_Frequency,nch_Changed(a5)
690 move.l pn_LoopStart(A6),nch_RepeatStart(a5)
691 move.l pn_Replen(A6),d0
692 move.l d0,nch_RepeatLength(a5)
693 bset.b #NCHB_Repeat,nch_Changed(a5)
697 MOVE.W mt_rsize,d0 ; !!!
698 ADD.W d0,mt_PatternPos
699 MOVE.B mt_PattDelTime,d0
701 MOVE.B d0,mt_PattDelTime2
703 mt_dskc TST.B mt_PattDelTime2
705 SUBQ.B #1,mt_PattDelTime2
708 SUB.W D0,mt_PatternPos
709 mt_dska TST.B mt_PBreakFlag
713 MOVE.W mt_PBreakPos,D0
716 MOVE.W D0,mt_PatternPos
718 MOVE.W mt_PatternPos,d0
722 MOVE.W mt_PBreakPos,d0
724 MOVE.W D0,mt_PatternPos
731 MOVE.W mt_StartPos,mt_SongPos
735 BNE.S mt_NextPosition
737 mt_exit MOVEM.L (SP)+,D2-D7/A2-A6
741 CMP.W #NCHD_Ignore,nch_Stereo(a5)
749 move.l efftable(pc),a0
755 SetBack move.w pn_Period(a6),nch_Frequency(a5)
756 bset.b #NCHB_Frequency,nch_Changed(a5)
761 dc.l mt_PerNop ; EFF_NULL
762 dc.l mt_PortaUp ; EFF_PORTAMENTOUP
763 dc.l mt_PortaDown ; EFF_PORTAMENTODOWN
764 dc.l mt_TonePortamento ; EFF_TONEPORTAMENTO
765 dc.l mt_Vibrato ; EFF_VIBRATO
766 dc.l mt_TonePlusVolSlide ; EFF_TONEPVOLSLIDE
767 dc.l mt_VibratoPlusVolSlide ; EFF_VIBRATOVOLSLIDE
768 dc.l mt_Tremolo ; EFF_TREMOLO
769 dc.l mt_PerNop ; EFF_UNUSED
770 dc.l mt_PerNop ; EFF_SAMPLEOFFSET
771 dc.l mt_VolumeSlide ; EFF_VOLSLIDE
772 dc.l mt_PerNop ; EFF_POSJUMP
773 dc.l mt_PerNop ; EFF_SETVOLUME
774 dc.l mt_PerNop ; EFF_PATTERNBREAK
775 dc.l mt_E_Commands ; EFF_MISC
776 dc.l mt_PerNop ; EFF_SETSPEED
777 dc.l mt_PerNop ; EFF_SETTEMPO
778 dc.l mt_Arpeggio ; EFF_ARPEGGIO
782 move.w pn_Period(A6),nch_Frequency(a5)
783 bset.b #NCHB_Frequency,nch_Changed(a5)
807 MOVE.W pn_Period(A6),D2
813 MOVE.B pn_FineTune(A6),D1
815 LEA mt_PeriodTable,A0
818 MOVE.W pn_Period(A6),D1
819 MOVEQ #35,D3 ; bugfix !!!
829 move.w d2,nch_Frequency(a5)
830 bset.b #NCHB_Frequency,nch_Changed(a5)
837 MOVE.B #$0F,mt_LowMask
842 MOVE.B #$FF,mt_LowMask
843 SUB.W D0,pn_Period(A6)
844 MOVE.W pn_Period(A6),D0
848 AND.W #$F000,pn_Period(A6)
849 OR.W #113,pn_Period(A6)
851 MOVE.W pn_Period(A6),D0
853 move.w d0,nch_Frequency(a5)
854 bset.b #NCHB_Frequency,nch_Changed(a5)
860 MOVE.B #$0F,mt_LowMask
865 MOVE.B #$FF,mt_LowMask
866 ADD.W D0,pn_Period(A6)
867 MOVE.W pn_Period(A6),D0
871 AND.W #$F000,pn_Period(A6)
872 OR.W #856,pn_Period(A6)
874 MOVE.W pn_Period(A6),D0
876 move.w d0,nch_Frequency(a5)
877 bset.b #NCHB_Frequency,nch_Changed(a5)
885 MOVE.B pn_FineTune(A6),D0
886 MULU #36*2,D0 ; bugfix !!!
887 LEA mt_PeriodTable,A0
894 CMP.W #36*2,D0 ; bugfix !!!
898 MOVE.B pn_FineTune(A6),D2
907 MOVE.W D2,pn_WantedPeriod(A6)
908 MOVE.W pn_Period(A6),D0
909 CLR.B pn_TonePortDirec(A6)
911 BEQ.S mt_ClearTonePorta
913 MOVE.B #1,pn_TonePortDirec(A6)
917 CLR.W pn_WantedPeriod(A6)
922 BEQ.S mt_TonePortNoChange
923 MOVE.B D0,pn_TonePortSpeed(A6)
926 TST.W pn_WantedPeriod(A6)
929 MOVE.B pn_TonePortSpeed(A6),D0
930 TST.B pn_TonePortDirec(A6)
933 ADD.W D0,pn_Period(A6)
934 MOVE.W pn_WantedPeriod(A6),D0
935 CMP.W pn_Period(A6),D0
936 BGT.S mt_TonePortaSetPer
937 MOVE.W pn_WantedPeriod(A6),pn_Period(A6)
938 CLR.W pn_WantedPeriod(A6)
939 BRA.S mt_TonePortaSetPer
942 SUB.W D0,pn_Period(A6)
943 MOVE.W pn_WantedPeriod(A6),D0
944 CMP.W pn_Period(A6),D0
945 BLT.S mt_TonePortaSetPer
946 MOVE.W pn_WantedPeriod(A6),pn_Period(A6)
947 CLR.W pn_WantedPeriod(A6)
950 MOVE.W pn_Period(A6),D2
951 MOVE.B pn_GlissFunk(A6),D0
955 MOVE.B pn_FineTune(A6),D0
957 LEA mt_PeriodTable,A0
970 move.w d2,nch_Frequency(a5)
971 bset.b #NCHB_Frequency,nch_Changed(a5)
977 MOVE.B pn_VibratoCmd(A6),D2
989 MOVE.B D2,pn_VibratoCmd(A6)
991 MOVE.B pn_VibratoPos(A6),D0
992 LEA mt_VibratoTable,A4
996 MOVE.B pn_WaveControl(A6),D2
1001 BEQ.S mt_vib_rampdown
1005 TST.B pn_VibratoPos(A6)
1006 BPL.S mt_vib_rampdown2
1016 MOVE.B pn_VibratoCmd(A6),D0
1020 MOVE.W pn_Period(A6),D0
1021 TST.B pn_VibratoPos(A6)
1028 move.w d0,nch_Frequency(a5)
1029 bset.b #NCHB_Frequency,nch_Changed(a5)
1030 MOVE.B pn_VibratoCmd(A6),D0
1033 ADD.B D0,pn_VibratoPos(A6)
1037 BSR mt_TonePortNoChange
1040 mt_VibratoPlusVolSlide
1045 MOVE.B pn_Val(A6),D0
1047 MOVE.B pn_TremoloCmd(A6),D2
1053 MOVE.B pn_Val(A6),D0
1059 MOVE.B D2,pn_TremoloCmd(A6)
1061 MOVE.B pn_TremoloPos(A6),D0
1062 LEA mt_VibratoTable,A4
1066 MOVE.B pn_WaveControl(A6),D2
1072 BEQ.S mt_tre_rampdown
1076 TST.B pn_VibratoPos(A6)
1077 BPL.S mt_tre_rampdown2
1087 MOVE.B pn_TremoloCmd(A6),D0
1092 MOVE.B pn_Volume(A6),D0
1093 TST.B pn_TremoloPos(A6)
1100 BPL.S mt_TremoloSkip
1107 move.w d0,nch_Volume(a5)
1108 bset.b #NCHB_Volume,nch_Changed(a5)
1109 MOVE.B pn_TremoloCmd(A6),D0
1112 ADD.B D0,pn_TremoloPos(A6)
1117 MOVE.B pn_Val(A6),D0
1119 MOVE.B D0,pn_SampleOffset(A6)
1121 MOVE.B pn_SampleOffset(A6),D0
1123 CMP.L pn_Length(A6),D0
1125 SUB.L D0,pn_Length(A6)
1127 ADD.L D0,pn_Start(A6)
1130 MOVE.L #$0001,pn_Length(A6)
1135 MOVE.B pn_Val(A6),D0
1138 BEQ.S mt_VolSlideDown
1140 ADD.B D0,pn_Volume(A6)
1141 CMP.B #$40,pn_Volume(A6)
1143 MOVE.B #$40,pn_Volume(A6)
1145 MOVE.B pn_Volume(A6),D0
1146 move.w d0,nch_Volume(a5)
1147 bset.b #NCHB_Volume,nch_Changed(a5)
1152 MOVE.B pn_Val(A6),D0
1155 SUB.B D0,pn_Volume(A6)
1159 MOVE.B pn_Volume(A6),D0
1160 move.w d0,nch_Volume(a5)
1161 bset.b #NCHB_Volume,nch_Changed(a5)
1165 MOVE.W mt_SongPos,D0
1170 mt_pj1 MOVE.B pn_Val(A6),D0
1178 MOVE.W D0,mt_SongPos
1181 mt_pj2 CLR.W mt_PBreakPos
1187 MOVE.B pn_Val(A6),D0
1192 MOVE.B D0,pn_Volume(A6)
1193 move.w d0,nch_Volume(a5)
1194 bset.b #NCHB_Volume,nch_Changed(a5)
1199 MOVE.B pn_Val(A6),D0
1207 MOVE.W D0,mt_PBreakPos
1244 MOVE.B pn_Val(A6),D0 ; !!!
1247 ; BEQ.S mt_FilterOnOff
1251 BEQ mt_FinePortaDown
1253 BEQ.S mt_SetGlissControl
1255 BEQ.S mt_SetVibratoControl
1257 BEQ.S mt_SetFineTune
1261 BEQ mt_SetTremoloControl
1267 BEQ mt_VolumeFineDown
1279 ; MOVE.B pn_Val(A6),D0
1282 ; AND.B #$FD,$BFE001
1287 MOVE.B pn_Val(A6),D0
1289 AND.B #$F0,pn_GlissFunk(A6)
1290 OR.B D0,pn_GlissFunk(A6)
1293 mt_SetVibratoControl
1294 MOVE.B pn_Val(A6),D0
1296 AND.B #$F0,pn_WaveControl(A6)
1297 OR.B D0,pn_WaveControl(A6)
1301 MOVE.B pn_Val(A6),D0
1303 MOVE.B D0,pn_FineTune(A6)
1309 MOVE.B pn_Val(A6),D0
1312 TST.B pn_LoopCount(A6)
1314 SUBQ.B #1,pn_LoopCount(A6)
1316 mt_jmploop MOVE.W pn_PattPos(A6),mt_PBreakPos
1321 MOVE.B D0,pn_LoopCount(A6)
1325 MOVE.W mt_PatternPos,D0
1327 MOVE.B D0,pn_PattPos(A6)
1330 mt_SetTremoloControl
1331 MOVE.B pn_Val(A6),D0
1334 AND.B #$0F,pn_WaveControl(A6)
1335 OR.B D0,pn_WaveControl(A6)
1341 MOVE.B pn_Val(A6),D0
1345 MOVE.W mt_counter,D1
1351 MOVE.W mt_counter,D1
1358 move.l pn_Start(a6),nch_SampleStart(a5)
1359 move.l pn_Length(a6),d0
1360 move.l d0,nch_SampleLength(a5)
1361 bset.b #NCHB_Sample,nch_Changed(a5)
1362 move.l pn_LoopStart(A6),nch_RepeatStart(a5)
1363 move.l pn_Replen(A6),d0
1364 move.l d0,nch_RepeatLength(a5)
1365 bset.b #NCHB_Repeat,nch_Changed(a5)
1366 move.w pn_Period(A6),nch_Frequency(a5)
1367 bset.b #NCHB_Frequency,nch_Changed(a5)
1376 MOVE.B pn_Val(A6),D0
1384 MOVE.B pn_Val(A6),D0
1386 BRA mt_VolSlideDown2
1390 MOVE.B pn_Val(A6),D0
1396 move.w d0,nch_Volume(a5)
1397 bset.b #NCHB_Volume,nch_Changed(a5)
1402 MOVE.B pn_Val(A6),D0
1415 MOVE.B pn_Val(A6),D0
1417 TST.B mt_PattDelTime2
1420 MOVE.B D0,mt_PattDelTime
1426 MOVE.B pn_Val(A6),D0
1429 AND.B #$0F,pn_GlissFunk(A6)
1430 OR.B D0,pn_GlissFunk(A6)
1436 MOVE.B pn_GlissFunk(A6),D0
1441 ADD.B D0,pn_FunkOffset(A6)
1442 BTST #7,pn_FunkOffset(A6)
1444 CLR.B pn_FunkOffset(A6)
1446 MOVE.L pn_LoopStart(A6),D0
1447 move.l pn_Replen(a6),d1
1450 MOVE.L pn_WaveStart(A6),A0
1454 MOVE.L pn_LoopStart(A6),A0
1456 MOVE.L A0,pn_WaveStart(A6)
1465 mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128
1468 dc.b 000,024,049,074,097,120,141,161
1469 dc.b 180,197,212,224,235,244,250,253
1470 dc.b 255,253,250,244,235,224,212,197
1471 dc.b 180,161,141,120,097,074,049,024
1475 dc.w 856,808,762,720,678,640,604,570,538,508,480,453
1476 dc.w 428,404,381,360,339,320,302,285,269,254,240,226
1477 dc.w 214,202,190,180,170,160,151,143,135,127,120,113
1479 dc.w 850,802,757,715,674,637,601,567,535,505,477,450
1480 dc.w 425,401,379,357,337,318,300,284,268,253,239,225
1481 dc.w 213,201,189,179,169,159,150,142,134,126,119,113
1483 dc.w 844,796,752,709,670,632,597,563,532,502,474,447
1484 dc.w 422,398,376,355,335,316,298,282,266,251,237,224
1485 dc.w 211,199,188,177,167,158,149,141,133,125,118,112
1487 dc.w 838,791,746,704,665,628,592,559,528,498,470,444
1488 dc.w 419,395,373,352,332,314,296,280,264,249,235,222
1489 dc.w 209,198,187,176,166,157,148,140,132,125,118,111
1491 dc.w 832,785,741,699,660,623,588,555,524,495,467,441
1492 dc.w 416,392,370,350,330,312,294,278,262,247,233,220
1493 dc.w 208,196,185,175,165,156,147,139,131,124,117,110
1495 dc.w 826,779,736,694,655,619,584,551,520,491,463,437
1496 dc.w 413,390,368,347,328,309,292,276,260,245,232,219
1497 dc.w 206,195,184,174,164,155,146,138,130,123,116,109
1499 dc.w 820,774,730,689,651,614,580,547,516,487,460,434
1500 dc.w 410,387,365,345,325,307,290,274,258,244,230,217
1501 dc.w 205,193,183,172,163,154,145,137,129,122,115,109
1503 dc.w 814,768,725,684,646,610,575,543,513,484,457,431
1504 dc.w 407,384,363,342,323,305,288,272,256,242,228,216
1505 dc.w 204,192,181,171,161,152,144,136,128,121,114,108
1507 dc.w 907,856,808,762,720,678,640,604,570,538,508,480
1508 dc.w 453,428,404,381,360,339,320,302,285,269,254,240
1509 dc.w 226,214,202,190,180,170,160,151,143,135,127,120
1511 dc.w 900,850,802,757,715,675,636,601,567,535,505,477
1512 dc.w 450,425,401,379,357,337,318,300,284,268,253,238
1513 dc.w 225,212,200,189,179,169,159,150,142,134,126,119
1515 dc.w 894,844,796,752,709,670,632,597,563,532,502,474
1516 dc.w 447,422,398,376,355,335,316,298,282,266,251,237
1517 dc.w 223,211,199,188,177,167,158,149,141,133,125,118
1519 dc.w 887,838,791,746,704,665,628,592,559,528,498,470
1520 dc.w 444,419,395,373,352,332,314,296,280,264,249,235
1521 dc.w 222,209,198,187,176,166,157,148,140,132,125,118
1523 dc.w 881,832,785,741,699,660,623,588,555,524,494,467
1524 dc.w 441,416,392,370,350,330,312,294,278,262,247,233
1525 dc.w 220,208,196,185,175,165,156,147,139,131,123,117
1527 dc.w 875,826,779,736,694,655,619,584,551,520,491,463
1528 dc.w 437,413,390,368,347,328,309,292,276,260,245,232
1529 dc.w 219,206,195,184,174,164,155,146,138,130,123,116
1531 dc.w 868,820,774,730,689,651,614,580,547,516,487,460
1532 dc.w 434,410,387,365,345,325,307,290,274,258,244,230
1533 dc.w 217,205,193,183,172,163,154,145,137,129,122,115
1535 dc.w 862,814,768,725,684,646,610,575,543,513,484,457
1536 dc.w 431,407,384,363,342,323,305,288,272,256,242,228
1537 dc.w 216,203,192,181,171,161,152,144,136,128,121,114
1543 *-----------------------------------------------------------------------*
1545 ; 14Bit/32Voices-NotePlayer
1550 move.l NoteInfo,d0 ; get NoteStructure
1554 move.l nst_Channels(a4),d0 ; pointer to first channel in list
1556 move.l d0,a2 ; ^NoteChannel
1558 cmpi.w #NCHD_Ignore,nch_Stereo(a2) ; skip this channel ?
1559 beq AO_PlayNext ; yes !
1561 move.l nch_NotePlayer(a2),d0 ; channel array
1562 beq AO_PlayNext ; no array !
1566 tst.l (a0) ; Channel disabled ?
1567 beq AO_PlayNext ; yes !
1569 move.l 4(a3),a3 ; ^TrackStructure
1571 btst.b #NCHB_Sample,nch_Changed(a2)
1572 beq.s AO_Repeat ; no new sample !
1574 move.l nch_SampleStart(a2),a0
1575 move.l nch_SampleLength(a2),d0
1577 move.l a0,td_SPtr(a3) ; Pointer auf das Sampleende
1579 move.l d0,td_SLen(a3) ; negative Sample-Restbytes
1581 clr.l td_LLen(a3) ; Kein LoopSample vorhanden
1583 clr.w td_FreC(a3) ; -> Kein Überlauf bei erstem Samplebyte!
1585 btst.b #NCHB_Repeat,nch_Changed(a2)
1586 beq.s AO_Frequency ; no new repeat !
1588 move.l nch_RepeatStart(a2),a0
1589 move.l nch_RepeatLength(a2),d0
1591 cmp.l d0,d1 ; Repeat-Length only 1 Word ?
1592 bne.s AO_RepSamp ; No !
1595 cmp.b (a1)+,d1 ; Is it a NullSample ?
1596 bne.s AO_RepSamp ; No !
1600 move.l a0,td_LPtr(a3) ; LoopSample-Endadr.
1602 move.l d0,td_LLen(a3) ; negative LoopSample-Länge
1604 btst.b #NCHB_Frequency,nch_Changed(a2)
1605 beq.s AO_Volume ; no new freq !
1607 move.l nch_Frequency(a2),td_Fre(a3) ; Frequency for this channel
1609 btst.b #NCHB_Volume,nch_Changed(a2)
1610 beq.s AO_PlayNext ; no new vol !
1613 move.w nch_Volume(a2),d0
1615 divu nst_MaxVolume(a4),d0
1616 move.w d0,td_Vol(a3) ; Volume for this channel
1618 move.l nch_NextChannel(a2),d0
1619 bne AO_PlayLoop ; next channel
1624 *-----------------------------------------------------------------------*
1626 ; Set the master volume/balance
1629 ; move.l NoteInfo,d0 ; get NoteStructure
1632 ; move.l delibase,a5 ; get DeliBase
1634 ; move.w dtg_SndVol(a5),d0
1635 ; mulu dtg_SndLBal(a5),d0
1637 ; move.w d0,Volume07 ; left volume
1639 ; move.w dtg_SndVol(a5),d0
1640 ; mulu dtg_SndRBal(a5),d0
1642 ; move.w d0,Volume8F ; right volume
1646 *-----------------------------------------------------------------------*
1648 ; Set the mixing frequency
1651 move.l ClockBase(pc),d0
1655 move.l ClockBase(pc),d1
1661 *-----------------------------------------------------------------------*
1663 ; Shut down the NotePlayer
1666 move.l NoteInfo,d0 ; get NoteStructure
1668 move.l d0,a4 ; copy Ptr
1671 move.w #$000f,dmacon(a0) ; Audio-DMA aus
1672 move.w #$00ff,adkcon(a0)
1673 move.w #$0780,intreq(a0) ; Audio-Req. löschen
1674 move.w #$0780,intena(a0) ; Audio-Int. aus
1676 move.l nst_Channels(a4),d0 ; pointer to first channel in list
1679 clr.l nch_NotePlayer(a0) ; clear channel array pointer
1681 move.l nch_NextChannel(a0),d0
1682 bne.s .FreeChan ; next channel
1685 move.l _OldAudio1,a1
1686 JSRLIB SetIntVector ; set old Audio1-IRQ
1689 move.l _OldAudio0,a1
1690 JSRLIB SetIntVector ; set old Audio0-IRQ
1692 lea AllocIORequest,a1 ; close audio.device
1695 clr.l NoteInfo ; shutdown complete
1700 *-----------------------------------------------------------------------*
1702 ; Boost-Value automatisch berechnen
1705 tst.l BoostFlag ; Boost-Wert automatisch berechnen ?
1706 beq.s .End ; nein, dann raus !
1709 move.w ChannelNum,d0
1722 *-----------------------------------------------------------------------*
1724 ; 14Bit-Output-Tabelle erzeugen (14Bit Routine by Markus "maw" Weichselbaum)
1726 IFEQ USE_CALIBRATION
1729 lea BitTable,a0 ; 14Bit-Tabelle erzeugen
1733 move.l BoostFactor,d2
1744 .Okay move.w d3,d4 ; ist das 16 bit sample negativ?
1746 .IsPos lsr.w #8,d3 ; hi byte fertig machen
1747 lsr.b #2,d4 ; vom lo nehmen wir nur die oberen 6 bits
1749 .IsNeg neg.w d3 ; erstmal auf positiv
1750 lsr.w #8,d3 ; das hi byte fertig machen
1751 neg.b d3 ; hi byte zurueck auf negativ
1752 neg.w d4 ; nochmal auf positiv
1753 lsr.b #2,d4 ; runter schieben
1754 neg.w d4 ; jetzt noch zurueck auf negativ
1755 .Write move.b d3,(a0)+ ; hier haben wir das hi byte
1756 move.b d4,(a0)+ ; hier haben wir das lo byte
1763 *-----------------------------------------------------------------------*
1765 ; 14Bit-Output-Tabelle erzeugen (14Bit Routine by Christian Buchner)
1767 IFNE USE_CALIBRATION
1769 TABLE_ENTRIES EQU 32768
1771 InitBoostTable movem.l a2-a3/d2-d7,-(sp)
1773 lea CalibData+128,a2
1775 .negative move.l a2,a1 ; count the number of steps
1776 moveq #128-1,d0 ; in the negative range
1778 .count1 move.b -(a1),d1
1782 dbra d0,.count1 ; d5=number of steps
1784 move.l #256*TABLE_ENTRIES/2,d6
1785 divu BoostFactor+2,d6 ; divide by boost factor
1786 divu d6,d5 ; calculate stepsize (d5) and
1789 move.w d5,d7 ; fractional part (d7)
1794 lea BTable,a0 ; place at the middle of table
1795 move.w #TABLE_ENTRIES/2-1,d0 ; number of negative values -1
1796 moveq #-1,d1 ; HI value
1797 moveq #-1,d2 ; LO value
1798 moveq #0,d3 ; counter
1799 .fetchnext1 move.b (a2,d1.w),d4 ; add calibtable to counter
1802 add.w d4,d2 ; maximize LO value
1803 .outerloop1 tst.w d3
1805 .negative1 subq.w #1,d1
1809 .positive1 move.b d2,-(a0) ; store LO and HI value
1811 sub.w d5,d2 ; subtract step size
1812 sub.w d5,d3 ; decrement counter
1813 sub.w d7,d6 ; sum up fractional part
1816 subq.w #1,d2 ; decrement lo value
1817 subq.w #1,d3 ; decrement counter
1818 .repeat1 dbra d0,.outerloop1
1821 .fillup1 move.w #$8000,-(a0) ; fill up the rest of the
1822 dbra d0,.fillup1 ; table with negative minimum
1824 .positive move.l a2,a1 ; count the number of steps
1825 moveq #128-1,d0 ; in the positive range
1827 .count2 move.b (a1)+,d1
1831 dbra d0,.count2 ; d5=number of steps
1833 move.l #256*TABLE_ENTRIES/2,d6
1834 divu BoostFactor+2,d6 ; divide by boost factor
1835 divu d6,d5 ; calculate stepsize (d5) and
1838 move.w d5,d7 ; fractional part (d7)
1843 lea BTable,a0 ; place at the middle of table
1844 move.w #TABLE_ENTRIES/2-1,d0 ; number of positive values -1
1845 moveq #0,d1 ; HI value
1846 moveq #0,d2 ; LO value
1847 moveq #0,d3 ; counter
1848 .fetchnext2 move.b (a2,d1.w),d4 ; add calibtable to counter
1851 .outerloop2 tst.w d3
1853 .negative2 addq.w #1,d1 ; increment HI value
1856 sub.w d4,d2 ; reset LO value
1858 .positive2 move.b d1,(a0)+ ; store HI and LO value
1860 add.w d5,d2 ; add step size
1861 sub.w d5,d3 ; decrement counter
1862 sub.w d7,d6 ; sum up fractional part
1865 addq.w #1,d2 ; increment LO value
1866 subq.w #1,d3 ; decrement counter
1867 .repeat2 dbra d0,.outerloop2
1870 .fillup2 move.w #$7F7E,(a0)+ ; fill up the rest of the
1871 dbra d0,.fillup2 ; table with positive maximum
1873 .finished movem.l (sp)+,a2-a3/d2-d7
1878 *-----------------------------------------------------------------------*
1880 ; Volume-Tabelle (signed) erzeugen
1883 lea VTable,a0 ; Volume-Tabelle erzeugen
1887 move.w ScaleFactor,d5
1892 muls d4,d3 ; Tabellennummer (0...64) * Samplewert
1898 add.w d5,d4 ; > 1 = Oversampling
1902 *-----------------------------------------------------------------------*
1904 ; Volume-Tabelle (unsigned) erzeugen
1907 lea VTable,a0 ; Volume-Tabelle erzeugen
1911 move.w ScaleFactor,d5
1912 .Loop1 moveq #-128,d0
1916 muls d4,d3 ; Tabellennummer (0...64) * Samplewert
1922 add.w d5,d4 ; > 1 = Oversampling
1926 *-----------------------------------------------------------------------*
1928 ; Alle 32 Software-Tracks initialisieren
1932 lea QuietInstr(pc),a1
1934 .Loop move.l (a1),td_SPtr(a0) ; Zum Abspielen vorbereiten
1935 move.l 4(a1),td_SLen(a0)
1936 move.l 8(a1),td_LPtr(a0)
1937 move.l 12(a1),td_LLen(a0)
1938 move.w #64,td_Vol(a0) ; Volle Lautstärke
1939 move.l #8287,td_Fre(a0) ; C 0
1944 * Alle 4 Audiokanäle initialisieren:
1948 .Init move.l #EmptyCBuf,ac_ptr(a0) ; Erstmal nichts spielen!
1949 move.w #MBuf_SIZE/2,ac_len(a0)
1950 move.w MixPeriod(pc),ac_per(a0)
1951 move.w #0,ac_vol(a0)
1952 adda.w #ac_SIZEOF,a0
1955 clr.w C03BufOff ; Erste Songdaten kommen in Buffer 0
1959 *-----------------------------------------------------------------------*
1964 move.l NoteInfo,d0 ; get NoteStructure
1968 bsr InitTracksNChannels
1971 move.l #InitSndTxt,-(sp)
1972 lea InformationFmt(pc),a0
1979 *-----------------------------------------------------------------------*
1984 move.l NoteInfo,d0 ; get NoteStructure
1988 bsr InitTracksNChannels
1991 move.l #EndSndTxt,-(sp)
1992 lea InformationFmt(pc),a0
1999 *-----------------------------------------------------------------------*
2005 move.w #$800f,dmacon(a0) ; Audio-DMA an
2006 move.w #$00ff,adkcon(a0)
2007 move.w #$0780,intreq(a0) ; Audio-Req. löschen
2008 move.w #$8180,intena(a0) ; Audio-Int. an
2010 move.w d0,aud0+ac_vol(a0)
2011 move.w d0,aud1+ac_vol(a0)
2013 move.w d0,aud2+ac_vol(a0)
2014 move.w d0,aud3+ac_vol(a0)
2018 *-----------------------------------------------------------------------*
2024 move.w #$000f,dmacon(a0) ; Audio-DMA aus
2025 move.w #$00ff,adkcon(a0)
2026 move.w #$0780,intreq(a0) ; Audio-Req. löschen
2027 move.w #$0780,intena(a0) ; Audio-Int. aus
2031 *-----------------------------------------------------------------------*
2033 ; Audio-Interrupts für 68000 und 68010
2035 * Tracks 00-0F zusammenmischen:
2039 * Achtung! Soeben begann das Abspielen des beim
2040 * letzten Interrupt gefüllten Channel-Buffers!
2042 move.w MixPeriod(pc),d0
2043 lea Softy0IRQ_000,a1
2044 cmpi.b #NT_SOFTINT,LN_TYPE(a1)
2046 addi.w #32,d0 ; step down
2048 move.l ClockBase(pc),d1
2052 move.w d0,aud0+ac_per(a0)
2053 move.w d0,aud3+ac_per(a0)
2054 move.w d0,aud1+ac_per(a0)
2055 move.w d0,aud2+ac_per(a0)
2059 move.w #INTF_AUD0,custom+intreq ; AudioInt-Request löschen
2063 movem.l d2-d7/a2-a6,-(sp)
2065 * Das rechenaufwendige Mixen passiert im Softint
2069 ; move.w #$f00,color(a0)
2072 move.w Volume07(pc),d2
2076 move.w Volume07(pc),d2
2080 move.w Volume07(pc),d2
2084 move.w Volume07(pc),d2
2088 move.w Volume07(pc),d2
2092 move.w Volume07(pc),d2
2096 move.w Volume07(pc),d2
2100 move.w Volume07(pc),d2
2104 move.w Volume07(pc),d2
2108 move.w Volume07(pc),d2
2112 move.w Volume07(pc),d2
2116 move.w Volume07(pc),d2
2120 move.w Volume07(pc),d2
2124 move.w Volume07(pc),d2
2128 move.w Volume07(pc),d2
2132 move.w Volume07(pc),d2
2135 ; move.w #$00f,color(a0)
2137 lea C0Buf,a2 ; Mix-Buffer konvertieren & löschen
2138 adda.w C03BufOff(pc),a2
2139 move.l a2,aud0+ac_ptr(a0)
2141 adda.w C03BufOff(pc),a3
2142 move.l a3,aud3+ac_ptr(a0)
2145 move.w #MBuf_SIZE/2-1,d0
2150 move.b 0(a5,d2.w),(a2)+ ; hier haben wir das hi byte
2151 move.b 0(a5,d3.w),(a2)+
2152 move.b 1(a5,d2.w),(a3)+ ; hier haben wir das lo byte
2153 move.b 1(a5,d3.w),(a3)+
2156 eor.w #MBuf_SIZE,C03BufOff ; Buffer flippen
2158 ; move.w #$000,color(a0)
2160 movem.l (sp)+,d2-d7/a2-a6
2164 * Tracks 10-1F zusammenmischen:
2168 * Achtung! Soeben begann das Abspielen des beim
2169 * letzten Interrupt gefüllten Channel-Buffers!
2171 move.w MixPeriod(pc),d0
2172 lea Softy1IRQ_000,a1
2173 cmpi.b #NT_SOFTINT,LN_TYPE(a1)
2175 addi.w #32,d0 ; step down
2177 move.l ClockBase(pc),d1
2181 move.w d0,aud0+ac_per(a0)
2182 move.w d0,aud3+ac_per(a0)
2183 move.w d0,aud1+ac_per(a0)
2184 move.w d0,aud2+ac_per(a0)
2188 move.w #INTF_AUD1,custom+intreq ; AudioInt-Request löschen
2192 movem.l d2-d7/a2-a6,-(sp)
2194 * Das rechenaufwendige Mixen passiert im Softint
2198 ; move.w #$0f0,color(a0)
2201 move.w Volume8F(pc),d2
2205 move.w Volume8F(pc),d2
2209 move.w Volume8F(pc),d2
2213 move.w Volume8F(pc),d2
2217 move.w Volume8F(pc),d2
2221 move.w Volume8F(pc),d2
2225 move.w Volume8F(pc),d2
2229 move.w Volume8F(pc),d2
2233 move.w Volume8F(pc),d2
2237 move.w Volume8F(pc),d2
2241 move.w Volume8F(pc),d2
2245 move.w Volume8F(pc),d2
2249 move.w Volume8F(pc),d2
2253 move.w Volume8F(pc),d2
2257 move.w Volume8F(pc),d2
2261 move.w Volume8F(pc),d2
2264 ; move.w #$00f,color(a0)
2266 lea C1Buf,a2 ; Mix-Buffer konvertieren & löschen
2267 adda.w C12BufOff(pc),a2
2268 move.l a2,aud1+ac_ptr(a0)
2270 adda.w C12BufOff(pc),a3
2271 move.l a3,aud2+ac_ptr(a0)
2274 move.w #MBuf_SIZE/2-1,d0
2279 move.b 0(a5,d2.w),(a2)+ ; hier haben wir das hi byte
2280 move.b 0(a5,d3.w),(a2)+
2281 move.b 1(a5,d2.w),(a3)+ ; hier haben wir das lo byte
2282 move.b 1(a5,d3.w),(a3)+
2285 eor.w #MBuf_SIZE,C12BufOff ; Buffer flippen
2287 ; move.w #$000,color(a0)
2289 movem.l (sp)+,d2-d7/a2-a6
2294 * Ein Sample zum Play-Buffer dazumixen
2296 * D2 = Gesamt-Volume des Channels
2297 * A2 = ^TrackData des zu mixenden Tracks
2301 move.l td_SPtr(a2),a3 ; Pointer auf das Sampleende
2302 move.l td_SLen(a2),d3 ; negative Restbytes des Samples
2303 bmi.s .MxCalc ; noch nicht am Sampleende angekommen!
2304 move.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2305 bpl .MxEnd ; Kein Loopsample da, also raus!
2306 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2307 .MxCalc mulu.w td_Vol(a2),d2 ; Volume des Samples
2311 lea VTable,a4 ; ^Volume-Table
2313 move.l td_Fre(a2),d5 ; individuelle Sample-Frequency
2314 divu MixFreq(pc),d5 ; globale Mix-Frequency
2316 move.w d5,d4 ; Period-Vorkommastellen
2318 divu MixFreq(pc),d5 ; Period-Nachkommastellen
2320 move.w td_FreC(a2),d6 ; Period-Nachkomma-Zähler
2329 add.l d3,d7 ; Restbytes nach dem Mixen
2332 * Hauptschleife - Registerbelegung:
2333 * D0.W = Temp.Register für die Samplebytes
2334 * D1.W = Temp.Register für die Samplewords
2335 * D2.W = Zähler für die MixLoop
2336 * D3.L = Restbytes vom Sample
2337 * D4.L = Vorkomma Faktor
2338 * D5.W = Nachkomma Faktor
2339 * D6.W = Nachkomma Zähler
2340 * D7 = Restbytes nach dem Mixen
2343 * A2 = Zeiger auf TrackData des Tracks
2344 * A3 = Zeiger auf das Ende des Samples
2345 * A4 = Zeiger auf Volume-Tabelle des Samples
2346 * A5 = Zeiger auf den Mix-Buffer
2350 .MxSamp lea MBuffer,a5 ; Pointer auf den Mix-Buffer
2351 move.w #MBuf_SIZE/2-1,d2 ; Zähler, bis MixBuffer voll
2353 tst.l d7 ; wird das Sampleende beim Mixen erreicht ?
2354 bmi .MxTst2 ; Nein, dann schnelle Mix-Routine benutzen!
2356 .MxTst1 tst.w d4 ; Period-Vorkommastellen Null?
2357 bne.s .MxLop3 ; Nein, dann normale Mix-Routine benutzen!
2362 move.b (a3)+,d0 ; erstes Samplebyte holen
2364 move.w 0(a4,d0.w),d1
2365 .MxLop0 add.w d1,(a5)+
2366 add.w d5,d6 ; Sample fortschalten
2369 bmi.s .MxGet1 ; noch nicht am Sampleende angekommen!
2370 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2371 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2372 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2375 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2377 move.w 0(a4,d0.w),d1
2378 .MxLop1 add.w d1,(a5)+
2379 add.w d5,d6 ; Sample fortschalten
2382 bmi.s .MxGet2 ; noch nicht am Sampleende angekommen!
2383 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2384 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2385 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2388 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2390 move.w 0(a4,d0.w),d1
2391 .MxLop2 dbra d2,.MxLop0 ; bis MixBuffer voll
2397 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2399 move.w 0(a4,d0.w),d1
2401 add.w d5,d6 ; Sample fortschalten
2403 bmi.s .MxLop4 ; noch nicht am Sampleende angekommen!
2404 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2405 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2406 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2408 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2410 move.w 0(a4,d0.w),d1
2412 add.w d5,d6 ; Sample fortschalten
2414 bmi.s .MxLop5 ; noch nicht am Sampleende angekommen!
2415 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2416 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2417 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2418 .MxLop5 dbra d2,.MxLop3 ; bis MixBuffer voll
2420 .MxPerC move.w d6,td_FreC(a2) ; Neuer Stand des Runtersample-Zählers
2421 .MxSPtr move.l a3,td_SPtr(a2) ; Endadresse des Samples sichern
2422 .MxSLen move.l d3,td_SLen(a2) ; Neue Position im Sample erreicht
2426 .MxTst2 tst.w d4 ; Period-Vorkommastellen Null?
2427 bne.s .MxLop9 ; Nein, dann normale Mix-Routine benutzen!
2433 move.b (a3)+,d0 ; erstes Samplebyte holen
2435 move.w 0(a4,d0.w),d1
2436 .MxLop6 add.w d1,(a5)+
2437 add.w d5,d6 ; Sample fortschalten
2440 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2442 move.w 0(a4,d0.w),d1
2443 .MxLop7 add.w d1,(a5)+
2444 add.w d5,d6 ; Sample fortschalten
2447 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2449 move.w 0(a4,d0.w),d1
2450 .MxLop8 dbra d2,.MxLop6 ; bis MixBuffer voll
2456 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2458 move.w 0(a4,d0.w),d1
2460 add.w d5,d6 ; Sample fortschalten
2463 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2465 move.w 0(a4,d0.w),d1
2467 add.w d5,d6 ; Sample fortschalten
2469 dbra d2,.MxLop9 ; bis MixBuffer voll
2472 *-----------------------------------------------------------------------*
2474 ; Audio-Interrupts für 68020 und höher
2476 * Tracks 00-0F zusammenmischen:
2480 * Achtung! Soeben begann das Abspielen des beim
2481 * letzten Interrupt gefüllten Channel-Buffers!
2483 move.w MixPeriod(pc),d0
2484 lea Softy0IRQ_020,a1
2485 cmpi.b #NT_SOFTINT,LN_TYPE(a1)
2487 addi.w #32,d0 ; step down
2489 move.l ClockBase(pc),d1
2493 move.w d0,aud0+ac_per(a0)
2494 move.w d0,aud3+ac_per(a0)
2495 move.w d0,aud1+ac_per(a0)
2496 move.w d0,aud2+ac_per(a0)
2500 move.w #INTF_AUD0,custom+intreq ; AudioInt-Request löschen
2504 movem.l d2-d7/a2-a6,-(sp)
2506 * Das rechenaufwendige Mixen passiert im Softint
2510 ; move.w #$f00,color(a0)
2513 move.w Volume07(pc),d2
2517 move.w Volume07(pc),d2
2521 move.w Volume07(pc),d2
2525 move.w Volume07(pc),d2
2529 move.w Volume07(pc),d2
2533 move.w Volume07(pc),d2
2537 move.w Volume07(pc),d2
2541 move.w Volume07(pc),d2
2545 move.w Volume07(pc),d2
2549 move.w Volume07(pc),d2
2553 move.w Volume07(pc),d2
2557 move.w Volume07(pc),d2
2561 move.w Volume07(pc),d2
2565 move.w Volume07(pc),d2
2569 move.w Volume07(pc),d2
2573 move.w Volume07(pc),d2
2576 ; move.w #$00f,color(a0)
2578 lea C0Buf,a2 ; Mix-Buffer konvertieren & löschen
2579 adda.w C03BufOff(pc),a2
2580 move.l a2,aud0+ac_ptr(a0)
2582 adda.w C03BufOff(pc),a3
2583 move.l a3,aud3+ac_ptr(a0)
2586 move.w #MBuf_SIZE/2-1,d0
2591 move.b 0(a5,d2.w),(a2)+ ; hier haben wir das hi byte
2592 move.b 0(a5,d3.w),(a2)+
2593 move.b 1(a5,d2.w),(a3)+ ; hier haben wir das lo byte
2594 move.b 1(a5,d3.w),(a3)+
2597 eor.w #MBuf_SIZE,C03BufOff ; Buffer flippen
2599 ; move.w #$000,color(a0)
2601 movem.l (sp)+,d2-d7/a2-a6
2605 * Tracks 10-1F zusammenmischen:
2609 * Achtung! Soeben begann das Abspielen des beim
2610 * letzten Interrupt gefüllten Channel-Buffers!
2612 move.w MixPeriod(pc),d0
2613 lea Softy1IRQ_020,a1
2614 cmpi.b #NT_SOFTINT,LN_TYPE(a1)
2616 addi.w #32,d0 ; step down
2618 move.l ClockBase(pc),d1
2622 move.w d0,aud0+ac_per(a0)
2623 move.w d0,aud3+ac_per(a0)
2624 move.w d0,aud1+ac_per(a0)
2625 move.w d0,aud2+ac_per(a0)
2629 move.w #INTF_AUD1,custom+intreq ; AudioInt-Request löschen
2633 movem.l d2-d7/a2-a6,-(sp)
2635 * Das rechenaufwendige Mixen passiert im Softint
2639 ; move.w #$0f0,color(a0)
2642 move.w Volume8F(pc),d2
2646 move.w Volume8F(pc),d2
2650 move.w Volume8F(pc),d2
2654 move.w Volume8F(pc),d2
2658 move.w Volume8F(pc),d2
2662 move.w Volume8F(pc),d2
2666 move.w Volume8F(pc),d2
2670 move.w Volume8F(pc),d2
2674 move.w Volume8F(pc),d2
2678 move.w Volume8F(pc),d2
2682 move.w Volume8F(pc),d2
2686 move.w Volume8F(pc),d2
2690 move.w Volume8F(pc),d2
2694 move.w Volume8F(pc),d2
2698 move.w Volume8F(pc),d2
2702 move.w Volume8F(pc),d2
2705 ; move.w #$00f,color(a0)
2707 lea C1Buf,a2 ; Mix-Buffer konvertieren & löschen
2708 adda.w C12BufOff(pc),a2
2709 move.l a2,aud1+ac_ptr(a0)
2711 adda.w C12BufOff(pc),a3
2712 move.l a3,aud2+ac_ptr(a0)
2715 move.w #MBuf_SIZE/2-1,d0
2720 move.b 0(a5,d2.w),(a2)+ ; hier haben wir das hi byte
2721 move.b 0(a5,d3.w),(a2)+
2722 move.b 1(a5,d2.w),(a3)+ ; hier haben wir das lo byte
2723 move.b 1(a5,d3.w),(a3)+
2726 eor.w #MBuf_SIZE,C12BufOff ; Buffer flippen
2728 ; move.w #$000,color(a0)
2730 movem.l (sp)+,d2-d7/a2-a6
2735 * Ein Sample zum Play-Buffer dazumixen
2737 * D2 = Gesamt-Volume des Channels
2738 * A2 = ^TrackData des zu mixenden Tracks
2742 move.l td_SPtr(a2),a3 ; Pointer auf das Sampleende
2743 move.l td_SLen(a2),d3 ; negative Restbytes des Samples
2744 bmi.s .MxCalc ; noch nicht am Sampleende angekommen!
2745 move.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2746 bpl .MxEnd ; Kein Loopsample da, also raus!
2747 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2748 .MxCalc mulu.w td_Vol(a2),d2 ; Volume des Samples
2752 lea VTable,a4 ; ^Volume-Table
2754 move.l td_Fre(a2),d5 ; individuelle Sample-Frequency
2755 divu MixFreq(pc),d5 ; globale Mix-Frequency
2757 move.w d5,d4 ; Period-Vorkommastellen
2759 divu MixFreq(pc),d5 ; Period-Nachkommastellen
2761 move.w td_FreC(a2),d6 ; Period-Nachkomma-Zähler
2770 add.l d3,d7 ; Restbytes nach dem Mixen
2773 * Hauptschleife - Registerbelegung:
2774 * D0.W = Temp.Register für die Samplebytes
2775 * D1.W = Temp.Register für die Samplewords
2776 * D2.W = Zähler für die MixLoop
2777 * D3.L = Restbytes vom Sample
2778 * D4.L = Vorkomma Faktor
2779 * D5.W = Nachkomma Faktor
2780 * D6.W = Nachkomma Zähler
2781 * D7 = Restbytes nach dem Mixen
2784 * A2 = Zeiger auf TrackData des Tracks
2785 * A3 = Zeiger auf das Ende des Samples
2786 * A4 = Zeiger auf Volume-Tabelle des Samples
2787 * A5 = Zeiger auf den Mix-Buffer
2791 .MxSamp lea MBuffer,a5 ; Pointer auf den Mix-Buffer
2792 move.w #MBuf_SIZE/2-1,d2 ; Zähler, bis MixBuffer voll
2794 tst.l d7 ; wird das Sampleende beim Mixen erreicht ?
2795 bmi .MxTst2 ; Nein, dann schnelle Mix-Routine benutzen!
2798 tst.w d4 ; Period-Vorkommastellen Null?
2799 bne.s .MxLop3 ; Nein, dann normale Mix-Routine benutzen!
2803 move.b (a3)+,d0 ; erstes Samplebyte holen
2804 move.w 0(a4,d0.w*2),d1
2805 .MxLop0 add.w d1,(a5)+
2806 add.w d5,d6 ; Sample fortschalten
2809 bmi.s .MxGet1 ; noch nicht am Sampleende angekommen!
2810 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2811 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2812 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2814 .MxGet1 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2815 move.w 0(a4,d0.w*2),d1
2816 .MxLop1 add.w d1,(a5)+
2817 add.w d5,d6 ; Sample fortschalten
2820 bmi.s .MxGet2 ; noch nicht am Sampleende angekommen!
2821 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2822 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2823 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2825 .MxGet2 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2826 move.w 0(a4,d0.w*2),d1
2827 .MxLop2 dbra d2,.MxLop0 ; bis MixBuffer voll
2832 .MxLop3 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2833 move.w 0(a4,d0.w*2),d1
2835 add.w d5,d6 ; Sample fortschalten
2837 bmi.s .MxLop4 ; noch nicht am Sampleende angekommen!
2838 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2839 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2840 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2841 .MxLop4 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2842 move.w 0(a4,d0.w*2),d1
2844 add.w d5,d6 ; Sample fortschalten
2846 bmi.s .MxLop5 ; noch nicht am Sampleende angekommen!
2847 add.l td_LLen(a2),d3 ; ist ein Loop-Sample vorhanden ?
2848 bpl.s .MxPerC ; Kein Loopsample da, also raus!
2849 move.l td_LPtr(a2),a3 ; Pointer auf das Loopende
2850 .MxLop5 dbra d2,.MxLop3 ; bis MixBuffer voll
2852 .MxPerC move.w d6,td_FreC(a2) ; Neuer Stand des Runtersample-Zählers
2853 .MxSPtr move.l a3,td_SPtr(a2) ; Endadresse des Samples sichern
2854 .MxSLen move.l d3,td_SLen(a2) ; Neue Position im Sample erreicht
2859 tst.w d4 ; Period-Vorkommastellen Null?
2860 bne.s .MxLop9 ; Nein, dann normale Mix-Routine benutzen!
2865 move.b (a3)+,d0 ; erstes Samplebyte holen
2866 move.w 0(a4,d0.w*2),d1
2867 .MxLop6 add.w d1,(a5)+
2868 add.w d5,d6 ; Sample fortschalten
2870 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2871 move.w 0(a4,d0.w*2),d1
2872 .MxLop7 add.w d1,(a5)+
2873 add.w d5,d6 ; Sample fortschalten
2875 move.b (a3)+,d0 ; ein Sample zum Buffer dazumixen
2876 move.w 0(a4,d0.w*2),d1
2877 .MxLop8 dbra d2,.MxLop6 ; bis MixBuffer voll
2882 .MxLop9 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2883 move.w 0(a4,d0.w*2),d1
2885 add.w d5,d6 ; Sample fortschalten
2887 move.b 0(a3,d3.l),d0 ; ein Sample zum Buffer dazumixen
2888 move.w 0(a4,d0.w*2),d1
2890 add.w d5,d6 ; Sample fortschalten
2892 dbra d2,.MxLop9 ; bis MixBuffer voll
2895 *-----------------------------------------------------------------------*
2897 ; Daten für die Audio-Interrupt Routine
2901 ClockBase: dc.l 0 ;Clock-Konstante
2902 MixPeriod: dc.w 256 ;Gesamt-Period für alle Kanäle
2903 MixFreq: dc.w 8287 ;Gesamt-Frequenz für alle Kanäle
2905 * Variablen der Audio-Interrupt-Routine:
2907 Volume07: dc.w 64 ;Channel-Volumes für links und rechts
2910 C03BufOff: dc.w 0 ;Buffer-Flip-Offset (0 oder MBuf_SIZE)
2914 * 32 Track-Data-Strukturen:
2917 td_SPtr rs.l 1 ; Zeiger auf das Sampleende
2918 td_SLen rs.l 1 ; negative Sample-Restbytes
2919 td_LPtr rs.l 1 ; Endadr. des Loopteils
2920 td_LLen rs.l 1 ; negative Länge des Loopteils
2921 td_Vol rs.w 1 ; Volume-Wert 0...64
2922 td_Fre rs.l 1 ; Frequenz-Wert
2923 td_FreC rs.w 1 ; Frequenz-Nachkomma-Zähler
2927 T00Data: ds.b td_SIZE
2928 T01Data: ds.b td_SIZE
2929 T02Data: ds.b td_SIZE
2930 T03Data: ds.b td_SIZE
2931 T04Data: ds.b td_SIZE
2932 T05Data: ds.b td_SIZE
2933 T06Data: ds.b td_SIZE
2934 T07Data: ds.b td_SIZE
2935 T08Data: ds.b td_SIZE
2936 T09Data: ds.b td_SIZE
2937 T0AData: ds.b td_SIZE
2938 T0BData: ds.b td_SIZE
2939 T0CData: ds.b td_SIZE
2940 T0DData: ds.b td_SIZE
2941 T0EData: ds.b td_SIZE
2942 T0FData: ds.b td_SIZE
2943 T10Data: ds.b td_SIZE
2944 T11Data: ds.b td_SIZE
2945 T12Data: ds.b td_SIZE
2946 T13Data: ds.b td_SIZE
2947 T14Data: ds.b td_SIZE
2948 T15Data: ds.b td_SIZE
2949 T16Data: ds.b td_SIZE
2950 T17Data: ds.b td_SIZE
2951 T18Data: ds.b td_SIZE
2952 T19Data: ds.b td_SIZE
2953 T1AData: ds.b td_SIZE
2954 T1BData: ds.b td_SIZE
2955 T1CData: ds.b td_SIZE
2956 T1DData: ds.b td_SIZE
2957 T1EData: ds.b td_SIZE
2958 T1FData: ds.b td_SIZE
2961 * Stummes Instrument:
2964 dc.l QuietInstr ; Endadresse
2966 dc.l QuietInstr ; Ende LoopSample
2967 dc.l 0 ; Länge LoopSample
2971 *-----------------------------------------------------------------------*
2975 SECTION GenieTabBuff,BSS
2979 * Umrechnungs-Tabelle für versch. Lautstärken:
2980 * (wird durch NoteInit initialisiert)
2985 *-----------------------------------------------------------------------*
2989 SECTION GenieBitBuff,BSS
2993 * Umrechnungs-Tabelle für 14Bit Ausgabe:
2994 * (wird beim Start initialisiert)
3002 *-----------------------------------------------------------------------*
3006 SECTION GenieMixBuff,BSS
3020 *-----------------------------------------------------------------------*
3022 ; NoteChannels - From TakeTracker player
3026 SECTION NoteChan,BSS
3030 NoteChannels ds.b NoteChannel_SIZE*32
3034 *-----------------------------------------------------------------------*
3038 SECTION GenieSampBuff,BSS_C
3045 C0Buf: ds.b MBuf_SIZE
3046 ds.b MBuf_SIZE ;Für Double-Buffering!
3047 C1Buf: ds.b MBuf_SIZE
3048 ds.b MBuf_SIZE ;Für Double-Buffering!
3049 C2Buf: ds.b MBuf_SIZE
3050 ds.b MBuf_SIZE ;Für Double-Buffering!
3051 C3Buf: ds.b MBuf_SIZE
3052 ds.b MBuf_SIZE ;Für Double-Buffering!
3059 *-----------------------------------------------------------------------*
3061 section __MERGED,data
3064 **********************************************************************
3066 **********************************************************************
3078 _OldAudio0: dc.l 0 ; Old audio interrupt vectors
3086 BoostFlag dc.l 1 ; Automatic Volume Boost Calculation
3091 **********************************************************************
3092 * From TakeTracker player
3093 **********************************************************************
3104 NotePlay dc.l NoteStructure
3106 NoteStructure dc.l NoteChannels ; NoteChannel Array
3107 dc.l NSTF_Period!NSTF_Signed!NSTF_8Bit ; 8-Bit signed sample data
3108 dc.l 28867 ; max. frequency
3109 dc.w 64 ; max. volume
3112 mt_ChanTemp ds.b pn_SIZEOF * MAXCHANNELS
3120 mt_PatternPos dc.w 0
3121 mt_PosJumpFlag dc.b 0
3122 mt_PBreakFlag dc.b 0
3124 mt_PattDelTime dc.b 0
3125 mt_PattDelTime2 dc.b 0
3129 **********************************************************************
3131 **********************************************************************
3136 dc.b NT_INTERRUPT ; Type
3138 dc.l audiointname ; Name
3140 dc.l Int0_000 ; Code
3145 dc.b NT_INTERRUPT ; Type
3147 dc.l audiointname ; Name
3149 dc.l Int1_000 ; Code
3154 dc.b NT_INTERRUPT ; Type
3156 dc.l audiointname ; Name
3158 dc.l Int0_020 ; Code
3163 dc.b NT_INTERRUPT ; Type
3165 dc.l audiointname ; Name
3167 dc.l Int1_020 ; Code
3170 **********************************************************************
3172 **********************************************************************
3177 dc.b NT_INTERRUPT ; Type
3179 dc.l audiointname ; Name
3181 dc.l Soft0_000 ; Code
3186 dc.b NT_INTERRUPT ; Type
3188 dc.l audiointname ; Name
3190 dc.l Soft1_000 ; Code
3196 dc.b NT_INTERRUPT ; Type
3198 dc.l audiointname ; Name
3200 dc.l Soft0_020 ; Code
3205 dc.b NT_INTERRUPT ; Type
3207 dc.l audiointname ; Name
3209 dc.l Soft1_020 ; Code
3212 **********************************************************************
3214 **********************************************************************
3220 dc.b ADALLOC_MAXPREC ; LN_PRI
3223 dc.l 0 ; message reply port
3224 dc.w 0 ; message len in bytes
3226 dc.l 0 ; device node pointer
3227 dc.l 0 ; unit (driver private)
3228 dc.w 0 ; device command
3229 dc.b 0 ; special flags
3230 dc.b 0 ; error or warning code
3231 dc.w 0 ; ioa_AllocKey
3232 dc.l ChannelMap ; ioa_Data
3242 dc.l 0 ; message reply port
3243 dc.w 0 ; message len in bytes
3246 ChannelMap dc.b $0f ; Alle Kanäle belegen
3248 audiointname dc.b 'XModule Player',0