Last active
November 28, 2022 11:15
-
-
Save johngirvin/8fb0c4bb83b7c80427e2f439bb074e95 to your computer and use it in GitHub Desktop.
Amiga ptplayer replay routine v5.4 (beta) adapted to allocate audio channels and CIA timer interrupts from AmigaOS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;************************************************** | |
;* ----- Protracker V2.3B Playroutine ----- * | |
;************************************************** | |
; | |
; Version 5.4 | |
; Written by Frank Wille in 2013, 2016, 2017, 2018, 2019, 2020. | |
; | |
; I, the copyright holder of this work, hereby release it into the | |
; public domain. This applies worldwide. | |
; | |
; The default version (single section, local base register) should | |
; work with most assemblers. Tested are: Devpac, vasm, PhxAss, | |
; Barfly-Asm, SNMA, AsmOne, AsmPro. | |
; | |
; The small data model can be enabled by defining the symbol SDATA. In | |
; this case all functions expect a4 to be initialised with the small | |
; data base register. Interrupt functions restore a4 from _LinkerDB. | |
; Small data may work with vasm and PhxAss only. | |
; | |
; Optionally you can build a minimal version, which includes just | |
; the player. No sound effects insert, no master volume, no sample | |
; volume, etc. Define the symbol MINIMAL for it. | |
; | |
; Exported functions and variables: | |
; (_custom is the custom-chip register set base address $dff000.) | |
; | |
; _mt_os_install(a6=_custom, d0=PALflag.b) | |
; Allocate audio channels and install CIA-B interrupts for calling _mt_music or mt_sfxonly. | |
; The music module is replayed via _mt_music when _mt_Enable is non-zero. | |
; Otherwise the interrupt handler calls mt_sfxonly to play sound | |
; effects only. A non-zero PALflag selects PAL-clock for the CIA timers | |
; (NTSC otherwise). | |
; | |
; _mt_os_remove(a6=_custom) | |
; Deallocate audio channels and remove the CIA-B music interrupts. | |
; | |
; _mt_init(a6=_custom, a0=TrackerModule, a1=Samples|NULL, d0=InitialSongPos.b) | |
; Initialize a new module. | |
; Reset speed to 6, tempo to 125 and start at the given song position. | |
; Master volume is at 64 (maximum). | |
; When a1 is NULL the samples are assumed to be stored after the patterns. | |
; | |
; _mt_end(a6=_custom) | |
; Stop playing current module. | |
; | |
; _mt_soundfx(a6=_custom, a0=SamplePointer, | |
; d0=SampleLength.w, d1=SamplePeriod.w, d2=SampleVolume.w) | |
; Request playing of an external sound effect on the most unused channel. | |
; This function is for compatibility with the old API only! | |
; You should call _mt_playfx instead. !MINIMAL only. | |
; | |
; channelStatus = _mt_playfx(a6=_custom, a0=SfxStructurePointer) | |
; Request playing of a prioritized external sound effect, either on a | |
; fixed channel or on the most unused one. | |
; Structure layout of SfxStructure: | |
; void *sfx_ptr (pointer to sample start in Chip RAM, even address) | |
; WORD sfx_len (sample length in words) | |
; WORD sfx_per (hardware replay period for sample) | |
; WORD sfx_vol (volume 0..64, is unaffected by the song's master volume) | |
; BYTE sfx_cha (0..3 selected replay channel, -1 selects best channel) | |
; BYTE sfx_pri (unsigned priority, must be non-zero) | |
; When multiple samples are assigned to the same channel the lower | |
; priority sample will be replaced. When priorities are the same, then | |
; the older sample is replaced. | |
; The chosen channel is blocked for music until the effect has | |
; completely been replayed. | |
; Returns a pointer to a channel-status structure when the sample | |
; is scheduled for playing and NULL when the request was ignored. | |
; !MINIMAL only. | |
; | |
; _mt_musicmask(a6=_custom, d0=ChannelMask.b) | |
; Bits set in the mask define which specific channels are reserved | |
; for music only. Set bit 0 for channel 0, ..., bit 3 for channel 3. | |
; When calling _mt_soundfx or _mt_playfx with automatic channel selection | |
; (sfx_cha=-1) then these masked channels will never be picked. | |
; The mask defaults to 0. !MINIMAL only. | |
; | |
; _mt_mastervol(a6=_custom, d0=MasterVolume.w) | |
; Set a master volume from 0 to 64 for all music channels. | |
; Note that the master volume does not affect the volume of external | |
; sound effects (which is desired). !MINIMAL only. | |
; | |
; _mt_samplevol(d0=SampleNumber.w, d1=Volume.b) | |
; Redefine a sample's volume. May also be done while the song is playing. | |
; Warning: Does not check arguments for valid range! You must have done | |
; _mt_init before calling this function! | |
; The new volume is persistent. Even when the song is restarted. | |
; !MINIMAL only. | |
; | |
; _mt_music(a6=_custom) | |
; The replayer routine. Is called automatically after _mt_install_cia. | |
; | |
; Byte Variables: | |
; | |
; _mt_Enable | |
; Set this byte to non-zero to play music, zero to pause playing. | |
; Note that you can still play sound effects, while music is stopped. | |
; It is set to 0 by _mt_install_cia. | |
; | |
; _mt_E8Trigger | |
; This byte reflects the value of the last E8 command. | |
; It is reset to 0 after _mt_init. | |
; | |
; _mt_SongEnd | |
; Set to -1 ($ff) if you want the song to stop automatically when | |
; the last position has been played (clears _mt_Enable). Otherwise, the | |
; song is restarted and _mt_SongEnd is incremented to count the restarts. | |
; It is reset to 0 after _mt_init. !MINIMAL only. | |
; | |
; _mt_MusicChannels | |
; This byte defines the number of channels which should be dedicated | |
; for playing music. So sound effects will never use more | |
; than 4 - _mt_MusicChannels channels at once. Defaults to 0. | |
; !MINIMAL only. | |
; | |
; Delay in CIA-ticks, which guarantees that at least one Audio-DMA | |
; took place, even with the lowest periods. | |
; 496 should be the correct value. But there are some A1200 which | |
; need at least 550. | |
DMADELAY equ 576 ; was 496 | |
; Audio channel registers | |
AUDLC equ 0 | |
AUDLEN equ 4 | |
AUDPER equ 6 | |
AUDVOL equ 8 | |
; Sound effects structure, passed into _mt_playfx | |
rsreset | |
sfx_ptr rs.l 1 | |
sfx_len rs.w 1 | |
sfx_per rs.w 1 | |
sfx_vol rs.w 1 | |
sfx_cha rs.b 1 | |
sfx_pri rs.b 1 | |
sfx_sizeof rs.b 0 | |
; Channel Status | |
rsreset | |
n_note rs.w 1 | |
n_cmd rs.b 1 | |
n_cmdlo rs.b 1 | |
n_index rs.b 1 | |
n_sfxpri rs.b 1 | |
n_reserved1 rs.b 2 | |
n_start rs.l 1 | |
n_loopstart rs.l 1 | |
n_length rs.w 1 | |
n_replen rs.w 1 | |
n_period rs.w 1 | |
n_volume rs.w 1 | |
n_pertab rs.l 1 | |
n_dmabit rs.w 1 | |
n_noteoff rs.w 1 | |
n_toneportspeed rs.w 1 | |
n_wantedperiod rs.w 1 | |
n_pattpos rs.w 1 | |
n_funk rs.w 1 | |
n_wavestart rs.l 1 | |
n_reallength rs.w 1 | |
n_intbit rs.w 1 | |
n_sfxptr rs.l 1 | |
n_sfxlen rs.w 1 | |
n_sfxper rs.w 1 | |
n_sfxvol rs.w 1 | |
n_looped rs.b 1 | |
n_minusft rs.b 1 | |
n_vibratoamp rs.b 1 | |
n_vibratospd rs.b 1 | |
n_vibratopos rs.b 1 | |
n_vibratoctrl rs.b 1 | |
n_tremoloamp rs.b 1 | |
n_tremolospd rs.b 1 | |
n_tremolopos rs.b 1 | |
n_tremoloctrl rs.b 1 | |
n_gliss rs.b 1 | |
n_sampleoffset rs.b 1 | |
n_loopcount rs.b 1 | |
n_funkoffset rs.b 1 | |
n_retrigcount rs.b 1 | |
ifnd MINIMAL | |
n_freecnt rs.b 1 | |
n_musiconly rs.b 1 | |
n_reserved2 rs.b 1 | |
else | |
n_reserved2 rs.b 3 | |
endc | |
n_sizeof rs.b 0 | |
;--------------------------------------------------------------------------- | |
; _mt_os_install | |
; Allocate audio channels and CIA-B interrupts from AmigaOS | |
; | |
; Entry: | |
; a6 = _custom | |
; d0 = PALflag.b (0 is NTSC) | |
; | |
; Exit: | |
; d0 = 0 if successful, NZ if not | |
_mt_os_install: movem.l d0-7/a0-6,-(sp) | |
clr.b mt_audio_alloc ;Clear flags | |
clr.l mt_ioaudio_msgport | |
clr.b mt_cia_alloc_ta | |
clr.b mt_cia_alloc_tb | |
; Allocate all audio.device channels | |
clr.l mt_ioaudio_msgport ;Create message port | |
EXECCALL CreateMsgPort | |
move.l a0,d0 | |
move.l d0,mt_ioaudio_msgport | |
beq .mt_failure | |
lea mt_audio_name(pc),a0 ;Open audio.device | |
lea mt_ioaudio(pc),a1 ;IOAudio is configured to allocate all channels on device open | |
move.l d0,MN_REPLYPORT(a1) ;Store MsgPort pointer in IOAudio | |
moveq #0,d0 | |
moveq #0,d1 | |
EXECCALL OpenDevice | |
tst.l d0 | |
seq mt_audio_alloc | |
bne .mt_failure | |
; Allocate interrupts for Timer A and B on CIA-B | |
EXECCALL Disable ;Disable interrupts while setting up | |
lea mt_cia_name(pc),a1 ;Open CIA-B resource (there is no CloseResource) | |
EXECCALL OpenResource | |
move.l d0,mt_cia_base ;Save CIA base | |
beq .mt_failure | |
moveq #CIAICRB_TA,d0 ;Install TA interrupt | |
lea mt_cia_interrupt_ta(pc),a1 | |
move.l mt_cia_base,a6 | |
CALLA6 AddICRVector | |
tst.l d0 | |
seq mt_cia_alloc_ta | |
bne .mt_failure | |
moveq #CIAICRB_TB,d0 ;Install TB interrupt | |
lea mt_cia_interrupt_tb(pc),a1 | |
move.l mt_cia_base,a6 | |
CALLA6 AddICRVector | |
tst.l d0 | |
seq mt_cia_alloc_tb | |
bne .mt_failure | |
; Initialise player | |
; Adapted from original _mt_install_cia | |
movem.l (sp),d0-7/a0-6 | |
lea mt_data(pc),a4 | |
clr.b mt_Enable(a4) | |
; reset TimerB toggle | |
lea TB_toggle(pc),a0 | |
clr.b (a0) | |
; disable CIA-B interrupts, stop all timers | |
lea CIAB,a0 | |
move.b #$7f,CIAICR(a0) | |
move.b #$10,CIACRA(a0) | |
move.b #$10,CIACRB(a0) | |
; determine if 02 clock for timers is based on PAL or NTSC | |
tst.b d0 | |
bne .1 | |
move.l #1789773,d0 ; NTSC | |
bra .2 | |
.1: move.l #1773447,d0 ; PAL | |
.2: move.l d0,mt_timerval(a4) | |
; load TimerA in continuous mode for the default tempo of 125 | |
divu #125,d0 | |
move.b d0,CIATALO(a0) | |
lsr.w #8,d0 | |
move.b d0,CIATAHI(a0) | |
move.b #$11,CIACRA(a0) ; load timer, start continuous | |
; load TimerB with DMADELAY ticks for setting DMA and repeat | |
move.b #DMADELAY&255,CIATBLO(a0) | |
move.b #DMADELAY>>8,CIATBHI(a0) | |
; TimerA and TimerB interrupt enable | |
tst.b CIAICR(a0) | |
move.b #$83,CIAICR(a0) | |
; Reset player internal data | |
pea .mt_reset_done(pc) | |
move.l a4,-(sp) | |
bra mt_reset | |
.mt_reset_done: | |
; Success! | |
moveq #0,d0 | |
; Complete | |
.mt_done: move.l d0,(sp) ;Set return code. Will be loaded to d0 by movem. | |
EXECCALL Enable ;Re-enable interrupts | |
movem.l (sp)+,d0-7/a0-6 | |
rts | |
.mt_failure: moveq #-1,d0 | |
bra .mt_done | |
;-------------------------------------- | |
; _mt_os_remove | |
; Free all audio channels and/or CIA-B interrupts previously allocated from AmigaOS | |
; | |
; Entry: | |
; a6 = _custom | |
_mt_os_remove: movem.l d0-7/a0-6,-(sp) | |
; De-init ptplayer | |
bsr _mt_end | |
; Deallocate CIA-B interrupts | |
EXECCALL Disable ;Disable interrupts | |
lea mt_cia_name(pc),a1 ;Open CIA-B | |
EXECCALL OpenResource | |
move.l d0,mt_cia_base ;Save CIA base | |
beq .mt_cia_done | |
tst.b mt_cia_alloc_ta(pc) ;Uninstall TA interrupt | |
beq .mt_cia_ta_done | |
moveq #CIAICRB_TA,d0 | |
lea mt_cia_interrupt_ta(pc),a1 | |
move.l mt_cia_base,a6 | |
CALLA6 RemICRVector | |
.mt_cia_ta_done: clr.b mt_cia_alloc_ta | |
tst.b mt_cia_alloc_tb(pc) ;Uninstall TB interrupt | |
beq .mt_cia_tb_done | |
moveq #CIAICRB_TB,d0 | |
lea mt_cia_interrupt_tb(pc),a1 | |
move.l mt_cia_base,a6 | |
CALLA6 RemICRVector | |
.mt_cia_tb_done: clr.b mt_cia_alloc_tb | |
.mt_cia_done: | |
EXECCALL Enable ;Re-enable interrupts | |
; Deallocate audio channels | |
tst.b mt_audio_alloc ;Close audio.device | |
beq .mt_audio_done | |
lea mt_ioaudio(pc),a1 | |
EXECCALL CloseDevice | |
.mt_audio_done: clr.b mt_audio_alloc | |
move.l mt_ioaudio_msgport(pc),d0 | |
beq .mt_audio_msgport_done | |
move.l d0,a0 | |
EXECCALL DeleteMsgPort | |
.mt_audio_msgport_done: | |
clr.l mt_ioaudio_msgport | |
movem.l (sp)+,d0-7/a0-6 | |
rts | |
;-------------------------------------- | |
mt_audio_name: AUDIONAME | |
mt_audio_alloc: dc.b 0 | |
CNOP 0,4 | |
mt_ioaudio_msgport: | |
dc.l 0 | |
; STRUCTURE IOAudio | |
mt_ioaudio: dc.l 0 ; LN_SUCC | |
dc.l 0 ; LN_PRED | |
dc.b 5 ; LN_TYPE | |
dc.b ADALLOC_MAXPREC ; LN_PRI | |
dc.l 0 ; LN_NAME | |
mt_ioaudio_mn_ReplyPort: | |
dc.l 0 ; MN_REPLYPORT | |
dc.w ioa_SIZEOF ; MN_LENGTH | |
dc.l 0 ; IO_DEVICE | |
dc.l 0 ; IO_UNIT | |
dc.w 0 ; IO_COMMAND | |
dc.b 0 ; IO_FLAGS | |
dc.b 0 ; IO_ERROR | |
dc.w 0 ; ioa_AllocKey - Alloc. key filled in by audio device | |
dc.l mt_ioaudio_channels ; ioa_Data - Pointer to a sample or allocation mask | |
dc.l 1 ; ioa_Length - Length of sample or allocation mask | |
dc.w 0 ; ioa_Period - Sample playback speed | |
dc.w 0 ; ioa_Volume - Volume of sound | |
dc.w 0 ; ioa_Cycles - # of times to play sample. 0=forever | |
dcb.b MN_SIZE ; struct Message ioa_WriteMsg | |
; mt_ioaudio channel allocation array: allocate all channels | |
mt_ioaudio_channels: | |
dc.b %1111 | |
EVEN | |
;-------------------------------------- | |
mt_cia_name: CIABNAME | |
mt_cia_alloc_ta: dc.b 0 | |
mt_cia_alloc_tb: dc.b 0 | |
CNOP 0,4 | |
mt_cia_base: dc.l 0 | |
mt_cia_interrupt_ta: | |
; STRUCTURE IS | |
dc.l 0 ; LN_SUCC | |
dc.l 0 ; LN_PRED | |
dc.b 2 ; LN_TYPE | |
dc.b 5 ; LN_PRI | |
dc.l 0 ; LN_NAME | |
dc.l 0 ; IS_DATA | |
dc.l mt_cia_is_ta ; IS_CODE | |
mt_cia_interrupt_tb: | |
; STRUCTURE IS | |
dc.l 0 ; LN_SUCC | |
dc.l 0 ; LN_PRED | |
dc.b 2 ; LN_TYPE | |
dc.b 5 ; LN_PRI | |
dc.l 0 ; LN_NAME | |
dc.l 0 ; IS_DATA | |
dc.l mt_cia_is_tb ; IS_CODE | |
;-------------------------------------- | |
; CIA-B Timer A Interrupt Server | |
mt_cia_is_ta: bsr mt_TimerAInt | |
moveq #0,d0 | |
rts | |
;-------------------------------------- | |
; CIA-B Timer B Interrupt Server | |
mt_cia_is_tb: bsr mt_TimerBInt | |
moveq #0,d0 | |
rts | |
;--------------------------------------------------------------------------- | |
mt_TimerAInt: | |
; TimerA interrupt calls _mt_music at a selectable tempo (Fxx command), | |
; which defaults to 50 times per second. | |
movem.l d0-d7/a0-a6,-(sp) | |
lea _custom,a6 | |
lea mt_data(pc),a4 | |
; do music when enabled | |
tst.b mt_Enable(a4) | |
beq .2 | |
tst.w mt_Delay(a4) ;Update any initial delay | |
beq .delay_done | |
subq.w #1,mt_Delay(a4) | |
bra .2 | |
.delay_done: move.w mt_MasterFade(a4),d1 ;Apply any fade in/out to master volume | |
beq .fade_done | |
move.w mt_MasterVol(a4),d0 ;d0=new volume | |
add.w d1,d0 | |
bpl .fade_pve | |
moveq #0,d0 | |
bra .fade_stop | |
.fade_pve: cmp.w #64,d0 | |
bls .fade_set | |
move.w #64,d0 | |
.fade_stop: clr.w mt_MasterFade(a4) | |
.fade_set: move.w d0,mt_MasterVol(a4) | |
bsr _mt_mastervol | |
.fade_done: | |
bsr _mt_music ; music with sfx inserted | |
.1: movem.l (sp)+,d0-d7/a0-a6 | |
nop | |
rts | |
.2: | |
ifnd MINIMAL | |
bsr mt_sfxonly ; no music, only sfx | |
endc | |
bra .1 | |
;--------------------------------------------------------------------------- | |
mt_TimerBInt: | |
; Handle one-shot TimerB interrupt. | |
; TB_toggle-technique suggested by Ross/EAB. | |
move.l a0,-(sp) | |
lea TB_toggle(pc),a0 | |
not.b (a0) | |
lea _custom+INTREQ,a0 | |
beq .mtb_setrep | |
; restart timer for repeat, enable audio DMA after DMADELAY ticks | |
move.b #$19,CIAB+CIACRB | |
move.w mt_dmaon(pc),DMACON-INTREQ(a0) | |
bra .mtb_done | |
.mtb_setrep: | |
; set repeat samples after another DMADELAY ticks. | |
; a0 = INTREQ | |
; clear possible audio interrupt flags | |
move.l a4,-(sp) | |
move.l d0,a4 | |
moveq #0,d0 | |
or.b mt_dmaon+1(pc),d0 | |
lsl.w #7,d0 | |
move.w d0,(a0) | |
move.l a4,d0 | |
; set repeat sample pointers and lengths | |
lea mt_data(pc),a4 | |
move.l mt_chan1+n_loopstart(a4),AUD0LC-INTREQ(a0) | |
move.w mt_chan1+n_replen(a4),AUD0LEN-INTREQ(a0) | |
move.l mt_chan2+n_loopstart(a4),AUD1LC-INTREQ(a0) | |
move.w mt_chan2+n_replen(a4),AUD1LEN-INTREQ(a0) | |
move.l mt_chan3+n_loopstart(a4),AUD2LC-INTREQ(a0) | |
move.w mt_chan3+n_replen(a4),AUD2LEN-INTREQ(a0) | |
move.l mt_chan4+n_loopstart(a4),AUD3LC-INTREQ(a0) | |
move.w mt_chan4+n_replen(a4),AUD3LEN-INTREQ(a0) | |
move.l (sp)+,a4 | |
.mtb_done: move.l (sp)+,a0 | |
nop | |
rts | |
;---------------------------------------- | |
mt_dmaon: dc.w $8000 | |
TB_toggle: dc.b 0 | |
even | |
;--------------------------------------------------------------------------- | |
_mt_init: | |
; Initialize new module. | |
; Reset speed to 6, tempo to 125 and start at given song position. | |
; Master volume is at 64 (maximum). | |
; a6 = _custom | |
; a0 = module pointer | |
; a1 = sample pointer (NULL means samples are stored within the module) | |
; d0 = initial song position | |
move.l a4,-(sp) | |
lea mt_data(pc),a4 | |
move.l a0,mt_mod(a4) | |
movem.l d2/a2,-(sp) | |
; set initial song position | |
cmp.b 950(a0),d0 | |
blo .1 | |
moveq #0,d0 | |
.1: move.b d0,mt_SongPos(a4) | |
move.l a1,d0 ; sample data location is given? | |
bne .4 | |
; get number of highest pattern | |
lea 952(a0),a1 ; song arrangement list | |
moveq #127,d0 | |
moveq #0,d2 | |
.2: move.b (a1)+,d1 | |
cmp.b d2,d1 | |
bls .3 | |
move.b d1,d2 | |
.3: dbf d0,.2 | |
addq.b #1,d2 ; number of patterns | |
; now we can calculate the base address of the sample data | |
moveq #10,d0 | |
asl.l d0,d2 | |
lea (a0,d2.l),a1 | |
add.w #1084,a1 | |
; save start address of each sample and do some fixes for broken mods | |
.4: lea mt_SampleStarts(a4),a2 | |
moveq #1,d2 | |
moveq #31-1,d0 | |
.5: move.l a1,(a2)+ | |
moveq #0,d1 | |
move.w 42(a0),d1 | |
cmp.w d2,d1 ; length 0 and 1 define unused samples | |
bls .6 | |
add.l d1,d1 | |
add.l d1,a1 | |
bra .7 | |
.6: clr.w 42(a0) ; length 1 means zero -> no sample | |
.7: lea 30(a0),a0 | |
dbf d0,.5 | |
movem.l (sp)+,d2/a2 | |
; reset CIA timer A to default (125) | |
move.l mt_timerval(a4),d0 | |
divu #125,d0 | |
move.b d0,CIAB+CIATALO | |
lsr.w #8,d0 | |
move.b d0,CIAB+CIATAHI | |
mt_reset: | |
; a4 must be initialised with base register | |
; reset speed and counters | |
move.b #6,mt_Speed(a4) | |
clr.b mt_Counter(a4) | |
clr.w mt_PatternPos(a4) | |
; disable the filter | |
or.b #2,CIAA+CIAPRA | |
ifnd MINIMAL | |
; set master volume to 64 | |
lea MasterVolTab64(pc),a0 | |
move.l a0,mt_MasterVolTab(a4) | |
endc | |
; set channel index | |
clr.b mt_chan1+n_index(a4) | |
move.b #1,mt_chan2+n_index(a4) | |
move.b #2,mt_chan3+n_index(a4) | |
move.b #3,mt_chan4+n_index(a4) | |
; initialise channel DMA and interrupt bits | |
move.w #$0001,mt_chan1+n_dmabit(a4) | |
move.w #$0002,mt_chan2+n_dmabit(a4) | |
move.w #$0004,mt_chan3+n_dmabit(a4) | |
move.w #$0008,mt_chan4+n_dmabit(a4) | |
move.w #$0080,mt_chan1+n_intbit(a4) | |
move.w #$0100,mt_chan2+n_intbit(a4) | |
move.w #$0200,mt_chan3+n_intbit(a4) | |
move.w #$0400,mt_chan4+n_intbit(a4) | |
; make sure n_period doesn't start as 0 | |
move.w #320,d0 | |
move.w d0,mt_chan1+n_period(a4) | |
move.w d0,mt_chan2+n_period(a4) | |
move.w d0,mt_chan3+n_period(a4) | |
move.w d0,mt_chan4+n_period(a4) | |
; disable sound effects | |
clr.w mt_chan1+n_sfxlen(a4) | |
clr.w mt_chan2+n_sfxlen(a4) | |
clr.w mt_chan3+n_sfxlen(a4) | |
clr.w mt_chan4+n_sfxlen(a4) | |
clr.b mt_E8Trigger(a4) | |
ifnd MINIMAL | |
clr.b mt_SongEnd(a4) | |
clr.b mt_SilCntValid(a4) | |
endc | |
move.l (sp)+,a4 | |
;--------------------------------------------------------------------------- | |
_mt_end: | |
; Stop playing current module. | |
; a6 = _custom | |
lea mt_data+mt_Enable(pc),a0 | |
clr.b (a0) | |
moveq #0,d0 | |
move.w d0,AUD0VOL(a6) | |
move.w d0,AUD1VOL(a6) | |
move.w d0,AUD2VOL(a6) | |
move.w d0,AUD3VOL(a6) | |
move.w #$000f,DMACON(a6) | |
rts | |
ifnd MINIMAL | |
;--------------------------------------------------------------------------- | |
_mt_soundfx: | |
; Request playing of an external sound effect on the most unused channel. | |
; This function is for compatibility with the old API only! | |
; You should call _mt_playfx instead! | |
; a6 = _custom | |
; a0 = sample pointer | |
; d0.w = sample length in words | |
; d1.w = sample period | |
; d2.w = sample volume | |
lea -sfx_sizeof(sp),sp | |
move.l a0,sfx_ptr(sp) | |
movem.w d0-d2,sfx_len(sp) | |
move.w #$ff01,sfx_cha(sp) ; any channel, priority=1 | |
move.l sp,a0 | |
bsr _mt_playfx | |
lea sfx_sizeof(sp),sp | |
rts | |
;--------------------------------------------------------------------------- | |
_mt_playfx: | |
; Request playing of a prioritized external sound effect, either on a | |
; fixed channel or on the most unused one. | |
; A negative channel specification means to use the best one. | |
; The priority is unsigned and should be greater than zero. | |
; This channel will be blocked for music until the effect has finished. | |
; a6 = _custom | |
; a0 = sfx-structure pointer with the following layout: | |
; 0: ptr, 4: len.w, 6: period.w, 8: vol.w, 10: channel.b, 11: priority.b | |
; -> d0 = pointer to channel status or NULL when sample was ignored | |
movem.l d2-d7/a0-a5,-(sp) | |
lea mt_data(pc),a4 | |
moveq #0,d0 | |
move.b sfx_cha(a0),d0 | |
bpl channelsfx ; use fixed channel for effect | |
; Did we already calculate the n_freecnt values for all channels? | |
tst.b mt_SilCntValid(a4) | |
bne freecnt_valid | |
; Look at the next 8 pattern steps to find the longest sequence | |
; of silence (no new note or instrument). | |
moveq #8,d2 | |
move.l #$fffff000,d3 ; mask to ignore effects | |
; remember which channels are not available for sound effects | |
move.b mt_chan1+n_musiconly(a4),d4 | |
move.b mt_chan2+n_musiconly(a4),d5 | |
move.b mt_chan3+n_musiconly(a4),d6 | |
move.b mt_chan4+n_musiconly(a4),d7 | |
; reset freecnts for all channels | |
moveq #0,d0 | |
move.b d0,mt_chan1+n_freecnt(a4) | |
move.b d0,mt_chan2+n_freecnt(a4) | |
move.b d0,mt_chan3+n_freecnt(a4) | |
move.b d0,mt_chan4+n_freecnt(a4) | |
; get pattern pointer | |
move.l mt_mod(a4),a3 ; a3 mod pointer | |
lea 952(a3),a5 ; a5 song arrangement list | |
move.w mt_PatternPos(a4),d1 | |
move.b mt_SongPos(a4),d0 | |
.1: move.b (a5,d0.w),d0 | |
swap d0 | |
lea 1084(a3),a1 | |
lsr.l #6,d0 | |
add.l d0,a1 | |
lea 1024(a1),a2 ; a2 end of pattern | |
add.w d1,a1 ; a1 current pattern pos | |
.2: moveq #4,d0 | |
move.l (a1)+,d1 | |
tst.b d4 | |
bne .3 | |
addq.b #1,mt_chan1+n_freecnt(a4) | |
and.l d3,d1 | |
sne d4 | |
.3: add.b d4,d0 | |
move.l (a1)+,d1 | |
tst.b d5 | |
bne .4 | |
addq.b #1,mt_chan2+n_freecnt(a4) | |
and.l d3,d1 | |
sne d5 | |
.4: add.b d5,d0 | |
move.l (a1)+,d1 | |
tst.b d6 | |
bne .5 | |
addq.b #1,mt_chan3+n_freecnt(a4) | |
and.l d3,d1 | |
sne d6 | |
.5: add.b d6,d0 | |
move.l (a1)+,d1 | |
tst.b d7 | |
bne .6 | |
addq.b #1,mt_chan4+n_freecnt(a4) | |
and.l d3,d1 | |
sne d7 | |
.6: add.b d7,d0 | |
; break the loop when no channel has any more free pattern steps | |
beq .7 | |
; otherwise break after 8 pattern steps | |
subq.w #1,d2 | |
beq .7 | |
; End of pattern reached? Then load next pattern pointer. | |
cmp.l a2,a1 | |
blo .2 | |
moveq #0,d1 | |
moveq #1,d0 | |
add.b mt_SongPos(a4),d0 | |
and.w #$007f,d0 | |
cmp.b 950(a3),d0 ; end of song reached? | |
blo .1 | |
moveq #0,d0 | |
bra .1 | |
.7: st mt_SilCntValid(a4) | |
freecnt_valid: | |
move.w #$4000,INTENA(a6) | |
sub.l a2,a2 | |
move.b sfx_pri(a0),d2 | |
; Determine which channels are already allocated for sound | |
; effects and check if the limit was reached. In this case only | |
; replace sound effect channels by higher priority. | |
moveq #3,d0 | |
sub.b mt_MusicChannels(a4),d0 | |
move.b mt_chan1+n_sfxpri(a4),d4 | |
sne d1 | |
add.b d1,d0 | |
move.b mt_chan2+n_sfxpri(a4),d5 | |
sne d1 | |
add.b d1,d0 | |
move.b mt_chan3+n_sfxpri(a4),d6 | |
sne d1 | |
add.b d1,d0 | |
move.b mt_chan4+n_sfxpri(a4),d7 | |
sne d1 | |
add.b d1,d0 | |
bmi .overwrite | |
; We will prefer a music channel which had an audio interrupt, | |
; because that means the last instrument sample has been played | |
; completely, and the channel is now in an idle loop. | |
; Also exclude channels which have set a repeat loop. | |
; Try not to break them! | |
moveq #0,d3 | |
tst.b mt_chan1+n_looped(a4) | |
bne .1 | |
or.w #$0080,d3 | |
.1: tst.b mt_chan2+n_looped(a4) | |
bne .2 | |
or.w #$0100,d3 | |
.2: tst.b mt_chan3+n_looped(a4) | |
bne .3 | |
or.w #$0200,d3 | |
.3: tst.b mt_chan4+n_looped(a4) | |
bne .4 | |
or.w #$0400,d3 | |
.4: move.w INTREQR(a6),d1 | |
and.w d3,d1 | |
bne .6 | |
; All channels are busy. Then break the non-looped ones first... | |
move.w d3,d1 | |
bne .6 | |
; ..except there are none. Then it doesn't matter. :| | |
move.w #$0780,d1 | |
; first look for the best unused channel | |
.6: moveq #0,d3 | |
btst #7,d1 | |
seq d0 | |
or.b d4,d0 | |
bne .7 | |
lea mt_chan1+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .7 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.7: btst #8,d1 | |
seq d0 | |
or.b d5,d0 | |
bne .8 | |
lea mt_chan2+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .8 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.8: btst #9,d1 | |
seq d0 | |
or.b d6,d0 | |
bne .9 | |
lea mt_chan3+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .9 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.9: btst #10,d1 | |
seq d0 | |
or.b d7,d0 | |
bne .10 | |
lea mt_chan4+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .10 | |
move.l a1,a2 | |
bra found_sfx_ch | |
.10: move.l a2,d3 | |
bne found_sfx_ch | |
.overwrite: | |
; finally try to overwrite a sound effect with lower/equal priority | |
moveq #0,d3 | |
tst.b d4 | |
beq .11 | |
cmp.b d4,d2 | |
blo .11 | |
lea mt_chan1+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .11 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.11: tst.b d5 | |
beq .12 | |
cmp.b d5,d2 | |
blo .12 | |
lea mt_chan2+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .12 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.12: tst.b d6 | |
beq .13 | |
cmp.b d6,d2 | |
blo .13 | |
lea mt_chan3+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .13 | |
move.l a1,a2 | |
move.b (a1),d3 | |
.13: tst.b d7 | |
beq .14 | |
cmp.b d7,d2 | |
blo .14 | |
lea mt_chan4+n_freecnt(a4),a1 | |
cmp.b (a1),d3 | |
bhi .14 | |
move.l a1,a2 | |
.14: move.l a2,d3 | |
beq exit_playfx ; ignore new sfx due to low priority | |
found_sfx_ch: | |
lea -n_freecnt(a2),a2 | |
bra set_sfx | |
channel_offsets: | |
dc.w 0*n_sizeof,1*n_sizeof,2*n_sizeof,3*n_sizeof | |
channelsfx: | |
; a0 = sfx structure | |
; d0 = fixed channel for new sound effect | |
add.w d0,d0 | |
lea mt_chan1(a4),a2 | |
add.w channel_offsets(pc,d0.w),a2 | |
; priority high enough to replace a present effect on this channel? | |
move.w #$4000,INTENA(a6) | |
move.b sfx_pri(a0),d2 | |
cmp.b n_sfxpri(a2),d2 | |
bhs set_sfx | |
sub.l a2,a2 | |
bra exit_playfx | |
set_sfx: | |
; activate the sound effect on this channel | |
; a0 = sfx structure | |
; d2 = sfx priority | |
; a2 = channel status | |
move.l (a0)+,n_sfxptr(a2) ; sfx_ptr | |
move.w (a0)+,n_sfxlen(a2) ; sfx_len | |
move.w (a0)+,n_sfxper(a2) ; sfx_per | |
move.w (a0),n_sfxvol(a2) ; sfx_vol | |
move.b d2,n_sfxpri(a2) | |
exit_playfx: | |
move.w #$c000,INTENA(a6) | |
move.l a2,d0 ; ptr to selected channel or NULL | |
movem.l (sp)+,d2-d7/a0-a5 | |
rts | |
;--------------------------------------------------------------------------- | |
_mt_musicmask: | |
; Set bits in the mask define which specific channels are reserved | |
; for music only. | |
; a6 = _custom | |
; d0.b = channel-mask (bit 0 for channel 0, ..., bit 3 for channel 3) | |
move.l a4,-(sp) | |
lea mt_data(pc),a4 | |
move.w #$4000,INTENA(a6) | |
lsl.b #5,d0 | |
scs mt_chan4+n_musiconly(a4) | |
add.b d0,d0 | |
scs mt_chan3+n_musiconly(a4) | |
add.b d0,d0 | |
scs mt_chan2+n_musiconly(a4) | |
add.b d0,d0 | |
scs mt_chan1+n_musiconly(a4) | |
move.w #$c000,INTENA(a6) | |
move.l (sp)+,a4 | |
rts | |
;--------------------------------------------------------------------------- | |
_mt_mastervol: | |
; Set a master volume from 0 to 64 for all music channels. | |
; Note that the master volume does not affect the volume of external | |
; sound effects (which is desired). | |
; a6 = _custom | |
; d0.w = master volume | |
; stingray, since each volume table has a size of 65 bytes | |
; we simply multiply (optimised of course) by 65 to get the | |
; offset to the correct table | |
lea MasterVolTab0(pc),a0 | |
add.w d0,a0 | |
lsl.w #6,d0 | |
add.w d0,a0 | |
move.w #$4000,INTENA(a6) | |
ifd SDATA | |
move.l a0,mt_MasterVolTab(a4) | |
else | |
lea mt_data+mt_MasterVolTab(pc),a1 | |
move.l a0,(a1) | |
endc | |
move.w #$c000,INTENA(a6) | |
rts | |
;--------------------------------------------------------------------------- | |
_mt_samplevol: | |
; Redefine a sample's volume. May also be done while the song is playing. | |
; Warning: Does not check arguments for valid range! You must have done | |
; _mt_init before calling this function! | |
; The new volume is persistent. Even when the song is restarted. | |
; d0.w = sample number (0-31) | |
; d1.b = volume (0-64) | |
move.l mt_data+mt_mod(pc),a0 | |
swap d1 | |
move.w d0,d1 | |
add.w d1,d1 | |
lsl.w #5,d0 | |
sub.w d1,d0 ; table index: sample number * 30 | |
swap d1 | |
move.b d1,12+3(a0,d0.w) ; set sample's volume | |
rts | |
endc ; !MINIMAL | |
;--------------------------------------------------------------------------- | |
_mt_music: | |
; Called from interrupt. | |
; Play next position when Counter equals Speed. | |
; Effects are always handled. | |
; a6 = _custom | |
moveq #0,d7 ; d7 is always zero | |
lea mt_dmaon+1(pc),a0 | |
move.b d7,(a0) | |
addq.b #1,mt_Counter(a4) | |
move.b mt_Counter(a4),d0 | |
cmp.b mt_Speed(a4),d0 | |
blo no_new_note | |
; handle a new note | |
move.b d7,mt_Counter(a4) | |
tst.b mt_PattDelTime2(a4) | |
beq get_new_note | |
; we have a pattern delay, check effects then step | |
lea AUD0LC(a6),a5 | |
lea mt_chan1(a4),a2 | |
bsr mt_checkfx | |
lea AUD1LC(a6),a5 | |
lea mt_chan2(a4),a2 | |
bsr mt_checkfx | |
lea AUD2LC(a6),a5 | |
lea mt_chan3(a4),a2 | |
bsr mt_checkfx | |
lea AUD3LC(a6),a5 | |
lea mt_chan4(a4),a2 | |
bsr mt_checkfx | |
bra settb_step | |
no_new_note: | |
; no new note, just check effects, don't step to next position | |
lea AUD0LC(a6),a5 | |
lea mt_chan1(a4),a2 | |
bsr mt_checkfx | |
lea AUD1LC(a6),a5 | |
lea mt_chan2(a4),a2 | |
bsr mt_checkfx | |
lea AUD2LC(a6),a5 | |
lea mt_chan3(a4),a2 | |
bsr mt_checkfx | |
lea AUD3LC(a6),a5 | |
lea mt_chan4(a4),a2 | |
bsr mt_checkfx | |
; set one-shot TimerB interrupt for enabling DMA, when needed | |
move.b mt_dmaon+1(pc),d0 | |
beq same_pattern | |
move.b #$19,CIAB+CIACRB ; load/start timer B, one-shot | |
bra same_pattern | |
get_new_note: | |
; determine pointer to current pattern line | |
move.l mt_mod(a4),a0 | |
lea 12(a0),a3 ; sample info table | |
lea 1084(a0),a1 ; pattern data | |
lea 952(a0),a0 | |
moveq #0,d0 | |
move.b mt_SongPos(a4),d0 | |
move.b (a0,d0.w),d0 ; current pattern number | |
swap d0 | |
lsr.l #6,d0 | |
add.l d0,a1 ; pattern base | |
add.w mt_PatternPos(a4),a1 ; a1 pattern line | |
; play new note for each channel, apply some effects | |
lea AUD0LC(a6),a5 | |
lea mt_chan1(a4),a2 | |
bsr mt_playvoice | |
lea AUD1LC(a6),a5 | |
lea mt_chan2(a4),a2 | |
bsr mt_playvoice | |
lea AUD2LC(a6),a5 | |
lea mt_chan3(a4),a2 | |
bsr mt_playvoice | |
lea AUD3LC(a6),a5 | |
lea mt_chan4(a4),a2 | |
bsr mt_playvoice | |
settb_step: | |
; set one-shot TimerB interrupt for enabling DMA, when needed | |
move.b mt_dmaon+1(pc),d0 | |
beq pattern_step | |
move.b #$19,CIAB+CIACRB ; load/start timer B, one-shot | |
pattern_step: | |
; next pattern line, handle delay and break | |
ifnd MINIMAL | |
clr.b mt_SilCntValid(a4) ; recalculate silence counters | |
endc | |
moveq #16,d2 ; offset to next pattern line | |
move.b mt_PattDelTime2(a4),d1 | |
move.b mt_PattDelTime(a4),d0 | |
beq .1 | |
move.b d0,d1 | |
move.b d7,mt_PattDelTime(a4) | |
.1: tst.b d1 | |
beq .3 | |
subq.b #1,d1 | |
beq .2 | |
moveq #0,d2 ; do not advance to next line | |
.2: move.b d1,mt_PattDelTime2(a4) | |
.3: add.w mt_PatternPos(a4),d2 ; d2 PatternPos | |
; check for break | |
bclr d7,mt_PBreakFlag(a4) | |
beq .4 | |
move.w mt_PBreakPos(a4),d2 | |
move.w d7,mt_PBreakPos(a4) | |
; check whether end of pattern is reached | |
.4: move.w d2,mt_PatternPos(a4) | |
cmp.w #1024,d2 | |
blo same_pattern | |
song_step: | |
move.w mt_PBreakPos(a4),mt_PatternPos(a4) | |
move.w d7,mt_PBreakPos(a4) | |
move.b d7,mt_PosJumpFlag(a4) | |
; next position in song | |
moveq #1,d0 | |
add.b mt_SongPos(a4),d0 | |
and.w #$007f,d0 | |
move.l mt_mod(a4),a0 | |
cmp.b 950(a0),d0 ; end of song reached? | |
blo .1 | |
moveq #0,d0 ; restart the song from the beginning | |
ifnd MINIMAL | |
addq.b #1,mt_SongEnd(a4) | |
bne .2 | |
clr.b mt_Enable(a4) ; stop the song when mt_SongEnd was -1 | |
.2: and.b #$7f,mt_SongEnd(a4) | |
endc | |
.1: move.b d0,mt_SongPos(a4) | |
same_pattern: | |
tst.b mt_PosJumpFlag(a4) | |
bne song_step | |
rts | |
ifnd MINIMAL | |
;--------------------------------------------------------------------------- | |
mt_sfxonly: | |
; Called from interrupt. | |
; Plays sound effects on free channels. | |
; a6 = _custom | |
moveq #0,d7 ; d7 is always zero | |
lea mt_dmaon+1(pc),a0 | |
move.b d7,(a0) | |
lea AUD0LC(a6),a5 | |
lea mt_chan1(a4),a2 | |
bsr chan_sfx_only | |
lea AUD1LC(a6),a5 | |
lea mt_chan2(a4),a2 | |
bsr chan_sfx_only | |
lea AUD2LC(a6),a5 | |
lea mt_chan3(a4),a2 | |
bsr chan_sfx_only | |
lea AUD3LC(a6),a5 | |
lea mt_chan4(a4),a2 | |
bsr chan_sfx_only | |
move.b mt_dmaon+1(pc),d0 | |
beq .1 | |
move.b #$19,CIAB+CIACRB ; load/start timer B, one-shot | |
.1: rts | |
chan_sfx_only: | |
; Check for new sound samples. Check if previous ones are finished. | |
; a2 = channel data | |
; a5 = audio registers | |
tst.b n_sfxpri(a2) | |
beq .1 | |
move.w n_sfxlen(a2),d0 | |
bne start_sfx | |
move.w n_intbit(a2),d0 | |
and.w INTREQR(a6),d0 | |
beq .1 | |
move.w n_dmabit(a2),d0 | |
and.w mt_dmaon(pc),d0 | |
bne .1 | |
; last sound effect sample has played, so unblock this channel again | |
move.b d7,n_sfxpri(a2) | |
.1: rts | |
;--------------------------------------------------------------------------- | |
start_sfx: | |
; d0 = sfx_len in words | |
; a2 = channel data | |
; a5 = audio registers | |
; play new sound effect on this channel | |
move.w n_dmabit(a2),d1 | |
move.w d1,DMACON(a6) | |
move.l n_sfxptr(a2),a0 | |
move.l a0,AUDLC(a5) | |
move.w d0,AUDLEN(a5) | |
move.w n_sfxper(a2),d0 | |
move.w d0,AUDPER(a5) | |
move.w n_sfxvol(a2),AUDVOL(a5) | |
; save repeat and period for TimerB interrupt | |
move.l a0,n_loopstart(a2) | |
move.w #1,n_replen(a2) | |
move.w d0,n_period(a2) | |
move.b d7,n_looped(a2) | |
move.w d7,n_sfxlen(a2) | |
lea mt_dmaon(pc),a0 | |
or.w d1,(a0) | |
rts | |
endc ; !MINIMAL | |
;--------------------------------------------------------------------------- | |
mt_checkfx: | |
; a2 = channel data | |
; a5 = audio registers | |
ifnd MINIMAL | |
tst.b n_sfxpri(a2) | |
beq .3 | |
move.w n_sfxlen(a2),d0 | |
beq .2 | |
bsr start_sfx | |
; channel is blocked, only check some E-commands | |
.1: move.w #$0fff,d4 | |
and.w n_cmd(a2),d4 | |
move.w d4,d0 | |
clr.b d0 | |
cmp.w #$0e00,d0 | |
bne mt_nop | |
and.w #$00ff,d4 | |
bra blocked_e_cmds | |
.2: move.w n_intbit(a2),d0 | |
and.w INTREQR(a6),d0 | |
beq .1 | |
move.w n_dmabit(a2),d0 | |
and.w mt_dmaon(pc),d0 | |
bne .1 | |
; sound effect sample has played, so unblock this channel again | |
move.b d7,n_sfxpri(a2) | |
endc ; !MINIMAL | |
; do channel effects between notes | |
.3: move.w n_funk(a2),d0 | |
beq .4 | |
bsr mt_updatefunk | |
.4: move.w #$0fff,d4 | |
and.w n_cmd(a2),d4 | |
beq mt_pernop | |
and.w #$00ff,d4 | |
moveq #$0f,d0 | |
and.b n_cmd(a2),d0 | |
add.w d0,d0 | |
move.w fx_tab(pc,d0.w),d0 | |
jmp fx_tab(pc,d0.w) | |
fx_tab: | |
dc.w mt_arpeggio-fx_tab ; $0 | |
dc.w mt_portaup-fx_tab | |
dc.w mt_portadown-fx_tab | |
dc.w mt_toneporta-fx_tab | |
dc.w mt_vibrato-fx_tab ; $4 | |
dc.w mt_tonevolslide-fx_tab | |
dc.w mt_vibrvolslide-fx_tab | |
dc.w mt_tremolo-fx_tab | |
dc.w mt_nop-fx_tab ; $8 | |
dc.w mt_nop-fx_tab | |
dc.w mt_volumeslide-fx_tab | |
dc.w mt_nop-fx_tab | |
dc.w mt_nop-fx_tab ; $C | |
dc.w mt_nop-fx_tab | |
dc.w mt_e_cmds-fx_tab | |
dc.w mt_nop-fx_tab | |
mt_pernop: | |
; just set the current period | |
move.w n_period(a2),AUDPER(a5) | |
mt_nop: | |
rts | |
;--------------------------------------------------------------------------- | |
mt_playvoice: | |
; a1 = pattern ptr | |
; a2 = channel data | |
; a3 = sample info table | |
; a5 = audio registers | |
move.l (a1)+,d6 ; d6 current note/cmd words | |
ifnd MINIMAL | |
; channel blocked by external sound effect? | |
tst.b n_sfxpri(a2) | |
beq .2 | |
move.w n_sfxlen(a2),d0 | |
beq .1 | |
bsr start_sfx | |
bra moreblockedfx | |
; do only some limited commands, while sound effect is in progress | |
.1: move.w n_intbit(a2),d0 | |
and.w INTREQR(a6),d0 | |
beq moreblockedfx | |
move.w n_dmabit(a2),d0 | |
and.w mt_dmaon(pc),d0 | |
bne moreblockedfx | |
; sound effect sample has played, so unblock this channel again | |
move.b d7,n_sfxpri(a2) | |
endc ; !MINIMAL | |
.2: tst.l (a2) ; n_note/cmd: any note or cmd set? | |
bne .3 | |
move.w n_period(a2),AUDPER(a5) | |
.3: move.l d6,(a2) | |
moveq #15,d5 | |
and.b n_cmd(a2),d5 | |
add.w d5,d5 ; d5 cmd*2 | |
moveq #0,d4 | |
move.b d6,d4 ; d4 cmd argument (in MSW) | |
swap d4 | |
move.w #$0ff0,d4 | |
and.w d6,d4 ; d4 for checking E-cmd (in LSW) | |
swap d6 | |
move.l d6,d0 ; S...S... | |
clr.b d0 | |
rol.w #4,d0 | |
rol.l #4,d0 ; ....00SS | |
and.w #$0fff,d6 ; d6 note | |
; get sample start address | |
add.w d0,d0 ; sample number * 2 | |
beq set_regs | |
move.w mult30tab(pc,d0.w),d1 ; d1 sample info table offset | |
lea mt_SampleStarts(a4),a0 | |
add.w d0,d0 | |
move.l -4(a0,d0.w),d2 | |
; read length, volume and repeat from sample info table | |
lea (a3,d1.w),a0 | |
move.w (a0)+,d0 ; length | |
bne .4 | |
; use the first two bytes from the first sample for empty samples | |
move.l mt_SampleStarts(a4),d2 | |
addq.w #1,d0 | |
.4: move.l d2,n_start(a2) | |
move.w d0,n_reallength(a2) | |
; determine period table from fine-tune parameter | |
moveq #0,d3 | |
move.b (a0)+,d3 | |
add.w d3,d3 | |
move.l a0,d1 | |
lea mt_PerFineTune(pc),a0 | |
add.w (a0,d3.w),a0 | |
move.l a0,n_pertab(a2) | |
move.l d1,a0 | |
cmp.w #2*8,d3 | |
shs n_minusft(a2) | |
moveq #0,d1 | |
move.b (a0)+,d1 ; volume | |
move.w d1,n_volume(a2) | |
move.w (a0)+,d3 ; repeat offset | |
beq no_offset | |
; set repeat | |
add.l d3,d2 | |
add.l d3,d2 | |
move.w (a0),d0 | |
; beq idle_looping ; @@@ shouldn't happen, d0=n_length!? | |
move.w d0,n_replen(a2) | |
exg d0,d3 ; n_replen to d3 | |
add.w d3,d0 | |
bra set_len_start | |
mult30tab: | |
dc.w 0*30,1*30,2*30,3*30,4*30,5*30,6*30,7*30 | |
dc.w 8*30,9*30,10*30,11*30,12*30,13*30,14*30,15*30 | |
dc.w 16*30,17*30,18*30,19*30,20*30,21*30,22*30,23*30 | |
dc.w 24*30,25*30,26*30,27*30,28*30,29*30,30*30,31*30 | |
no_offset: | |
move.w (a0),d3 | |
bne set_replen | |
idle_looping: | |
; repeat length zero means idle-looping | |
moveq #0,d2 ; FIXME: expect two zero bytes at $0 | |
addq.w #1,d3 | |
set_replen: | |
move.w d3,n_replen(a2) | |
set_len_start: | |
move.w d0,n_length(a2) | |
move.l d2,n_loopstart(a2) | |
move.l d2,n_wavestart(a2) | |
ifnd MINIMAL | |
move.l mt_MasterVolTab(a4),a0 | |
move.b (a0,d1.w),d1 | |
endc | |
move.w d1,AUDVOL(a5) | |
; remember if sample is looped | |
; @@@ FIXME: also need to check if n_loopstart equals n_start | |
subq.w #1,d3 | |
sne n_looped(a2) | |
set_regs: | |
; d4 = cmd argument | masked E-cmd | |
; d5 = cmd*2 | |
; d6 = cmd.w | note.w | |
move.w d4,d3 ; d3 masked E-cmd | |
swap d4 ; d4 cmd argument into LSW | |
tst.w d6 | |
beq checkmorefx ; no new note | |
cmp.w #$0e50,d3 | |
beq set_finetune | |
move.w prefx_tab(pc,d5.w),d0 | |
jmp prefx_tab(pc,d0.w) | |
prefx_tab: | |
dc.w set_period-prefx_tab,set_period-prefx_tab,set_period-prefx_tab | |
dc.w set_toneporta-prefx_tab ; $3 | |
dc.w set_period-prefx_tab | |
dc.w set_toneporta-prefx_tab ; $5 | |
dc.w set_period-prefx_tab,set_period-prefx_tab,set_period-prefx_tab | |
dc.w set_sampleoffset-prefx_tab ; $9 | |
dc.w set_period-prefx_tab,set_period-prefx_tab,set_period-prefx_tab | |
dc.w set_period-prefx_tab,set_period-prefx_tab,set_period-prefx_tab | |
set_toneporta: | |
move.l n_pertab(a2),a0 ; tuned period table | |
; find first period which is less or equal the note in d6 | |
moveq #36-1,d0 | |
moveq #-2,d1 | |
.1: addq.w #2,d1 | |
cmp.w (a0)+,d6 | |
dbhs d0,.1 | |
tst.b n_minusft(a2) ; negative fine tune? | |
beq .2 | |
tst.w d1 | |
beq .2 | |
subq.l #2,a0 ; then take previous period | |
subq.w #2,d1 | |
.2: move.w d1,n_noteoff(a2) ; note offset in period table | |
move.w n_period(a2),d2 | |
move.w -(a0),d1 | |
cmp.w d1,d2 | |
bne .3 | |
moveq #0,d1 | |
.3: move.w d1,n_wantedperiod(a2) | |
move.w n_funk(a2),d0 | |
beq .4 | |
bsr mt_updatefunk | |
.4: move.w d2,AUDPER(a5) | |
rts | |
set_sampleoffset: | |
; cmd 9 x y (xy = offset in 256 bytes) | |
; d4 = xy | |
moveq #0,d0 | |
move.b d4,d0 | |
bne .1 | |
move.b n_sampleoffset(a2),d0 | |
bra .2 | |
.1: move.b d0,n_sampleoffset(a2) | |
.2: lsl.w #7,d0 | |
cmp.w n_length(a2),d0 | |
bhs .3 | |
sub.w d0,n_length(a2) | |
add.w d0,d0 | |
add.l d0,n_start(a2) | |
bra set_period | |
.3: move.w #1,n_length(a2) | |
bra set_period | |
set_finetune: | |
lea mt_PerFineTune(pc),a0 | |
moveq #$0f,d0 | |
and.b n_cmdlo(a2),d0 | |
add.w d0,d0 | |
add.w (a0,d0.w),a0 | |
move.l a0,n_pertab(a2) | |
cmp.w #2*8,d0 | |
shs n_minusft(a2) | |
set_period: | |
; find nearest period for a note value, then apply finetuning | |
; d3 = masked E-cmd | |
; d4 = cmd argument | |
; d5 = cmd*2 | |
; d6 = note.w | |
lea mt_PeriodTable(pc),a0 | |
moveq #36-1,d0 | |
moveq #-2,d1 | |
.1: addq.w #2,d1 ; table offset | |
cmp.w (a0)+,d6 | |
dbhs d0,.1 | |
; apply finetuning, set period and note-offset | |
move.l n_pertab(a2),a0 | |
move.w (a0,d1.w),d2 | |
move.w d2,n_period(a2) | |
move.w d1,n_noteoff(a2) | |
; check for notedelay | |
cmp.w #$0ed0,d3 ; notedelay | |
beq checkmorefx | |
; disable DMA | |
move.w n_dmabit(a2),d0 | |
move.w d0,DMACON(a6) | |
btst #2,n_vibratoctrl(a2) | |
bne .2 | |
move.b d7,n_vibratopos(a2) | |
.2: btst #2,n_tremoloctrl(a2) | |
bne .3 | |
move.b d7,n_tremolopos(a2) | |
.3: move.l n_start(a2),AUDLC(a5) | |
move.w n_length(a2),AUDLEN(a5) | |
move.w d2,AUDPER(a5) | |
lea mt_dmaon(pc),a0 | |
or.w d0,(a0) | |
checkmorefx: | |
; d4 = cmd argument | |
; d5 = cmd*2 | |
; d6 = note.w | |
move.w n_funk(a2),d0 | |
beq .1 | |
bsr mt_updatefunk | |
.1: move.w morefx_tab(pc,d5.w),d0 | |
jmp morefx_tab(pc,d0.w) | |
morefx_tab: | |
dc.w mt_pernop-morefx_tab,mt_pernop-morefx_tab,mt_pernop-morefx_tab | |
dc.w mt_pernop-morefx_tab,mt_pernop-morefx_tab,mt_pernop-morefx_tab | |
dc.w mt_pernop-morefx_tab,mt_pernop-morefx_tab,mt_pernop-morefx_tab | |
dc.w mt_pernop-morefx_tab ; $9 | |
dc.w mt_pernop-morefx_tab | |
dc.w mt_posjump-morefx_tab ; $B | |
dc.w mt_volchange-morefx_tab | |
dc.w mt_patternbrk-morefx_tab ; $D | |
dc.w mt_e_cmds-morefx_tab | |
dc.w mt_setspeed-morefx_tab | |
ifnd MINIMAL | |
moreblockedfx: | |
; d6 = note.w | cmd.w | |
moveq #0,d4 | |
move.b d6,d4 ; cmd argument | |
and.w #$0f00,d6 | |
lsr.w #7,d6 | |
move.w blmorefx_tab(pc,d6.w),d0 | |
jmp blmorefx_tab(pc,d0.w) | |
blmorefx_tab: | |
dc.w mt_nop-blmorefx_tab,mt_nop-blmorefx_tab | |
dc.w mt_nop-blmorefx_tab,mt_nop-blmorefx_tab | |
dc.w mt_nop-blmorefx_tab,mt_nop-blmorefx_tab | |
dc.w mt_nop-blmorefx_tab,mt_nop-blmorefx_tab | |
dc.w mt_nop-blmorefx_tab,mt_nop-blmorefx_tab | |
dc.w mt_nop-blmorefx_tab | |
dc.w mt_posjump-blmorefx_tab ; $B | |
dc.w mt_nop-blmorefx_tab | |
dc.w mt_patternbrk-blmorefx_tab ; $D | |
dc.w blocked_e_cmds-blmorefx_tab | |
dc.w mt_setspeed-blmorefx_tab ; $F | |
endc ; !MINIMAL | |
mt_arpeggio: | |
; cmd 0 x y (x = first arpeggio offset, y = second arpeggio offset) | |
; d4 = xy | |
moveq #0,d0 | |
move.b mt_Counter(a4),d0 | |
move.b arptab(pc,d0.w),d0 | |
beq mt_pernop ; step 0, just use normal period | |
bmi .1 | |
; step 1, arpeggio by left nibble | |
lsr.b #4,d4 | |
bra .2 | |
; step 2, arpeggio by right nibble | |
.1: and.w #$000f,d4 | |
; offset current note | |
.2: add.w d4,d4 | |
add.w n_noteoff(a2),d4 | |
cmp.w #2*36,d4 | |
bhs .4 | |
; set period with arpeggio offset from note table | |
move.l n_pertab(a2),a0 | |
move.w (a0,d4.w),AUDPER(a5) | |
.4: rts | |
arptab: | |
dc.b 0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0 | |
dc.b 1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1 | |
mt_fineportaup: | |
; cmd E 1 x (subtract x from period) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
beq do_porta_up | |
rts | |
mt_portaup: | |
; cmd 1 x x (subtract xx from period) | |
; d4 = xx | |
move.w d4,d0 | |
do_porta_up: | |
move.w n_period(a2),d1 | |
sub.w d0,d1 | |
cmp.w #113,d1 | |
bhs .1 | |
moveq #113,d1 | |
.1: move.w d1,n_period(a2) | |
move.w d1,AUDPER(a5) | |
rts | |
mt_fineportadn: | |
; cmd E 2 x (add x to period) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
beq do_porta_down | |
rts | |
mt_portadown: | |
; cmd 2 x x (add xx to period) | |
; d4 = xx | |
move.w d4,d0 | |
do_porta_down: | |
move.w n_period(a2),d1 | |
add.w d0,d1 | |
cmp.w #856,d1 | |
bls .1 | |
move.w #856,d1 | |
.1: move.w d1,n_period(a2) | |
move.w d1,AUDPER(a5) | |
rts | |
mt_toneporta: | |
; cmd 3 x y (xy = tone portamento speed) | |
; d4 = xy | |
tst.b d4 | |
beq mt_toneporta_nc | |
move.w d4,n_toneportspeed(a2) | |
move.b d7,n_cmdlo(a2) | |
mt_toneporta_nc: | |
move.w n_wantedperiod(a2),d1 | |
beq .6 | |
move.w n_toneportspeed(a2),d0 | |
move.w n_period(a2),d2 | |
cmp.w d1,d2 | |
blo .2 | |
; tone porta up | |
sub.w d0,d2 | |
cmp.w d1,d2 | |
bgt .3 | |
move.w d1,d2 | |
move.w d7,n_wantedperiod(a2) | |
bra .3 | |
; tone porta down | |
.2: add.w d0,d2 | |
cmp.w d1,d2 | |
blt .3 | |
move.w d1,d2 | |
move.w d7,n_wantedperiod(a2) | |
.3: move.w d2,n_period(a2) | |
tst.b n_gliss(a2) | |
beq .5 | |
; glissando: find nearest note for new period | |
move.l n_pertab(a2),a0 | |
moveq #36-1,d0 | |
moveq #-2,d1 | |
.4: addq.w #2,d1 | |
cmp.w (a0)+,d2 | |
dbhs d0,.4 | |
move.w d1,n_noteoff(a2) ; @@@ needed? | |
move.w -(a0),d2 | |
.5: move.w d2,AUDPER(a5) | |
.6 rts | |
mt_vibrato: | |
; cmd 4 x y (x = speed, y = amplitude) | |
; d4 = xy | |
moveq #$0f,d2 | |
and.b d4,d2 | |
beq .1 | |
move.b d2,n_vibratoamp(a2) | |
bra .2 | |
.1: move.b n_vibratoamp(a2),d2 | |
.2: lsr.b #4,d4 | |
beq .3 | |
move.b d4,n_vibratospd(a2) | |
bra mt_vibrato_nc | |
.3: move.b n_vibratospd(a2),d4 | |
mt_vibrato_nc: | |
; calculate vibrato table offset: 64 * amplitude + (pos & 63) | |
lsl.w #6,d2 | |
moveq #63,d0 | |
and.b n_vibratopos(a2),d0 | |
add.w d0,d2 | |
; select vibrato waveform | |
moveq #3,d1 | |
and.b n_vibratoctrl(a2),d1 | |
beq .6 | |
subq.b #1,d1 | |
beq .5 | |
; ctrl 2 & 3 select a rectangle vibrato | |
lea mt_VibratoRectTable(pc),a0 | |
bra .9 | |
; ctrl 1 selects a sawtooth vibrato | |
.5: lea mt_VibratoSawTable(pc),a0 | |
bra .9 | |
; ctrl 0 selects a sine vibrato | |
.6: lea mt_VibratoSineTable(pc),a0 | |
; add vibrato-offset to period | |
.9: move.b (a0,d2.w),d0 | |
ext.w d0 | |
add.w n_period(a2),d0 | |
move.w d0,AUDPER(a5) | |
; increase vibratopos by speed | |
add.b d4,n_vibratopos(a2) | |
rts | |
mt_tonevolslide: | |
; cmd 5 x y (x = volume-up, y = volume-down) | |
; d4 = xy | |
pea mt_volumeslide(pc) | |
bra mt_toneporta_nc | |
mt_vibrvolslide: | |
; cmd 6 x y (x = volume-up, y = volume-down) | |
; d4 = xy | |
move.w d4,d3 | |
move.b n_vibratoamp(a2),d2 | |
move.b n_vibratospd(a2),d4 | |
bsr mt_vibrato_nc | |
move.w d3,d4 | |
bra mt_volumeslide | |
mt_tremolo: | |
; cmd 7 x y (x = speed, y = amplitude) | |
; d4 = xy | |
moveq #$0f,d2 | |
and.b d4,d2 | |
beq .1 | |
move.b d2,n_tremoloamp(a2) | |
bra .2 | |
.1: move.b n_tremoloamp(a2),d2 | |
.2: lsr.b #4,d4 | |
beq .3 | |
move.b d4,n_tremolospd(a2) | |
bra .4 | |
.3: move.b n_tremolospd(a2),d4 | |
; calculate tremolo table offset: 64 * amplitude + (pos & 63) | |
.4: lsl.w #6,d2 | |
moveq #63,d0 | |
and.b n_tremolopos(a2),d0 | |
add.w d0,d2 | |
; select tremolo waveform | |
moveq #3,d1 | |
and.b n_tremoloctrl(a2),d1 | |
beq .6 | |
subq.b #1,d1 | |
beq .5 | |
; ctrl 2 & 3 select a rectangle tremolo | |
lea mt_VibratoRectTable(pc),a0 | |
bra .9 | |
; ctrl 1 selects a sawtooth tremolo | |
.5: lea mt_VibratoSawTable(pc),a0 | |
bra .9 | |
; ctrl 0 selects a sine tremolo | |
.6: lea mt_VibratoSineTable(pc),a0 | |
; add tremolo-offset to volume | |
.9: move.w n_volume(a2),d0 | |
add.b (a0,d2.w),d0 | |
bpl .10 | |
moveq #0,d0 | |
.10: cmp.w #64,d0 | |
bls .11 | |
moveq #64,d0 | |
.11: move.w n_period(a2),AUDPER(a5) | |
ifnd MINIMAL | |
move.l mt_MasterVolTab(a4),a0 | |
move.b (a0,d0.w),d0 | |
endc | |
move.w d0,AUDVOL(a5) | |
; increase tremolopos by speed | |
add.b d4,n_tremolopos(a2) | |
rts | |
mt_volumeslide: | |
; cmd A x y (x = volume-up, y = volume-down) | |
; d4 = xy | |
move.w n_volume(a2),d0 | |
moveq #$0f,d1 | |
and.b d4,d1 | |
lsr.b #4,d4 | |
beq vol_slide_down | |
; slide up, until 64 | |
add.b d4,d0 | |
vol_slide_up: | |
cmp.b #64,d0 | |
bls set_vol | |
moveq #64,d0 | |
bra set_vol | |
; slide down, until 0 | |
vol_slide_down: | |
sub.b d1,d0 | |
bpl set_vol | |
moveq #0,d0 | |
set_vol: | |
move.w d0,n_volume(a2) | |
move.w n_period(a2),AUDPER(a5) | |
ifnd MINIMAL | |
move.l mt_MasterVolTab(a4),a0 | |
move.b (a0,d0.w),d0 | |
endc | |
move.w d0,AUDVOL(a5) | |
rts | |
mt_posjump: | |
; cmd B x y (xy = new song position) | |
; d4 = xy | |
move.b d4,d0 | |
subq.b #1,d0 | |
move.b d0,mt_SongPos(a4) | |
jump_pos0: | |
move.w d7,mt_PBreakPos(a4) | |
st mt_PosJumpFlag(a4) | |
rts | |
mt_volchange: | |
; cmd C x y (xy = new volume) | |
; d4 = xy | |
cmp.w #64,d4 | |
bls .1 | |
moveq #64,d4 | |
.1: move.w d4,n_volume(a2) | |
ifnd MINIMAL | |
move.l mt_MasterVolTab(a4),a0 | |
move.b (a0,d4.w),d4 | |
endc | |
move.w d4,AUDVOL(a5) | |
rts | |
mt_patternbrk: | |
; cmd D x y (xy = break pos in decimal) | |
; d4 = xy | |
moveq #$0f,d0 | |
and.w d4,d0 | |
move.w d4,d1 | |
lsr.w #4,d1 | |
add.b mult10tab(pc,d1.w),d0 | |
cmp.b #63,d0 | |
bhi jump_pos0 | |
lsl.w #4,d0 | |
move.w d0,mt_PBreakPos(a4) | |
st mt_PosJumpFlag(a4) | |
rts | |
mult10tab: | |
dc.b 0,10,20,30,40,50,60,70,80,90,0,0,0,0,0,0 | |
mt_setspeed: | |
; cmd F x y (xy<$20 new speed, xy>=$20 new tempo) | |
; d4 = xy | |
cmp.b #$20,d4 | |
bhs .1 | |
move.b d4,mt_Speed(a4) | |
beq _mt_end | |
rts | |
; set tempo (CIA only) | |
.1: and.w #$00ff,d4 | |
move.l mt_timerval(a4),d0 | |
divu d4,d0 | |
move.b d0,CIAB+CIATALO | |
lsr.w #8,d0 | |
move.b d0,CIAB+CIATAHI | |
rts | |
mt_e_cmds: | |
; cmd E x y (x=command, y=argument) | |
; d4 = xy | |
moveq #$0f,d0 | |
and.w d4,d0 ; pass E-cmd argument in d0 | |
move.w d4,d1 | |
lsr.w #4,d1 | |
add.w d1,d1 | |
move.w ecmd_tab(pc,d1.w),d1 | |
jmp ecmd_tab(pc,d1.w) | |
ecmd_tab: | |
dc.w mt_filter-ecmd_tab | |
dc.w mt_fineportaup-ecmd_tab | |
dc.w mt_fineportadn-ecmd_tab | |
dc.w mt_glissctrl-ecmd_tab | |
dc.w mt_vibratoctrl-ecmd_tab | |
dc.w mt_finetune-ecmd_tab | |
dc.w mt_jumploop-ecmd_tab | |
dc.w mt_tremoctrl-ecmd_tab | |
dc.w mt_e8-ecmd_tab | |
dc.w mt_retrignote-ecmd_tab | |
dc.w mt_volfineup-ecmd_tab | |
dc.w mt_volfinedn-ecmd_tab | |
dc.w mt_notecut-ecmd_tab | |
dc.w mt_notedelay-ecmd_tab | |
dc.w mt_patterndelay-ecmd_tab | |
dc.w mt_funk-ecmd_tab | |
blocked_e_cmds: | |
; cmd E x y (x=command, y=argument) | |
; d4 = xy | |
moveq #$0f,d0 | |
and.w d4,d0 ; pass E-cmd argument in d0 | |
move.w d4,d1 | |
lsr.w #4,d1 | |
add.w d1,d1 | |
move.w blecmd_tab(pc,d1.w),d1 | |
jmp blecmd_tab(pc,d1.w) | |
blecmd_tab: | |
dc.w mt_filter-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_glissctrl-blecmd_tab | |
dc.w mt_vibratoctrl-blecmd_tab | |
dc.w mt_finetune-blecmd_tab | |
dc.w mt_jumploop-blecmd_tab | |
dc.w mt_tremoctrl-blecmd_tab | |
dc.w mt_e8-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
dc.w mt_patterndelay-blecmd_tab | |
dc.w mt_rts-blecmd_tab | |
mt_filter: | |
; cmd E 0 x (x=1 disable, x=0 enable) | |
; d0 = x | |
lsr.b #1,d0 | |
bcs .1 | |
bclr #2,CIAA+CIAPRA | |
rts | |
.1: bset #2,CIAA+CIAPRA | |
mt_rts: | |
rts | |
mt_glissctrl: | |
; cmd E 3 x (x gliss) | |
; d0 = x | |
move.b d0,n_gliss(a2) | |
rts | |
mt_vibratoctrl: | |
; cmd E 4 x (x = vibrato) | |
; d0 = x | |
move.b d0,n_vibratoctrl(a2) | |
rts | |
mt_finetune: | |
; cmd E 5 x (x = finetune) | |
; d0 = x | |
lea mt_PerFineTune(pc),a0 | |
add.w d0,d0 | |
add.w (a0,d0.w),a0 | |
move.l a0,n_pertab(a2) | |
cmp.w #2*8,d0 | |
shs n_minusft(a2) | |
rts | |
mt_jumploop: | |
; cmd E 6 x (x=0 loop start, else loop count) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
bne .4 | |
.1: tst.b d0 | |
beq .3 ; set start | |
; otherwise we are at the end of the loop | |
subq.b #1,n_loopcount(a2) | |
beq .4 ; loop finished | |
bpl .2 | |
; initialize loop counter | |
move.b d0,n_loopcount(a2) | |
; jump back to start of loop | |
.2: move.w n_pattpos(a2),mt_PBreakPos(a4) | |
st mt_PBreakFlag(a4) | |
rts | |
; remember start of loop position | |
.3: move.w mt_PatternPos(a4),n_pattpos(a2) | |
.4: rts | |
mt_tremoctrl: | |
; cmd E 7 x (x = tremolo) | |
; d0 = x | |
move.b d0,n_tremoloctrl(a2) | |
rts | |
mt_e8: | |
; cmd E 8 x (x = trigger value) | |
; d0 = x | |
move.b d0,mt_E8Trigger(a4) | |
rts | |
mt_retrignote: | |
; cmd E 9 x (x = retrigger count) | |
; d0 = x | |
tst.b d0 | |
beq .1 | |
; set new retrigger count when Counter=0 | |
tst.b mt_Counter(a4) | |
bne .2 | |
move.b d0,n_retrigcount(a2) | |
; avoid double retrigger, when Counter=0 and a note was set | |
move.w #$0fff,d2 | |
and.w (a2),d2 | |
beq do_retrigger | |
.1: rts | |
; check if retrigger count is reached | |
.2: subq.b #1,n_retrigcount(a2) | |
bne .1 | |
move.b d0,n_retrigcount(a2) ; reset | |
do_retrigger: | |
; DMA off, set sample pointer and length | |
move.w n_dmabit(a2),d0 | |
move.w d0,DMACON(a6) | |
move.l n_start(a2),AUDLC(a5) | |
move.w n_length(a2),AUDLEN(a5) | |
lea mt_dmaon(pc),a0 | |
or.w d0,(a0) | |
rts | |
mt_volfineup: | |
; cmd E A x (x = volume add) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
beq .1 | |
rts | |
.1: add.w n_volume(a2),d0 | |
bra vol_slide_up | |
mt_volfinedn: | |
; cmd E B x (x = volume sub) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
beq .1 | |
rts | |
.1: move.b d0,d1 | |
move.w n_volume(a2),d0 | |
bra vol_slide_down | |
mt_notecut: | |
; cmd E C x (x = counter to cut at) | |
; d0 = x | |
cmp.b mt_Counter(a4),d0 | |
bne .1 | |
move.w d7,n_volume(a2) | |
move.w d7,AUDVOL(a5) | |
.1: rts | |
mt_notedelay: | |
; cmd E D x (x = counter to retrigger at) | |
; d0 = x | |
cmp.b mt_Counter(a4),d0 | |
bne .1 | |
tst.w (a2) ; trigger note when given | |
bne do_retrigger | |
.1: rts | |
mt_patterndelay: | |
; cmd E E x (x = delay count) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
bne .1 | |
tst.b mt_PattDelTime2(a4) | |
bne .1 | |
addq.b #1,d0 | |
move.b d0,mt_PattDelTime(a4) | |
.1: rts | |
mt_funk: | |
; cmd E F x (x = funk speed) | |
; d0 = x | |
tst.b mt_Counter(a4) | |
bne .1 | |
move.w d0,n_funk(a2) | |
bne mt_updatefunk | |
.1: rts | |
mt_updatefunk: | |
; d0 = funk speed | |
move.b mt_FunkTable(pc,d0.w),d0 | |
add.b d0,n_funkoffset(a2) | |
bpl .2 | |
move.b d7,n_funkoffset(a2) | |
move.l n_loopstart(a2),d0 | |
moveq #0,d1 | |
move.w n_replen(a2),d1 | |
add.l d1,d1 | |
add.l d0,d1 | |
move.l n_wavestart(a2),a0 | |
addq.l #1,a0 | |
cmp.l d1,a0 | |
blo .1 | |
move.l d0,a0 | |
.1: move.l a0,n_wavestart(a2) | |
not.b (a0) | |
.2: rts | |
mt_FunkTable: | |
dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128 | |
mt_VibratoSineTable: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
dc.b -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0 | |
dc.b 0,0,0,1,1,1,2,2,2,3,3,3,3,3,3,3 | |
dc.b 3,3,3,3,3,3,3,3,2,2,2,1,1,1,0,0 | |
dc.b 0,0,0,-1,-1,-1,-2,-2,-2,-3,-3,-3,-3,-3,-3,-3 | |
dc.b -3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-1,-1,-1,0,0 | |
dc.b 0,0,1,1,2,2,3,3,4,4,4,5,5,5,5,5 | |
dc.b 5,5,5,5,5,5,4,4,4,3,3,2,2,1,1,0 | |
dc.b 0,0,-1,-1,-2,-2,-3,-3,-4,-4,-4,-5,-5,-5,-5,-5 | |
dc.b -5,-5,-5,-5,-5,-5,-4,-4,-4,-3,-3,-2,-2,-1,-1,0 | |
dc.b 0,0,1,2,3,3,4,5,5,6,6,7,7,7,7,7 | |
dc.b 7,7,7,7,7,7,6,6,5,5,4,3,3,2,1,0 | |
dc.b 0,0,-1,-2,-3,-3,-4,-5,-5,-6,-6,-7,-7,-7,-7,-7 | |
dc.b -7,-7,-7,-7,-7,-7,-6,-6,-5,-5,-4,-3,-3,-2,-1,0 | |
dc.b 0,0,1,2,3,4,5,6,7,7,8,8,9,9,9,9 | |
dc.b 9,9,9,9,9,8,8,7,7,6,5,4,3,2,1,0 | |
dc.b 0,0,-1,-2,-3,-4,-5,-6,-7,-7,-8,-8,-9,-9,-9,-9 | |
dc.b -9,-9,-9,-9,-9,-8,-8,-7,-7,-6,-5,-4,-3,-2,-1,0 | |
dc.b 0,1,2,3,4,5,6,7,8,9,9,10,11,11,11,11 | |
dc.b 11,11,11,11,11,10,9,9,8,7,6,5,4,3,2,1 | |
dc.b 0,-1,-2,-3,-4,-5,-6,-7,-8,-9,-9,-10,-11,-11,-11,-11 | |
dc.b -11,-11,-11,-11,-11,-10,-9,-9,-8,-7,-6,-5,-4,-3,-2,-1 | |
dc.b 0,1,2,4,5,6,7,8,9,10,11,12,12,13,13,13 | |
dc.b 13,13,13,13,12,12,11,10,9,8,7,6,5,4,2,1 | |
dc.b 0,-1,-2,-4,-5,-6,-7,-8,-9,-10,-11,-12,-12,-13,-13,-13 | |
dc.b -13,-13,-13,-13,-12,-12,-11,-10,-9,-8,-7,-6,-5,-4,-2,-1 | |
dc.b 0,1,3,4,6,7,8,10,11,12,13,14,14,15,15,15 | |
dc.b 15,15,15,15,14,14,13,12,11,10,8,7,6,4,3,1 | |
dc.b 0,-1,-3,-4,-6,-7,-8,-10,-11,-12,-13,-14,-14,-15,-15,-15 | |
dc.b -15,-15,-15,-15,-14,-14,-13,-12,-11,-10,-8,-7,-6,-4,-3,-1 | |
dc.b 0,1,3,5,6,8,9,11,12,13,14,15,16,17,17,17 | |
dc.b 17,17,17,17,16,15,14,13,12,11,9,8,6,5,3,1 | |
dc.b 0,-1,-3,-5,-6,-8,-9,-11,-12,-13,-14,-15,-16,-17,-17,-17 | |
dc.b -17,-17,-17,-17,-16,-15,-14,-13,-12,-11,-9,-8,-6,-5,-3,-1 | |
dc.b 0,1,3,5,7,9,11,12,14,15,16,17,18,19,19,19 | |
dc.b 19,19,19,19,18,17,16,15,14,12,11,9,7,5,3,1 | |
dc.b 0,-1,-3,-5,-7,-9,-11,-12,-14,-15,-16,-17,-18,-19,-19,-19 | |
dc.b -19,-19,-19,-19,-18,-17,-16,-15,-14,-12,-11,-9,-7,-5,-3,-1 | |
dc.b 0,2,4,6,8,10,12,13,15,16,18,19,20,20,21,21 | |
dc.b 21,21,21,20,20,19,18,16,15,13,12,10,8,6,4,2 | |
dc.b 0,-2,-4,-6,-8,-10,-12,-13,-15,-16,-18,-19,-20,-20,-21,-21 | |
dc.b -21,-21,-21,-20,-20,-19,-18,-16,-15,-13,-12,-10,-8,-6,-4,-2 | |
dc.b 0,2,4,6,9,11,13,15,16,18,19,21,22,22,23,23 | |
dc.b 23,23,23,22,22,21,19,18,16,15,13,11,9,6,4,2 | |
dc.b 0,-2,-4,-6,-9,-11,-13,-15,-16,-18,-19,-21,-22,-22,-23,-23 | |
dc.b -23,-23,-23,-22,-22,-21,-19,-18,-16,-15,-13,-11,-9,-6,-4,-2 | |
dc.b 0,2,4,7,9,12,14,16,18,20,21,22,23,24,25,25 | |
dc.b 25,25,25,24,23,22,21,20,18,16,14,12,9,7,4,2 | |
dc.b 0,-2,-4,-7,-9,-12,-14,-16,-18,-20,-21,-22,-23,-24,-25,-25 | |
dc.b -25,-25,-25,-24,-23,-22,-21,-20,-18,-16,-14,-12,-9,-7,-4,-2 | |
dc.b 0,2,5,8,10,13,15,17,19,21,23,24,25,26,27,27 | |
dc.b 27,27,27,26,25,24,23,21,19,17,15,13,10,8,5,2 | |
dc.b 0,-2,-5,-8,-10,-13,-15,-17,-19,-21,-23,-24,-25,-26,-27,-27 | |
dc.b -27,-27,-27,-26,-25,-24,-23,-21,-19,-17,-15,-13,-10,-8,-5,-2 | |
dc.b 0,2,5,8,11,14,16,18,21,23,24,26,27,28,29,29 | |
dc.b 29,29,29,28,27,26,24,23,21,18,16,14,11,8,5,2 | |
dc.b 0,-2,-5,-8,-11,-14,-16,-18,-21,-23,-24,-26,-27,-28,-29,-29 | |
dc.b -29,-29,-29,-28,-27,-26,-24,-23,-21,-18,-16,-14,-11,-8,-5,-2 | |
mt_VibratoSawTable: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1 | |
dc.b 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3 | |
dc.b -3,-3,-3,-3,-3,-3,-3,-3,-2,-2,-2,-2,-2,-2,-2,-2 | |
dc.b -1,-1,-1,-1,-1,-1,-1,-1,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2 | |
dc.b 3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5 | |
dc.b -5,-5,-5,-5,-5,-5,-4,-4,-4,-4,-4,-3,-3,-3,-3,-3 | |
dc.b -2,-2,-2,-2,-2,-2,-1,-1,-1,-1,-1,0,0,0,0,0 | |
dc.b 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3 | |
dc.b 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7 | |
dc.b -7,-7,-7,-7,-6,-6,-6,-6,-5,-5,-5,-5,-4,-4,-4,-4 | |
dc.b -3,-3,-3,-3,-2,-2,-2,-2,-1,-1,-1,-1,0,0,0,0 | |
dc.b 0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4 | |
dc.b 5,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9 | |
dc.b -9,-9,-9,-9,-8,-8,-8,-7,-7,-7,-6,-6,-6,-5,-5,-5 | |
dc.b -4,-4,-4,-4,-3,-3,-3,-2,-2,-2,-1,-1,-1,0,0,0 | |
dc.b 0,0,0,1,1,1,2,2,3,3,3,4,4,4,5,5 | |
dc.b 6,6,6,7,7,7,8,8,9,9,9,10,10,10,11,11 | |
dc.b -11,-11,-11,-10,-10,-10,-9,-9,-8,-8,-8,-7,-7,-7,-6,-6 | |
dc.b -5,-5,-5,-4,-4,-4,-3,-3,-2,-2,-2,-1,-1,-1,0,0 | |
dc.b 0,0,0,1,1,2,2,3,3,3,4,4,5,5,6,6 | |
dc.b 7,7,7,8,8,9,9,10,10,10,11,11,12,12,13,13 | |
dc.b -13,-13,-13,-12,-12,-11,-11,-10,-10,-10,-9,-9,-8,-8,-7,-7 | |
dc.b -6,-6,-6,-5,-5,-4,-4,-3,-3,-3,-2,-2,-1,-1,0,0 | |
dc.b 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 | |
dc.b 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15 | |
dc.b -15,-15,-14,-14,-13,-13,-12,-12,-11,-11,-10,-10,-9,-9,-8,-8 | |
dc.b -7,-7,-6,-6,-5,-5,-4,-4,-3,-3,-2,-2,-1,-1,0,0 | |
dc.b 0,0,1,1,2,2,3,3,4,5,5,6,6,7,7,8 | |
dc.b 9,9,10,10,11,11,12,12,13,14,14,15,15,16,16,17 | |
dc.b -17,-17,-16,-16,-15,-15,-14,-13,-13,-12,-12,-11,-11,-10,-10,-9 | |
dc.b -8,-8,-7,-7,-6,-6,-5,-4,-4,-3,-3,-2,-2,-1,-1,0 | |
dc.b 0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9 | |
dc.b 10,10,11,11,12,13,13,14,15,15,16,16,17,18,18,19 | |
dc.b -19,-19,-18,-18,-17,-16,-16,-15,-14,-14,-13,-13,-12,-11,-11,-10 | |
dc.b -9,-9,-8,-8,-7,-6,-6,-5,-4,-4,-3,-3,-2,-1,-1,0 | |
dc.b 0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,10 | |
dc.b 11,11,12,13,13,14,15,15,16,17,17,18,19,19,20,21 | |
dc.b -21,-21,-20,-19,-19,-18,-17,-17,-16,-15,-15,-14,-13,-12,-12,-11 | |
dc.b -10,-10,-9,-8,-8,-7,-6,-6,-5,-4,-4,-3,-2,-1,-1,0 | |
dc.b 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11 | |
dc.b 12,12,13,14,15,15,16,17,18,18,19,20,21,21,22,23 | |
dc.b -23,-23,-22,-21,-20,-20,-19,-18,-17,-17,-16,-15,-14,-14,-13,-12 | |
dc.b -11,-11,-10,-9,-8,-8,-7,-6,-5,-5,-4,-3,-2,-2,-1,0 | |
dc.b 0,0,1,2,3,4,4,5,6,7,8,8,9,10,11,12 | |
dc.b 13,13,14,15,16,17,17,18,19,20,21,21,22,23,24,25 | |
dc.b -25,-25,-24,-23,-22,-21,-21,-20,-19,-18,-17,-16,-16,-15,-14,-13 | |
dc.b -12,-12,-11,-10,-9,-8,-8,-7,-6,-5,-4,-3,-3,-2,-1,0 | |
dc.b 0,0,1,2,3,4,5,6,7,7,8,9,10,11,12,13 | |
dc.b 14,14,15,16,17,18,19,20,21,21,22,23,24,25,26,27 | |
dc.b -27,-27,-26,-25,-24,-23,-22,-21,-20,-20,-19,-18,-17,-16,-15,-14 | |
dc.b -13,-13,-12,-11,-10,-9,-8,-7,-6,-6,-5,-4,-3,-2,-1,0 | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 | |
dc.b 15,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 | |
dc.b -29,-28,-28,-27,-26,-25,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15 | |
dc.b -14,-13,-13,-12,-11,-10,-9,-8,-7,-6,-5,-4,-3,-2,-1,0 | |
mt_VibratoRectTable: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
dc.b -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 | |
dc.b 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 | |
dc.b 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 | |
dc.b -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3 | |
dc.b -3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3,-3 | |
dc.b 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 | |
dc.b 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5 | |
dc.b -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5 | |
dc.b -5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5,-5 | |
dc.b 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 | |
dc.b 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 | |
dc.b -7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7 | |
dc.b -7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7,-7 | |
dc.b 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 | |
dc.b 9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9 | |
dc.b -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 | |
dc.b -9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9,-9 | |
dc.b 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11 | |
dc.b 11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11 | |
dc.b -11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11 | |
dc.b -11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11,-11 | |
dc.b 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 | |
dc.b 13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13 | |
dc.b -13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13 | |
dc.b -13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13,-13 | |
dc.b 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 | |
dc.b 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 | |
dc.b -15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15 | |
dc.b -15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15,-15 | |
dc.b 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 | |
dc.b 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17 | |
dc.b -17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17 | |
dc.b -17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17,-17 | |
dc.b 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19 | |
dc.b 19,19,19,19,19,19,19,19,19,19,19,19,19,19,19,19 | |
dc.b -19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19 | |
dc.b -19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19,-19 | |
dc.b 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21 | |
dc.b 21,21,21,21,21,21,21,21,21,21,21,21,21,21,21,21 | |
dc.b -21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21 | |
dc.b -21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21,-21 | |
dc.b 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 | |
dc.b 23,23,23,23,23,23,23,23,23,23,23,23,23,23,23,23 | |
dc.b -23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23 | |
dc.b -23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23,-23 | |
dc.b 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25 | |
dc.b 25,25,25,25,25,25,25,25,25,25,25,25,25,25,25,25 | |
dc.b -25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25 | |
dc.b -25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25,-25 | |
dc.b 27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27 | |
dc.b 27,27,27,27,27,27,27,27,27,27,27,27,27,27,27,27 | |
dc.b -27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27 | |
dc.b -27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27,-27 | |
dc.b 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 | |
dc.b 29,29,29,29,29,29,29,29,29,29,29,29,29,29,29,29 | |
dc.b -29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29 | |
dc.b -29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29,-29 | |
mt_PerFineTune: | |
dc.w mt_Tuning0-mt_PerFineTune,mt_Tuning1-mt_PerFineTune | |
dc.w mt_Tuning2-mt_PerFineTune,mt_Tuning3-mt_PerFineTune | |
dc.w mt_Tuning4-mt_PerFineTune,mt_Tuning5-mt_PerFineTune | |
dc.w mt_Tuning6-mt_PerFineTune,mt_Tuning7-mt_PerFineTune | |
dc.w mt_TuningM8-mt_PerFineTune,mt_TuningM7-mt_PerFineTune | |
dc.w mt_TuningM6-mt_PerFineTune,mt_TuningM5-mt_PerFineTune | |
dc.w mt_TuningM4-mt_PerFineTune,mt_TuningM3-mt_PerFineTune | |
dc.w mt_TuningM2-mt_PerFineTune,mt_TuningM1-mt_PerFineTune | |
mt_PeriodTable: | |
mt_Tuning0: ; Tuning 0, Normal c-1 - b3 | |
dc.w 856,808,762,720,678,640,604,570,538,508,480,453 | |
dc.w 428,404,381,360,339,320,302,285,269,254,240,226 | |
dc.w 214,202,190,180,170,160,151,143,135,127,120,113 | |
mt_Tuning1: | |
dc.w 850,802,757,715,674,637,601,567,535,505,477,450 | |
dc.w 425,401,379,357,337,318,300,284,268,253,239,225 | |
dc.w 213,201,189,179,169,159,150,142,134,126,119,113 | |
mt_Tuning2: | |
dc.w 844,796,752,709,670,632,597,563,532,502,474,447 | |
dc.w 422,398,376,355,335,316,298,282,266,251,237,224 | |
dc.w 211,199,188,177,167,158,149,141,133,125,118,112 | |
mt_Tuning3: | |
dc.w 838,791,746,704,665,628,592,559,528,498,470,444 | |
dc.w 419,395,373,352,332,314,296,280,264,249,235,222 | |
dc.w 209,198,187,176,166,157,148,140,132,125,118,111 | |
mt_Tuning4: | |
dc.w 832,785,741,699,660,623,588,555,524,495,467,441 | |
dc.w 416,392,370,350,330,312,294,278,262,247,233,220 | |
dc.w 208,196,185,175,165,156,147,139,131,124,117,110 | |
mt_Tuning5: | |
dc.w 826,779,736,694,655,619,584,551,520,491,463,437 | |
dc.w 413,390,368,347,328,309,292,276,260,245,232,219 | |
dc.w 206,195,184,174,164,155,146,138,130,123,116,109 | |
mt_Tuning6: | |
dc.w 820,774,730,689,651,614,580,547,516,487,460,434 | |
dc.w 410,387,365,345,325,307,290,274,258,244,230,217 | |
dc.w 205,193,183,172,163,154,145,137,129,122,115,109 | |
mt_Tuning7: | |
dc.w 814,768,725,684,646,610,575,543,513,484,457,431 | |
dc.w 407,384,363,342,323,305,288,272,256,242,228,216 | |
dc.w 204,192,181,171,161,152,144,136,128,121,114,108 | |
mt_TuningM8: | |
dc.w 907,856,808,762,720,678,640,604,570,538,508,480 | |
dc.w 453,428,404,381,360,339,320,302,285,269,254,240 | |
dc.w 226,214,202,190,180,170,160,151,143,135,127,120 | |
mt_TuningM7: | |
dc.w 900,850,802,757,715,675,636,601,567,535,505,477 | |
dc.w 450,425,401,379,357,337,318,300,284,268,253,238 | |
dc.w 225,212,200,189,179,169,159,150,142,134,126,119 | |
mt_TuningM6: | |
dc.w 894,844,796,752,709,670,632,597,563,532,502,474 | |
dc.w 447,422,398,376,355,335,316,298,282,266,251,237 | |
dc.w 223,211,199,188,177,167,158,149,141,133,125,118 | |
mt_TuningM5: | |
dc.w 887,838,791,746,704,665,628,592,559,528,498,470 | |
dc.w 444,419,395,373,352,332,314,296,280,264,249,235 | |
dc.w 222,209,198,187,176,166,157,148,140,132,125,118 | |
mt_TuningM4: | |
dc.w 881,832,785,741,699,660,623,588,555,524,494,467 | |
dc.w 441,416,392,370,350,330,312,294,278,262,247,233 | |
dc.w 220,208,196,185,175,165,156,147,139,131,123,117 | |
mt_TuningM3: | |
dc.w 875,826,779,736,694,655,619,584,551,520,491,463 | |
dc.w 437,413,390,368,347,328,309,292,276,260,245,232 | |
dc.w 219,206,195,184,174,164,155,146,138,130,123,116 | |
mt_TuningM2: | |
dc.w 868,820,774,730,689,651,614,580,547,516,487,460 | |
dc.w 434,410,387,365,345,325,307,290,274,258,244,230 | |
dc.w 217,205,193,183,172,163,154,145,137,129,122,115 | |
mt_TuningM1: | |
dc.w 862,814,768,725,684,646,610,575,543,513,484,457 | |
dc.w 431,407,384,363,342,323,305,288,272,256,242,228 | |
dc.w 216,203,192,181,171,161,152,144,136,128,121,114 | |
ifnd MINIMAL | |
MasterVolTab0: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0 | |
MasterVolTab1: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 1 | |
MasterVolTab2: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b 2 | |
MasterVolTab3: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2 | |
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 | |
dc.b 3 | |
MasterVolTab4: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 | |
dc.b 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 | |
dc.b 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2 | |
dc.b 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3 | |
dc.b 4 | |
MasterVolTab5: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1 | |
dc.b 1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2 | |
dc.b 2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3 | |
dc.b 3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4 | |
dc.b 5 | |
MasterVolTab6: | |
dc.b 0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 | |
dc.b 1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2 | |
dc.b 3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4 | |
dc.b 4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5 | |
dc.b 6 | |
MasterVolTab7: | |
dc.b 0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1 | |
dc.b 1,1,1,2,2,2,2,2,2,2,2,2,3,3,3,3 | |
dc.b 3,3,3,3,3,4,4,4,4,4,4,4,4,4,5,5 | |
dc.b 5,5,5,5,5,5,5,6,6,6,6,6,6,6,6,6 | |
dc.b 7 | |
MasterVolTab8: | |
dc.b 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1 | |
dc.b 2,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3 | |
dc.b 4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5 | |
dc.b 6,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7 | |
dc.b 8 | |
MasterVolTab9: | |
dc.b 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,2 | |
dc.b 2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4 | |
dc.b 4,4,4,4,5,5,5,5,5,5,5,6,6,6,6,6 | |
dc.b 6,6,7,7,7,7,7,7,7,8,8,8,8,8,8,8 | |
dc.b 9 | |
MasterVolTab10: | |
dc.b 0,0,0,0,0,0,0,1,1,1,1,1,1,2,2,2 | |
dc.b 2,2,2,2,3,3,3,3,3,3,4,4,4,4,4,4 | |
dc.b 5,5,5,5,5,5,5,6,6,6,6,6,6,7,7,7 | |
dc.b 7,7,7,7,8,8,8,8,8,8,9,9,9,9,9,9 | |
dc.b 10 | |
MasterVolTab11: | |
dc.b 0,0,0,0,0,0,1,1,1,1,1,1,2,2,2,2 | |
dc.b 2,2,3,3,3,3,3,3,4,4,4,4,4,4,5,5 | |
dc.b 5,5,5,6,6,6,6,6,6,7,7,7,7,7,7,8 | |
dc.b 8,8,8,8,8,9,9,9,9,9,9,10,10,10,10,10 | |
dc.b 11 | |
MasterVolTab12: | |
dc.b 0,0,0,0,0,0,1,1,1,1,1,2,2,2,2,2 | |
dc.b 3,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5 | |
dc.b 6,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8 | |
dc.b 9,9,9,9,9,9,10,10,10,10,10,11,11,11,11,11 | |
dc.b 12 | |
MasterVolTab13: | |
dc.b 0,0,0,0,0,1,1,1,1,1,2,2,2,2,2,3 | |
dc.b 3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6 | |
dc.b 6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9 | |
dc.b 9,9,10,10,10,10,10,11,11,11,11,11,12,12,12,12 | |
dc.b 13 | |
MasterVolTab14: | |
dc.b 0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3 | |
dc.b 3,3,3,4,4,4,4,5,5,5,5,5,6,6,6,6 | |
dc.b 7,7,7,7,7,8,8,8,8,8,9,9,9,9,10,10 | |
dc.b 10,10,10,11,11,11,11,12,12,12,12,12,13,13,13,13 | |
dc.b 14 | |
MasterVolTab15: | |
dc.b 0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3 | |
dc.b 3,3,4,4,4,4,5,5,5,5,6,6,6,6,7,7 | |
dc.b 7,7,7,8,8,8,8,9,9,9,9,10,10,10,10,11 | |
dc.b 11,11,11,11,12,12,12,12,13,13,13,13,14,14,14,14 | |
dc.b 15 | |
MasterVolTab16: | |
dc.b 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3 | |
dc.b 4,4,4,4,5,5,5,5,6,6,6,6,7,7,7,7 | |
dc.b 8,8,8,8,9,9,9,9,10,10,10,10,11,11,11,11 | |
dc.b 12,12,12,12,13,13,13,13,14,14,14,14,15,15,15,15 | |
dc.b 16 | |
MasterVolTab17: | |
dc.b 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3 | |
dc.b 4,4,4,5,5,5,5,6,6,6,6,7,7,7,7,8 | |
dc.b 8,8,9,9,9,9,10,10,10,10,11,11,11,11,12,12 | |
dc.b 12,13,13,13,13,14,14,14,14,15,15,15,15,16,16,16 | |
dc.b 17 | |
MasterVolTab18: | |
dc.b 0,0,0,0,1,1,1,1,2,2,2,3,3,3,3,4 | |
dc.b 4,4,5,5,5,5,6,6,6,7,7,7,7,8,8,8 | |
dc.b 9,9,9,9,10,10,10,10,11,11,11,12,12,12,12,13 | |
dc.b 13,13,14,14,14,14,15,15,15,16,16,16,16,17,17,17 | |
dc.b 18 | |
MasterVolTab19: | |
dc.b 0,0,0,0,1,1,1,2,2,2,2,3,3,3,4,4 | |
dc.b 4,5,5,5,5,6,6,6,7,7,7,8,8,8,8,9 | |
dc.b 9,9,10,10,10,10,11,11,11,12,12,12,13,13,13,13 | |
dc.b 14,14,14,15,15,15,16,16,16,16,17,17,17,18,18,18 | |
dc.b 19 | |
MasterVolTab20: | |
dc.b 0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4 | |
dc.b 5,5,5,5,6,6,6,7,7,7,8,8,8,9,9,9 | |
dc.b 10,10,10,10,11,11,11,12,12,12,13,13,13,14,14,14 | |
dc.b 15,15,15,15,16,16,16,17,17,17,18,18,18,19,19,19 | |
dc.b 20 | |
MasterVolTab21: | |
dc.b 0,0,0,0,1,1,1,2,2,2,3,3,3,4,4,4 | |
dc.b 5,5,5,6,6,6,7,7,7,8,8,8,9,9,9,10 | |
dc.b 10,10,11,11,11,12,12,12,13,13,13,14,14,14,15,15 | |
dc.b 15,16,16,16,17,17,17,18,18,18,19,19,19,20,20,20 | |
dc.b 21 | |
MasterVolTab22: | |
dc.b 0,0,0,1,1,1,2,2,2,3,3,3,4,4,4,5 | |
dc.b 5,5,6,6,6,7,7,7,8,8,8,9,9,9,10,10 | |
dc.b 11,11,11,12,12,12,13,13,13,14,14,14,15,15,15,16 | |
dc.b 16,16,17,17,17,18,18,18,19,19,19,20,20,20,21,21 | |
dc.b 22 | |
MasterVolTab23: | |
dc.b 0,0,0,1,1,1,2,2,2,3,3,3,4,4,5,5 | |
dc.b 5,6,6,6,7,7,7,8,8,8,9,9,10,10,10,11 | |
dc.b 11,11,12,12,12,13,13,14,14,14,15,15,15,16,16,16 | |
dc.b 17,17,17,18,18,19,19,19,20,20,20,21,21,21,22,22 | |
dc.b 23 | |
MasterVolTab24: | |
dc.b 0,0,0,1,1,1,2,2,3,3,3,4,4,4,5,5 | |
dc.b 6,6,6,7,7,7,8,8,9,9,9,10,10,10,11,11 | |
dc.b 12,12,12,13,13,13,14,14,15,15,15,16,16,16,17,17 | |
dc.b 18,18,18,19,19,19,20,20,21,21,21,22,22,22,23,23 | |
dc.b 24 | |
MasterVolTab25: | |
dc.b 0,0,0,1,1,1,2,2,3,3,3,4,4,5,5,5 | |
dc.b 6,6,7,7,7,8,8,8,9,9,10,10,10,11,11,12 | |
dc.b 12,12,13,13,14,14,14,15,15,16,16,16,17,17,17,18 | |
dc.b 18,19,19,19,20,20,21,21,21,22,22,23,23,23,24,24 | |
dc.b 25 | |
MasterVolTab26: | |
dc.b 0,0,0,1,1,2,2,2,3,3,4,4,4,5,5,6 | |
dc.b 6,6,7,7,8,8,8,9,9,10,10,10,11,11,12,12 | |
dc.b 13,13,13,14,14,15,15,15,16,16,17,17,17,18,18,19 | |
dc.b 19,19,20,20,21,21,21,22,22,23,23,23,24,24,25,25 | |
dc.b 26 | |
MasterVolTab27: | |
dc.b 0,0,0,1,1,2,2,2,3,3,4,4,5,5,5,6 | |
dc.b 6,7,7,8,8,8,9,9,10,10,10,11,11,12,12,13 | |
dc.b 13,13,14,14,15,15,16,16,16,17,17,18,18,18,19,19 | |
dc.b 20,20,21,21,21,22,22,23,23,24,24,24,25,25,26,26 | |
dc.b 27 | |
MasterVolTab28: | |
dc.b 0,0,0,1,1,2,2,3,3,3,4,4,5,5,6,6 | |
dc.b 7,7,7,8,8,9,9,10,10,10,11,11,12,12,13,13 | |
dc.b 14,14,14,15,15,16,16,17,17,17,18,18,19,19,20,20 | |
dc.b 21,21,21,22,22,23,23,24,24,24,25,25,26,26,27,27 | |
dc.b 28 | |
MasterVolTab29: | |
dc.b 0,0,0,1,1,2,2,3,3,4,4,4,5,5,6,6 | |
dc.b 7,7,8,8,9,9,9,10,10,11,11,12,12,13,13,14 | |
dc.b 14,14,15,15,16,16,17,17,18,18,19,19,19,20,20,21 | |
dc.b 21,22,22,23,23,24,24,24,25,25,26,26,27,27,28,28 | |
dc.b 29 | |
MasterVolTab30: | |
dc.b 0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7 | |
dc.b 7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14 | |
dc.b 15,15,15,16,16,17,17,18,18,19,19,20,20,21,21,22 | |
dc.b 22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29 | |
dc.b 30 | |
MasterVolTab31: | |
dc.b 0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7 | |
dc.b 7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15 | |
dc.b 15,15,16,16,17,17,18,18,19,19,20,20,21,21,22,22 | |
dc.b 23,23,24,24,25,25,26,26,27,27,28,28,29,29,30,30 | |
dc.b 31 | |
MasterVolTab32: | |
dc.b 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 | |
dc.b 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15 | |
dc.b 16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23 | |
dc.b 24,24,25,25,26,26,27,27,28,28,29,29,30,30,31,31 | |
dc.b 32 | |
MasterVolTab33: | |
dc.b 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 | |
dc.b 8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15 | |
dc.b 16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24 | |
dc.b 24,25,25,26,26,27,27,28,28,29,29,30,30,31,31,32 | |
dc.b 33 | |
MasterVolTab34: | |
dc.b 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 | |
dc.b 8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16 | |
dc.b 17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24 | |
dc.b 25,26,26,27,27,28,28,29,29,30,30,31,31,32,32,33 | |
dc.b 34 | |
MasterVolTab35: | |
dc.b 0,0,1,1,2,2,3,3,4,4,5,6,6,7,7,8 | |
dc.b 8,9,9,10,10,11,12,12,13,13,14,14,15,15,16,16 | |
dc.b 17,18,18,19,19,20,20,21,21,22,22,23,24,24,25,25 | |
dc.b 26,26,27,27,28,28,29,30,30,31,31,32,32,33,33,34 | |
dc.b 35 | |
MasterVolTab36: | |
dc.b 0,0,1,1,2,2,3,3,4,5,5,6,6,7,7,8 | |
dc.b 9,9,10,10,11,11,12,12,13,14,14,15,15,16,16,17 | |
dc.b 18,18,19,19,20,20,21,21,22,23,23,24,24,25,25,26 | |
dc.b 27,27,28,28,29,29,30,30,31,32,32,33,33,34,34,35 | |
dc.b 36 | |
MasterVolTab37: | |
dc.b 0,0,1,1,2,2,3,4,4,5,5,6,6,7,8,8 | |
dc.b 9,9,10,10,11,12,12,13,13,14,15,15,16,16,17,17 | |
dc.b 18,19,19,20,20,21,21,22,23,23,24,24,25,26,26,27 | |
dc.b 27,28,28,29,30,30,31,31,32,32,33,34,34,35,35,36 | |
dc.b 37 | |
MasterVolTab38: | |
dc.b 0,0,1,1,2,2,3,4,4,5,5,6,7,7,8,8 | |
dc.b 9,10,10,11,11,12,13,13,14,14,15,16,16,17,17,18 | |
dc.b 19,19,20,20,21,21,22,23,23,24,24,25,26,26,27,27 | |
dc.b 28,29,29,30,30,31,32,32,33,33,34,35,35,36,36,37 | |
dc.b 38 | |
MasterVolTab39: | |
dc.b 0,0,1,1,2,3,3,4,4,5,6,6,7,7,8,9 | |
dc.b 9,10,10,11,12,12,13,14,14,15,15,16,17,17,18,18 | |
dc.b 19,20,20,21,21,22,23,23,24,24,25,26,26,27,28,28 | |
dc.b 29,29,30,31,31,32,32,33,34,34,35,35,36,37,37,38 | |
dc.b 39 | |
MasterVolTab40: | |
dc.b 0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9 | |
dc.b 10,10,11,11,12,13,13,14,15,15,16,16,17,18,18,19 | |
dc.b 20,20,21,21,22,23,23,24,25,25,26,26,27,28,28,29 | |
dc.b 30,30,31,31,32,33,33,34,35,35,36,36,37,38,38,39 | |
dc.b 40 | |
MasterVolTab41: | |
dc.b 0,0,1,1,2,3,3,4,5,5,6,7,7,8,8,9 | |
dc.b 10,10,11,12,12,13,14,14,15,16,16,17,17,18,19,19 | |
dc.b 20,21,21,22,23,23,24,24,25,26,26,27,28,28,29,30 | |
dc.b 30,31,32,32,33,33,34,35,35,36,37,37,38,39,39,40 | |
dc.b 41 | |
MasterVolTab42: | |
dc.b 0,0,1,1,2,3,3,4,5,5,6,7,7,8,9,9 | |
dc.b 10,11,11,12,13,13,14,15,15,16,17,17,18,19,19,20 | |
dc.b 21,21,22,22,23,24,24,25,26,26,27,28,28,29,30,30 | |
dc.b 31,32,32,33,34,34,35,36,36,37,38,38,39,40,40,41 | |
dc.b 42 | |
MasterVolTab43: | |
dc.b 0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,10 | |
dc.b 10,11,12,12,13,14,14,15,16,16,17,18,18,19,20,20 | |
dc.b 21,22,22,23,24,24,25,26,26,27,28,28,29,30,30,31 | |
dc.b 32,32,33,34,34,35,36,36,37,38,38,39,40,40,41,42 | |
dc.b 43 | |
MasterVolTab44: | |
dc.b 0,0,1,2,2,3,4,4,5,6,6,7,8,8,9,10 | |
dc.b 11,11,12,13,13,14,15,15,16,17,17,18,19,19,20,21 | |
dc.b 22,22,23,24,24,25,26,26,27,28,28,29,30,30,31,32 | |
dc.b 33,33,34,35,35,36,37,37,38,39,39,40,41,41,42,43 | |
dc.b 44 | |
MasterVolTab45: | |
dc.b 0,0,1,2,2,3,4,4,5,6,7,7,8,9,9,10 | |
dc.b 11,11,12,13,14,14,15,16,16,17,18,18,19,20,21,21 | |
dc.b 22,23,23,24,25,26,26,27,28,28,29,30,30,31,32,33 | |
dc.b 33,34,35,35,36,37,37,38,39,40,40,41,42,42,43,44 | |
dc.b 45 | |
MasterVolTab46: | |
dc.b 0,0,1,2,2,3,4,5,5,6,7,7,8,9,10,10 | |
dc.b 11,12,12,13,14,15,15,16,17,17,18,19,20,20,21,22 | |
dc.b 23,23,24,25,25,26,27,28,28,29,30,30,31,32,33,33 | |
dc.b 34,35,35,36,37,38,38,39,40,40,41,42,43,43,44,45 | |
dc.b 46 | |
MasterVolTab47: | |
dc.b 0,0,1,2,2,3,4,5,5,6,7,8,8,9,10,11 | |
dc.b 11,12,13,13,14,15,16,16,17,18,19,19,20,21,22,22 | |
dc.b 23,24,24,25,26,27,27,28,29,30,30,31,32,33,33,34 | |
dc.b 35,35,36,37,38,38,39,40,41,41,42,43,44,44,45,46 | |
dc.b 47 | |
MasterVolTab48: | |
dc.b 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11 | |
dc.b 12,12,13,14,15,15,16,17,18,18,19,20,21,21,22,23 | |
dc.b 24,24,25,26,27,27,28,29,30,30,31,32,33,33,34,35 | |
dc.b 36,36,37,38,39,39,40,41,42,42,43,44,45,45,46,47 | |
dc.b 48 | |
MasterVolTab49: | |
dc.b 0,0,1,2,3,3,4,5,6,6,7,8,9,9,10,11 | |
dc.b 12,13,13,14,15,16,16,17,18,19,19,20,21,22,22,23 | |
dc.b 24,25,26,26,27,28,29,29,30,31,32,32,33,34,35,35 | |
dc.b 36,37,38,39,39,40,41,42,42,43,44,45,45,46,47,48 | |
dc.b 49 | |
MasterVolTab50: | |
dc.b 0,0,1,2,3,3,4,5,6,7,7,8,9,10,10,11 | |
dc.b 12,13,14,14,15,16,17,17,18,19,20,21,21,22,23,24 | |
dc.b 25,25,26,27,28,28,29,30,31,32,32,33,34,35,35,36 | |
dc.b 37,38,39,39,40,41,42,42,43,44,45,46,46,47,48,49 | |
dc.b 50 | |
MasterVolTab51: | |
dc.b 0,0,1,2,3,3,4,5,6,7,7,8,9,10,11,11 | |
dc.b 12,13,14,15,15,16,17,18,19,19,20,21,22,23,23,24 | |
dc.b 25,26,27,27,28,29,30,31,31,32,33,34,35,35,36,37 | |
dc.b 38,39,39,40,41,42,43,43,44,45,46,47,47,48,49,50 | |
dc.b 51 | |
MasterVolTab52: | |
dc.b 0,0,1,2,3,4,4,5,6,7,8,8,9,10,11,12 | |
dc.b 13,13,14,15,16,17,17,18,19,20,21,21,22,23,24,25 | |
dc.b 26,26,27,28,29,30,30,31,32,33,34,34,35,36,37,38 | |
dc.b 39,39,40,41,42,43,43,44,45,46,47,47,48,49,50,51 | |
dc.b 52 | |
MasterVolTab53: | |
dc.b 0,0,1,2,3,4,4,5,6,7,8,9,9,10,11,12 | |
dc.b 13,14,14,15,16,17,18,19,19,20,21,22,23,24,24,25 | |
dc.b 26,27,28,28,29,30,31,32,33,33,34,35,36,37,38,38 | |
dc.b 39,40,41,42,43,43,44,45,46,47,48,48,49,50,51,52 | |
dc.b 53 | |
MasterVolTab54: | |
dc.b 0,0,1,2,3,4,5,5,6,7,8,9,10,10,11,12 | |
dc.b 13,14,15,16,16,17,18,19,20,21,21,22,23,24,25,26 | |
dc.b 27,27,28,29,30,31,32,32,33,34,35,36,37,37,38,39 | |
dc.b 40,41,42,43,43,44,45,46,47,48,48,49,50,51,52,53 | |
dc.b 54 | |
MasterVolTab55: | |
dc.b 0,0,1,2,3,4,5,6,6,7,8,9,10,11,12,12 | |
dc.b 13,14,15,16,17,18,18,19,20,21,22,23,24,24,25,26 | |
dc.b 27,28,29,30,30,31,32,33,34,35,36,36,37,38,39,40 | |
dc.b 41,42,42,43,44,45,46,47,48,48,49,50,51,52,53,54 | |
dc.b 55 | |
MasterVolTab56: | |
dc.b 0,0,1,2,3,4,5,6,7,7,8,9,10,11,12,13 | |
dc.b 14,14,15,16,17,18,19,20,21,21,22,23,24,25,26,27 | |
dc.b 28,28,29,30,31,32,33,34,35,35,36,37,38,39,40,41 | |
dc.b 42,42,43,44,45,46,47,48,49,49,50,51,52,53,54,55 | |
dc.b 56 | |
MasterVolTab57: | |
dc.b 0,0,1,2,3,4,5,6,7,8,8,9,10,11,12,13 | |
dc.b 14,15,16,16,17,18,19,20,21,22,23,24,24,25,26,27 | |
dc.b 28,29,30,31,32,32,33,34,35,36,37,38,39,40,40,41 | |
dc.b 42,43,44,45,46,47,48,48,49,50,51,52,53,54,55,56 | |
dc.b 57 | |
MasterVolTab58: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,9,10,11,12,13 | |
dc.b 14,15,16,17,18,19,19,20,21,22,23,24,25,26,27,28 | |
dc.b 29,29,30,31,32,33,34,35,36,37,38,38,39,40,41,42 | |
dc.b 43,44,45,46,47,48,48,49,50,51,52,53,54,55,56,57 | |
dc.b 58 | |
MasterVolTab59: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,11,12,13 | |
dc.b 14,15,16,17,18,19,20,21,22,23,23,24,25,26,27,28 | |
dc.b 29,30,31,32,33,34,35,35,36,37,38,39,40,41,42,43 | |
dc.b 44,45,46,47,47,48,49,50,51,52,53,54,55,56,57,58 | |
dc.b 59 | |
MasterVolTab60: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 | |
dc.b 15,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29 | |
dc.b 30,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44 | |
dc.b 45,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59 | |
dc.b 60 | |
MasterVolTab61: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 | |
dc.b 15,16,17,18,19,20,20,21,22,23,24,25,26,27,28,29 | |
dc.b 30,31,32,33,34,35,36,37,38,39,40,40,41,42,43,44 | |
dc.b 45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60 | |
dc.b 61 | |
MasterVolTab62: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 | |
dc.b 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 | |
dc.b 31,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45 | |
dc.b 46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61 | |
dc.b 62 | |
MasterVolTab63: | |
dc.b 0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14 | |
dc.b 15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30 | |
dc.b 31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46 | |
dc.b 47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62 | |
dc.b 63 | |
MasterVolTab64: | |
dc.b 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 | |
dc.b 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 | |
dc.b 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47 | |
dc.b 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63 | |
dc.b 64 | |
even | |
endc ; !MINIMAL | |
rsreset | |
mt_chan1 rs.b n_sizeof | |
mt_chan2 rs.b n_sizeof | |
mt_chan3 rs.b n_sizeof | |
mt_chan4 rs.b n_sizeof | |
mt_SampleStarts rs.l 31 | |
mt_mod rs.l 1 | |
mt_oldLev6 rs.l 1 | |
mt_timerval rs.l 1 | |
mt_oldtimers rs.b 4 | |
mt_Lev6Int rs.l 1 | |
mt_Lev6Ena rs.w 1 | |
mt_PatternPos rs.w 1 | |
mt_PBreakPos rs.w 1 | |
mt_PosJumpFlag rs.b 1 | |
mt_PBreakFlag rs.b 1 | |
mt_Speed rs.b 1 | |
mt_Counter rs.b 1 | |
mt_SongPos rs.b 1 | |
mt_PattDelTime rs.b 1 | |
mt_PattDelTime2 rs.b 1 | |
ifnd MINIMAL | |
mt_SilCntValid rs.b 1 | |
mt_MasterVolTab rs.l 1 | |
endc | |
_MT_INT_SIZEOF: equ __RS | |
mt_Enable rs.b 1 ; exported as _mt_Enable | |
mt_E8Trigger rs.b 1 ; exported as _mt_E8Trigger | |
mt_Delay: rs.w 1 | |
mt_MasterVol: rs.w 1 | |
mt_MasterFade: rs.w 1 | |
ifnd MINIMAL | |
mt_MusicChannels rs.b 1 ; exported as _mt_MusicChannels | |
mt_SongEnd rs.b 1 ; exported as _mt_SongEnd | |
endc ; !MINIMAL | |
_MT_SIZEOF: equ __RS | |
mt_data: ds.b _MT_INT_SIZEOF | |
_mt_Enable ds.b 1 | |
_mt_E8Trigger ds.b 1 | |
_mt_Delay: ds.w 1 | |
_mt_MasterVol: ds.w 1 | |
_mt_MasterFade: ds.w 1 | |
ifnd MINIMAL | |
_mt_MusicChannels: ds.b 1 | |
_mt_SongEnd: ds.b 1 | |
endc ; !MINIMAL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment