;Fred editor replay commented
;----------------------------
;module 'fred.the journey'
;
;Replay and editor coded by Frederic Hahn & Julien Clermonte in 1989
;the editor can be found on Exotica (http://exotica.amigascne.org)
;
;disassembled and commented by [mailto:lclevy@club-internet.fr] in nov 1999
;please tell me if you have any corrections/remarks, or if you write any code based on this commented file



000000	JMP	(START+$12,PC)		;init (d0=subsong, first=0)

000004	JMP	(START+$AA,PC)		;play music

000008	JMP	(START+$98,PC)		;stop music

00000C	JMP	(START+$8A,PC)		;music stop with vol fading

000010	ff				;audio DMA (bits 3-0. bit set=voice on, bit clr=voice off)
000011	00

;init
000012	MOVE.B	(START+$0895,PC),D1	;max subsong (6 means 7 subsongs)
	CMP.B	D1,D0			;compare with requested song
	BHI.W	START+$98		;error -> stop music
	LEA	(START+$0894,PC),A3
	MOVE.B	D0,(A3)			;store current played song
	LEA	(START+$0897,PC),A2	;song tempos table
	LEA	(START+$0896,PC),A4
	ADDA.L	D0,A2
	MOVE.B	(A2),(A4)		;song tempo
	LSL.L	#3,D0			;*8
	MOVEQ	#3,D7			;voice loop 3->0
	MOVEQ	#0,D6
	LEA	(START+$090E,PC),A0	;voice data (128 bytes per voice)

000038	MOVE.W	#1,($20,A0)		;song initial tempo
	CLR.W	($3A,A0)		;pos in voice
	LEA	(START+$0B0E,PC),A1	;subsong voices table (4 word offsets in pattern ptr table)
	MOVEA.L	A1,A2
	LEA	(A1,D0.W),A1		;points on first voice ptr on current table
	ADDA.W	(A1,D6.W),A2		;points on d7 th (d6=word index) voice of current song
	MOVE.L	A2,(0,A0)		;voicedata+0 = voice offset
	LEA	(START+$00,PC),A3
	ADDA.L	(START+$08A6,PC),A3	;pattern ptr table
	ADDA.W	(A2),A3			;first pattern position
	MOVE.L	A3,(8,A0)		; in voicedata+8
	ST	($1E,A0)		;voicedata[d7]+$1e = 1.b
	ADDA.L	#$80,A0			;next voice
	ADDI.B	#2,D6			;next voice offset
	DBRA	D7,START+$38		;voice loop

	LEA	(START+$07FE,PC),A3	;-1 = stop song
	CLR.B	(A3)
	LEA	(START+$0800,PC),A3 	;master volume ?
	MOVE.W	#$1000,(A3)		;4096
	LEA	(START+$07FF,PC),A3 	;vol fading flag
	SF	(A3)			;0=no vol fading
000088	RTS

00008A	LEA	(START+$0802,PC),A3	;volume fading speed
	MOVE.B	D0,(A3)
	LEA	(START+$07FF,PC),A3
	ST	(A3)			;1=vol fading started
	RTS

;stop music
000098	LEA	(START+$07FE,PC),A3
	MOVE.B	#$FF,(A3)		;music stopped
	MOVE.W	#15,($DFF096).L		;audio DMA off
	RTS

;play music
0000AA	LEA	(START+$07FE,PC),A3
	TST.B	(A3)			;music stopped ?
	BEQ.W	START+$B6		;no
	RTS				;yes

0000B6	MOVEQ	#3,D5			;voice	3->0
	MOVEQ	#0,D4
0000BA	MOVEQ	#0,D7
	MOVE.W	D5,D0
	LSL.W	#4,D0			;*16 = voice offset to related audio hard register 
	LEA	($DFF000).L,A6		;hardware register base
	ADDA.W	D0,A6			;0=$00 will be $a0, 1=$10 will be $b0, ...
	MOVE.W	D5,D0 			;voice index
	LSL.W	#7,D0			;voice data index (voice data are 128 bytes long)
	LEA	(START+$090E,PC),A0
	ADDA.W	D0,A0			;current voice data 
	MOVEA.L	(8,A0),A1		;current voice position = ptr to pattern 
	MOVEA.L	(12,A0),A5		;current instr ptr in instr info table 
	TST.B	($1E,A0)		;DMA
	BNE.W	START+$012A
	ST	($1E,A0)
	MOVEQ	#0,D0
	MOVE.W	(4,A5),D0		;is current instr synthetic ?
	BEQ.W	START+$011C		;0 = no loop
	BMI.W	START+$012A		;yes = -1


	LEA	(START+$00,PC),A2
	ADDA.L	(0,A5),A2		;add the instr offset
	ADDA.L	D0,A2			;instr repeat adress
	MOVE.W	(6,A5),D1		;sample lenght
	SUB.W	D0,D1			:sample repeat len ?
	TST.B	($27,A5)
	BEQ.W	START+$0110		;0 = sampled instr

	LEA	($40,A0),A2		;pulse or blend instr

000110	MOVE.L	A2,($A0,A6)		;sample ptr audio register
	MOVE.W	D1,($A4,A6)		;sample len audio register
	BRA.W	START+$012A

00011C	LEA	(START+$08AA,PC),A2
	MOVE.L	A2,($A0,A6)		;sample ptr audio register
	MOVE.W	#$32,($A4,A6)		;sample len (decimal 50)
	
00012A	SUBQ.W	#1,($20,A0)		;same note/cmd counter = used for tempo
	TST.W	($20,A0)		
	BEQ.W	START+$0156		;next note/cmd
	CMPI.W	#1,($20,A0)
	BNE.W	START+$03E4		;same note/cmd
	CMPI.B	#$A0,(A1)
	BPL.W	START+$03E4		;same note/cmd
	MOVEQ	#0,D1
	BSET	D5,D1			:voice dma OFF
	MOVE.W	D1,($DFF096).L
	BRA.W	START+$03E4


;next note/command
000156	MOVEA.L	(12,A0),A5		;ptr on current instr info
	MOVEQ	#0,D0
	MOVE.B	(A1)+,D0		;next command/note
	BPL.W	START+$02C0
	CMPI.B	#$83,D0			;change intrument command
	BEQ.W	START+$01A0
	CMPI.B	#$82,D0			;change song tempo
	BEQ.W	START+$01BC
	CMPI.B	#$81,D0			;portamento
	BEQ.W	START+$01CC		
	CMPI.B	#$84,D0			;voice dma off
	BEQ.W	START+$021C
	CMPI.B	#$80,D0			;jump to position command
	BEQ.W	START+$023C
	NEG.B	D0			;empty steps
	MOVEQ	#0,D1
	MOVE.B	(START+$0896,PC),D1	;song tempo
	MULU.W	D1,D0			;ticks with same note/cmd
	MOVE.W	D0,($20,A0)
	MOVE.L	A1,(8,A0)		;current pos ptr
	BRA.W	START+$03E4

;$83 xx : change to instrument xx
0001A0	MOVE.B	(A1)+,D0		;instrument number
	LEA	(START+$00,PC),A5
	ADDA.L	(START+$08A2,PC),A5	;instrument info table
	LSL.W	#6,D0			;64 bytes per instrument in this table
	ADDA.L	D0,A5
	MOVE.L	A5,(12,A0)		;ptr on current instr info
	MOVEQ	#-1,D7
	MOVE.L	A1,(8,A0)		;new current position
	BRA.W	START+$0156		;next command/note

;$82 xx		: new song tempo
0001BC	MOVE.B	(A1)+,D0		;new subsong tempo
	LEA	(START+$0896,PC),A4
	MOVE.B	D0,(A4)
	MOVE.L	A1,(8,A0)		;new current position
	BRA.W	START+$0156		;next command/note

;$81 xx yy zz	: portamento
0001CC	MOVE.B	(A1)+,D0		;parameter
	MOVE.L	D0,D2
	MOVEQ	#0,D1
	MOVE.B	(START+$0896,PC),D1	;current subsong value...
	MULU.W	D2,D1
	MOVE.W	D1,($2A,A0)		;xx * tempo = port speed ?
	LEA	(START+$0804,PC),A2	;period table
	MOVE.W	(8,A5),D1		;instr info...
	MOVEQ	#10,D2
	MOVE.B	(A1)+,D0		;port target note ?
	MOVE.B	D0,($23,A0)
	LSL.W	#1,D0			;size of a period = 1 word = 2 bytes
	MOVE.W	(A2,D0.W),D0		;period associated to note
	MULU.W	D1,D0
	LSR.L	D2,D0			
	MOVE.W	D0,($1A,A0)		;((instr info+8)*period)/1024
	MOVE.W	#0,($24,A0)
	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVE.B	(A1)+,D0		;zz
	MOVE.B	(START+$0896,PC),D1
	MULU.W	D1,D0
	MOVE.W	D0,($16,A0)		;zz * tempo = port delay
	ST	($15,A0)		;set to 1 : port ON
	MOVE.L	A1,(8,A0)		;new current position
	BRA.W	START+$0156		;next note/cmd

;$84 (no following argument)
00021C	MOVEQ	#0,D1
	BSET	D5,D1			;voice = bit set
	MOVE.W	D1,($DFF096).L		;voice DMA OFF
	MOVEQ	#0,D1
	MOVE.B	(START+$0896,PC),D1	;current subsong value...
	MOVE.W	D1,($20,A0)
	ST	($1E,A0)
	MOVE.L	A1,(8,A0)		;new current position
	BRA.W	lbC0003DE		;next voice

;$80 (no following argument) : end of pattern, next voice pos
00023C	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVEQ	#0,D3
	MOVE.W	($3A,A0),D0		;voice pos already played = current pos offset 
	ADDQ.W	#2,D0			;next pos
00024A	MOVEA.L	(0,A0),A3		;voice pos ptr
	ADDA.L	D0,A3			;current pos adr
	MOVE.W	(A3),D2			;ptr in seq/note table
	CMPI.W	#$FFFF,D2		;stop song ?
	BEQ.W	START+$028E
	CMPI.W	#0,D2
	BMI.W	START+$027E		;<0 change pos in voice = jump to ?
	MOVE.W	D0,($3A,A0)		;new voice pos offset  
	LEA	(START+$00,PC),A3
	ADDA.L	(START+$08A6,PC),A3	;offset of seq/note table
	ADDA.L	D2,A3			;current adr in seq/note table 
	MOVE.L	A3,(8,A0)		;seq/note ptr
	MOVE.W	#1,($20,A0)		;initial tempo
	BRA.W	START+$BA		;play same voice

;new pos
00027E	BCLR	#15,D2			;clr sign bit
	MOVE.W	D2,D0
	ANDI.L	#$FFFF,D0		;16 bit mask
	BRA.W	START+$024A

;all voices  off
00028E	LEA	(START+$07FE,PC),A2
	MOVE.B	#????$FF,(A2)
	MOVE.W	#0,($DFF0A8).L
	MOVE.W	#0,($DFF0B8).L
	MOVE.W	#0,($DFF0C8).L
	MOVE.W	#0,($DFF0D8).L
	MOVE.W	#15,($DFF096).L
	RTS

;d0 >0 : new note/command
0002C0	MOVE.L	A1,(8,A0)		;new note ptr
	MOVE.B	D0,($19,A0)		;note/command
	SF	($2F,A0)
	MOVE.B	($26,A5),($30,A0)	;arp speed
	MOVE.B	(10,A5),($10,A0)	;vibrato delay
	MOVE.B	(12,A5),($12,A0)	;vib speed
	MOVE.B	(13,A5),($13,A0)	;vib ampl
	ST	($22,A0)		;start vibrato
	MOVE.B	#0,($14,A0)		;vib initial value
	CMPI.B	#1,($27,A5)
	BEQ.W	START+$0306		;pulse instr
	CMPI.B	#2,($27,A5)
	BEQ.W	START+$031E		;blend instr
	BRA.W	START+$0336		;sampled instr

	;pulse instr
000306	TST.B	D7			;instr changed in this voice ?
	BNE.W	START+$0316		;yes if d7==-1
	BTST	#1,($2E,A5)		;pulse synchro == $11 (%1011) ?
	BEQ.W	START+$0336
000316	BSR.W	START+$0782		;copy with "Rate -" and "Rate +"
	BRA.W	START+$0336

	;blend instr
00031E	TST.B	D7			;instr changed
	BNE.W	START+$032E		;yes = copy it
	BTST	#3,($2E,A5)
	BEQ.W	START+$0336
00032E	BSR.W	START+$07D0
	BRA.W	START+$0336


000336	MOVEQ	#0,D1
	MOVE.B	(START+$0896,PC),D1
	MOVE.W	D1,($20,A0)		;song tempo
	LEA	(START+$00,PC),A2
	ADDA.L	(0,A5),A2		;sample adress
	TST.B	($27,A5)
	BEQ.W	START+$0354		;sampled instr

	LEA	($40,A0),A2		;voicedata+$40

000354	MOVE.L	A2,($A0,A6)		;sample ptr audio reg
	MOVE.W	(6,A5),($A4,A6)		;sample len audio reg
	MOVEQ	#0,D1
	MOVE.B	D1,($2C,A0)		;voicedata+$2c.b = volume
	MOVE.W	D1,($A8,A6)		;sample volume audio reg
	MOVE.B	#0,($2D,A0)		;env state
	MOVE.B	($13,A5),($2E,A0)	;sustain speed
	MOVE.W	#0,D0
	LEA	(START+$0804,PC),A2	;period table
	MOVE.W	(8,A5),D1
	MOVEQ	#10,D2
	MOVE.B	($19,A0),D0		;note number
	LSL.W	#1,D0			;*2
	MOVE.W	(A2,D0.W),D0		;note period in table
	MULU.W	D1,D0
	LSR.L	D2,D0			;(note period*(instr_info+8))/1024
	MOVE.W	D0,($A6,A6)		;sample period audio reg
	MOVE.W	D0,($1C,A0)		;current sample period

	TST.B	($15,A0)		:portamento running ?
	BEQ.W	START+$03C0

	TST.W	($24,A0)
	BNE.W	START+$03C0

:portamento start
	MOVE.W	($1A,A0),D0
	SUB.W	($1C,A0),D0		;current per
	MOVE.W	D0,($26,A0)
	MOVE.W	#1,($28,A0)
	MOVE.W	($1C,A0),($24,A0)	;current per

0003C0	MOVE.B	(START+$10,PC),D1	;voices enabled ? 
	BTST	D5,D1			;current voice on ?
	BEQ.W	lbC0003DE		;no
	MOVE.W	#$8200,D1		;yes
	BSET	D5,D1
	MOVE.W	D1,($DFF096).L		;voice DMA on
	SF	($1E,A0)
0003DA	BRA.W	START+$03E4

lbC0003DE	DBRA	D5,START+$BA	;next voice
	RTS

0003E4	BTST	D5,($DFF003).L		;voice dma audio set ?
	BEQ.W	lbC0003DE		;no, next voice

;arpeggiato
	MOVEQ	#0,D0
	MOVE.B	($19,A0),D0		;note
	MOVEQ	#0,D1
	MOVE.B	($2F,A0),D1		;current index in arpeggio table
	MOVE.B	($16,A5,D1.W),D2	;current arp value
	ADD.B	D2,D0			;note = note + arp val
	SUBQ.B	#1,($30,A0)		;arp speed
	BNE.W	START+$0424		;reached 0 ? no = same arp value
	MOVE.B	($26,A5),($30,A0)	;set speed to initial value

	ADDQ.B	#1,($2F,A0)		;index+1
	MOVE.B	($33,A5),D3		;arp count reached ?
	CMP.B	($2F,A0),D3		;compared with current index 
	BNE.W	START+$0424		;no
	MOVE.B	#0,($2F,A0)		;index = 0 : start of the arp table

000424	LEA	(START+$0804,PC),A2	;period table
	MOVE.W	(8,A5),D1
	MOVEQ	#10,D2
	LSL.W	#1,D0			;period index = note+arp
	MOVE.W	(A2,D0.W),D0		;period
	MULU.W	D1,D0			;(a5+8)*period
	LSR.L	D2,D0			;((a5+8)*period)/1024
	MOVE.W	D0,($1C,A0)		

;portamento
	TST.B	($15,A0)		;port running ?
	BEQ.W	START+$0482

	TST.W	($16,A0)
	BEQ.W	START+$0454		;NOW
	SUBQ.W	#1,($16,A0)		;port delay (3rd parameter of 0x81 command)
	BRA.W	START+$0482		;NOT YET

;port delay expired
000454	MOVEQ	#0,D1
	MOVE.W	($28,A0),D1		;counter : 1 to a0+$2a
	MULS.W	($26,A0),D1		;initialised to (a0+$1a) - (a0+$1c)
	DIVS.W	($2A,A0),D1		;tempo * 1st parameter of 0x81 portamento command
	ADD.W	D1,($1C,A0)		;vd+$1c + = (vd+$28 * vd+$26) / vd+$2a
	ADDI.W	#1,($28,A0)		;varies from (1*$26/$2a) to ($2a/2a * $26/$2a)  
	MOVE.W	($28,A0),D2
	CMP.W	($2A,A0),D2		;target value reached ?
	BLE.W	START+$0482		;no
	MOVE.B	($23,A0),($19,A0)	;yes : new per = 2nd parameter in 0x81 command
	SF	($15,A0)		;port OFF


000482	MOVE.W	($1C,A0),D0		;period

;vibrato
	TST.B	($10,A0)		;vib delay (counter to 0)
	BEQ.W	START+$0496		;vib NOW
	SUBQ.B	#1,($10,A0)
	BRA.W	START+$04FA		;vib later

000496	TST.B	($22,A0)		;new note = vibrato started 
	BEQ.W	START+$04FA		;first value = 1

	BPL.W	START+$04C2
	MOVEQ	#0,D1
	MOVE.B	($14,A0),D1
	ADD.B	($12,A0),D1		;vib speed
	MOVE.B	D1,($14,A0)		;$14 = $14 + $12
	CMP.B	($13,A0),D1		;vib ampl == max value ?
	BNE.W	START+$04D8
	BCHG	#7,($22,A0)		;change sign
	BRA.W	START+$04D8

0004C2	MOVE.B	($14,A0),D1		;initially set to 0
	SUB.B	($12,A0),D1		;vib speed
	MOVE.B	D1,($14,A0)		;$14 = $14 - $12
	BNE.W	START+$04D8 		;$14!=0
	BCHG	#7,($22,A0)		;change sign 
0004D8	TST.B	($14,A0)
	BNE.W	START+$04E6
	BCHG	#0,($22,A0)

0004E6	EXT.W	D1			;sign extension
	BTST	#0,($22,A0)
	BEQ.W	START+$04F8		;negative vibrato
	ADD.W	D1,D0			;positif vibrato
	BRA.W	START+$04FA

0004F8	SUB.W	D1,D0


0004FA	MOVE.W	D0,($A6,A6)		;period

	CMPI.B	#0,($2D,A0)
	BEQ.W	START+$052A		;attack enveloppe state
	CMPI.B	#1,($2D,A0)
	BEQ.W	START+$0556		;delay state
	CMPI.B	#2,($2D,A0)
	BEQ.W	START+$0582		;sustain
	CMPI.B	#3,($2D,A0)
	BEQ.W	START+$059C		;release
	BRA.W	START+$05C8

	;attack
00052A	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVE.B	(15,A5),D2		;attack speed
	MOVE.B	($10,A5),D1		;attack vol
	MOVE.B	($2C,A0),D0		;current volume
	ADD.W	D2,D0			;vol up
	MOVE.B	D0,($2C,A0)		;new current vol
	CMP.W	D1,D0
	BLT.W	START+$05C8		;attack vol reached ?
	MOVE.B	D1,($2C,A0)		;yes = new volume

	MOVE.B	#1,($2D,A0)		;new state = delay
	BRA.W	START+$05C8

	;delay
000556	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVE.B	($11,A5),D2		;delay speed
	MOVE.B	($12,A5),D1		;delay vol
	MOVE.B	($2C,A0),D0		;current vol
	SUB.W	D2,D0			;vol down
	MOVE.B	D0,($2C,A0)		;new current vol
	CMP.W	D1,D0			;delay vol reached ?
	BGT.W	START+$05C8
	MOVE.B	D1,($2C,A0)		;yes : new volume
	MOVE.B	#2,($2D,A0)		;next state = sustain
	BRA.W	START+$05C8

	;sustain
000582	TST.B	($2E,A0)
	BNE.W	START+$0594
	MOVE.B	#3,($2D,A0)		;next state = release
	BRA.W	START+$05C8

000594	SUBQ.B	#1,($2E,A0)
	BRA.W	START+$05C8

	;release
00059C	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVE.B	($14,A5),D2		;release speed
	MOVE.B	($15,A5),D1		;release vol
	MOVE.B	($2C,A0),D0		;volume
	SUB.W	D2,D0			;vol down
	MOVE.B	D0,($2C,A0)
	CMP.W	D1,D0
	BGT.W	START+$05C8
	MOVE.B	D1,($2C,A0)		;new volume ?
	MOVE.B	#4,($2D,A0)		;end of enveloppe control
	BRA.W	START+$05C8

0005C8	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVEQ	#0,D4
	MOVE.B	($2C,A0),D0		;volume
	MOVE.B	(14,A5),D1		;vib ampl
	LEA	(START+$0800,PC),A3	;master volume ?
	MOVE.W	(A3),D2

	MOVE.B	(START+$07FF,PC),D3	;volume fade down ?
	TST.B	D3
	BEQ.W	START+$0608		;no
	
	MOVE.B	(START+$0802,PC),D4	;fade down speed ?
	SUB.W	D4,D2			;d2 = $800.w-$802.b
	TST.W	D2
	BMI.W	START+$05FA		;song stop
	MOVE.W	D2,(A3)			;new master vol
	BRA.W	START+$0608

0005FA	CLR.W	(A3)			;vol = 0
	CLR.L	D2
	LEA	(START+$07FE,PC),A3
	MOVE.B	#$FF,(A3)		:stop the song
	RTS

000608	MULU.W	D2,D1			:d2 = master vol, d1=vib amp, d0=voice vol ?
	LSR.L	#8,D1			;
	LSR.L	#4,D1			;/16=/4096
	MULU.W	D1,D0
	LSR.L	#8,D0
	LSR.L	#1,D0			;((d2*d1)/4096 *d0)  /512
	MOVE.W	D0,($A8,A6)		;resulting volume
	TST.B	($27,A5)
	BNE.W	START+$0624		;not a sampled instr
	BRA.W	lbC0003DE		;sampled instr : next voice

000624	CMPI.B	#2,($27,A5)
	BEQ.W	START+$06CE		;jump if blend instr

00062E	TST.B	($32,A0)
	BEQ.W	START+$063E		;pulse delay expired
	SUBQ.B	#1,($32,A0)
	BRA.W	lbC0003DE		;next voice

00063E	TST.B	($34,A0)		;pulse speed counter to 0
	BEQ.W	START+$064E
	SUBQ.B	#1,($34,A0)
	BRA.W	lbC0003DE		;next voice

00064E	BTST	#0,($2E,A5)		;synchro
	BEQ.W	START+$0660
000658	TST.B	($3C,A0)		;pulse shoot
	BEQ.W	START+$0770		;next voice
000660	MOVE.B	($2A,A5),($34,A0)	;pulse speed

	;build pulse instrument :
	;1. d0=pos L, a2=sample start (0 <= pos l < pos h <= 0x10) 
	;2. for i=$3c(a0) to 0
	 	for (d0=pos L; d0<pos H; d0++)
			bit#2 of $33(a0)==0
			a2+d0 = "rate -" value
		for (d0=pos H; d0>pos L; d0--)
			bit#2 of $33(a0)==1
			a2+d0 = "rate +" value

	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVE.B	($31,A0),D0		;pulse pos L
	MOVE.B	($2B,A5),D1		;pos L
	MOVE.B	($2C,A5),D2		;pos H
	LEA	($40,A0),A2
	BTST	#2,($33,A0)
	BNE.W	START+$0698

000686	CMP.B	D2,D0			;bit#2 == 0
	BLE.W	START+$06AE
					;d0 : pos L -> pos H
	BSET	#2,($33,A0)
	SUBQ.B	#1,($3C,A0)		;pulse shoot
	SUBQ.B	#1,D0

000698	CMP.B	D1,D0			;bit#2 == 1
	BGE.W	START+$06BE
					;d0 : pos H -> pos L
	BCLR	#2,($33,A0)
	SUBQ.B	#1,($3C,A0)		;pulse shoot
	ADDQ.B	#1,D0
	BRA.W	START+$0686
					;d0 goes up
0006AE	MOVE.B	($28,A5),(A2,D0.W)	;pulse rate -
	ADDQ.B	#1,D0
	MOVE.B	D0,($31,A0)
	BRA.W	lbC0003DE		;next voice

					;d0 goes up
0006BE	MOVE.B	($29,A5),(A2,D0.W)	;pulse rate + 
	SUBQ.B	#1,D0
	MOVE.B	D0,($31,A0)		;pos L
	BRA.W	lbC0003DE		;next voice

	;blend
0006CE	TST.B	($39,A0)
	BEQ.W	START+$06DE		;delay ?
	SUBQ.B	#1,($39,A0)
	BRA.W	lbC0003DE		;next voice

0006DE	BTST	#2,($2E,A5)		;synchro
	BEQ.W	START+$06F0
	TST.B	($3D,A0)		;counter
	BEQ.W	START+$0770

0006F0	TST.B	($38,A0)		;initially set to 0=up, 1=down
	BNE.W	START+$072C

	;up direction
	MOVEQ	#0,D1
	MOVE.B	($2F,A5),D1
	MOVEQ	#1,D0
	LSL.L	D1,D0			; d0<<1
	CMP.W	($36,A0),D0		;initially to 1 (up to 2^$2f(a5))
	BEQ.W	START+$0774

	MOVEQ	#0,D3
	ADDI.W	#1,($36,A0)		;up
	MOVE.W	($36,A0),D3
	LEA	($40,A0),A4
	LEA	(START+$00,PC),A3
	ADDA.L	(0,A5),A3		;instr offset
	LEA	($20,A3),A2		;source adr
	MOVEQ	#$1F,D2			;sample len
	BRA.W	START+$075C

	;down direction
00072C	MOVEQ	#0,D0
	MOVE.W	($36,A0),D0
	CMPI.W	#1,D0
	BEQ.W	START+$0774

	MOVEQ	#0,D3
	SUBI.W	#1,($36,A0)		;down
	MOVE.W	($36,A0),D3
	LEA	($40,A0),A4
	LEA	(START+$00,PC),A3
	ADDA.L	(0,A5),A3
	LEA	($20,A3),A2
	MOVEQ	#$1F,D2			;sample len
	BRA.W	START+$075C

00075C	MOVEQ	#0,D6
	MOVE.B	($2F,A5),D6
lbC000762	MOVE.L	D3,D1
	MULS.W	(A2)+,D1		;a2 = sample adr
	LSR.L	D6,D1
	ADD.B	(A3)+,D1
	MOVE.B	D1,(A4)+		;new byte = (a2)*(a0+$36) / 2^(a5+$2f) + last copied byte
	DBRA	D2,lbC000762		;32 times
000770	BRA.W	lbC0003DE

000774	EORI.B	#1,($38,A0)		;change direction
	SUBQ.B	#1,($3D,A0)
	BRA.W	START+$06DE

	;if new instr = pulse : pulse instr initialization
000782	MOVEQ	#0,D1
	MOVEQ	#0,D2
	MOVEQ	#0,D3
	MOVE.B	($31,A5),($3C,A0)	;pulse shoot
	MOVE.B	($2D,A5),($32,A0)	;pulse delay
	MOVE.B	($2A,A5),($34,A0)	;pulse speed
	MOVE.B	#0,($33,A0)
	MOVE.B	($2B,A5),($31,A0)	;pulse pos L
	LEA	($40,A0),A4
	MOVE.W	(6,A5),D1		;len in word
	ADD.B	D1,D1			;in bytes
	MOVE.B	D1,D2			;not used ?
	MOVE.B	($2B,A5),D3		;pos L times
	SUBQ.B	#1,D3
0007B8	MOVE.B	($28,A5),(A4)+		;rate -
	DBRA	D3,START+$07B8
	SUB.B	($2B,A5),D1		;len - (pos L)  times
	SUBQ.B	#1,D1
0007C6	MOVE.B	($29,A5),(A4)+		;rate +
	DBRA	D1,START+$07C6
	RTS

	;if new instr == blend : initialization
0007D0	MOVE.B	#0,($38,A0)
	MOVE.W	#1,($36,A0)
	MOVE.B	($32,A5),($3D,A0)
	MOVE.B	($30,A5),($39,A0)		;blend delay
	LEA	(START+$00,PC),A3		:copy synth instr ?
	ADDA.L	(0,A5),A3			;instr adr
	LEA	($40,A0),A4
	MOVEQ	#$1F,D1				;len = 32 bytes
0007F6	MOVE.B	(A3)+,(A4)+
	DBRA	D1,START+$07F6
	RTS

0007FE	db	$FF				;0=song on, 1=song off
0007FF	db	0				;music stop with vol fading flag
000800	dw	0				;master volume
000802	dw	0				;stop volume fading value
000804	dw	$2000, $1E30,$1C80,$1AE8,$1968,$17F8
...
00088E	dw	$98, $8F,$87

000894	db	0
000895	db	0
000896	db	0
000897	db	6
000898	db	2,2,2,2,2,2,2,2,2,0
0008A2	dl	$1540
0008A6	dl	$C6E
0008AA	dw	0
0008AC	dw	0
0008AE	dw	0
0008B0	dw	0
0008B2	dw	0
0008B4	dw	0
0008B6	dw	0
0008B8	dw	0
0008BA	dw	0
0008BC	dw	0
0008BE	dw	0
