*********************
* ptplay v 1.0 beta *
*********************
* by Otis/InfoCorner*
*********************

;<<<< Needs powerpacker.library >>>>
	
	incdir	df0:include/

	include	powerpacker_lib.i
	include ppbase.i

	incdir	df0:

AddICRVector	=   -6
RemICRVector	=  -12
LVOOpenResource	= -498
LVOOpenLibrary 	= -552
LVOCloseLibrary	= -414
LVODelay	= -198

MEMF_CHIP = 1<<1
MEMF_PUBLIC =1<<0

ciatalo = $400
ciatahi = $500
ciatblo = $600
ciatbhi = $700
ciacra  = $E00
ciacrb  = $F00

;********* Exec offsets ************

forbid	= -132
permit	= -138

;************ code ***************

	section	ptplay,CODE

start
	movem.l	d0-d7/a0-a6,-(a7)
	move.l	a0,argv
	move.l	d0,argv_length

	lea	dos_name,a1
	moveq	#0,d0
	move.l	$4.w,a6
	jsr	-552(a6)	;open dos lib
	tst.l	d0
	bne.s	opened
	bra.w	exit

opened
	move.l	d0,dos_base

	move.l	d0,a6
	jsr	-60(a6)		;get cli stdout
	move.l	d0,stdout
	
	move.l	argv,a0
	move.b	(a0),d0
	cmp.b	#"?",d0
	beq.s	print_usage
	move.l	argv_length,d0
	cmp.b	#1,d0
	bgt.s	args_passed


print_usage
	;write: Usage: ptplay module[.pp] [text[.pp]]
	move.l	#usage_text,d2
	move.l	stdout,d1
	move.l	#38,d3
	move.l	dos_base,a6
	jsr	-48(a6)
	bra.w	exit

	
args_passed	
	bsr	get_arguments	;first in filename1, second in filename2
	;write: PtPlay - protracker module player. (c)1993 Otis/InfoCorner
	move.l	stdout,d1
	move.l	dos_base,a6
	move.l	#opening_text,d2
	move.l	#59,d3
	jsr	-48(a6)

	;open powerpacker.library
	lea	pp_name,a1
	moveq	#0,d0
	move.l	$4.w,a6
	jsr	-552(a6)
	tst.l	d0
	bne.s	pp_opened

	;write	Needs powerpacker.library!!!!!
	move.l	#pp_needed,d2
	move.l	stdout,d1
	move.l	#31,d3
	move.l	dos_base,a6
	jsr	-48(a6)
	bra 	exit

pp_opened
	move.l	d0,pp_base

	;load module
	lea	filename1,a0
	moveq	#DECR_POINTER,d0
	moveq	#MEMF_CHIP,d1
	lea	mt_data,a1
	lea	tune_length,a2
	move.l	#0,a3
	move.l	pp_base,a6
	jsr	_LVOpploaddata(a6)

	tst.l	d0
	beq.s	mod_load_succeeded

	move.l	pp_base,a6
	jsr	_LVOpperrormessage(a6)

	bsr	dump_pp_error_message

	move.l	pp_base,a1
	move.l	$4.w,a6
	jsr	-414(a6)		;close pp.library

	bra.w	exit

mod_load_succeeded		
	bsr	kill_disk_motor

	lea	filename2,a0
	move.b	(a0),d0
	tst.b	d0
	beq.s	no_mod_text_specified
	
	;load text
	moveq	#DECR_POINTER,d0
	moveq	#MEMF_PUBLIC,d1
	lea	mod_text,a1
	lea	mod_text_length,a2
	move.w	#0,a3
	move.l	pp_base,a6
	jsr	_LVOpploaddata(a6)

	tst.l	d0
	beq.s	text_load_succeeded

	move.l	#0,mod_text_length

	move.l	pp_base,a6
	jsr	_LVOpperrormessage(a6)

	bsr	dump_pp_error_message

	move.l	pp_base,a1
	move.l	$4.w,a6
	jsr	-414(a6)		;close pp.library

	bsr	free_tune
	bra.w	exit

no_mod_text_specified
	lea	mod_text_struct,a0
	move.l	#no_mod_text_text,(a0)
	move.w	no_mod_text_text_length,10(a0)
	bra.s	n_m_t_s_skip
		
text_load_succeeded
	bsr	kill_disk_motor
	lea	mod_text_struct,a0
	move.l	mod_text,(a0)
	move.l	mod_text_length,d0
	move.w	d0,10(a0)		;chop at 64K

n_m_t_s_skip
	move.l	pp_base,a1
	move.l	$4.w,a6
	jsr	-414(a6)		;close pp.library

	lea	about_text_struct,a0
	bsr	get_number_of_lines
	bsr	allocate_text_bitmap_space
	tst.l	d0
	bne.s	s_cont1
	lea	about_text_struct,a0
	bsr	insert_empty_space
	bsr	get_number_of_lines
s_cont1
	bsr	clear_bitplane

	lea	mod_text_struct,a0
	bsr	get_number_of_lines
	bsr	allocate_text_bitmap_space
	tst.l	d0
	bne.s	s_cont2
	lea	mod_text_struct,a0
	bsr	insert_empty_space
	bsr	get_number_of_lines
s_cont2
	bsr	clear_bitplane

	lea	uga_text_struct,a0
	bsr	get_number_of_lines
	bsr	allocate_text_bitmap_space
	tst.l	d0
	bne.s	s_verder1
	lea	uga_text_struct,a0
	bsr	insert_empty_space
	bsr	get_number_of_lines

s_verder1
	bsr	clear_bitplane

	;fix AGA

	move.l	$4.w,a6
	lea	graph_name,a1
	moveq	#0,d0
	jsr	-552(a6)	;open gfx.lib
	move.l	d0,gfx_base
	beq.w	exit

	move.l	d0,a6
	move.l	34(a6),old_view

	move.l	#0,a1
	jsr	-222(a6)	;loadview(0)

	move.l	gfx_base,a6
	jsr	-270(a6)	;waitTOF

	move.l	gfx_base,a6
	jsr	-270(a6)	;waitTOF

	move.l	gfx_base,a6
	jsr	-456(a6)	;get blitter

	move.l	gfx_base,a6
	jsr	-228(a6)	;wait for blitter

	move.l	$4.w,a6
	move.l	gfx_base,a1
	jsr	-414(a6)	;close lib

	;fix sprites if AGA
	;check if AGA
	move.w	$dff07c,d0
	cmp.b	#$f8,d0
	bne.s	.not_AGA
	move.w	#0,$dff1fc	

.not_AGA
	lea	getvbr(pc),a5
	jsr	-$1e(a6)	; call function in supervisor mode

	move.l	$4.W,a6
	jsr	forbid(a6)	;no multitasking, coz no rastertime left....

	bsr.w	init_program	;several tables setup, screen setup etc.
	bsr.w	init_song

	bsr.w	main

	jsr	ResetCIAInt

	bsr	free_text_bitmaps
	bsr	free_tune
	bsr	free_mod_text

	lea	graph_name,a1
	moveq	#0,d0

	move.l	$4.w,a6
	jsr	-552(a6)
	move.l	d0,gfx_base

	move.l	d0,a6
	bsr.w	waittil00
	move.l	38(a6),$dff080

	move.w	d0,$dff088

	move.l	old_view,a1
	jsr	-222(a6)	;loadview(old_view)

	move.l	gfx_base,a6
	jsr	-462(a6)	;bye blitter

	move.l	gfx_base,a1
	move.l	$4.w,a6
	jsr	-414(a6)	;close lib

exit
	move.l	dos_base,a1	;close dosbase
	move.l	$4.w,a6
	jsr	-414(a6)

	move.l	$4.w,a6
	jsr	permit(a6)

	movem.l	(a7)+,d0-d7/a0-a6
	rts


dump_pp_error_message
	;d0 is pointer to string...(0 terminated)
	move.l	d0,d2
	moveq	#0,d3
	move.l	d0,a0
.loop
	move.b	(a0)+,d0
	tst.b	d0
	beq.s	.finished
	addq	#1,d3
	bra.s	.loop
.finished
	move.l	stdout,d1
	move.l	dos_base,a6
	jsr	-48(a6)
	
	move.l	#return,d2
	moveq	#1,d3
	move.l	stdout,d1
	move.l	dos_base,a6
	jsr	-48(a6)
	rts	


get_arguments
	move.l	argv,a0
	lea	filename1,a1
	move.l	argv_length,d7
	moveq	#1,d6
	moveq	#0,d5			;d5 =1 => quoted string d5=0 =>not

	move.b	(a0),d0
	cmp.b	#34,d0
	bne.s	g_a_loop1
	moveq	#1,d5
	addq	#1,d6
	addq.l	#1,a0
g_a_loop1
	move.b	(a0)+,d0
	tst.b	d5
	beq.s	.no_quoted_string
	cmp.b	#34,d0
	bne.s	g_a_loop1_v
	addq	#1,a0
	addq	#1,d6
	cmp.l	d7,d6
	bge.s	g_a_finished1
	bra.s	nextarg
.no_quoted_string	
	cmp.b	#" ",d0
	beq.s	nextarg
g_a_loop1_v
	addq	#1,d6
	cmp.l	d7,d6
	bgt.s	g_a_finished1
	move.b	d0,(a1)+
	bra.s	g_a_loop1
nextarg
	moveq	#0,d5
	move.b	#0,(a1)+
	lea	filename2,a1
.loop2
	move.b	(a0)+,d0
	cmp.b	#" ",d0
	bne.s	.skip
	addq	#1,d6
	bra.s	.loop2
.skip
	cmp.b	#34,d0
	bne.s	.not_quoted_string
	moveq	#1,d5
	addq	#1,d6
	addq	#1,a0

.not_quoted_string
	subq	#1,a0
.loop3
	move.b	(a0)+,d0
	tst.b	d5
	beq.s	.not_quoted
	cmp.b	#34,d0
	beq.s	g_a_finished2
.not_quoted	
	addq	#1,d6
	cmp.l	d7,d6
	bge.s	g_a_finished2
	move.b	d0,(a1)+
	bra.s	.loop3


g_a_finished1
	move.l	#0,filename2
	bra.s	g_a_end
g_a_finished2
	move.b	#0,(a1)
g_a_end
	rts		
			

;This function gets the vbr so this thingy also works on a '030
getvbr:	move.l	4.w,a6
	btst	#1,$129(a6)
	beq.s	.no68020
	dc.l	$4e7a8801	; movec	vbr,a0
	move.l	a0,vbr
.no68020
	rte


waittil00
	lea	$dff000,a5
wt00_l1
	tst.b	5(a5)	
	beq.s	wt00_l1
wt00_l2
	tst.b	5(a5)
	bne.s	wt00_l2
	rts	


;****************** initialisation *****************

init_song
	jsr	SetCIAInt
	jsr	mt_init
	rts


init_program
	bsr.b	all_black	;all colors black....
	bsr.w	copy_scopes_bitplane_to_buffers

	bsr.w	fill_char_tab
	bsr.w	fill_track_pos_tab
	bsr.w	blit_slotnos

	bsr.w	blit_text_bitmaps

	move.l	mt_data,a0
	lea	952(a0),a0
	move.b	(a0),pattern_pointer

	bsr.w	init_copplist
	bsr.w	blit_song_name
	bsr.w	blit_song_length

	bsr.w	fill_sample_info_buffer
	bsr.w	do_sample_up

	lea	about_text_struct,a0
	bsr	show_text_in_window

	rts	


all_black
	moveq	#16-1,d7
	lea	$dff180,a0
a_b_l
	clr.w	(a0)+
	dbf	d7,a_b_l

	rts		


put_colors
	moveq	#16-1,d7
	lea	colors,a0
	lea	$dff180,a1
p_c_l
	move.w	(a0)+,(a1)+
	dbf	d7,p_c_l

	;colors vu meters

	lea	$dff180,a0
	move.w	#$00f0,42(a0)
	move.w	#$00c0,44(a0)
	move.w	#$0090,46(a0)

	move.w	#$00f0,50(a0)
	move.w	#$00c0,52(a0)
	move.w	#$0090,54(a0)

	move.w	#$0d0f,58(a0)
	move.w	#$0a0c,60(a0)
	move.w	#$080a,62(a0)
	
	;colors	mouse pointer

	move.w	#$0f00,34(a0)
	move.w	#$0c00,36(a0)
	move.w	#$0900,38(a0)

	rts	


init_copplist
	move.l	#screen_picture,d0
	lea	scherm,a0
	
	swap	d0
	move.w	d0,2(a0)
	swap	d0
	move.w	d0,6(a0)

	add.l	#[80*200],d0
	add.l	#8,a0

	swap	d0
	move.w	d0,2(a0)
	swap	d0
	move.w	d0,6(a0)

	add.l	#[80*200],d0
	add.l	#8,a0

	swap	d0
	move.w	d0,2(a0)
	swap	d0
	move.w	d0,6(a0)

	;insert sprites

	lea	c_pointer,a0
	move.l	#mouse_pointer,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)

	lea	8(a0),a0
	move.l	#dummy_sprite,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)

	lea	c_vu_meters,a0
	move.l	#vu_meter_1,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	lea	8(a0),a0
	move.l	#vu_meter_2,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	lea	8(a0),a0
	move.l	#vu_meter_3,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	lea	8(a0),a0
	move.l	#vu_meter_4,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	lea	8(a0),a0
	move.l	#dummy_sprite,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	lea	8(a0),a0
	move.l	#dummy_sprite,d0

	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
		
	move.l	#tracks_bitplane,d0
	lea	track_wait,a0

	move.w	#[$2909+$1800],(a0)+
	move.w	#$fffe,(a0)+

	move.w	#$00e0,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$00e2,(a0)+
	swap	d0
	move.w	d0,(a0)+

	move.w	#[$2909+$6800],(a0)+
	move.w	#$fffe,(a0)+

	move.l	#screen_picture+3*80*200+104*80,d0
	move.w	#$00ec,(a0)+
	swap	d0
	move.w	d0,(a0)+
	swap	d0
	move.w	#$00ee,(a0)+
	move.w	d0,(a0)+
		
	move.l	#$b909fffe,(a0)+
	move.l	#$0100b200,(a0)+

	move.l	#screen_picture+[[24+120]*80],d0

	move.l	a0,scope_screen

	move.w	#$00e0,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$00e2,(a0)+
	swap	d0
	move.w	d0,(a0)+

	add.l	#[80*200],d0

	move.w	#$00e4,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$00e6,(a0)+
	swap	d0
	move.w	d0,(a0)+

	add.l	#[80*200],d0

	move.w	#$00e8,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$00ea,(a0)+
	swap	d0
	move.w	d0,(a0)+
	
	;chop sprites... (insert dummies in the vu meter pointers)

	move.l	#dummy_sprite,d0

	move.w	#$0128,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$012a,(a0)+
	swap	d0
	move.w	d0,(a0)+		

	move.w	#$012c,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$012e,(a0)+
	swap	d0
	move.w	d0,(a0)+		

	move.w	#$0130,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$0132,(a0)+
	swap	d0
	move.w	d0,(a0)+		

	move.w	#$0134,(a0)+
	swap	d0
	move.w	d0,(a0)+
	move.w	#$0136,(a0)+
	swap	d0
	move.w	d0,(a0)+		

	move.l	#$f109fffe,(a0)+
	move.l	#$01000000,(a0)+
	move.l	#$fffffffe,(a0)+
	rts	
	

init_about_text_stuff
	lea	about_text_struct,a0
	bsr	blit_text
	bsr	calc_scrollbar_info
	bsr	generate_scrollbar_sprite
	move.w	#24,scrollbar+6
	lea	about_text_struct,a0
	move.l	12(a0),a1
	move.w	4(a1),d0
	add.w	#24,d0
	move.w	d0,scrollbar+8
	bsr	show_text_in_window
	rts


init_mod_text_stuff
	lea	mod_text_struct,a0
	bsr	blit_text
	bsr	calc_scrollbar_info
	bsr	generate_scrollbar_sprite
	rts


init_uga_text_stuff
	lea	uga_text_struct,a0
	bsr	blit_text
	bsr	calc_scrollbar_info
	bsr	generate_scrollbar_sprite
	rts


blit_text_bitmaps
	bsr	init_about_text_stuff
	bsr	init_mod_text_stuff
	bsr	init_uga_text_stuff
	rts


free_text_bitmaps
	lea	about_text_struct,a0
	bsr	free_memory

	lea	mod_text_struct,a0
	bsr	free_memory

	lea	uga_text_struct,a0
	bsr	free_memory
	rts


free_tune
	move.l	mt_data,a1
	move.l	tune_length,d0
	move.l	$4.w,a6
	jsr	-210(a6)
	rts


free_mod_text
	move.l	mod_text_length,d0
	tst.l	d0
	beq.s	.end			;no mod text specified
	move.l	mod_text,a1
	move.l	$4.w,a6
	jsr	-210(a6)
.end	
	rts


main
	bsr.w	waittil00
	lea	$dff000,a6
	move.l	#copper_list,$80(a6)
	move	d0,$88(a6)		; write dummy value

	bsr.w	put_colors

	move.w	#$b200,$100(a6)

	move.w	$1c(a6),intena_save
	move.w	$02(a6),dmacon_save

	move.w	#$7fff,$9a(a6)
	move.w	#$7fff,$9c(a6)

	move.l	vbr,a0
	move.l	$6c(a0),vbl_save
	move.l	#wait_vbl,$6c(a0)	;st vbl.

	move.w	#$8060,$96(a6)	
	move.w	#$e020,$9a(a6)

	move.w	#0,$36(a6)

	jsr	main_control	;go to the main loop

	;end of proggy, restore everything...

	clr.b	mt_enable

	lea	$dff000,a6
	move.w	#$7fff,$9a(a6)
	move.w	#$7fff,$9c(a6)

	move.l	vbr,a0
	move.l	vbl_save,$6c(a0)
	move.w	intena_save,d0
	or.w	#$8000,d0
	move.w	d0,$9a(a6)

	move.w	dmacon_save,d0
	or.w	#$8000,d0
	move.w	d0,$96(a6)

	jsr	mt_end
	
	rts


wait_vbl
 	movem.l	d0-d7/a0-a6,-(a7)
	ST	mt_enable
	bsr.w	swap_scopes_screen
	bsr.w	clear_scope_area
	bsr.w	plot_scopes
	bsr.w	update_playing_time
	bsr.w	move_vu_meters
	bsr.w	move_pointer
	tst.b	scrollbar_moved
	beq.s	end_vbl
	move.b	#0,scrollbar_moved
	bsr	move_scrollbar

end_vbl
	move.w	#$0070,$dff09c
	movem.l (a7)+,d0-d7/a0-a6

.end	rte


main_control
	tst.b	quit_program
	bne.w	quit_main_control

	tst.b	new_pattern
	beq.s	m_c_v1
	
	move.b	#0,new_pattern
	bsr.w	blit_pattern_no
	bsr.w	blit_song_pos
m_c_v1
	tst.b	new_bpm
	beq.s	m_c_v2

	move.b	#0,new_bpm
	bsr.w	blit_bpm
m_c_v2
	tst.b	new_vbl_tempo
	beq.s	m_c_v3

	move.b	#0,new_vbl_tempo
	bsr.w	blit_vbl_tempo
m_c_v3
	tst.b	new_time
	beq.s	m_c_v4

	bsr.w	blit_play_time
m_c_v4		
	bsr.w	blit_pattern

	moveq	#0,d1
	
	btst	#6,$bfe001
	bne.w	no_left_button

	move.b	#0,mouse_button_status

	tst.b	mouse_button_status
	bne.s	no_button_last_time

	;button was pressed last time.

	cmp.w	#10,button_id
	bne.s	.no_scrollbar1
	move.b	#1,scrollbar_moved
	bra.w	main_control	

.no_scrollbar1
	bsr.w	check_which_button	;d0 is button id, a0 is pointr to strct
	move.w	button_id,d1
	move.l	button_struct_address,a1
	
	move.w	d0,button_id
	move.l	a0,button_struct_address

	cmp.w	#10,d0
	bne.s	.no_scrollbar2
	move.b	#1,scrollbar_moved
	bra.w	main_control	

.no_scrollbar2
	cmp.w	d1,d0
	beq.w	main_control

	tst.w	d1
	beq.s	.nothing_to_restore

	;new futton pressed so restore old.
	bsr.w	restore_button		;button that has to be restored
					;is in d1, address of structure in
					;a1
.nothing_to_restore
	move.l	button_struct_address,a0
	move.w	button_id,d0
	tst.w	d0
	beq.w	main_control	;no button pressed anymore

	;new button pressed

	bsr.w	blit_new_button
	bra.w	main_control

no_button_last_time
	bsr.w	check_which_button
	move.w	d0,button_id
	move.l	a0,button_struct_address

	tst.w	d0
	beq.w	main_control

	cmp.w	#10,d0
	bne.s	.no_scrollbar
	move.b	#1,scrollbar_moved
	bra.w	main_control

.no_scrollbar
	bsr.b	blit_new_button
	bra.w	main_control

no_left_button
	move.b	#1,mouse_button_status
	bsr.w	check_which_button
	move.w	button_id,d1
	move.l	button_struct_address,a1
	tst.w	d1
	beq.w	main_control

	cmp.w	#10,d1
	beq.s	.not_the_same

	cmp.w	d0,d1

	bne.s	.not_the_same
	;do action
	bsr.b	restore_button
	bsr.b	do_action
.not_the_same
	move.w	#0,button_id	
	bra.w	main_control

quit_main_control	
	rts


restore_button
	;d1=button_id, a1 is pointer to button_structure....
	lea	button_blit_jump_table,a6

	and.w	#$00ff,d1	;not more than 256 buttons :-)

	add.w 	d1,d1
	add.w	d1,d1		;d1 * 4

	move.l	(a6,d1.w),a5	;get address of routine....
	move.l	10(a1),a4	;get address of unselected image to render.

.end_of_routine
	jmp	(a5)		;jsr + rts to restore routine...


blit_new_button
	;d0=button_id, a0 is pointer to button_structure....
	lea	button_blit_jump_table,a6

	and.w	#$00ff,d0

	add.w	d0,d0
	add.w	d0,d0		;d0 * 4	

	move.l	(a6,d0.w),a5	;get address of blit_routine
	move.l	14(a0),a4	;get address of selected image to render.

.end_of_routine
	jmp	(a5)		;jsr + rts to blit routine...


do_action
	lea	button_action_jump_table,a6

	add.w	d0,d0
	add.w	d0,d0

	move.l	(a6,d0.w),a5
	jmp	(a5)		;jsr + rts to action routine..

show_about
	lea	about_text_struct,a0
	bsr	show_text_in_window
	rts
	
show_mod_text
	lea	mod_text_struct,a0
	bsr	show_text_in_window
	rts
	
do_restart
	move.w	#$0020,$dff09a

	jsr	ResetCIAInt
	jsr	mt_end

	bsr	clear_sample_structs

	move.b	#0,hours
	move.b	#0,minutes
	move.b	#0,seconds
	move.w	#0,pattern_slot_teller
	move.w	#0,blit_note_slot_teller
	move.b	#1,new_time
	move.b	#1,new_pattern	
	move.l	mt_data,a0
	lea	952(a0),a0
	move.b	(a0),pattern_pointer

	jsr	init_song

	move.w	#$8020,$dff09a
	rts


do_quit
	move.b	#1,quit_program
	rts


show_uga
	lea	uga_text_struct,a0
	bsr	show_text_in_window
	rts


do_sample_up
	moveq	#0,d0
	move.b	sample_info_shown,d0
	cmp.b	#31,d0
	beq.s	end_do_sample_up
	addq.b	#1,d0
	move.b	d0,sample_info_shown
	bsr.w	blit_sample_info
end_do_sample_up	
	rts

	
do_sample_down
	moveq	#0,d0
	move.b	sample_info_shown,d0
	cmp.b	#1,d0
	beq.s	end_do_sample_down
	subq.b	#1,d0
	move.b	d0,sample_info_shown
	bsr.w	blit_sample_info
end_do_sample_down
	rts


do_textwindow_up
	bsr	move_text_up
	rts


do_textwindow_down
	bsr	move_text_down
	rts


blit_about_button
	lea	screen_picture+188*80+40+200*80,a3
	bsr.b	blit_major_buttons
	rts

	
blit_mod_text_button
	lea	screen_picture+188*80+48+200*80,a3
	bsr.b	blit_major_buttons
	rts


blit_restart_button
	lea	screen_picture+188*80+56+200*80,a3
	bsr.b	blit_major_buttons
	rts


blit_quit_button
	lea	screen_picture+188*80+64+200*80,a3
	bsr.b	blit_major_buttons
	rts


blit_uga_button
	lea	screen_picture+188*80+72+200*80,a3
	bsr.b	blit_major_buttons
	rts


blit_sample_arrow_up
	lea	screen_picture+162*80+74+200*80,a3
	bsr.w	blit_arrow
	rts


blit_sample_arrow_down
	lea	screen_picture+172*80+74+200*80,a3
	bsr.w	blit_arrow
	rts


blit_scrollbar_arrow_up
	lea	screen_picture+85*80+78+200*80,a3
	bsr.w	blit_arrow
	rts


blit_scrollbar_arrow_down
	lea	screen_picture+95*80+78+200*80,a3
	bsr.w	blit_arrow
	rts


blit_close_button
	lea	screen_picture+200*80,a3
	bsr.w	blit_cl_button
	rts


blit_major_buttons	;about ... UGA button...
;destination in a3, source in a4...
	lea	$dff000,a6

	;bitplane 1
.wait_blitter1
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter1

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a4,$50(a6)
	move.l	a3,$54(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00200048,$64(a6)
	move.w	#$0304,$58(a6)

	move.w	#$8020,$9a(A6)

	add.l	#40*12,a4
	add.l	#200*80,a3

	;bitplane 2
.wait_blitter2
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter2

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a4,$50(a6)
	move.l	a3,$54(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00200048,$64(a6)
	move.w	#$0304,$58(a6)

	move.w	#$8020,$9a(A6)

	rts


blit_arrow
;destination in a3, source in a4...
	lea	$dff000,a6
	lea	arrow_button_mask,a2
	;bitplane 1
.wait_blitter1
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter1

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a2,$50(a6)
	move.l	a3,$54(a6)
	move.l	a3,$48(a6)
	move.l	a4,$4c(a6)
	move.l	#$fff8fff8,$44(a6)	;mask only the most left 13 bits.
	move.l	#$0fca0000,$40(a6)
	move.l	#$004e0000,$60(a6)
	move.l	#$0000004e,$64(a6)
	move.w	#$0281,$58(a6)

	move.w	#$8020,$9a(A6)

	add.l	#200*80,a3
	add.l	#2*10,a4

	;bitplane 2
.wait_blitter2
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter2

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a2,$50(a6)
	move.l	a3,$54(a6)
	move.l	a3,$48(a6)
	move.l	a4,$4c(a6)
	move.l	#$fff8fff8,$44(a6)	;mask only the most left 13 bits.
	move.l	#$0fca0000,$40(a6)
	move.l	#$004e0000,$60(a6)
	move.l	#$0000004e,$64(a6)
	move.w	#$0281,$58(a6)

	move.w	#$8020,$9a(A6)

	rts


blit_cl_button
;destination in a3, source in a4...
	lea	$dff000,a6
	;bitplane 1
.wait_blitter1
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.w	.wait_blitter1

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a4,$50(a6)
	move.l	a3,$54(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$0000004e,$64(a6)
	move.w	#$0281,$58(a6)

	move.w	#$8020,$9a(A6)

	add.l	#200*80,a3
	add.l	#2*10,a4

	;bitplane 2
.wait_blitter2
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter2

	move.w	#$0070,$9a(a6)		;no vbl interrupt...

	move.l	a4,$50(a6)
	move.l	a3,$54(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$0000004e,$64(a6)
	move.w	#$0281,$58(a6)

	move.w	#$8020,$9a(A6)

	rts


blit_sample_info
	subq.b	#1,d0
	mulu	#[23*26],d0
	lea	sample_info_buffer,a0
	add.l	d0,a0

	move.l	scopes_clear_buffer,a1
	add.l	#[18*80]+48,a1

	lea	$dff000,a6

	move.w	#$0070,$9a(a6)
.wait_blitter
	btst	#14,2(a6)
	btst	#14,2(a6)
	bne.s	.wait_blitter

	move.l	a1,$54(a6)
	move.l	a0,$50(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00000036,$64(a6)
	move.w	#$05cd,$58(a6)

	move.w	#$8020,$9a(a6)

	move.l	scopes_build_buffer,a1
	add.l	#[18*80]+48,a1

	move.w	#$0070,$9a(a6)
.wait_blitter2
	btst	#14,2(a6)
	btst	#14,2(a6)
	bne.s	.wait_blitter2

	move.l	a1,$54(a6)
	move.l	a0,$50(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00000036,$64(a6)
	move.w	#$05cd,$58(a6)

	move.w	#$8020,$9a(a6)

	move.l	scopes_show_buffer,a1
	add.l	#[18*80]+48,a1

	move.w	#$0070,$9a(a6)
.wait_blitter3
	btst	#14,2(a6)
	btst	#14,2(a6)
	bne.s	.wait_blitter3

	move.l	a1,$54(a6)
	move.l	a0,$50(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00000036,$64(a6)
	move.w	#$05cd,$58(a6)

	move.w	#$8020,$9a(a6)

	rts


update_playing_time
	move.b	frame_counter,d0
	tst.b	pal_ntsc
	bne.s	u_p_t_ntsc
u_p_t_pal	
	move.b	#50,d1
	bra.s	u_p_t_v	
u_p_t_ntsc	
	move.b	#60,d1
u_p_t_v
	cmp.b	d1,d0
	bge.s	u_p_t_new_second
	addq.b	#1,frame_counter
	bra.s	u_p_t_end

u_p_t_new_second
	move.b	#0,frame_counter
	move.b	#1,new_time		;to force a timeblit		
	move.b	seconds,d0
	cmp.b	#59,d0
	bge.s	u_p_t_new_minute
	addq.b	#1,seconds
	bra.s	u_p_t_end
u_p_t_new_minute
	move.b	#0,seconds
	move.b	minutes,d0
	cmp.b	#59,d0
	bge.s	u_p_t_new_hour		;'hmm it's gonna get annoying, jim'
	addq.b	#1,minutes
	bra.s	u_p_t_end
u_p_t_new_hour
	move.b	#0,minutes
	move.b	hours,d0
	cmp.b	#99,d0
	blt.s	u_p_t_end
	move.b	#0,hours		;if it last that long, hmm!
u_p_t_end
	rts	


clear_sample_structs
	lea	mt_chan1temp,a0
	move.l	#0,4(a0)
	move.w	#0,8(a0)
	move.l	#0,10(a0)
	move.w	#0,14(a0)
	move.l	#0,36(a0)
	move.w	#0,40(a0)

	lea	mt_chan2temp,a0
	move.l	#0,4(a0)
	move.w	#0,8(a0)
	move.l	#0,10(a0)
	move.w	#0,14(a0)
	move.l	#0,36(a0)
	move.w	#0,40(a0)

	lea	mt_chan3temp,a0
	move.l	#0,4(a0)
	move.w	#0,8(a0)
	move.l	#0,10(a0)
	move.w	#0,14(a0)
	move.l	#0,36(a0)
	move.w	#0,40(a0)

	lea	mt_chan4temp,a0
	move.l	#0,4(a0)
	move.w	#0,8(a0)
	move.l	#0,10(a0)
	move.w	#0,14(a0)
	move.l	#0,36(a0)
	move.w	#0,40(a0)
	rts	


fill_char_tab
	lea	char_tab,a0
	lea	font,a1
	move.l	#6-1,d7
	move.w	#$09f0,d6
	move.w	#$8bfa,d5
f_c_l1
	move.l	#20-1,d2
f_c_l2
	move.l	a1,(a0)+
	addq.l	#2,a1
	move.w	d5,(a0)+
	move.w	d6,(a0)+

	dbf	d2,f_c_l2

	add.l	#[8*40],a1

	dbf	d7,f_c_l1

	rts
	

fill_track_pos_tab
	lea	tracks_bitplane,a0
	lea	track_pos_tab,a1

	move.l	#[64+7+8]-1,d7
f_t_p_t_l
	move.l	a0,(a1)+
	add.l	#[8*80],a0
	dbf	d7,f_t_p_t_l

	rts

	
move_track_bitplane
	lea	track_wait,a0
	lea	track_pos_tab,a1
	move.w	mt_patternpos,d0
	lsr.w	#4,d0

	add.w	d0,d0
	add.w	d0,d0

	move.w	(a1,d0.w),d1
	move.w	d1,6(a0)
	addq.w	#2,d0
	move.w	(a1,d0.w),d1
	move.w	d1,$a(a0)

	rts


store_original_sample_area
	lea	sample_info_buffer,a0
	lea	screen_picture+[162*80]+48,a1
	lea	$dff000,a6

	move.l	#32-1,d7
s_o_s_a_l
.waitblitter
	btst	#14,2(a6)
	btst	#14,2(a6)
	bne.s	.waitblitter

	move.l	a0,$54(a6)
	move.l	a1,$50(a6)
	move.l	#-1,$44(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00360000,$64(a6)
	move.w	#$05cd,$58(a6)

	lea	[23*26](a0),a0

	dbf	d7,s_o_s_a_l

	rts



fill_sample_info_buffer
	bsr.b	store_original_sample_area

	move.l	mt_data,a2
	lea	20(a2),a2
	lea	sample_info_buffer,a4

	moveq	#1,d7
f_s_i_b_l
	;blit_sample_name of number (d7)
	lea	4(a4),a5
	lea	(a2),a0
.loop
	move.b	(a0)+,d0
	tst.b	d0
	beq.s	.end_of_samplename
	lea	(a5),a1
	bsr.w	blit_char_II

	addq.l	#1,a5
	bra.s	.loop

.end_of_samplename
	moveq	#0,d1
	move.w	22(a2),d1		;get samplelength
	add.l	d1,d1
	lea	[13*26](a4),a5

;blit samplelength
	moveq	#5-1,d6
	move.l	#10000,d4
.loop2
	divu	d4,d1
	move.w	d1,d0
	add.b	#"0",d0
	lea	(a5),a1
	bsr.b	blit_char_II
	move.w	#0,d1
	swap	d1
	addq.l	#1,a5		
	divu	#10,d4
	dbf	d6,.loop2

;blit sample volume
	moveq	#0,d1
	move.b	25(a2),d1
	lea	[14+[13*26]](a4),a5
	
	move.w	d1,d0
	and.b	#$f0,d0
	lsr.w	#4,d0
	bsr.w	bits_to_char
	lea	(a5),a1
	bsr.b	blit_char_II

	addq.l	#1,a5
		
	move.w	d1,d0
	and.b	#$0f,d0
	bsr.w	bits_to_char
	lea	(a5),a1
	bsr.b	blit_char_II

;blit sample_number
	lea	[23+[13*26]](a4),a5
	move.l	d7,d0
	and.b	#$f0,d0
	lsr.b	#4,d0
	bsr.w	bits_to_char
	lea	(a5),a1
	bsr.b	blit_char_II

	addq.l	#1,a5

	move.l	d7,d0
	and.b	#$0f,d0
	bsr.w	bits_to_char
	lea	(a5),a1
	bsr.b	blit_char_II

	lea	30(a2),a2
	lea	[26*23](a4),a4
	addq.b	#1,d7
	cmp.b	#31,d7
	ble.w	f_s_i_b_l
	rts

	
;this blitter routine is used only by fill_sample_info_buffer
;this is done to prevent a modulo passing to the other blit_char
blit_char_II
	lea	$dff000,a6
	lea	char_tab,a3

	and.l	#$ff,d0
	sub.b	#32,d0
	lsl.w	#3,d0
	add.l	d0,a3

	move.w	#$0070,$9a(a6)		;prevent for a lev3 interrupt

.wait_blitter
	btst	#14,$02(a6)
	btst	#14,$02(a6)
	bne.s	.wait_blitter	

	move.l	a1,d2
	btst	#0,d2
	bne.s	b_c_II_dest_is_odd
b_c_II_dest_is_even
	move.w	6(a3),$40(a6)
	clr.w	$42(a6)
	bra.s	b_c_II_v
b_c_II_dest_is_odd
	subq.l	#1,a1
	move.w	4(a3),$40(a6)
	clr.w	$42(a6)
b_c_II_v			
	move.l	#$ff00ff00,$44(a6)
	move.l	(a3),$50(a6)
	move.l	a1,$48(a6)
	move.l	a1,$54(a6)		;this blitteroperation is unsplittable!
	move.l	#$00260018,$64(a6)
	move.w	#$0018,$60(a6)
	move.w	#$0201,$58(a6)  	

	move.w	#$8020,$9a(a6)		;set vbl enable. 

	rts


bits_to_char
	;d0 has to be number e [0..15]

	cmp.b	#10,d0
	blt.s	b_t_c_digit
	add.b	#55,d0
	rts

b_t_c_digit
	add.b	#48,d0
	rts	

	

;blits da 64 slotnumbers in the patternbitplane

blit_slotnos
	lea	tracks_bitplane+[7*8*80],a1
	moveq	#0,d7

b_s_l
	move.l	d7,d0

	addq.l	#1,a1
	divu.w	#10,d0
	move.l	d0,d3
	add.b	#48,d0

	bsr.b	blit_char

	addq.l	#2,a1
	swap	d3
	move.w	d3,d0
	add.b	#48,d0
	bsr.b	blit_char

	add.l	#[[80*8]-2],a1
	addq.b	#1,d7
	cmp.b	#64,d7
	blt.s	b_s_l
	rts
			
		
	

blit_char
	;d0 = char
	;a1 = destination	if a1 is odd, the character is placed in
				;the 8 bits folowing the even part of
				;the addres a1 is containing.
				;a1 is made even before dumped in blitter.
				;this is a fast solution to solve the 
				;problem with 8 bit wide fontblitting ...
				;this font is (sneaky) 16 bits for 1 8bit char
				;to prevent left shifting, (and nasty 
				;calculations..

	lea	$dff000,a6
	lea	char_tab,a3

	and.l	#$ff,d0
	sub.b	#32,d0
	lsl.w	#3,d0
	add.l	d0,a3

	move.w	#$0070,$9a(a6)		;prevent for a lev3 interrupt

.wait_blitter
	btst	#14,$02(a6)
	btst	#14,$02(a6)
	bne.s	.wait_blitter	

	move.l	a1,d2
	btst	#0,d2
	bne.s	b_c_dest_is_odd
b_c_dest_is_even
	move.w	6(a3),$40(a6)
	clr.w	$42(a6)
	bra.s	b_c_v
b_c_dest_is_odd
	subq.l	#1,a1
	move.w	4(a3),$40(a6)
	clr.w	$42(a6)
b_c_v			
	move.l	#$ff00ff00,$44(a6)
	move.l	(a3),$50(a6)
	move.l	a1,$48(a6)
	move.l	a1,$54(a6)		;this blitteroperation is unsplittable!
	move.l	#$0026004e,$64(a6)
	move.w	#$004e,$60(a6)
	move.w	#$0201,$58(a6)  	

	move.w	#$8020,$9a(a6)		;set vbl enable. 

	rts


blit_note
	;d0.l = note from pattern

	lea	notetab,a0
 	move.l	a4,a1			;use a4(is notedestination)
	lea	mt_periodtable,a2

	move.l	d0,d3
	move.l	d0,d4

	swap	d0
	and.l	#$0fff,d0

	moveq	#0,d1
search_period	
	move.w	(a2)+,d2
	cmp.w	d0,d2
	beq.s	b_n_v
	addq.w	#1,d1
	cmp.w	#36,d1
	blt.s	search_period

b_n_v
	add.w	d1,d1			
	add.w	d1,d1			

	add.l	d1,a0

	; blit note 
	
	moveq	#0,d0
	move.b	(a0)+,d0
	bsr.w	blit_char	
	add.l	d5,a1

	moveq	#0,d0
	move.b	(a0)+,d0
	bsr.w	blit_char	
	add.l	d6,a1

	moveq	#0,d0
	move.b	(a0)+,d0
	bsr.w	blit_char	

	;blit samplenr 

	moveq	#12,d2

	and.l	#$f000f000,d3	;get only the sample number.
	lsr.l	d2,d3

	swap	d3
	move.w	d3,d0
	bsr.w	bits_to_char

	add.l	d5,a1		;skip a space between samplenr and note.
	bsr.w	blit_char

	swap	d3
	move.w	d3,d0
	bsr.w	bits_to_char	;in d0 da bits, returns in d0 the asciicode

	add.l	d6,a1
	bsr.w	blit_char

	;blit effect command and command data

	and.l	#$0fff,d4	;to get only the effect command and the data
	
	move.l	d4,d0

	lsr.w	#8,d0
	bsr.w	bits_to_char

	add.l	d5,a1
	bsr.w	blit_char		

	move.l	d4,d0
	lsr.w	#4,d0
	and.b	#$0f,d0
	bsr.w	bits_to_char

	add.l	d6,a1
	bsr.w	blit_char

	move.l	d4,d0
	and.b	#$0f,d0
	bsr.w	bits_to_char

	add.l	d5,a1
	bsr.w	blit_char

	add.l	d6,a1
	move.l	#32,d0
	bsr.w	blit_char
	rts		


blit_row
	move.l	pattern_pos,a5	;patternpos is slotpointer. (no trackpointer)
	move.l	note_dest,a4
	moveq	#1,d5		;skip a1 on odd addies	
	moveq	#2,d6		;skip a1 on even$addies

	move.l	a4,a1

	move.l	(a5),d0
	bsr.w	blit_note
	add.l	#9,a4
	
	exg	d5,d6

	move.l	4(a5),d0
	bsr.w	blit_note
	add.l	#9,a4

	exg	d5,d6
		
	move.l	8(a5),d0
	bsr.w	blit_note
	add.l	#9,a4

	exg	d5,d6

	move.l	12(a5),d0
	bsr.w	blit_note

	add.l	#[8*80],note_dest	;next pos in bitplane
	rts


blit_pattern
	moveq	#0,d1
	lea	track_pos_tab,a0
	move.w	blit_note_slot_teller,d1

	cmp.w	#64,d1

	bge.b	b_p_e	

	;calc note_destination
	add.w	d1,d1
	add.w	d1,d1

	add.w	#[7*4],d1
	move.l	(a0,d1.w),a1

	add.l	#4,a1
	move.l	a1,note_dest

	moveq	#0,d0
	move.b	pattern_pointer,d0

	moveq	#10,d2
	lsl 	d2,d0		;d0 * 1024	(pattern is 1K long.)

	add.l	#1084,d0	
	add.l	mt_data,d0
	sub.w	#[7*4],d1

	add.w	d1,d1
	add.w	d1,d1
	add.l	d1,d0

	move.l	d0,pattern_pos	;start pattern.

	bsr.w	blit_row

	add.w	#1,blit_note_slot_teller

b_p_e
	rts



clear_area
	;a0=destination address
	;d0=bltsize
	;d1=mask
	;d2=modulo a & d
	;d3=modulo c

	move.w	#$0070,$9a(a6)		;prevent for a lev3 interrupt

c_a_wait_blitter
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	c_a_wait_blitter

	move.l	#clear_block,$50(a6)
	move.l	d1,$44(a6)		;this blit is unsplittable!!!!
	move.l	a0,$48(a6)
	move.l	a0,$54(a6)
	move.l	#$0ba00000,$40(a6)
	move.l	d2,$64(a6)
	move.w	d3,$60(a6)
	move.w	d0,$58(a6)

	move.w	#$8020,$9a(a6)		;set vbl enable

	rts



blit_play_time
	move.b	#0,new_time

	;blit hours
	moveq	#0,d1
	move.b	hours,d1

	divu	#10,d1
	moveq	#0,d0
	move.b	d1,d0

	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+53,a1
	bsr.w	blit_char

	swap	d1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+54,a1

	bsr.w	blit_char

	;blit ':'

	moveq	#0,d0
	move.b	#":",d0
	lea	screen_picture+[3*80*200]+[111*80]+55,a1

	bsr.w	blit_char

	;blit_minutes
	
	moveq	#0,d1
	move.b	minutes,d1

	divu	#10,d1
	moveq	#0,d0
	move.b	d1,d0

	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+56,a1
	bsr.w	blit_char

	swap	d1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+57,a1

	bsr.w	blit_char

	;blit '.'

	moveq	#0,d0
	move.b	#".",d0
	lea	screen_picture+[3*80*200]+[111*80]+58,a1

	bsr.w	blit_char

	moveq	#0,d1
	move.b	seconds,d1

	divu	#10,d1
	moveq	#0,d0
	move.b	d1,d0

	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+59,a1
	bsr.w	blit_char

	swap	d1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	lea	screen_picture+[3*80*200]+[111*80]+60,a1

	bsr.w	blit_char

	rts


blit_pattern_no
	lea	$dff000,a6

	move.l	#$000000ff,d1
	lea	screen_picture+[13*80]+4,a0
	move.l	#$0000004c,d2
	move.w	#$004c,d3
	move.w	#$0202,d0
	
	bsr.w	clear_area

	moveq	#0,d1
	move.b	pattern_pointer,d1

	cmp.b	#10,d1
	blt.b	b_p_n_only_tens

	divu	#10,d1

	lea	screen_picture+[13*80]+4+1,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char
	swap	d1

b_p_n_only_tens	
	lea	screen_picture+[13*80]+4+2,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char

	rts


blit_song_name:
	move.l	mt_data,a0
	lea	screen_picture+[3*80*200]+[123*80]+50,a1
	moveq	#1,d5
	moveq	#2,d6

	moveq	#20-1,d7
b_sng_n_l
	moveq	#0,d0
	move.b	(a0)+,d0
	tst.b	d0
	beq.s	b_sng_n_v

	bsr.w	blit_char
	add.l	d5,a1
	exg	d5,d6
	dbf	d7,b_sng_n_l

b_sng_n_v
	rts	


blit_song_length
	lea	$dff000,a6

	move.l	#$000000ff,d1
	lea	screen_picture+[3*80*200]+[135*80]+48,a0
	move.l	#$0000004c,d2
	move.w	#$004c,d3
	move.w	#$0202,d0

	bsr.w	clear_area	

	move.l	mt_data,a6
	moveq	#0,d1
	move.b	950(a6),d1	

	lea	$dff000,a6

	cmp.b	#10,d1
	blt.s	b_sng_l_only_tens
	cmp.b	#100,d1
	blt.s	b_sng_l_under_hundred

	divu	#100,d1
	
	lea	screen_picture+[3*80*200]+[135*80]+48,a1
	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	bsr.w	blit_char

	move.w	#0,d1
	swap 	d1
	
b_sng_l_under_hundred
	divu	#10,d1

	lea	screen_picture+[3*80*200]+[135*80]+48+1,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char
	swap	d1

b_sng_l_only_tens	
	lea	screen_picture+[3*80*200]+[135*80]+48+2,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char

	rts



blit_song_pos
	lea	$dff000,a6

	moveq	#0,d1
	lea	screen_picture+[3*80*200]+[135*80]+56,a0
	move.l	#$0000004e,d2
	move.w	#$004e,d3
	move.w	#$0201,d0

	bsr.w	clear_area

	moveq	#0,d1
	move.b	mt_SongPos,d1
	cmp.b	#10,d1
	blt.b	b_s_p_only_tens
	cmp.b	#100,d1
	blt.s	b_s_p_under_hundred

	divu	#100,d1
	
	lea	screen_picture+[3*80*200]+[135*80]+56,a1
	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	bsr.w	blit_char

	move.w	#0,d1
	swap 	d1
	
b_s_p_under_hundred

	divu	#10,d1

	lea	screen_picture+[3*80*200]+[135*80]+56+1,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char
	swap	d1

b_s_p_only_tens	
	lea	screen_picture+[3*80*200]+[135*80]+56+2,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char

	rts



blit_vbl_tempo
	lea	$dff000,a6

	moveq	#0,d1
	lea	screen_picture+[3*80*200]+[135*80]+68,a0
	move.l	#$0000004e,d2
	move.w	#$004e,d3
	move.w	#$0201,d0

	bsr.w	clear_area

	moveq	#0,d1
	move.b	mt_speed,d1

	cmp.b	#10,d1
	blt.b	b_vbl_t_only_tens

	divu	#10,d1

	lea	screen_picture+[3*80*200]+[135*80]+68,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char
	swap	d1

b_vbl_t_only_tens	
	lea	screen_picture+[3*80*200]+[135*80]+68+1,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char

	rts



blit_bpm
	lea	$dff000,a6

	move.l	#$000000ff,d1
	lea	screen_picture+[3*200*80]+[135*80]+76,a0
	move.l	#$0000004c,d2
	move.w	#$004c,d3
	move.w	#$0202,d0

	bsr.w	clear_area

	moveq	#0,d1
	move.w	RealTempo,d1

	cmp.w	#10,d1
	blt.b	b_bpm_only_tens
	cmp.w	#100,d1
	blt.s	b_bpm_under_hundred

	divu	#100,d1
	
	lea	screen_picture+[3*80*200]+[135*80]+76,a1
	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0
	bsr.w	blit_char

	move.w	#0,d1
	swap 	d1
	
b_bpm_under_hundred

	divu	#10,d1

	lea	screen_picture+[3*80*200]+[135*80]+76+1,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char
	swap	d1

b_bpm_only_tens	
	lea	screen_picture+[3*80*200]+[135*80]+76+2,a1

	moveq	#0,d0
	move.b	d1,d0
	add.b	#"0",d0

	bsr.w	blit_char

	rts

copy_scopes_bitplane_to_buffers
	lea	screen_picture+[[24+120]*80],a0
	lea	second_buf_scopes,a1
	lea	third_buf_scopes,a2
	lea	$dff000,a6

.wait
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait

	;blit to second buffer

	move.l	a0,$50(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00000000,$64(a6)
	move.l	a1,$54(a6)
	move.l	#-1,$44(a6)

	move.w	#$1068,$58(a6)


.wait2
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait2

	;blit to third buffer

	move.l	a0,$50(a6)
	move.l	#$09f00000,$40(a6)
	move.l	#$00000000,$64(a6)
	move.l	a2,$54(a6)
	move.l	#-1,$44(a6)

	move.w	#$1068,$58(a6)

	rts



clear_scope_area
	lea	$dff000,a6

c_s_a_wb_l
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	c_s_a_wb_l

	move.l	#$01000000,$40(a6)
	move.w	#$2c,$66(a6)
	move.l	scopes_clear_buffer,d0
	add.l	#[16*80]+4,d0
	move.l	d0,$54(a6)
	move.w	#$0812,$58(a6)
	rts

plot_scopes
	;check for pal or NTWC, now only PAL...
	;PAL has 318 lines in a frame, NTSC 262.
	;this means that there are 318 words read in a frame. NTSC
	;audio hardware reads 262 words in a frame.

	;after that, the number of sample bytes per frame is calculated
	;no of bytes per frame = (clockconstant/50)/periode)

	lea	plot_table,a0
	move.l	scopes_build_buffer,a6
	add.l	#[15*80],a6

	tst.b	pal_ntsc
	bne.s	p_s_ntsc

p_s_pal
	lea	[3546895/50],a5	;clockconstante /50
	bra.s	p_s_verder

p_s_ntsc
	lea	[3579545/60],a5	;clockconstante /60

p_s_verder
	lea	mt_chan1temp,a1
	move.w	n_replen(a1),chan1_replen
	move.l	n_loopstart(a1),chan1_loopstart
	move.w	n_length(a1),chan1_length
	move.l	n_start(a1),chan1_start
	move.w	n_period(a1),chan1_period
	move.b	n_volume(a1),chan1_volume

	lea	mt_chan2temp,a1
	move.w	n_replen(a1),chan2_replen
	move.l	n_loopstart(a1),chan2_loopstart
	move.w	n_length(a1),chan2_length
	move.l	n_start(a1),chan2_start
	move.w	n_period(a1),chan2_period
	move.b	n_volume(a1),chan2_volume
	

	lea	mt_chan3temp,a1
	move.w	n_replen(a1),chan3_replen
	move.l	n_loopstart(a1),chan3_loopstart
	move.w	n_length(a1),chan3_length
	move.l	n_start(a1),chan3_start
	move.w	n_period(a1),chan3_period
	move.b	n_volume(a1),chan3_volume

	lea	mt_chan4temp,a1
	move.w	n_replen(a1),chan4_replen
	move.l	n_loopstart(a1),chan4_loopstart
	move.w	n_length(a1),chan4_length
	move.l	n_start(a1),chan4_start
	move.w	n_period(a1),chan4_period
	move.b	n_volume(a1),chan4_volume

;scope1	
	lea	chan1_start,a1
	move.l	#32,d5
	lea	sample_chan1_pointer,a4
	move.l	a5,d0
	bsr.b	plot_a_scope
;scope2	
	lea	chan2_start,a1
	move.l	#104,d5
	lea	sample_chan2_pointer,a4
	move.l	a5,d0
	bsr.b	plot_a_scope
;scope3	
	lea	chan3_start,a1
	move.l	#176,d5
	lea	sample_chan3_pointer,a4
	move.l	a5,d0
	bsr.b	plot_a_scope
;scope4	
	lea	chan4_start,a1
	move.l	#248,d5
	lea	sample_chan4_pointer,a4
	move.l	a5,d0
	bsr.b	plot_a_scope

	rts


plot_a_scope
	;a1 = pointer to tempstructure
	;d5=start x xcoordinate
	;a0=plottab	
	;a4=sample_chanx_pointer

	moveq	#0,d1
	move.w	12(a1),d1	;get period

	tst.w	d1
	bne.s	sc_period

	moveq	#0,d2
	bra.s	sc_v

sc_period	
	move.l	d0,d2
	divu 	d1,d2			;calc number of bytes per frame
	bclr	#0,d2			;even no of bytes!
	and.l	#$ffff,d2

sc_v
	cmp.w	#1,10(a1)
	bgt.s	scope_loop

	;plot the sample

	move.l	(a4),d3			;get hardware position in sample
	
	move.l	d3,a2

	add.l	d2,d3	
	move.l	d3,(a4)

	moveq	#0,d7
	move.l	0(a1),d4	;start
	move.w	4(a1),d7
	add.w	d7,d7
	add.l	d7,d4		;add length

	move.l	#64-1,d7

	moveq	#0,d6
	move.b	14(a1),d6	;get volume
	
sc_p_l
	moveq	#0,d0
	move.b	(a2)+,d0
	cmp.l	d4,a2
	bge.s	sc_p_l0

	ext.w	d0
	muls	d6,d0
	asr.w	#6,d0
	bra.s	sc_p_l_n0

sc_p_l0
	moveq	#0,d0
sc_p_l_n0
	add.w	#128,d0
	add.w	d0,d0

	moveq	#0,d1
	
	move.w	(a0,d0.w),d1
	move.l	a6,a3
	add.l	d1,a3	

	move.l	d5,d0
	lsr.w	#3,d0
	
	move.l	d5,d1
	and.l	#$07,d1
	eor.b	#7,d1

	bset	d1,(a3,d0.w)
	addq.l	#1,d5

	dbf	d7,sc_p_l	
	rts


scope_loop
	;plot the sample

	move.l	(a4),d3			;get hardware position in sample
	move.l	6(a1),d1	;loopstart

	moveq	#0,d4
	move.w	10(a1),d4
	lsl.w	#1,d4
	add.l	d4,d1		;replen

	add.l	d2,d3	
	move.l	d3,a2

	cmp.l	d1,d3
	ble.s	l_sc_no_loop_restart

	sub.l	d1,d3
	
	moveq	#0,d4
	move.w	10(a1),d4

	add.w	d4,d4
	divu	d4,d3
	move.w	#0,d3
	swap	d3
	add.l	6(a1),d3	;loopstart

	move.l	d3,a2
l_sc_no_loop_restart
	move.l	d3,(a4)

	move.l	#64-1,d7

	moveq	#0,d6
	move.b	14(a1),d6
		
l_sc_p_l
	moveq	#0,d0
	move.b	(a2)+,d0
	cmp.l	d1,a2
	bge.s	l_sc_p_l_rs

	ext.w	d0
	muls	d6,d0
	asr.w	#6,d0
	bra.s	l_sc_p_l_nrs
	
l_sc_p_l_rs
	move.l	6(a1),a2	;loopstart
	move.b	(a2)+,d0
	ext.w	d0
	muls	d6,d0
	asr.w	#6,d0
			
l_sc_p_l_nrs
	add.w	#128,d0
	add.w	d0,d0

	moveq	#0,d2

	move.w	(a0,d0.w),d2

	move.l	a6,a3
	add.l	d2,a3

	move.l	d5,d0
	lsr.w	#3,d0
	
	move.l	d5,d2
	and.l	#$07,d2
	eor.b	#7,d2

	bset	d2,(a3,d0.w)
	addq.l	#1,d5

	dbf	d7,l_sc_p_l	

	rts


swap_scopes_screen
	move.l	scopes_show_buffer,d0
	move.l	scopes_clear_buffer,d1
	move.l	scopes_build_buffer,d2

	move.l	d2,scopes_show_buffer
	move.l	d1,scopes_build_buffer
	move.l	d0,scopes_clear_buffer

	move.l	scope_screen,a0
	swap	d2
	move.w	d2,2(a0)
	swap	d2
	move.w	d2,6(a0)

	rts


move_vu_meters
	;chan1
	tst.w	mt_chan1temp
	beq.s	move_down_chan1
chan1_up	
	move.w	#0,mt_chan1temp
	moveq	#0,d0
	move.b	chan1_volume,d0
	lsl.w	#7,d0
	move.b	#0,d0
	move.w	#$b84e,d1
	sub.w	d0,d1
	move.w	d1,vu1_xy
	move.w	#$b900,vu1_stop
	bra.s	chan2_up

move_down_chan1
	moveq	#0,d0
	move.w	vu1_xy,d0
	add.w	#$0100,d0
	cmp.l	#$b84e,d0
	ble.s	.vu1skip	
	move.w	#$b84e,d0
.vu1skip
	move.w	d0,vu1_xy

	;chan2
chan2_up
	tst.w	mt_chan2temp
	beq.s	move_down_chan2
	move.w	#0,mt_chan2temp
	moveq	#0,d0
	move.b	chan2_volume,d0
	lsl.w	#7,d0
	move.b	#0,d0
	move.w	#$b860,d1
	sub.w	d0,d1
	move.w	d1,vu2_xy
	move.w	#$b900,vu2_stop
	bra.s	chan3_up

move_down_chan2
	moveq	#0,d0
	move.w	vu2_xy,d0
	add.w	#$0100,d0
	cmp.l	#$b860,d0
	ble.s	.vu2skip	

	move.w	#$b860,d0
.vu2skip
	move.w	d0,vu2_xy

	;chan3
chan3_up
	tst.w	mt_chan3temp
	beq.s	move_down_chan3
	move.w	#0,mt_chan3temp
	moveq	#0,d0
	move.b	chan3_volume,d0
	lsl.w	#7,d0
	move.b	#0,d0
	move.w	#$b872,d1
	sub.w	d0,d1
	move.w	d1,vu3_xy
	move.w	#$b900,vu3_stop
	bra.s	chan4_up

move_down_chan3
	moveq	#0,d0
	move.w	vu3_xy,d0
	add.w	#$0100,d0
	cmp.l	#$b872,d0
	ble.s	.vu3skip	

	move.w	#$b872,d0
.vu3skip
	move.w	d0,vu3_xy


	;chan4
chan4_up
	tst.w	mt_chan4temp
	beq.s	move_down_chan4
	move.w	#0,mt_chan4temp
	moveq	#0,d0
	move.b	chan4_volume,d0
	lsl.w	#7,d0
	move.b	#0,d0
	move.w	#$b884,d1
	sub.w	d0,d1
	move.w	d1,vu4_xy
	move.w	#$b900,vu4_stop
	bra.s	m_v_m_end
	
move_down_chan4
	moveq	#0,d0
	move.w	vu4_xy,d0
	add.w	#$0100,d0
	cmp.l	#$b884,d0
	ble.s	.vu4skip	

	move.w	#$b884,d0
.vu4skip
	move.w	d0,vu4_xy

m_v_m_end
	rts
	

move_pointer
	moveq	#0,d1
	moveq	#0,d2
	moveq	#0,d3
	move.w	$dff00a,d0
	move.b	last_pulses_x,d1
	move.b	last_pulses_y,d2
	move.w	d0,d3

	move.b	d3,last_pulses_x
	lsr.w	#8,d3
	move.b	d3,last_pulses_y

	;d3 contains the current Y pulse count

m_p_check_x
	sub.b	d1,d0	;calculate speed in x direction
	tst.b	d0
	blt.s	m_p_x_left

m_p_x_right
	and.w	#$00ff,d0
	move.w	x_coordinate,d4
	move.w	d4,x_coordinate_old
	add.w	d0,d4
	cmp.w	#319,d4
	ble.s	.put_coordinate
	move.w	#319,d4
.put_coordinate
	move.w	d4,x_coordinate

	bra.s	m_p_check_y		
	
m_p_x_left
	;d0.b is negative
	
	and.w	#$00ff,d0
	move.w	x_coordinate,d4
	move.w	d4,x_coordinate_old
	neg.b	d0
	sub.w	d0,d4
	tst.w	d4
	bge.s	.put_coordinate
	moveq	#0,d4
.put_coordinate
	move.w	d4,x_coordinate

m_p_check_y
	sub.b	d2,d3	;calculate speed in x direction
	tst.b	d3
	blt.s	m_p_y_up

m_p_y_down
	and.w	#$00ff,d3
	move.w	y_coordinate,d5
	move.w	d5,y_coordinate_old
	add.w	d3,d5
	cmp.w	#199,d5
	ble.s	.put_coordinate
	move.w	#199,d5
.put_coordinate
	move.w	d5,y_coordinate

	bra.s	update_sprite_struct		
	
m_p_y_up
	and.w	#$00ff,d3
	move.w	y_coordinate,d5
	move.w	d5,y_coordinate_old
	neg.b	d3
	sub.w	d3,d5
	tst.w	d5
	bge.s	.put_coordinate
	moveq	#0,d5
.put_coordinate
	move.w	d5,y_coordinate


update_sprite_struct
	;highbits of vstart and vstop are always 0 (range y = e[0-200])
	
	move.w	#$0080,d0
	add.w	x_coordinate,d0
	move.w	d0,d1
	and.w	#1,d1
	lsr.w	#1,d0
	move.w	#$0029,d2
	add.w	y_coordinate,d2
	lsl.w	#8,d2
	add.w	d0,d2		;d2=sprxpos (sprite control word 1)

	move.w	d2,d0
	and.w	#$ff00,d0
	add.w	d0,d1
	add.w	#$0600,d1	;calc vstop
	and.w	#$ff01,d1	;clear unused bits

	move.w	d1,pointer_stop
	move.w	d2,pointer_xy	
	rts



;the following routine is called when a mousebutton is pressed.
;this routine compares the current mousepointer coordinates with all the
;known buttons. if there is a button that is pressed, the ID of the button
;is returned (in d0) and the address of the structure in a0
;when there is no button pressed, thus an unkown area, 0 is returned in d0
;a0 is then not valid.
;after this routine a jumptable is used to blit the buttons.

check_which_button
	lea	button_structures,a0
	move.w	x_coordinate,d1
	move.w	y_coordinate,d2

	add.w	d1,d1

	moveq	#11-1,d7
c_w_b_l
	move.w	(a0),d0
	move.w	2(a0),d3
	move.w	4(a0),d4
	cmp.w	d3,d1
	blt.s	.skip
	cmp.w	d4,d1
	bge.s	.skip
	move.w	6(a0),d3
	move.w	8(a0),d4
	cmp.w	d3,d2
	blt.s	.skip
	cmp.w	d4,d2
	bge.s	.skip
	bra.s	c_w_b_found
.skip
	lea	18(a0),a0
	dbf	d7,c_w_b_l	

	;not found => 0 in d0
	moveq	#0,d0
c_w_b_found
	rts	


;a0 is pointing to text_structure
allocate_text_bitmap_space
	moveq	#0,d0
	move.w	8(a0),d0
	move.l	a0,-(sp)
	mulu	#80*8,d0	;#lines * 80 * 9 is # of bytes
	move.l	$4.w,a6
	move.l	#MEMF_CHIP,d1		;chipmem
	jsr	-198(a6)	;allocate memory
	move.l	(sp)+,a0
	move.l	d0,4(a0)
	rts


;a0 is pointing to text_structure
free_memory
	move.l	4(a0),d0
	cmp.l	#dummy_bitplane,d0
	beq.s	.end
	moveq	#0,d0
	move.w	8(a0),d0
	mulu	#8*80,d0
	move.l	$4.w,a6
	move.l	4(a0),a1
	jsr	-210(a6)
.end
	rts


;a0 is pointer to textstruct
clear_bitplane
	lea	$dff000,a6
	move.l	4(a0),d6

	moveq	#0,d0
	move.w	8(a0),d0
	lsl.l	#3,d0		;mulu 8 is no of lines to clear

	;check if we can clear it all in 1 blit

	divu 	#1024,d0	;to get the number of times to do a 1024
				;line blit (huge!!!:)

	tst.w	d0
	beq.s	c_b_not_max_blit		
c_b_max_blit
	moveq	#0,d7
	move.w	d0,d7
	subq	#1,d7
c_b_m_b_l	
	move.w	#40,d0
.wait_blitter
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter

	move.l	d6,$54(a6)
	move.l	#$01000000,$40(a6)
	move.w	#$0000,$66(a6)
	move.l	#-1,$44(a6)
	move.w	d0,$58(a6)
	add.l	#1024*80,d6

	dbf	d7,c_b_m_b_l
	
c_b_not_max_blit
	swap	d0
	lsl.w	#6,d0
	add.w	#40,d0
.wait_blitter
	btst	#14,$2(a6)
	btst	#14,$2(a6)
	bne.s	.wait_blitter

	move.l	d6,$54(a6)
	move.l	#$01000000,$40(a6)
	move.w	#$0000,$66(a6)
	move.l	#$ffffffff,$44(a6)
	move.w	d0,$58(a6)
	rts


;a0 is pointer to text structure
insert_empty_space
	lea	no_mem_text_struct,a3	;insert text 'not enuff chipmemory'
	move.l	(a3),(a0)
	move.l	4(a3),4(a0)
	move.w	8(a3),8(a0)
	move.w	10(a3),10(a0)
	rts


;a0=pointer to text_structure
blit_text
	move.l	(a0),a4
	move.l	a4,a2
	move.l	4(a0),a1	;get bitplane pointer
	add.l	#40,a1
	move.l	a1,a5
	moveq	#0,d3
	move.w	10(a0),d3
	add.l	d3,a2
	moveq	#0,d3		;x counter
	move.b	#" ",d0
	move.l	a5,a1
	bsr	blit_char	;blit a space to prevent nasty bars...
b_t_loop
	move.b	(a4)+,d0
	cmp.l	a2,a4
	bgt.s	b_t_end
	addq	#1,d3
	cmp.b	#10,d0
	bne.s	.no_cr
	moveq	#0,d3
	add.l	#8*80,a5
	move.l	#" ",d0
	move.l	a5,a1
	bsr	blit_char
	bra.s	b_t_loop
.no_cr
	cmp.b	#36,d3
	ble.s	.not_end_of_line
	add.l	#8*80,a5
	moveq	#0,d3
	move.b	d0,d4
	move.l	#" ",d0
	move.l	a5,a1
	bsr	blit_char	;blit a space to prevent nasty bars ;-)
	move.b	d4,d0
	addq	#1,d3
	move.l	a5,a1
	add.l	d3,a1
	bsr	blit_char
	bra.s	b_t_loop
.not_end_of_line
	move.l	a5,a1
	add.l	d3,a1
	bsr	blit_char
	bra.s	b_t_loop
b_t_end
	rts


;a0 is pointing to the text_structure that has to be examined
get_number_of_lines
	move.l	(a0),a1
	move.l	a1,a2
	moveq	#0,d0
	move.w	10(a0),d0
	add.l	d0,a2
	moveq	#0,d0		;x counter
	moveq	#0,d1		;line counter
g_n_o_l_loop
	move.b	(a1)+,d7
	cmp.l	a2,a1
	bgt.s	g_n_o_l_end
	addq	#1,d0
	cmp.b	#10,d7
	bne.s	.no_cr
	addq	#1,d1
	moveq	#0,d0
	bra.s	g_n_o_l_loop

.no_cr
	cmp.b	#36,d0
	ble.s	.not_end_of_line
	moveq	#0,d0
	addq	#1,d1
.not_end_of_line
	bra.s	g_n_o_l_loop

g_n_o_l_end
	cmp.w	#10,d1
	bgt.s	.greater_10
	moveq	#10,d1
.greater_10	
	move.w	d1,8(a0)
	rts


;a0 is pointer to text_structure
show_text_in_window
	move.w	#0,actual_line
	move.l	a0,actual_text

	move.l	4(a0),d0
	move.w	d0,bpl_4+6
	swap	d0
	move.w	d0,bpl_4+2
	move.l	12(a0),a1
	move.w	#0,8(a1)
	moveq	#24,d0
	move.w	d0,scrollbar+6
	add.w	4(a1),d0
	move.w	d0,scrollbar+8
	bsr	update_scrollbar_sprite
	
	move.l	(a1),d0
	lea	c_scrollbar,a0
	move.w	d0,6(a0)
	swap	d0
	move.w	d0,2(a0)
	rts


;used by routine that handles the arrow down event
move_text_up
	move.l	actual_text,a0
	moveq	#0,d0
	move.w	actual_line,d0
	move.w	8(a0),d1
	move.w	d0,d2
	add.w	#10,d2
	cmp.w	d1,d2
	bge.s	.end		;no more lines to show

	addq.w	#1,d0
	move.w	d0,actual_line
	mulu	#80*8,d0
	move.l	4(a0),d1
	add.l	d0,d1
	move.l	d1,d0
	move.w	d0,bpl_4+6
	swap	d0
	move.w	d0,bpl_4+2

	move.l	12(a0),a1
	move.w	6(a1),d6	;update_scrollteller
	add.w	d6,8(a1)
	
	move.w	8(a1),d6
	lsr.w	#8,d6		;get scroll counter y
	add.w	#24,d6
	move.w	d6,scrollbar+6
	add.w	4(a1),d6
	move.w	d6,scrollbar+8

	bsr	update_scrollbar_sprite
.end
	rts




move_text_down
	move.l	actual_text,a0
	moveq	#0,d0
	move.w	actual_line,d0
	tst.w	d0
	beq.s	.end

	subq.w	#1,d0
	move.w	d0,actual_line
	move.l	4(a0),d1
	mulu	#8*80,d0
	add.l	d0,d1
	move.l	d1,d0
	move.w	d0,bpl_4+6
	swap	d0
	move.w	d0,bpl_4+2
	
	move.l	12(a0),a1
	move.w	6(a1),d6
	sub.w	d6,8(a1)

	move.w	8(a1),d6
	lsr.w	#8,d6		;get scroll counter y
	add.w	#24,d6
	move.w	d6,scrollbar+6
	add.w	4(a1),d6
	move.w	d6,scrollbar+8

	bsr	update_scrollbar_sprite
.end	
	rts	


;used by move_scrollbar
move_text_up_2
	move.l	actual_text,a0
	moveq	#0,d0
	move.w	actual_line,d0
	move.w	8(a0),d1
	move.w	d0,d2
	add.w	#10,d2
	cmp.w	d1,d2
	bge.s	.end		;no more lines to show

	move.w	6(a1),d6	;update_scrollteller
	add.w	d6,8(a1)

	addq.w	#1,d0
	move.w	d0,actual_line
	mulu	#80*8,d0
	move.l	4(a0),d1
	add.l	d0,d1
	move.l	d1,d0
	move.w	d0,bpl_4+6
	swap	d0
	move.w	d0,bpl_4+2
.end
	rts


;used by move_scrollbar
move_text_down_2
	move.l	actual_text,a0
	moveq	#0,d0
	move.w	actual_line,d0
	tst.w	d0
	beq.s	.end

	move.w	6(a1),d6
	sub.w	d6,8(a1)

	subq.w	#1,d0
	move.w	d0,actual_line
	move.l	4(a0),d1
	mulu	#8*80,d0
	add.l	d0,d1
	move.l	d1,d0
	move.w	d0,bpl_4+6
	swap	d0
	move.w	d0,bpl_4+2
.end	
	rts	


;a1 is pointing to sprite_struct (NOT sprite DATA!!!!!)
update_scrollbar_sprite
	move.w	scrollbar+6,d0
	move.w	scrollbar+8,d1
	move.l	(a1),a2
	move.w	(a2),d2
	and.w	#$00ff,d2
	add.w	#$29,d0
	lsl.w	#8,d0
	add.w	d0,d2
	move.w	d2,(a2)
	move.w	2(a2),d2
	add.w	#$29,d1
	and.w	#$00ff,d2
	lsl.w	#8,d1
	add.w	d1,d2
	move.w	d2,2(a2)
	rts



;a0 is pointer to text_structure
calc_scrollbar_info
	moveq	#0,d0
	move.w	8(a0),d0
	cmp	#10,d0
	bgt.s	.greater_10
	moveq	#10,d0
.greater_10	
	move.l	12(a0),a1
	move.l	#600,d1
	divu	d0,d1		;(60*10)/#lines in text = size of bar
	tst.w	d1
	bne.s	.not_null
	move.w	#3,d1		;minimal 3 lines in scrollbar
.not_null	
	move.w	d1,4(a1)	;store length in lines
	move.l	#60,d2
	sub.w	d1,d2
	sub.w	#10,d0
	lsl.w	#8,d2
	tst.w	d0
	beq.s	.stay
	divu	d0,d2		;(60-size)/(#lines - 10) * 2^8 = scrolloffset
.stay
	move.w	d2,6(a1)
	move.w	#0,8(a1)
	rts


;a0=pointer to text_structure
generate_scrollbar_sprite
	move.l	12(a0),a1
	move.l	(a1),a2
	addq.l	#4,a2
	moveq	#0,d7
	move.w	4(a1),d7
	subq	#3,d7
	move.w	#$f000,(a2)+
	move.w	#$1000,(a2)+
.loop
	move.w	#$9000,(a2)+
	move.w	#$7000,(a2)+
	dbf	d7,.loop
	move.w	#$8000,(a2)+
	move.w	#$7000,(a2)+
	
	move.l	(a1),a2
	move.w	#[$2900+$18dc],(a2)+
	move.w	#[$2900+$1801],d4
	move.w	4(a1),d0
	lsl.w	#8,d0
	add.w	d0,d4
	move.w	d4,(a2)
	rts


move_scrollbar
	move.l	actual_text,a0
	move.l	12(a0),a1
	tst.w	6(a1)			;check if scrollbar CAN be moved
	beq.w	m_s_end
	move.w	y_coordinate,d0
	move.w	y_coordinate_old,d1
	cmp.w	d1,d0
	beq.w	m_s_end
	blt.s	m_s_up

m_s_down
	sub.w	d1,d0		;get amount of scrolled screenlines
	move.w	scrollbar+6,d2	
	move.w	scrollbar+8,d3	;get y coordinate of underside of bar
	add.w	d0,d3
	cmp.w	#83,d3	
	ble.s	m_s_not_end
	move.w	#84,d3
	move.w	d3,d2
	sub.w	4(a1),d2
	bra.s	m_s_v1
m_s_not_end
	add.w	d0,d2
m_s_v1
	move.w	d2,scrollbar+6
	move.w	d3,scrollbar+8
	move.w	#24,d0
	add.w	4(a1),d0
	sub.w	d0,d3

	move.w	8(a1),d4
	lsr.w	#8,d4
	cmp.w	d3,d4
	bgt.s	m_s_no_scroll
	;scroll text x lines up
	sub.w	d4,d3
	move.w	6(a1),d5
	lsl.w	#8,d3
.loop
	bsr	move_text_up_2
	sub.w	d5,d3
	cmp.w	d5,d3
	bge.s	.loop
	bra.s	m_s_no_scroll

m_s_up
	sub.w	d0,d1		;get amount of scrolled screenlines
	move.w	scrollbar+6,d2	
	move.w	scrollbar+8,d3	;get y coordinate of underside of bar
	sub.w	d1,d2
	cmp.w	#25,d2	
	bge.s	m_s_not_start
	move.w	#24,d2
	move.w	d2,d3
	add.w	4(a1),d3
	bra.s	m_s_v2
m_s_not_start
	sub.w	d1,d3
m_s_v2
	move.w	d2,scrollbar+6
	move.w	d3,scrollbar+8
	move.w	#24,d0
	add.w	4(a1),d0
	sub.w	d0,d3

	move.w	8(a1),d4
	lsr.w	#8,d4
	cmp.w	d3,d4
	blt.s	m_s_no_scroll
	;scroll text x lines down
	sub.w	d3,d4
	move.w	6(a1),d5
	lsl.w	#8,d4
.loop
	bsr	move_text_down_2
	sub.w	d5,d4
	cmp.w	d5,d4
	bge.s	.loop

m_s_no_scroll
	bsr	update_scrollbar_sprite
m_s_end
	rts


dummy_routine
	rts


kill_disk_motor
	;we don't know which drive is on, so kill all.
	lea	$bfd100,a6
	moveq	#3,d0
	moveq	#4-1,d7
.loop	
	move.b	#$fd,(a6)
	nop
	bclr	d0,(a6)
	nop
	bset	d0,(a6)
	addq	#1,d0
	dbf	d7,.loop
	rts


;************ tables *********************

	SECTION tables,BSS


char_tab	ds.b	128*2*4	;1l: addy to char in font
				;2w: bltcon 0  if destination is 8 bit range
				;3w: bltcon 0  if destination is 16 bit range

track_pos_tab	ds.b	2*[2*[64+7+8]]
				;this table is used for putting fast
				;the track bitplane address in the copperlist
				;in contains 64 longwords whitch are the 
				;addresses of the 64 lines....

			
clean_block	ds.b	256




;*************** variables ******************

	SECTION variables,data

				;table used for fast plotting the scopes.
				;in this table are the offsets for the
				;256 possible values of a samplebyte.
				;scopes are 32 lines high so every line is 
				;mentioned in the table 8 times...
				;(saves a divu operation (or shift))

plot_table
tempvar set 32*80
	rept 32
	 blk.w 8,tempvar
tempvar set tempvar-80
	endr

	rept 32
	 blk.w 8,tempvar
tempvar set tempvar+80
	endr


mt_data		dc.l	0
tune_length	dc.l	0		

argv		dc.l	0
argv_length	dc.l	0

stdout		dc.l	0

dos_base	dc.l	0
pp_base		dc.l	0
gfx_base	dc.l	0

vbl_save	dc.l	0	
pattern_pos	dc.l	0
note_dest	dc.l	0
scope_screen	dc.l	0	

vbr		dc.l	0

old_view	dc.l	0

pattern_slot_teller	dc.w	0	;offset in track_pos_tab

blit_note_slot_teller	dc.w	0

dmacon_save	dc.w	0
intena_save	dc.w	0	

clear_block	blk.w	20*8,$ffff

scopes_clear_buffer	dc.l	second_buf_scopes
scopes_build_buffer	dc.l	third_buf_scopes
scopes_show_buffer	dc.l	screen_picture+[[24+120]*80]

sample_chan1_pointer	dc.l	clean_block
chan1_start	dc.l	0
chan1_length	dc.w	0
chan1_loopstart	dc.l	0
chan1_replen	dc.w	0
chan1_period	dc.w	0
chan1_volume	dc.b	0		

	EVEN	

sample_chan2_pointer	dc.l	clean_block
chan2_start	dc.l	0
chan2_length	dc.w	0
chan2_loopstart	dc.l	0
chan2_replen	dc.w	0
chan2_period	dc.w	0
chan2_volume	dc.b	0		

	EVEN

sample_chan3_pointer	dc.l	clean_block
chan3_start	dc.l	0
chan3_length	dc.w	0
chan3_loopstart	dc.l	0
chan3_replen	dc.w	0
chan3_period	dc.w	0
chan3_volume	dc.b	0		

	EVEN

sample_chan4_pointer	dc.l	clean_block
chan4_start	dc.l	0
chan4_length	dc.w	0
chan4_loopstart	dc.l	0
chan4_replen	dc.w	0
chan4_period	dc.w	0
chan4_volume	dc.b	0	

	EVEN
	
graph_name	dc.b	'graphics.library',0

	EVEN
pp_name		dc.b	'powerpacker.library',0

	EVEN
dos_name	dc.b	'dos.library',0

	EVEN

pattern_pointer	dc.b	0

scrollbar_moved	dc.b	0

new_pattern	dc.b	1
new_bpm		dc.b	1
new_vbl_tempo	dc.b	1

hours		dc.b	0
minutes		dc.b	0
seconds		dc.b	0
frame_counter	dc.b	0
new_time	dc.b	1

last_pulses_x	dc.b	0
last_pulses_y	dc.b	0

pal_ntsc	dc.b	0	;0 = pal ; 1 = Never The Same Color

quit_program	dc.b	0

	EVEN

x_coordinate		dc.w	0
x_coordinate_old	dc.w	0
y_coordinate		dc.w	0	
y_coordinate_old	dc.w	0

	EVEN

button_id		dc.w	0
button_struct_address	dc.l	0

mouse_button_status	dc.b	1	;1 is no button pressed

	EVEN

sample_info_shown	
			dc.b	0	;number of sample that is current
					;shown in the sampleinfo area
	EVEN
	
actual_line		dc.w	0	;top line of text in textwindow
actual_text		dc.l	0	;pointer to text_structure of text
					;that's in the textwindow
	EVEN

;button_structs:
;button id (word)
;minimal x, maximal x	(words)
;minimal y, maximal y	(words)
;pointer to unselected image	(long)
;pointer to selected image (long)

button_structures
about_button_struct
	dc.w	1			;id = 1			offset 0
	dc.w	320,384			;min x, max x		offset 2
	dc.w	188,200			;min y, max y		offset 6
	dc.l	buttons_1_normal+40*12	;pointer to unselect image offset 10
	dc.l	buttons_1_pressed+40*12	;pointer to select image  offset 14

mod_text_button_struct
	dc.w	2			;id = 2
	dc.w	384,448
	dc.w	188,200
	dc.l	buttons_1_normal+8+40*12
	dc.l	buttons_1_pressed+8+40*12

restart_button_struct
	dc.w	3			;id = 3
	dc.w	448,512
	dc.w	188,200
	dc.l	buttons_1_normal+16+40*12
	dc.l	buttons_1_pressed+16+40*12

quit_button
	dc.w	4			;id = 4
	dc.w	512,576
	dc.w	188,200
	dc.l	buttons_1_normal+24+40*12
	dc.l	buttons_1_pressed+24+40*12

uga_button
	dc.w	5			;id = 5
	dc.w	576,640
	dc.w	188,200
	dc.l	buttons_1_normal+32+40*12
	dc.l	buttons_1_pressed+32+40*12

sample_arrow_up
	dc.w	6	;id = 6
	dc.w	592,605
	dc.w	162,172
	dc.l	arrow_up_normal+2*10
	dc.l	arrow_up_pressed+2*10
	
sample_arrow_down
	dc.w	7	;id = 7
	dc.w	592,605
	dc.w	172,182
	dc.l	arrow_down_normal+2*10
	dc.l	arrow_down_pressed+2*10

scrollbar_arrow_up
	dc.w	8	;id = 8
	dc.w	624,637
	dc.w	85,95
	dc.l	arrow_up_normal+2*10
	dc.l	arrow_up_pressed+2*10

scrollbar_arrow_down
	dc.w	9	;id = 9
	dc.w	624,637
	dc.w	95,105
	dc.l	arrow_down_normal+2*10
	dc.l	arrow_down_pressed+2*10

scrollbar
	dc.w	10	;id = 10
	dc.w	626,635
	dc.w	0,0	;y coordinates are dynamic.
	dc.l	0
	dc.l	0

close_button
	dc.w	11
	dc.w	0,16
	dc.w	0,10
	dc.l	close_button_normal+2*10
	dc.l	close_button_pressed+2*10


colors
	dc.w	$0000,$0fff,$0abd,$0ed0
	dc.w	$078a,$0fff,$0568,$0f52
	dc.w	$0fff,$0000,$0ed0,$0000
	dc.w	$0,0,$0eef,0


notetab
	;use the offset in the finetunetab, and get the string from this
	;table to put it in the display.
	
	dc.b	"C-1",0
	dc.b	"C#1",0
	dc.b	"D-1",0
	dc.b	"D#1",0
	dc.b	"E-1",0
	dc.b	"F-1",0
	dc.b	"F#1",0
	dc.b	"G-1",0
	dc.b	"G#1",0
	dc.b	"A-1",0
	dc.b	"A#1",0
	dc.b	"B-1",0

	dc.b	"C-2",0
	dc.b	"C#2",0
	dc.b	"D-2",0
	dc.b	"D#2",0
	dc.b	"E-2",0
	dc.b	"F-2",0
	dc.b	"F#2",0
	dc.b	"G-2",0
	dc.b	"G#2",0
	dc.b	"A-2",0
	dc.b	"A#2",0
	dc.b	"B-2",0

	dc.b	"C-3",0
	dc.b	"C#3",0
	dc.b	"D-3",0
	dc.b	"D#3",0
	dc.b	"E-3",0
	dc.b	"F-3",0
	dc.b	"F#3",0
	dc.b	"G-3",0
	dc.b	"G#3",0
	dc.b	"A-3",0
	dc.b	"A#3",0
	dc.b	"B-3",0

	dc.b	"---",0

	EVEN

button_blit_jump_table
	dc.l	0			;dummy long. coz aboutbutton has id 1.
	dc.l	blit_about_button
	dc.l	blit_mod_text_button
	dc.l	blit_restart_button
	dc.l	blit_quit_button
	dc.l	blit_uga_button
	dc.l	blit_sample_arrow_up
	dc.l	blit_sample_arrow_down
	dc.l	blit_scrollbar_arrow_up
	dc.l	blit_scrollbar_arrow_down
	dc.l	dummy_routine		;dummy long (scrollbar)
	dc.l	blit_close_button

button_action_jump_table
	dc.l	0	;dummy
	dc.l	show_about
	dc.l	show_mod_text
	dc.l	do_restart
	dc.l	do_quit
	dc.l	show_uga
	dc.l	do_sample_up
	dc.l	do_sample_down
	dc.l	do_textwindow_down
	dc.l	do_textwindow_up
	dc.l	dummy_routine
	dc.l	do_quit

	
	section	texts,DATA

;if the first longword of each structure is 0, there is no text of this
;subject availabe
;about text and UGA (or IC) text are ELWAYS available.

about_text_struct
	dc.l	about_text	;about_text
	dc.l	0		;about_text_bitplane
	dc.w	0		;a_t_no_of_lines
	dc.w	898		;a_b_text_length	(bytes)
	dc.l	about_scrollbar_struct	;pointer to scrollbar_struct	

mod_text_struct
	dc.l	0		;mod_text
	dc.l	0		;mod_text_bitplane
	dc.w	0		;m_t_no_of_lines
	dc.w	0		;m_t_text_length	(bytes)
	dc.l	mod_text_scrollbar_struct ;pointer to scrollbar_struct	

uga_text_struct
	dc.l	uga_text	;text
	dc.l	0		;3rd text bitplane
	dc.w	0		;t_t_no_of_lines
	dc.w	294		;t_t_text_length	(bytes)
	dc.l	uga_text_scrollbar_struct ;pointer to scrollbar_struct

no_mem_text_struct
	dc.l	no_mem_text
	dc.l	dummy_bitplane
	dc.w	1
	dc.w	36
	dc.l	0

about_scrollbar_struct
	dc.l	scrollbar_about	;pointer to scrollbar sprite
	dc.w	0		;length (in screenlines)
	dc.w	0		;no of pixels : no of lines
	dc.w	0		;scroll counter (in screenlines)

mod_text_scrollbar_struct
	dc.l	scrollbar_mod_text	;pointer to scrollbar sprite
	dc.w	0		;length (in screenlines)
	dc.w	0		;no of pixels : no of lines
	dc.w	0		;scroll counter (in screenlines)

uga_text_scrollbar_struct
	dc.l	scrollbar_uga_text	;pointer to scrollbar sprite
	dc.w	0		;length (in screenlines)
	dc.w	0		;no of pixels : no of lines
	dc.w	0		;scroll counter (in screenlines)

mod_text		dc.l	0
mod_text_length		dc.l	0

about_text
	incbin	"about_text"

uga_text
	incbin	"uga_text"

no_mem_text
	dc.b	"  Not enuff CHIP mem available :(   "

no_mod_text_text	dc.b	'      no mod text specified!!!      ',0

	EVEN
	
no_mod_text_text_length		dc.w	36

return		dc.b	$0a

usage_text	dc.b 'Usage: ptplay module[.pp] [text[.pp]]',10,0

opening_text	
	dc.b 'PtPlay - protracker module player. (c)1993 Otis/InfoCorner',10,0

pp_needed
	dc.b 'Needs powerpacker.library!!!!!',10,0

filename1	blk.b	200,0

filename2	blk.b	200,0

	EVEN

	Section	replayer,CODE

;**************************************************
;*    ----- Protracker V2.3A Playroutine -----    *
;**************************************************


; Call SetCIAInt to install the interrupt server. Then call mt_init
; to initialize the song. Playback starts when the mt_enable flag
; is set to a nonzero value. To end the song and turn off all voices,
; call mt_end. At last, call ResetCIAInt to remove the interrupt.


SetCIAInt
	MOVEQ	#2,D6
	LEA	$BFD000,A5
	MOVE.B	#'b',CIAAname+3
SetCIALoop
	MOVEQ	#0,D0
	LEA	CIAAname(PC),A1
	MOVE.L	4.W,A6
	JSR	LVOOpenResource(A6)
	MOVE.L	D0,CIAAbase
	BEQ.W	mt_Return

	LEA	GfxName(PC),A1
	MOVEQ	#0,D0
	JSR	LVOOpenLibrary(A6)
	TST.L	D0
	BEQ.W	ResetCIAInt
	MOVE.L	D0,A1
	MOVE.W	206(A1),D0	; DisplayFlags
	BTST	#2,D0		; PAL?
	BEQ.S	WasNTSC
	move.b	#0,pal_ntsc
	MOVE.L	#1773447,D7 ; PAL
	BRA.S	sciask
WasNTSC	MOVE.L	#1789773,D7 ; NTSC
	move.b	#1,pal_ntsc
sciask	MOVE.L	D7,TimerValue
	DIVU	#125,D7 ; Default to normal 50 Hz timer
	JSR	LVOCloseLibrary(A6)

	MOVE.L	CIAAbase(PC),A6
	CMP.W	#2,D6
	BEQ.S	TryTimerA
TryTimerB
	LEA	MusicIntServer(PC),A1
	MOVEQ	#1,D0	; Bit 1: Timer B
	JSR	AddICRVector(A6)
	MOVE.L	#1,TimerFlag
	TST.L	D0
	BNE.S	CIAError
	MOVE.L	A5,CIAAaddr
	MOVE.B	D7,ciatblo(A5)
	LSR.W	#8,D7
	MOVE.B	D7,ciatbhi(A5)
	BSET	#0,ciacrb(A5)
	RTS

TryTimerA
	LEA	MusicIntServer(PC),A1
	MOVEQ	#0,D0	; Bit 0: Timer A
	JSR	AddICRVector(A6)
	CLR.L	TimerFlag
	TST.L	D0
	BNE.S	CIAError
	MOVE.L	A5,CIAAaddr
	MOVE.B	D7,ciatalo(A5)
	LSR.W	#8,D7
	MOVE.B	D7,ciatahi(A5)
	BSET	#0,ciacra(A5)
	RTS

CIAError
	MOVE.B	#'a',CIAAname+3
	LEA	$BFE001,A5
	SUBQ.W	#1,D6
	BNE.W	SetCIALoop
	CLR.L	CIAAbase
	RTS

ResetCIAInt
	MOVE.L	CIAAbase(PC),D0
	BEQ.W	mt_Return
	CLR.L	CIAAbase
	MOVE.L	D0,A6
	MOVE.L	CIAAaddr(PC),A5
	TST.L	TimerFlag
	BEQ.S	ResTimerA

	BCLR	#0,ciacrb(A5)
	MOVEQ	#1,D0
	BRA.S	RemInt

ResTimerA
	BCLR	#0,ciacra(A5)
	MOVEQ	#0,D0
RemInt	LEA	MusicIntServer(PC),A1
	MOVEQ	#0,d0
	JSR	RemICRVector(A6)
	RTS

;---- Tempo ----

SetTempo
	MOVE.L	CIAAbase(PC),D2
	BEQ.W	mt_Return
	CMP.W	#32,D0
	BHS.S	setemsk
	MOVEQ	#32,D0
setemsk	MOVE.W	D0,RealTempo
	move.b	#1,new_bpm
	MOVE.L	TimerValue(PC),D2
	DIVU	D0,D2
	MOVE.L	CIAAaddr(PC),A4
	MOVE.L	TimerFlag(PC),D0
	BEQ.S	SetTemA
	MOVE.B	D2,ciatblo(A4)
	LSR.W	#8,D2
	MOVE.B	D2,ciatbhi(A4)
	RTS

SetTemA	MOVE.B	D2,ciatalo(A4)
	LSR.W	#8,D2
	MOVE.B	D2,ciatahi(A4)
	RTS

RealTempo	dc.w 125
CIAAaddr	dc.l 0
CIAAname	dc.b "ciaa.resource",0
CIAAbase	dc.l 0
TimerFlag	dc.l 0
TimerValue	dc.l 0
GfxName		dc.b "graphics.library",0,0

MusicIntServer
	dc.l 0,0
	dc.b 2,5 ; type, priority
	dc.l musintname
	dc.l 0,mt_music

musintname	dc.b "Protracker MusicInt",0

;---- Playroutine ----

n_note		EQU	0  ; W
n_cmd		EQU	2  ; W
n_cmdlo		EQU	3  ; B
n_start		EQU	4  ; L
n_length	EQU	8  ; W
n_loopstart	EQU	10 ; L
n_replen	EQU	14 ; W
n_period	EQU	16 ; W
n_finetune	EQU	18 ; B
n_volume	EQU	19 ; B
n_dmabit	EQU	20 ; W
n_toneportdirec	EQU	22 ; B
n_toneportspeed	EQU	23 ; B
n_wantedperiod	EQU	24 ; W
n_vibratocmd	EQU	26 ; B
n_vibratopos	EQU	27 ; B
n_tremolocmd	EQU	28 ; B
n_tremolopos	EQU	29 ; B
n_wavecontrol	EQU	30 ; B
n_glissfunk	EQU	31 ; B
n_sampleoffset	EQU	32 ; B
n_pattpos	EQU	33 ; B
n_loopcount	EQU	34 ; B
n_funkoffset	EQU	35 ; B
n_wavestart	EQU	36 ; L
n_reallength	EQU	40 ; W

mt_init	move.l	mt_data,A0
	MOVE.L	A0,mt_SongDataPtr
	MOVE.L	A0,A1
	LEA	952(A1),A1
	MOVEQ	#127,D0
	MOVEQ	#0,D1
mtloop	MOVE.L	D1,D2
	SUBQ.W	#1,D0
mtloop2	MOVE.B	(A1)+,D1
	CMP.B	D2,D1
	BGT.S	mtloop
	DBRA	D0,mtloop2
	ADDQ.B	#1,D2
			
	LEA	mt_SampleStarts(PC),A1
	ASL.L	#8,D2
	ASL.L	#2,D2
	ADD.L	#1084,D2
	ADD.L	A0,D2
	MOVE.L	D2,A2
	MOVEQ	#30,D0
mtloop3	CLR.L	(A2)
	MOVE.L	A2,(A1)+
	MOVEQ	#0,D1
	MOVE.W	42(A0),D1
	ASL.L	#1,D1
	ADD.L	D1,A2
	ADD.L	#30,A0
	DBRA	D0,mtloop3

	OR.B	#2,$BFE001
	MOVE.B	#6,mt_speed
	CLR.B	mt_counter
	CLR.B	mt_SongPos
	CLR.W	mt_PatternPos
mt_end	SF	mt_Enable
	LEA	$DFF000,A0
	CLR.W	$A8(A0)
	CLR.W	$B8(A0)
	CLR.W	$C8(A0)
	CLR.W	$D8(A0)
	MOVE.W	#$F,$DFF096
	RTS

mt_music
	MOVEM.L	D0-D7/A0-A6,-(SP)
	TST.B	mt_Enable
	BEQ.W	mt_exit
	ADDQ.B	#1,mt_counter
	MOVE.B	mt_counter(PC),D0
	CMP.B	mt_speed(PC),D0
	BLO.S	mt_NoNewNote
	CLR.B	mt_counter
	TST.B	mt_PattDelTime2
	BEQ.S	mt_GetNewNote
	BSR.S	mt_NoNewAllChannels
	BRA.W	mt_dskip

mt_NoNewNote
	BSR.S	mt_NoNewAllChannels
	BRA.W	mt_NoNewPosYet

mt_NoNewAllChannels
	LEA	$DFF0A0,A5
	LEA	mt_chan1temp(PC),A6
	BSR.W	mt_CheckEfx
	LEA	$DFF0B0,A5
	LEA	mt_chan2temp(PC),A6
	BSR.W	mt_CheckEfx
	LEA	$DFF0C0,A5
	LEA	mt_chan3temp(PC),A6
	BSR.W	mt_CheckEfx
	LEA	$DFF0D0,A5
	LEA	mt_chan4temp(PC),A6
	BRA.W	mt_CheckEfx

mt_GetNewNote
	jsr	move_track_bitplane		;moves the tracks on screen
						;1 slot up
						
	MOVE.L	mt_SongDataPtr(PC),A0
	LEA	12(A0),A3
	LEA	952(A0),A2	;pattpo
	LEA	1084(A0),A0	;patterndata
	MOVEQ	#0,D0
	MOVEQ	#0,D1
	MOVE.B	mt_SongPos(PC),D0
	MOVE.B	(A2,D0.W),D1
	ASL.L	#8,D1
	ASL.L	#2,D1
	ADD.W	mt_PatternPos(PC),D1
	CLR.W	mt_DMACONtemp

	LEA	$DFF0A0,A5
	LEA	mt_chan1temp(PC),A6
	lea	sample_chan1_pointer,a4
	BSR.S	mt_PlayVoice
	LEA	$DFF0B0,A5
	LEA	mt_chan2temp(PC),A6
	lea	sample_chan2_pointer,a4
	BSR.S	mt_PlayVoice
	LEA	$DFF0C0,A5
	LEA	mt_chan3temp(PC),A6
	lea	sample_chan3_pointer,a4
	BSR.S	mt_PlayVoice
	LEA	$DFF0D0,A5
	LEA	mt_chan4temp(PC),A6
	lea	sample_chan4_pointer,a4
	BSR.S	mt_PlayVoice
	BRA.W	mt_SetDMA

mt_PlayVoice
	TST.L	(A6)
	BNE.S	mt_plvskip
	BSR.W	mt_PerNop
mt_plvskip
	MOVE.L	(A0,D1.L),(A6)
	ADDQ.L	#4,D1
	MOVEQ	#0,D2
	MOVE.B	n_cmd(A6),D2
	AND.B	#$F0,D2
	LSR.B	#4,D2
	MOVE.B	(A6),D0
	AND.B	#$F0,D0
	OR.B	D0,D2
	TST.B	D2
	beq.w	mt_SetRegs

	MOVEQ	#0,D3
	LEA	mt_SampleStarts(PC),A1
	MOVE	D2,D4
	SUBQ.L	#1,D2
	ASL.L	#2,D2
	MULU	#30,D4
	MOVE.L	(A1,D2.L),n_start(A6)
	
	MOVE.W	(A3,D4.L),n_length(A6)
	MOVE.W	(A3,D4.L),n_reallength(A6)
	MOVE.B	2(A3,D4.L),n_finetune(A6)
	MOVE.B	3(A3,D4.L),n_volume(A6)
	MOVE.W	4(A3,D4.L),D3 ;$Get repeat
	TST.W	D3
	BEQ.S	mt_NoLoop
	MOVE.L	n_start(A6),D2	; Get start
	ASL.W	#1,D3
	ADD.L	D3,D2		; Add repeat
	MOVE.L	D2,n_loopstart(A6)
	MOVE.L	D2,n_wavestart(A6)
	MOVE.W	4(A3,D4.L),D0	; Get repeat
	ADD.W	6(A3,D4.L),D0	; Add replen
	MOVE.W	D0,n_length(A6)
	MOVE.W	6(A3,D4.L),n_replen(A6)	; Save replen	
	MOVEQ	#0,D0
	MOVE.B	n_volume(A6),D0
	MOVE.W	D0,8(A5)	; Set volume
	BRA.S	mt_SetRegs

mt_NoLoop
	MOVE.L	n_start(A6),D2
	ADD.L	D3,D2
	MOVE.L	D2,n_loopstart(A6)
	MOVE.L	D2,n_wavestart(A6)
	MOVE.W	6(A3,D4.L),n_replen(A6)	; Save replen
	MOVEQ	#0,D0
	MOVE.B	n_volume(A6),D0
	MOVE.W	D0,8(A5)	; Set volume
mt_SetRegs
	MOVE.W	(A6),D0
	AND.W	#$0FFF,D0
	BEQ.W	mt_CheckMoreEfx	; If no note

	move.l	n_start(a6),(a4)

	MOVE.W	2(A6),D0
	AND.W	#$0FF0,D0
	CMP.W	#$0E50,D0
	BEQ.S	mt_DoSetFineTune
	MOVE.B	2(A6),D0
	AND.B	#$0F,D0
	CMP.B	#3,D0	; TonePortamento
	BEQ.S	mt_ChkTonePorta
	CMP.B	#5,D0
	BEQ.S	mt_ChkTonePorta
	CMP.B	#9,D0	; Sample Offset
	BNE.S	mt_SetPeriod
	BSR.W	mt_CheckMoreEfx
	BRA.S	mt_SetPeriod

mt_DoSetFineTune
	BSR.W	mt_SetFineTune
	BRA.S	mt_SetPeriod

mt_ChkTonePorta
	BSR.W	mt_SetTonePorta
	BRA.W	mt_CheckMoreEfx

mt_SetPeriod
	MOVEM.L	D0-D1/A0-A1,-(SP)
	MOVE.W	(A6),D1
	AND.W	#$0FFF,D1
	LEA	mt_PeriodTable(PC),A1
	MOVEQ	#0,D0
	MOVEQ	#36,D2
mt_ftuloop
	CMP.W	(A1,D0.W),D1
	BHS.S	mt_ftufound
	ADDQ.L	#2,D0
	DBRA	D2,mt_ftuloop
mt_ftufound
	MOVEQ	#0,D1
	MOVE.B	n_finetune(A6),D1
	MULU	#36*2,D1
	ADD.L	D1,A1
	MOVE.W	(A1,D0.W),n_period(A6)
	MOVEM.L	(SP)+,D0-D1/A0-A1

	MOVE.W	2(A6),D0
	AND.W	#$0FF0,D0
	CMP.W	#$0ED0,D0 ; Notedelay
	BEQ.W	mt_CheckMoreEfx

	MOVE.W	n_dmabit(A6),$DFF096
	BTST	#2,n_wavecontrol(A6)
	BNE.S	mt_vibnoc
	CLR.B	n_vibratopos(A6)
mt_vibnoc
	BTST	#6,n_wavecontrol(A6)
	BNE.S	mt_trenoc
	CLR.B	n_tremolopos(A6)
mt_trenoc
	MOVE.L	n_start(A6),(A5)	; Set start
	MOVE.W	n_length(A6),4(A5)	; Set length
	MOVE.W	n_period(A6),D0
	MOVE.W	D0,6(A5)		; Set period
	MOVE.W	n_dmabit(A6),D0
	OR.W	D0,mt_DMACONtemp
	BRA.W	mt_CheckMoreEfx

;wait 10 rasterlines instead of a dbfloop of 300 loops! (now also '030!)
wait10lines:
	movem.w	d1/d2,-(sp)
	moveq	#10,d0			; number of rasterlines to wait
	move.b	$dff006,d1
.loop	move.b	$dff006,d2
	cmp.b	d1,d2
	beq.s	.loop			; wait until difference
	move.b	d2,d1
	dbf	d0,.loop
	movem.w	(sp)+,d1/d2
	rts

mt_SetDMA
	bsr.b	wait10lines

	MOVE.W	mt_DMACONtemp(PC),D0
	OR.W	#$8000,D0
	MOVE.W	D0,$DFF096

	bsr.b	wait10lines

	LEA	$DFF000,A5
	LEA	mt_chan4temp(PC),A6
	MOVE.L	n_loopstart(A6),$D0(A5)
	MOVE.W	n_replen(A6),$D4(A5)
	LEA	mt_chan3temp(PC),A6
	MOVE.L	n_loopstart(A6),$C0(A5)
	MOVE.W	n_replen(A6),$C4(A5)
	LEA	mt_chan2temp(PC),A6
	MOVE.L	n_loopstart(A6),$B0(A5)
	MOVE.W	n_replen(A6),$B4(A5)
	LEA	mt_chan1temp(PC),A6
	MOVE.L	n_loopstart(A6),$A0(A5)
	MOVE.W	n_replen(A6),$A4(A5)

mt_dskip
	ADD.W	#16,mt_PatternPos
	MOVE.B	mt_PattDelTime,D0
	BEQ.S	mt_dskc
	MOVE.B	D0,mt_PattDelTime2
	CLR.B	mt_PattDelTime
mt_dskc	TST.B	mt_PattDelTime2
	BEQ.S	mt_dska
	SUBQ.B	#1,mt_PattDelTime2
	BEQ.S	mt_dska
	SUB.W	#16,mt_PatternPos
mt_dska	TST.B	mt_PBreakFlag
	BEQ.S	mt_nnpysk
	SF	mt_PBreakFlag
	MOVEQ	#0,D0
	MOVE.B	mt_PBreakPos(PC),D0
	CLR.B	mt_PBreakPos
	LSL.W	#4,D0
	MOVE.W	D0,mt_PatternPos
mt_nnpysk

	CMP.W	#1024,mt_PatternPos
	BLO.S	mt_NoNewPosYet

	tst.b	mt_posjumpflag
	bne.s	mt_nextposition

	clr.w	blit_note_slot_teller

mt_NextPosition	
	MOVEQ	#0,D0
	MOVE.B	mt_PBreakPos(PC),D0

	move.b	#1,new_pattern

	LSL.W	#4,D0
	MOVE.W	D0,mt_PatternPos
	CLR.B	mt_PBreakPos
	CLR.B	mt_PosJumpFlag
	ADDQ.B	#1,mt_SongPos

	AND.B	#$7F,mt_SongPos
	MOVE.B	mt_SongPos(PC),D1
	MOVE.L	mt_SongDataPtr(PC),A0
	
	CMP.B	950(A0),D1
	BLO.S	mt_NoNewPosYet
	CLR.B	mt_SongPos

mt_NoNewPosYet	
	TST.B	mt_PosJumpFlag
	BNE.S	mt_NextPosition

;store the value of the pattern current played

mt_exit
	move.l	mt_data,a0
	lea	952(a0),a0
	
	moveq	#0,d0
	move.b	mt_SongPos(PC),d0
	move.b	(a0,d0.w),pattern_pointer

	MOVEM.L	(SP)+,D0-D7/A0-A6
	RTS

mt_CheckEfx
	BSR.W	mt_UpdateFunk
	MOVE.W	n_cmd(A6),D0
	AND.W	#$0FFF,D0
	BEQ.S	mt_PerNop
	MOVE.B	n_cmd(A6),D0
	AND.B	#$0F,D0
	BEQ.S	mt_Arpeggio
	CMP.B	#1,D0
	BEQ.W	mt_PortaUp
	CMP.B	#2,D0
	BEQ.W	mt_PortaDown
	CMP.B	#3,D0
	BEQ.W	mt_TonePortamento
	CMP.B	#4,D0
	BEQ.W	mt_Vibrato
	CMP.B	#5,D0
	BEQ.W	mt_TonePlusVolSlide
	CMP.B	#6,D0
	BEQ.W	mt_VibratoPlusVolSlide
	CMP.B	#$E,D0
	BEQ.W	mt_E_Commands
SetBack	MOVE.W	n_period(A6),6(A5)
	CMP.B	#7,D0
	BEQ.W	mt_Tremolo
	CMP.B	#$A,D0
	BEQ.W	mt_VolumeSlide
mt_Return
	RTS

mt_PerNop
	MOVE.W	n_period(A6),6(A5)
	RTS

mt_Arpeggio
	MOVEQ	#0,D0
	MOVE.B	mt_counter(PC),D0
	DIVS	#3,D0
	SWAP	D0
	CMP.W	#0,D0
	BEQ.S	mt_Arpeggio2
	CMP.W	#2,D0
	BEQ.S	mt_Arpeggio1
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	LSR.B	#4,D0
	BRA.S	mt_Arpeggio3

mt_Arpeggio1
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#15,D0
	BRA.S	mt_Arpeggio3

mt_Arpeggio2
	MOVE.W	n_period(A6),D2
	BRA.S	mt_Arpeggio4

mt_Arpeggio3
	ASL.W	#1,D0
	MOVEQ	#0,D1
	MOVE.B	n_finetune(A6),D1
	MULU	#36*2,D1
	LEA	mt_PeriodTable(PC),A0
	ADD.L	D1,A0
	MOVEQ	#0,D1
	MOVE.W	n_period(A6),D1
	MOVEQ	#36,D3
mt_arploop
	MOVE.W	(A0,D0.W),D2
	CMP.W	(A0),D1
	BHS.S	mt_Arpeggio4
	ADDQ.L	#2,A0
	DBRA	D3,mt_arploop
	RTS

mt_Arpeggio4
	MOVE.W	D2,6(A5)
	RTS

mt_FinePortaUp
	TST.B	mt_counter
	BNE.S	mt_Return
	MOVE.B	#$0F,mt_LowMask
mt_PortaUp
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	mt_LowMask(PC),D0
	MOVE.B	#$FF,mt_LowMask
	SUB.W	D0,n_period(A6)
	MOVE.W	n_period(A6),D0
	AND.W	#$0FFF,D0
	CMP.W	#113,D0
	BPL.S	mt_PortaUskip
	AND.W	#$F000,n_period(A6)
	OR.W	#113,n_period(A6)
mt_PortaUskip
	MOVE.W	n_period(A6),D0
	AND.W	#$0FFF,D0
	MOVE.W	D0,6(A5)
	RTS	
 
mt_FinePortaDown
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVE.B	#$0F,mt_LowMask
mt_PortaDown
	CLR.W	D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	mt_LowMask(PC),D0
	MOVE.B	#$FF,mt_LowMask
	ADD.W	D0,n_period(A6)
	MOVE.W	n_period(A6),D0
	AND.W	#$0FFF,D0
	CMP.W	#856,D0
	BMI.S	mt_PortaDskip
	AND.W	#$F000,n_period(A6)
	OR.W	#856,n_period(A6)
mt_PortaDskip
	MOVE.W	n_period(A6),D0
	AND.W	#$0FFF,D0
	MOVE.W	D0,6(A5)
	RTS

mt_SetTonePorta
	MOVE.L	A0,-(SP)
	MOVE.W	(A6),D2
	AND.W	#$0FFF,D2
	MOVEQ	#0,D0
	MOVE.B	n_finetune(A6),D0
	MULU	#36*2,D0 ;37?
	LEA	mt_PeriodTable(PC),A0
	ADD.L	D0,A0
	MOVEQ	#0,D0
mt_StpLoop
	CMP.W	(A0,D0.W),D2
	BHS.S	mt_StpFound
	ADDQ.W	#2,D0
	CMP.W	#36*2,D0 ;37?
	BLO.S	mt_StpLoop
	MOVEQ	#35*2,D0
mt_StpFound
	MOVE.B	n_finetune(A6),D2
	AND.B	#8,D2
	BEQ.S	mt_StpGoss
	TST.W	D0
	BEQ.S	mt_StpGoss
	SUBQ.W	#2,D0
mt_StpGoss
	MOVE.W	(A0,D0.W),D2
	MOVE.L	(SP)+,A0
	MOVE.W	D2,n_wantedperiod(A6)
	MOVE.W	n_period(A6),D0
	CLR.B	n_toneportdirec(A6)
	CMP.W	D0,D2
	BEQ.S	mt_ClearTonePorta
	BGE.W	mt_Return
	MOVE.B	#1,n_toneportdirec(A6)
	RTS

mt_ClearTonePorta
	CLR.W	n_wantedperiod(A6)
	RTS

mt_TonePortamento
	MOVE.B	n_cmdlo(A6),D0
	BEQ.S	mt_TonePortNoChange
	MOVE.B	D0,n_toneportspeed(A6)
	CLR.B	n_cmdlo(A6)
mt_TonePortNoChange
	TST.W	n_wantedperiod(A6)
	BEQ.W	mt_Return
	MOVEQ	#0,D0
	MOVE.B	n_toneportspeed(A6),D0
	TST.B	n_toneportdirec(A6)
	BNE.S	mt_TonePortaUp
mt_TonePortaDown
	ADD.W	D0,n_period(A6)
	MOVE.W	n_wantedperiod(A6),D0
	CMP.W	n_period(A6),D0
	BGT.S	mt_TonePortaSetPer
	MOVE.W	n_wantedperiod(A6),n_period(A6)
	CLR.W	n_wantedperiod(A6)
	BRA.S	mt_TonePortaSetPer

mt_TonePortaUp
	SUB.W	D0,n_period(A6)
	MOVE.W	n_wantedperiod(A6),D0
	CMP.W	n_period(A6),D0
	BLT.S	mt_TonePortaSetPer
	MOVE.W	n_wantedperiod(A6),n_period(A6)
	CLR.W	n_wantedperiod(A6)

mt_TonePortaSetPer
	MOVE.W	n_period(A6),D2
	MOVE.B	n_glissfunk(A6),D0
	AND.B	#$0F,D0
	BEQ.B	mt_GlissSkip
	MOVEQ	#0,D0
	MOVE.B	n_finetune(A6),D0
	MULU	#36*2,D0
	LEA	mt_PeriodTable(PC),A0
	ADD.L	D0,A0
	MOVEQ	#0,D0
mt_GlissLoop
	CMP.W	(A0,D0.W),D2
	BHS.S	mt_GlissFound
	ADDQ.W	#2,D0
	CMP.W	#36*2,D0
	BLO.S	mt_GlissLoop
	MOVEQ	#35*2,D0
mt_GlissFound
	MOVE.W	(A0,D0.W),D2
mt_GlissSkip
	MOVE.W	D2,6(A5) ; Set period
	RTS

mt_Vibrato
	MOVE.B	n_cmdlo(A6),D0
	BEQ.S	mt_Vibrato2
	MOVE.B	n_vibratocmd(A6),D2
	AND.B	#$0F,D0
	BEQ.S	mt_vibskip
	AND.B	#$F0,D2
	OR.B	D0,D2
mt_vibskip
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$F0,D0
	BEQ.S	mt_vibskip2
	AND.B	#$0F,D2
	OR.B	D0,D2
mt_vibskip2
	MOVE.B	D2,n_vibratocmd(A6)
mt_Vibrato2
	MOVE.B	n_vibratopos(A6),D0
	LEA	mt_VibratoTable(PC),A4
	LSR.W	#2,D0
	AND.W	#$001F,D0
	MOVEQ	#0,D2
	MOVE.B	n_wavecontrol(A6),D2
	AND.B	#$03,D2
	BEQ.S	mt_vib_sine
	LSL.B	#3,D0
	CMP.B	#1,D2
	BEQ.S	mt_vib_rampdown
	MOVE.B	#255,D2
	BRA.S	mt_vib_set
mt_vib_rampdown
	TST.B	n_vibratopos(A6)
	BPL.S	mt_vib_rampdown2
	MOVE.B	#255,D2
	SUB.B	D0,D2
	BRA.S	mt_vib_set
mt_vib_rampdown2
	MOVE.B	D0,D2
	BRA.S	mt_vib_set
mt_vib_sine
	MOVE.B	(A4,D0.W),D2
mt_vib_set
	MOVE.B	n_vibratocmd(A6),D0
	AND.W	#15,D0
	MULU	D0,D2
	LSR.W	#7,D2
	MOVE.W	n_period(A6),D0
	TST.B	n_vibratopos(A6)
	BMI.S	mt_VibratoNeg
	ADD.W	D2,D0
	BRA.S	mt_Vibrato3
mt_VibratoNeg
	SUB.W	D2,D0
mt_Vibrato3
	MOVE.W	D0,6(A5)
	MOVE.B	n_vibratocmd(A6),D0
	LSR.W	#2,D0
	AND.W	#$003C,D0
	ADD.B	D0,n_vibratopos(A6)
	RTS

mt_TonePlusVolSlide
	BSR.W	mt_TonePortNoChange
	BRA.W	mt_VolumeSlide

mt_VibratoPlusVolSlide
	BSR.S	mt_Vibrato2
	BRA.W	mt_VolumeSlide

mt_Tremolo
	MOVE.B	n_cmdlo(A6),D0
	BEQ.S	mt_Tremolo2
	MOVE.B	n_tremolocmd(A6),D2
	AND.B	#$0F,D0
	BEQ.S	mt_treskip
	AND.B	#$F0,D2
	OR.B	D0,D2
mt_treskip
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$F0,D0
	BEQ.S	mt_treskip2
	AND.B	#$0F,D2
	OR.B	D0,D2
mt_treskip2
	MOVE.B	D2,n_tremolocmd(A6)
mt_Tremolo2
	MOVE.B	n_tremolopos(A6),D0
	LEA	mt_VibratoTable(PC),A4
	LSR.W	#2,D0
	AND.W	#$001F,D0
	MOVEQ	#0,D2
	MOVE.B	n_wavecontrol(A6),D2
	LSR.B	#4,D2
	AND.B	#$03,D2
	BEQ.S	mt_tre_sine
	LSL.B	#3,D0
	CMP.B	#1,D2
	BEQ.S	mt_tre_rampdown
	MOVE.B	#255,D2
	BRA.S	mt_tre_set
mt_tre_rampdown
	TST.B	n_vibratopos(A6)
	BPL.S	mt_tre_rampdown2
	MOVE.B	#255,D2
	SUB.B	D0,D2
	BRA.S	mt_tre_set
mt_tre_rampdown2
	MOVE.B	D0,D2
	BRA.S	mt_tre_set
mt_tre_sine
	MOVE.B	(A4,D0.W),D2
mt_tre_set
	MOVE.B	n_tremolocmd(A6),D0
	AND.W	#15,D0
	MULU	D0,D2
	LSR.W	#6,D2
	MOVEQ	#0,D0
	MOVE.B	n_volume(A6),D0
	TST.B	n_tremolopos(A6)
	BMI.S	mt_TremoloNeg
	ADD.W	D2,D0
	BRA.S	mt_Tremolo3
mt_TremoloNeg
	SUB.W	D2,D0
mt_Tremolo3
	BPL.S	mt_TremoloSkip
	CLR.W	D0
mt_TremoloSkip
	CMP.W	#$40,D0
	BLS.S	mt_TremoloOk
	MOVE.W	#$40,D0
mt_TremoloOk
	MOVE.W	D0,8(A5)
	MOVE.B	n_tremolocmd(A6),D0
	LSR.W	#2,D0
	AND.W	#$003C,D0
	ADD.B	D0,n_tremolopos(A6)
	RTS
	
mt_SampleOffset
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	BEQ.S	mt_sononew
	MOVE.B	D0,n_sampleoffset(A6)
mt_sononew
	MOVE.B	n_sampleoffset(A6),D0
	LSL.W	#7,D0
	CMP.W	n_length(A6),D0
	BGE.S	mt_sofskip
	SUB.W	D0,n_length(A6)
	LSL.W	#1,D0
	ADD.L	D0,n_start(A6)
	RTS
mt_sofskip
	MOVE.W	#$0001,n_length(A6)
	RTS

mt_VolumeSlide
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	LSR.B	#4,D0
	TST.B	D0
	BEQ.S	mt_VolSlideDown
mt_VolSlideUp
	ADD.B	D0,n_volume(A6)
	CMP.B	#$40,n_volume(A6)
	BMI.S	mt_vsuskip
	MOVE.B	#$40,n_volume(A6)
mt_vsuskip
	MOVE.B	n_volume(A6),D0
	MOVE.W	D0,8(A5)
	RTS

mt_VolSlideDown
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
mt_VolSlideDown2
	SUB.B	D0,n_volume(A6)
	BPL.S	mt_vsdskip
	CLR.B	n_volume(A6)
mt_vsdskip
	MOVE.B	n_volume(A6),D0
	MOVE.W	D0,8(A5)
	RTS

mt_PositionJump
	MOVE.B	n_cmdlo(A6),D0
	SUBQ.B	#1,D0
	MOVE.B	D0,mt_SongPos
mt_pj2	CLR.B	mt_PBreakPos
	ST 	mt_PosJumpFlag

	move.b	#1,new_pattern
	move.w	#0,blit_note_slot_teller	

	RTS

mt_VolumeChange
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	CMP.B	#$40,D0
	BLS.S	mt_VolumeOk
	MOVEQ	#$40,D0
mt_VolumeOk
	MOVE.B	D0,n_volume(A6)
	MOVE.W	D0,8(A5)
	RTS

mt_PatternBreak
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0


	MOVE.L	D0,D2
	LSR.B	#4,D0
	MULU	#10,D0
	AND.B	#$0F,D2
	ADD.B	D2,D0
	CMP.B	#63,D0
	BHI.S	mt_pj2
	MOVE.B	D0,mt_PBreakPos

;pattern break, so store the restart position in the two tellers

	move.b	#1,new_pattern
	move.w	d0,blit_note_slot_teller	

	ST	mt_PosJumpFlag
	RTS

mt_SetSpeed
	MOVEQ	#0,D0
	MOVE.B	3(A6),D0
	BEQ.W	mt_end
	CMP.B	#32,D0
	BHS.W	SetTempo
	CLR.B	mt_counter
	MOVE.B	D0,mt_speed
	move.b	#1,new_vbl_tempo
	RTS

mt_CheckMoreEfx
	BSR.W	mt_UpdateFunk
	MOVE.B	2(A6),D0
	AND.B	#$0F,D0
	CMP.B	#$9,D0
	BEQ.W	mt_SampleOffset
	CMP.B	#$B,D0
	BEQ.W	mt_PositionJump
	CMP.B	#$D,D0
	BEQ.S	mt_PatternBreak
	CMP.B	#$E,D0
	BEQ.S	mt_E_Commands
	CMP.B	#$F,D0
	BEQ.S	mt_SetSpeed
	CMP.B	#$C,D0
	BEQ.W	mt_VolumeChange
	BRA.W	mt_PerNop

mt_E_Commands
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$F0,D0
	LSR.B	#4,D0
	BEQ.S	mt_FilterOnOff
	CMP.B	#1,D0
	BEQ.W	mt_FinePortaUp
	CMP.B	#2,D0
	BEQ.W	mt_FinePortaDown
	CMP.B	#3,D0
	BEQ.S	mt_SetGlissControl
	CMP.B	#4,D0
	BEQ.W	mt_SetVibratoControl
	CMP.B	#5,D0
	BEQ.W	mt_SetFineTune
	CMP.B	#6,D0
	BEQ.W	mt_JumpLoop
	CMP.B	#7,D0
	BEQ.W	mt_SetTremoloControl
	CMP.B	#9,D0
	BEQ.W	mt_RetrigNote
	CMP.B	#$A,D0
	BEQ.W	mt_VolumeFineUp
	CMP.B	#$B,D0
	BEQ.W	mt_VolumeFineDown
	CMP.B	#$C,D0
	BEQ.W	mt_NoteCut
	CMP.B	#$D,D0
	BEQ.W	mt_NoteDelay
	CMP.B	#$E,D0
	BEQ.W	mt_PatternDelay
	CMP.B	#$F,D0
	BEQ.W	mt_FunkIt
	RTS

mt_FilterOnOff
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#1,D0
	ASL.B	#1,D0
	AND.B	#$FD,$BFE001
	OR.B	D0,$BFE001
	RTS	

mt_SetGlissControl
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	AND.B	#$F4,n_glissfunk(A6)
	OR.B	D0,n_glissfunk(A6)
	RTS

mt_SetVibratoControl
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	AND.B	#$F0,n_wavecontrol(A6)
	OR.B	D0,n_wavecontrol(A6)
	RTS

mt_SetFineTune
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	MOVE.B	D0,n_finetune(A6)
	RTS

mt_JumpLoop
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	BEQ.S	mt_SetLoop
	TST.B	n_loopcount(A6)
	BEQ.S	mt_jumpcnt
	SUBQ.B	#1,n_loopcount(A6)
	BEQ.W	mt_Return
mt_jmploop	MOVE.B	n_pattpos(A6),mt_PBreakPos
	ST	mt_PBreakFlag
	RTS

mt_jumpcnt
	MOVE.B	D0,n_loopcount(A6)
	BRA.S	mt_jmploop

mt_SetLoop
	MOVE.W	mt_PatternPos(PC),D0
	LSR.W	#4,D0
	MOVE.B	D0,n_pattpos(A6)
	RTS

mt_SetTremoloControl
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	LSL.B	#4,D0
	AND.B	#$0F,n_wavecontrol(A6)
	OR.B	D0,n_wavecontrol(A6)
	RTS

mt_RetrigNote
	MOVE.L	D1,-(SP)
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	BEQ.S	mt_rtnend
	MOVEQ	#0,D1
	MOVE.B	mt_counter(PC),D1
	BNE.S	mt_rtnskp
	MOVE.W	(A6),D1
	AND.W	#$0FFF,D1
	BNE.S	mt_rtnend
	MOVEQ	#0,D1
	MOVE.B	mt_counter(PC),D1
mt_rtnskp
	DIVU	D0,D1
	SWAP	D1
	TST.W	D1
	BNE.S	mt_rtnend
mt_DoRetrig
	MOVE.W	n_dmabit(A6),$DFF096	; Channel DMA off
	MOVE.L	n_start(A6),(A5)	; Set sampledata pointer
	MOVE.W	n_length(A6),4(A5)	; Set length

* changed
	bsr.w	wait10lines

	MOVE.W	n_dmabit(A6),D0
	BSET	#15,D0
	MOVE.W	D0,$DFF096

* changed
	bsr.w	wait10lines

	MOVE.L	n_loopstart(A6),(A5)
	MOVE.L	n_replen(A6),4(A5)
mt_rtnend
	MOVE.L	(SP)+,D1
	RTS

mt_VolumeFineUp
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$F,D0
	BRA.W	mt_VolSlideUp

mt_VolumeFineDown
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	BRA.W	mt_VolSlideDown2

mt_NoteCut
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	CMP.B	mt_counter(PC),D0
	BNE.W	mt_Return
	CLR.B	n_volume(A6)
	MOVE.W	#0,8(A5)
	RTS

mt_NoteDelay
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	CMP.B	mt_Counter,D0
	BNE.W	mt_Return
	MOVE.W	(A6),D0
	BEQ.W	mt_Return
	MOVE.L	D1,-(SP)
	BRA.W	mt_DoRetrig

mt_PatternDelay
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVEQ	#0,D0
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	TST.B	mt_PattDelTime2
	BNE.W	mt_Return
	ADDQ.B	#1,D0
	MOVE.B	D0,mt_PattDelTime
	RTS

mt_FunkIt
	TST.B	mt_counter
	BNE.W	mt_Return
	MOVE.B	n_cmdlo(A6),D0
	AND.B	#$0F,D0
	LSL.B	#4,D0
	AND.B	#$0F,n_glissfunk(A6)
	OR.B	D0,n_glissfunk(A6)
	TST.B	D0
	BEQ.W	mt_Return
mt_UpdateFunk
	MOVEM.L	A0/D1,-(SP)
	MOVEQ	#0,D0
	MOVE.B	n_glissfunk(A6),D0
	LSR.B	#4,D0
	BEQ.S	mt_funkend
	LEA	mt_FunkTable(PC),A0
	MOVE.B	(A0,D0.W),D0
	ADD.B	D0,n_funkoffset(A6)
	BTST	#7,n_funkoffset(A6)
	BEQ.S	mt_funkend
	CLR.B	n_funkoffset(A6)

	MOVE.L	n_loopstart(A6),D0
	MOVEQ	#0,D1
	MOVE.W	n_replen(A6),D1
	ADD.L	D1,D0
	ADD.L	D1,D0
	MOVE.L	n_wavestart(A6),A0
	ADDQ.L	#1,A0
	CMP.L	D0,A0
	BLO.S	mt_funkok
	MOVE.L	n_loopstart(A6),A0
mt_funkok
	MOVE.L	A0,n_wavestart(A6)
	MOVEQ	#-1,D0
	SUB.B	(A0),D0
	MOVE.B	D0,(A0)
mt_funkend
	MOVEM.L	(SP)+,A0/D1
	RTS


mt_FunkTable dc.b 0,5,6,7,8,10,11,13,16,19,22,26,32,43,64,128

mt_VibratoTable	
	dc.b   0, 24, 49, 74, 97,120,141,161
	dc.b 180,197,212,224,235,244,250,253
	dc.b 255,253,250,244,235,224,212,197
	dc.b 180,161,141,120, 97, 74, 49, 24

mt_PeriodTable
; 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
; Tuning 1
	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
; Tuning 2
	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
; Tuning 3
	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
; Tuning 4
	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
; Tuning 5
	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
; Tuning 6
	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
; Tuning 7
	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
; Tuning -8
	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
;$Tuning -7
	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
;$Tuning -6
	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
; Tuning -5
	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
;$Tuning -4
	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
; Tuning -3
	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
;$Tuning -2
	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
; Tuning -1
	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

mt_chan1temp	dc.l	0,0,0,0,0,$00010000,0,  0,0,0,0
mt_chan2temp	dc.l	0,0,0,0,0,$00020000,0,  0,0,0,0
mt_chan3temp	dc.l	0,0,0,0,0,$00040000,0,  0,0,0,0
mt_chan4temp	dc.l	0,0,0,0,0,$00080000,0,  0,0,0,0

mt_SampleStarts	dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
		dc.l	0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

mt_SongDataPtr	dc.l 0
mt_speed	dc.b 6
mt_counter	dc.b 0
mt_SongPos	dc.b 0
mt_PBreakPos	dc.b 0
mt_PosJumpFlag	dc.b 0
mt_PBreakFlag	dc.b 0
mt_LowMask	dc.b 0
mt_PattDelTime	dc.b 0
mt_PattDelTime2	dc.b 0
mt_Enable	dc.b 0
mt_PatternPos	dc.w 0
mt_DMACONtemp	dc.w 0


;******************* chip data ***************


	SECTION CHIP_DATA,DATA_C

copper_list
	dc.l	$01800000

scherm
	dc.l	$00e00000,$00e20000
	dc.l	$00e40000,$00e60000
	dc.l	$00e80000,$00ea0000

	dc.l	$008e2981,$0090f4c1
	dc.l	$0092003c,$009400d4
	dc.l	$0100b200,$01020000	
	dc.l	$01080000,$010a0000

c_pointer
	dc.l	$01200000,$01220000
	dc.l	$01240000,$01260000

c_vu_meters
	dc.l	$01280000,$012a0000
	dc.l	$012c0000,$012e0000
	dc.l	$01300000,$01320000
	dc.l	$01340000,$01360000

c_scrollbar
	dc.l	$01380000,$013a0000

c_other	
	dc.l	$013c0000,$013e0000

	dc.l	$4101fffe
	dc.l	$0100c200

bpl_4
	dc.l	$00ec0000,$00ee0000

track_wait
	blk.l	100,0


;*********** buffers**************

	SECTION bitplanebuffers,BSS_C

tracks_bitplane
	ds.b	[[16+64]*8*80]

second_buf_scopes
	ds.b	[65*80]

third_buf_scopes
	ds.b	[65*80]

sample_info_buffer
	ds.b	[26*23*32]	;32 buffers of 208x23 pixels.

	EVEN

dummy_bitplane
	ds.b	[80*11*8]	;dummy bitplane for textwindow

;************** gfx data *****************

	SECTION gfx,DATA_C

screen_picture
	incbin	"gfx/ptplay_screen.raw"

font
	incbin 	"gfx/ptplay_font.raw"

	even

buttons_1_normal
	incbin "gfx/ptplay_buttons.raw"

	even

buttons_1_pressed
	incbin "gfx/ptplay_buttons_pressed.raw"

	even	

arrow_up_normal
	incbin	"gfx/ptplay_arrow_up_button.raw"

	even

arrow_up_pressed
	incbin	"gfx/ptplay_arrow_up_button_pressed"

	even

arrow_down_normal
	incbin	"gfx/ptplay_arrow_down_button.raw"

	even

arrow_down_pressed
	incbin	"gfx/ptplay_arrow_down_button_press"

	even

close_button_normal
	incbin	"gfx/ptplay_close_button.raw"

	even

arrow_button_mask
	blk.w	10,$fff8

close_button_pressed
	incbin	"gfx/ptplay_close_button_pressed.ra"

	even

vu_meter_1
vu1_xy		dc.w	$b74e
vu1_stop	dc.w	$b900	
	dc.w	$ff00,$0000,$ff00,$0100,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00


vu_meter_2
vu2_xy		dc.w	$b760
vu2_stop	dc.w	$b900	
	dc.w	$ff00,$0000,$ff00,$0100,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00


vu_meter_3
vu3_xy		dc.w	$b772
vu3_stop	dc.w	$b900	
	dc.w	$ff00,$0000,$ff00,$0100,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00


vu_meter_4
vu4_xy		dc.w	$b784
vu4_stop	dc.w	$b900	
	dc.w	$ff00,$0000,$ff00,$0100,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00,$c300,$3f00,$c300,$3f00,$c300,$3f00
	dc.w	$c300,$3f00

mouse_pointer
pointer_xy	dc.w	0
pointer_stop	dc.w	0	
	dc.w	$fc00,$0000,$8800,$7800,$9000,$7000,$a000,$6000
	dc.w	$c000,$4000,$8000,$0000,$0000,$0000
	dc.w	0,0


scrollbar_about
s_b_a_xy	dc.w	0
s_b_a_stop	dc.w	0
		blk.w	122,0

scrollbar_mod_text
s_b_m_t_xy	dc.w	0
s_b_m_t_stop	dc.w	0
		blk.w	122,0
		
scrollbar_uga_text
s_b_t_t_xy	dc.w	0
s_b_t_t_stop	dc.w	0
		blk.w	122,0

dummy_sprite
	dc.l	0
	dc.w	0,0,0,0
	dc.w	0,0
