*************************************************************************
*			Groden and Kvack Kvack type demo		*
*			--------------------------------		*
*									*
*									*
* Written by:	MAC SYS DATA of PERSISTENCE OF VISION			*
*									*
*									*
* Date:		April 1996 -  May 1997 					*
*									*
*									*
*									*
* Inspired by the TCB version in SO WATT DEMO				*
*									*
*************************************************************************


yes=1
YES=yes
no=0
NO=no

FINAL		equ	yes
TEST		equ	no	;yes turns off tracker to hopefully prevent total bomb out
DEVELOP		equ	no	;yes for development to include 9 PI1s
DISASSEM	equ	no	;yes to check using MONST, no for hard scroll
DOWNLOAD	equ	no


******************************************************************************
* DOWNLOAD is the widget downloader written by POV. Using a special parallel
* lead you can code on one machine and run the executable on a slave machine.
* This saves you time rebooting your main machine plus you can code for the
* Falcon from an STE or code for an STE on your Falcon. A PC version is
* available that allows you to code on PC, download to ST/STE/FALCON.
		ifne	DOWNLOAD
		include	TRANSMIT.S
		org	$20000
Code_Start
Exec_Addr
		endc


LINEWID		equ	80


******************************************************************************

******************************************************************************


;-----------------------------------------------------------------------;
; 	Replay STe							;
; 	by WizzCat the 21st of May 1991					;
;-----------------------------------------------------------------------;
; Uses no registers							;
;									;
; Replay is started by calling MUSON in supervisor mode. Returns with	;
; timer A running. Calling MUSOFF will stop music.			;
;									;
; This routine needs some workspace after the module to work properly.	;
; We've set it to 16k, some modules needs more, some need less. If the	;
; workspace is too small, initialization will hang on an ILLEGAL	;
; instruction. Adjust workspace size to fit the specific module.	;
;									;
; MVOL = Main volume	  (Unnecessary to adjust. $80 default)		;
; FREQ = replay frequency (See below)					;
;-----------------------------------------------------------------------;

MVOL	EQU $80
FREQ	EQU 1				; 0=6.259, 1=12.517, 2=25.036
					; 3=50.072 (MegaSTe/TT)

	IFEQ FREQ
PARTS	EQU 5-1				; 6.259
LEN	EQU 25
INC	EQU $023BF313			; 3579546/6125*65536
	ELSEIF
	IFEQ FREQ-1
PARTS	EQU 5-1				; 12.517
LEN	EQU 50
INC	EQU $011DF989			; 3579546/12517*65536
	ELSEIF
	IFEQ FREQ-2
PARTS	EQU 5-1				; 25.035
LEN	EQU 100
INC	EQU $008EFB4E			; 3579546/25035*65536
	ELSEIF
	IFEQ FREQ-3
PARTS	EQU 5-1				; 50.072
LEN	EQU 200
INC	EQU $00477CEC			; 3579546/50072*65536
	ELSEIF
	FAIL
	END
	ENDC
	ENDC
	ENDC
	ENDC


	opt	o+,w-

		bsr	set_up
		tst.w	ste_flag
		beq.s	finish
		move.w	#$2300,sr


		move.w	pic1+6,$ffff8246.w	;prevent colour overlap
;	move.w	#007,$ffff8246.w

****** REMEMBER:
******          FROM HERE ONWARDS THE SCREEN IS 320 BYTES LONG
******


main_loop
		ifeq	DISASSEM
	bsr	vsync
		elseif
		movem.l	d0/d1/d2/a0/a1/a2,-(sp)
		move.w	#$25,-(sp)
		trap	#14
		addq.l	#2,sp
		movem.l	(sp)+,d0/d1/d2/a0/a1/a2
		endc


;	move.w	#$123,$ffff8240.w

		bsr	hardware_scroll
		bsr	software_scroll

	bsr	scroller

;	clr.w	$ffff8240.w


		cmp.b	#$39,$fffffc02.w
		bne.s	main_loop


		clr.b	$ffff8264.w		;bit offset

* $ffff820e is byte on STE ($ffff820f)
* $ffff820e is word on Falcon
		move.b	#0,$ffff820f.w		;offset to next word of screen
		move.w	#0,$ffff8264.w

		move.l	old_vbl,$70.w

		bsr	set_old_palette

		move.w	#1,-(sp)
		move.l	#-1,-(sp)
		move.l	(sp),-(sp)
		move.w	#5,-(sp)
		trap	#14
		add.l	#12,sp

finish		move.b	#$8,$fffffc02.w

		ifeq	DOWNLOAD
		bsr	set_user
		endc

		ifne	DOWNLOAD
		move.l	4.w,-(sp)
		rts
		endc

		clr.w	-(sp)
		trap	#1


*******************
* CUSTOM ROUTINES *
*******************

scroller
	rts










hardware_scroll	move.l	offset_pointer,a0
.get		move.l	(a0)+,d0
		bpl.s	.no_reset
		lea	table1,a0
		move.l	(a0)+,d0
*here we go to do hardware scroll
.no_reset	move.l	a0,offset_pointer
		move.w	d0,d1
		move.w	d0,d2
		move.l	d0,d4
		swap	d4
		move.w	d0,screen2_pixel_offset	;0-15 shift number

		and.l	#$f0,d1		;shift = /8
		lsr.w	#1,d1

		move.l	scr_now,d6
		and.l	#$ff00,d2	;256 boundary
		lsr.l	#1,d2
		add.w	d1,d2
		add.l	d2,d6

		; Y offset
		move.l	d4,d5	;*320	4 cycles
		lsl.l	#8,d4	;	24
		lsl.l	#6,d5	;	20
		add.l	d5,d4	;	8

		add.l	d4,d6
		move.l	d6,hard_addr
* screen 2
		add.l	d4,d2
		move.l	d2,screen2_address	;address to print screen 2
*

		and.w	#15,d0		;bit shift
		bne.s	.extra_fetch

		ifeq	DISASSEM
		move.b	#LINEWID,$ffff820f.w	;offset to next line
		move.b	d0,$ffff8265.w		;pixel shift
		endc
		move.b	hard_addr+1,$ffff8205.w
		move.b	hard_addr+2,$ffff8207.w
		move.b	hard_addr+3,$ffff8209.w
		rts
.extra_fetch
		ifeq	DISASSEM
		move.b	#LINEWID-4,$ffff820f.w	;offset to next line
		move.b	d0,$ffff8265.w		;pixel shift
		endc
		move.b	hard_addr+1,$ffff8205.w
		move.b	hard_addr+2,$ffff8207.w
		move.b	hard_addr+3,$ffff8209.w
		rts









*Software scroll routine will get offset from table and lookup correct
* preshifted picture, add screen word offset and display.
software_scroll
		lea	pic2_data,a0		;pre shifted data start
		move.w	screen2_pixel_offset,d0	;pixel shift of hard scroll rout
		and.w	#$f,d0			;mask off for 16 bits
		mulu	#80*200,d0		;multiply screen data size

;	add.w	#20,d0	;for testing...

		add.l	d0,a0		;A0 now points to pre-scrolled picture


**now get the word offset from our table + Y offset
		move.l	table2_pointer,a2	;get offset into table
.get		move.l	(a2)+,d0		;get data
		bpl.s	.no_reset		;if positive (not -1) then continue
		lea	table2,a2		;get start of table
		move.l	(a2)+,d0		;get data
.no_reset	move.l	a2,table2_pointer	;save position in table

		move.l	d0,d1
		swap	d0
		and.w	#$ff,d0
		and.w	#255,d1

		move.w	d1,d2	;mulu #160,d1
		lsl.w	#7,d1
		lsl.w	#5,d2
		add.w	d2,d1


** now d0.w = word offset
** and d1.w = Y offset

		add.w	d1,d0
		add.w	d0,a0

		move.l	scr_now,a1	;screen that hardware is showing
		add.l	screen2_address,a1
		add.w	#2,a1	;A1 now points to position we want to draw new screen

destin	set	0
		rept	200
		move.w	(a0)+,(a1)		;12
		move.w	(a0)+,destin+8(a1)	;16
		move.w	(a0)+,destin+16(a1)	;16
		move.w	(a0)+,destin+24(a1)	;16
		move.w	(a0)+,destin+32(a1)	;16
		move.w	(a0)+,destin+40(a1)	;16
		move.w	(a0)+,destin+48(a1)	;16
		move.w	(a0)+,destin+56(a1)	;16
		move.w	(a0)+,destin+64(a1)	;16
		move.w	(a0)+,destin+72(a1)	;16
		move.w	(a0)+,destin+80(a1)	;16
		move.w	(a0)+,destin+88(a1)	;16
		move.w	(a0)+,destin+96(a1)	;16
		move.w	(a0)+,destin+104(a1)	;16
		move.w	(a0)+,destin+112(a1)	;16
		move.w	(a0)+,destin+120(a1)	;16
		move.w	(a0)+,destin+128(a1)	;16
		move.w	(a0)+,destin+136(a1)	;16
		move.w	(a0)+,destin+144(a1)	;16
		move.w	(a0)+,destin+152(a1)	;16
		move.w	(a0)+,destin+160(a1)	;16  needed cos hardware scroll displays an extra word
		lea	38(a0),a0		;8 cycles
		lea	320(a1),a1		;8 cycles
		endr
		rts






*make a picture of a 2 wide pi1
shift_pic2	lea	screens,a6
		lea	pic2+34+2,a0
		move.w	#200-1,d0
.move
offset	set	0
		rept	160/4
		move.l	offset(a0),(a6)+
offset	set	offset+4
		endr


offset	set	0
		rept	160/4
		move.l	offset(a0),(a6)+
offset	set	offset+4
		endr

		lea	160(a0),a0
		add.w	#8,a6

		dbf	d0,.move




**now make a picture for the software scroll
		lea	pic2_data,a6
* Save the screen then shift it
		move.w	#16-1,d1
.times16
		lea	screens,a0
		move.w	#200-1,d0
.loop
		move.w	(a0),(a6)+
		move.w	8(a0),(a6)+
		move.w	16(a0),(a6)+
		move.w	24(a0),(a6)+
		move.w	32(a0),(a6)+
		move.w	40(a0),(a6)+
		move.w	48(a0),(a6)+
		move.w	56(a0),(a6)+
		move.w	64(a0),(a6)+
		move.w	72(a0),(a6)+
		move.w	80(a0),(a6)+
		move.w	88(a0),(a6)+
		move.w	96(a0),(a6)+
		move.w	104(a0),(a6)+
		move.w	112(a0),(a6)+
		move.w	120(a0),(a6)+
		move.w	128(a0),(a6)+
		move.w	136(a0),(a6)+
		move.w	144(a0),(a6)+
		move.w	152(a0),(a6)+

		move.w	160(a0),(a6)+
		move.w	160+8(a0),(a6)+
		move.w	160+16(a0),(a6)+
		move.w	160+24(a0),(a6)+
		move.w	160+32(a0),(a6)+
		move.w	160+40(a0),(a6)+
		move.w	160+48(a0),(a6)+
		move.w	160+56(a0),(a6)+
		move.w	160+64(a0),(a6)+
		move.w	160+72(a0),(a6)+
		move.w	160+80(a0),(a6)+
		move.w	160+88(a0),(a6)+
		move.w	160+96(a0),(a6)+
		move.w	160+104(a0),(a6)+
		move.w	160+112(a0),(a6)+
		move.w	160+120(a0),(a6)+
		move.w	160+128(a0),(a6)+
		move.w	160+136(a0),(a6)+
		move.w	160+144(a0),(a6)+
		move.w	160+152(a0),(a6)+

		lea	328(a0),a0
		dbf	d0,.loop

		lea	screens,a0
		move.w	#200-1,d0
.shift
		roxr	(a0)
		roxr	8(a0)
		roxr	16(a0)
		roxr	24(a0)
		roxr	32(a0)
		roxr	40(a0)
		roxr	48(a0)
		roxr	56(a0)
		roxr	64(a0)
		roxr	72(a0)
		roxr	80(a0)
		roxr	88(a0)
		roxr	96(a0)
		roxr	104(a0)
		roxr	112(a0)
		roxr	120(a0)
		roxr	128(a0)
		roxr	136(a0)
		roxr	144(a0)
		roxr	152(a0)

		roxr	160+0(a0)
		roxr	160+8(a0)
		roxr	160+16(a0)
		roxr	160+24(a0)
		roxr	160+32(a0)
		roxr	160+40(a0)
		roxr	160+48(a0)
		roxr	160+56(a0)
		roxr	160+64(a0)
		roxr	160+72(a0)
		roxr	160+80(a0)
		roxr	160+88(a0)
		roxr	160+96(a0)
		roxr	160+104(a0)
		roxr	160+112(a0)
		roxr	160+120(a0)
		roxr	160+128(a0)
		roxr	160+136(a0)
		roxr	160+144(a0)
		roxr	160+152(a0)

		lea	328(a0),a0
		dbf	d0,.shift

		dbf	d1,.times16
		rts








vsync
		move.w	#-1,vsync_flag
.sync		tst.w	vsync_flag
		bne.s	.sync
		rts





***********************
* SUBROUTINES SECTION *
***********************
v_sync	movem.l	d0-d3/a0-a3,-(sp)
	move.w	#$25,-(sp)
	trap	#14
	addq.l	#2,sp
	movem.l	(sp)+,d0-d3/a0-a3
	rts

tst_key	move.w	#11,-(sp)
	trap	#1
	addq.l	#2,sp
	rts

get_key	move.w	#7,-(sp)
	trap	#1
	addq.l	#2,sp
	rts


set_user
	move.l	stack_save,-(sp)
	move.w	#$20,-(sp)
	trap	#1
	addq.l	#6,sp
	rts


set_old_palette
	lea	old_st_palette,a0
set_pal	lea	$ffff8240.w,a1
	movem.l	(a0),d0-d7
	movem.l	d0-d7,(a1)
	rts




set_up
		ifeq	DOWNLOAD
		clr.l	-(sp)		;supervisor
		move.w	#$20,-(sp)
		trap	#1
		addq.l	#6,sp
		move.l	d0,stack_save
		endc

		move.b	#$12,$fffffc02.w	;DI mouse

		move.w	#3,-(sp)	;get screen base
		trap	#14
		addq.l	#2,sp
		move.l	d0,screen_base

		movem.l	$ffff8240.w,d0-d7
		movem.l	d0-d7,old_st_palette

		move.w	#$2700,sr
		move.l	$70.w,old_vbl
		bclr	#3,$fffffa17.w

		bsr	test_for_ste

		move.w	#4,-(sp)	;get_original_rez
		trap	#14
		addq.l	#2,sp
		move.w	d0,original_rez

	ifeq	DEVELOP
		movem.l	pic1+2,d0-d7
		movem.l	d0-d7,$ffff8240.w
	endc

		clr.w	-(sp)
		move.l	#-1,-(sp)
		move.l	(sp),-(sp)
		move.w	#5,-(sp)
		trap	#14
		add.l	#12,sp

		move.l	#screens,d0
		clr.b	d0
		move.l	d0,scr_now

		bsr	text_on

		bsr	shift_pic2

		clr.b	$484.w
***development code...
		ifne	DEVELOP
		movem.l	pic1+2,d0-d7
		movem.l	d0-d7,$ffff8240.w
		lea	pic1+34,a0
		move.l	scr_now,a1
		move.w	#200-1,d0
.loop
offset	set	0
		rept	40
		move.l	(a0)+,offset(a1)
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop


*set up pic 2
		lea	pic2+34,a0
		move.l	scr_now,a1
		lea	160(a1),a1
		move.w	#200-1,d0
.loop2
offset	set	0
		rept	40
		move.l	(a0)+,offset(a1)
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop2


*set up pic 3
		lea	pic3+34,a0
		move.l	scr_now,a1
		add.l	#320*200,a1
		move.w	#200-1,d0
.loop3
offset	set	0
		rept	40
		move.l	(a0)+,offset(a1)
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop3

*set up pic 4
		lea	pic4+34,a0
		move.l	scr_now,a1
		add.l	#320*200+160,a1
		move.w	#200-1,d0
.loop4
offset	set	0
		rept	40
		move.l	(a0)+,offset(a1)
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop4
		endc
****end of development code




*This bit will make the main backdrop into a 2*2 matrix (hardware scrolled screens)
		ifeq	DEVELOP		;only do this if development is set to NO
		lea	pic1+34,a5
		move.l	scr_now,a4


		move.l	a5,a0
		move.l	a4,a1
		move.w	#200-1,d0
.loop
offset	set	0
		rept	40
		move.l	(a0),offset(a1)		;pic1
		move.l	(a0)+,offset+160(a1)	;pic2
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop


*set up pic 3
		move.l	a5,a0
		move.l	a4,a1
		add.l	#320*200,a1
		move.w	#200-1,d0
.loop3
offset	set	0
		rept	40
		move.l	(a0),offset(a1)		;pic 3
		move.l	(a0)+,offset+160(a1)	;set up pic 4
offset	set	offset+4
		endr
		lea	320(a1),a1
		dbf	d0,.loop3
		endc


*start of mod setup
;---------------------------------------------------- Interrupts on/off --
muson	jsr	vol			; Calculate volume tables
	jsr	incrcal			; Calculate tonetables

	jsr	init			; Initialize music
	jsr	prepare			; Prepare samples

	move	#$2700,sr

	bset	#5,$FFFFFA07.w
	bset	#5,$FFFFFA13.w

	clr.b	$FFFFFA19.w
	move.b	#1,$FFFFFA1F.w
	move.b	#8,$FFFFFA19.w

	move.l	$0134.w,oldtima
	move.l	#stereo,$0134.w

	move.b	#FREQ,$FFFF8921.w		; Frequency

	lea	$FFFF8907.w,a0

	move.l	#sample1,d0
	move.b	d0,(a0)
	lsr.w	#8,d0
	move.l	d0,-5(a0)

	move.l	#sample1+LEN*2,d0
	move.b	d0,12(a0)
	lsr.w	#8,d0
	move.l	d0,7(a0)

	move.b	#3,$FFFF8901.w		; Start DMA
**end of mod setup

		ifeq	DEVELOP		;only do this if development is set to NO
		movem.l	pic1+2,d0-d7
		movem.l	d0-d7,$ffff8240.w
		endc

		move.b	#80,$ffff820f.w	;word offset to next line +160
		move.l	#newvbl,$70.w
		move.w	#$2300,sr
		rts



test_for_ste	lea	$ffff8205.w,a5
		move.b	(a5),d0		;get original value
		move.b	#-1,(a5)	;poke new value
		cmp.b	(a5),d0		;get value again, is it same?
		bne	.notSTE		;yes same so not ste
		move.b	d0,(a5)		;yes so poke original value back
.ste_found	move.w	#-1,ste_flag
.notSTE		rts



*** ISRs
newvbl		clr.w	vsync_flag
		rte


text_on		bsr	set_screen
		move.l	scr_now,a1
		lea	ascii,a2
	move.w	#$777,$ffff8242.w
		move.l	a1,a6
.loop		moveq	#0,d7
		move.b	(a2)+,d7
		beq	aquit
		cmp.b	#10,d7
		bne.s	.nocrlf
		add.w	#160*16,a1
		move.l	a1,a6
		bra.s	.loop
.nocrlf		sub.w	#32,d7
		mulu	#32,d7
		lea	font,a3
		add.w	d7,a3
offset		set	0
		rept	16
		bsr	pause
		move.w	(a3)+,offset(a6)
offset		set	offset+160
		endr
		add.w	#8,a6
		bra	.loop
aquit		move.w	#$2300,sr
		move.w	#800,d7
.wait		move.w	#$25,-(sp)
		trap	#14
		add.w	#2,sp
		cmp.b	#$39,$fffffc02.w
		beq.s	.yes
		dbf	d7,.wait
.yes		movem.l	black,d0-d7
		movem.l	d0-d7,$ffff8240.w
		rts


set_screen	move.l	scr_now,d6
		lsr.l	#8,d6
		lea	$ffff8201.w,a6
		movep.w	d6,(a6)
		rts


pause		move.w	#500,d5
.nop		nop
		dbf	d5,.nop
		rts







;--------------------------------------------------------- Volume table --
vol	moveq	#64,d0
	lea	vtabend,a0

.ploop	move.w	#255,d1
.mloop	move.w	d1,d2
	ext.w	d2
	muls	d0,d2
	divs	#MVOL,d2		; <---- Master volume
	move.b	d2,-(a0)
	dbra	d1,.mloop
	dbra	d0,.ploop

	rts


;------------------------------------------------------ Increment-table --
incrcal	lea	stab(pc),a0
	move.w	#$30,d1
	move.w	#$039F-$30,d0
	move.l	#INC,d2

recalc	swap	d2
	moveq	#0,d3
	move.w	d2,d3
	divu	d1,d3
	move.w	d3,d4
	swap	d4

	swap	d2
	move.w	d2,d3
	divu	d1,d3
	move.w	d3,d4
	move.l	d4,(a0)+

	addq.w	#1,d1
	dbra	d0,recalc
	rts

itab	DS.L $30
stab	DS.L $03A0-$30

;-------------------------------------------------------- DMA interrupt --
stereo	move	#$2500,sr
	bclr	#5,$FFFFFA0F.w
	movem.l	d0-a6,-(sp)

	move.l	samp1(pc),d0
	move.l	samp2(pc),samp1
	move.l	d0,samp2

	lea	$FFFF8907.w,a0

	move.l	samp1(pc),d0
	move.b	d0,(a0)
	lsr.w	#8,d0
	move.l	d0,-5(a0)

	move.l	samp1(pc),d0
	add.l	#LEN*2,d0
	move.b	d0,12(a0)
	lsr.w	#8,d0
	move.l	d0,7(a0)

	subq.w	#1,count
	bpl.s	.nomus

	move.w	#PARTS,count
	bsr	music

.nomus	lea	itab(pc),a5
	lea	vtab,a3
	moveq	#0,d0
	moveq	#0,d4

v1	movea.l	wiz2lc(pc),a0

	move.w	wiz2pos(pc),d0
	move.w	wiz2frc(pc),d1

	move.w	aud2per(pc),d7
	add.w	d7,d7
	add.w	d7,d7
	move.w	0(a5,d7.w),d2

	movea.w	2(a5,d7.w),a4

	move.w	aud2vol(pc),d7
	asl.w	#8,d7
	lea	0(a3,d7.w),a2


	movea.l	wiz3lc(pc),a1

	move.w	wiz3pos(pc),d4
	move.w	wiz3frc(pc),d5

	move.w	aud3per(pc),d7
	add.w	d7,d7
	add.w	d7,d7
	move.w	0(a5,d7.w),d6
	movea.w	2(a5,d7.w),a5

	move.w	aud3vol(pc),d7
	asl.w	#8,d7
	lea	0(a3,d7.w),a3

	movea.l	samp1(pc),a6
	moveq	#0,d3

	REPT LEN
	add.w	a4,d1
	addx.w	d2,d0
	add.w	a5,d5
	addx.w	d6,d4
	move.b	0(a0,d0.l),d3
	move.b	0(a2,d3.w),d7
	move.b	0(a1,d4.l),d3
	add.b	0(a3,d3.w),d7
	move.w	d7,(a6)+
	ENDR

	cmp.l	wiz2len(pc),d0
	blt.s	.ok2
	sub.w	wiz2rpt(pc),d0

.ok2	move.w	d0,wiz2pos
	move.w	d1,wiz2frc

	cmp.l	wiz3len(pc),d4
	blt.s	.ok3
	sub.w	wiz3rpt(pc),d4

.ok3	move.w	d4,wiz3pos
	move.w	d5,wiz3frc



	lea	itab(pc),a5
	lea	vtab,a3
	moveq	#0,d0
	moveq	#0,d4

v2	movea.l	wiz1lc(pc),a0

	move.w	wiz1pos(pc),d0
	move.w	wiz1frc(pc),d1

	move.w	aud1per(pc),d7
	add.w	d7,d7
	add.w	d7,d7
	move.w	0(a5,d7.w),d2
	movea.w	2(a5,d7.w),a4

	move.w	aud1vol(pc),d7
	asl.w	#8,d7
	lea	0(a3,d7.w),a2


	movea.l	wiz4lc(pc),a1

	move.w	wiz4pos(pc),d4
	move.w	wiz4frc(pc),d5

	move.w	aud4per(pc),d7
	add.w	d7,d7
	add.w	d7,d7
	move.w	0(a5,d7.w),d6
	movea.w	2(a5,d7.w),a5

	move.w	aud4vol(pc),d7
	asl.w	#8,d7
	lea	0(a3,d7.w),a3

	movea.l	samp1(pc),a6
	moveq	#0,d3

	REPT LEN
	add.w	a4,d1
	addx.w	d2,d0
	add.w	a5,d5
	addx.w	d6,d4
	move.b	0(a0,d0.l),d3
	move.b	0(a2,d3.w),d7
	move.b	0(a1,d4.l),d3
	add.b	0(a3,d3.w),d7
	move.b	d7,(a6)
	addq.w	#2,a6
	ENDR

	cmp.l	wiz1len(pc),d0
	blt.s	.ok1
	sub.w	wiz1rpt(pc),d0

.ok1	move.w	d0,wiz1pos
	move.w	d1,wiz1frc

	cmp.l	wiz4len(pc),d4
	blt.s	.ok4
	sub.w	wiz4rpt(pc),d4

.ok4	move.w	d4,wiz4pos
	move.w	d5,wiz4frc

	movem.l	(sp)+,d0-a6
	rte

;-------------------------------------------- Hardware-registers & data --
count	DC.W PARTS

wiz1lc	DC.L sample1
wiz1len	DC.L 0
wiz1rpt	DC.W 0
wiz1pos	DC.W 0
wiz1frc	DC.W 0

wiz2lc	DC.L sample1
wiz2len	DC.L 0
wiz2rpt	DC.W 0
wiz2pos	DC.W 0
wiz2frc	DC.W 0

wiz3lc	DC.L sample1
wiz3len	DC.L 0
wiz3rpt	DC.W 0
wiz3pos	DC.W 0
wiz3frc	DC.W 0

wiz4lc	DC.L sample1
wiz4len	DC.L 0
wiz4rpt	DC.W 0
wiz4pos	DC.W 0
wiz4frc	DC.W 0

aud1lc	DC.L dummy
aud1len	DC.W 0
aud1per	DC.W 0
aud1vol	DC.W 0
	DS.W 3

aud2lc	DC.L dummy
aud2len	DC.W 0
aud2per	DC.W 0
aud2vol	DC.W 0
	DS.W 3

aud3lc	DC.L dummy
aud3len	DC.W 0
aud3per	DC.W 0
aud3vol	DC.W 0
	DS.W 3

aud4lc	DC.L dummy
aud4len	DC.W 0
aud4per	DC.W 0
aud4vol	DC.W 0

dmactrl	DC.W 0

dummy	DC.L 0

samp1	DC.L sample1
samp2	DC.L sample2

sample1	DS.W LEN
sample2	DS.W LEN

;========================================================= EMULATOR END ==

prepare	lea	workspc,a6
	movea.l	samplestarts(pc),a0
	movea.l	end_of_samples(pc),a1

tostack	move.w	-(a1),-(a6)
	cmpa.l	a0,a1			; Move all samples to stack
	bgt.s	tostack

	lea	samplestarts(pc),a2
	lea	mod(pc),a1		; Module
	movea.l	(a2),a0			; Start of samples
	movea.l	a0,a5			; Save samplestart in a5

	moveq	#30,d7

roop	move.l	a0,(a2)+		; Sampleposition

	tst.w	$2A(a1)
	beq.s	samplok			; Len=0 -> no sample

	tst.w	$2E(a1)			; Test repstrt
	bne.s	repne			; Jump if not zero


repeq	move.w	$2A(a1),d0		; Length of sample
	move.w	d0,d4
	subq.w	#1,d0

	movea.l	a0,a4
fromstk	move.w	(a6)+,(a0)+		; Move all samples back from stack
	dbra	d0,fromstk

	bra.s	rep



repne	move.w	$2E(a1),d0
	move.w	d0,d4
	subq.w	#1,d0

	movea.l	a6,a4
get1st	move.w	(a4)+,(a0)+		; Fetch first part
	dbra	d0,get1st

	adda.w	$2A(a1),a6		; Move a6 to next sample
	adda.w	$2A(a1),a6



rep	movea.l	a0,a5
	moveq	#0,d1
toosmal	movea.l	a4,a3
	move.w	$30(a1),d0
	subq.w	#1,d0
moverep	move.w	(a3)+,(a0)+		; Repeatsample
	addq.w	#2,d1
	dbra	d0,moverep
	cmp.w	#320,d1			; Must be > 320
	blt.s	toosmal

	move.w	#320/2-1,d2
last320	move.w	(a5)+,(a0)+		; Safety 320 bytes
	dbra	d2,last320

done	add.w	d4,d4

	move.w	d4,$2A(a1)		; length
	move.w	d1,$30(a1)		; Replen
	clr.w	$2E(a1)

samplok	lea	$1E(a1),a1
	dbra	d7,roop

	cmp.l	#workspc,a0
	bgt.s	.nospac

	rts

.nospac	illegal

end_of_samples	DC.L 0

;------------------------------------------------------ Main replayrout --
init	lea	mod(pc),a0
	lea	$03B8(a0),a1

	moveq	#$7F,d0
	moveq	#0,d1
loop	move.l	d1,d2
	subq.w	#1,d0
lop2	move.b	(a1)+,d1
	cmp.b	d2,d1
	bgt.s	loop
	dbra	d0,lop2
	addq.b	#1,d2

	lea	samplestarts(pc),a1
	asl.l	#8,d2
	asl.l	#2,d2
	add.l	#$043C,d2
	add.l	a0,d2
	movea.l	d2,a2

	moveq	#$1E,d0
lop3	clr.l	(a2)
	move.l	a2,(a1)+
	moveq	#0,d1
	move.w	42(a0),d1
	add.l	d1,d1
	adda.l	d1,a2
	adda.l	#$1E,a0
	dbra	d0,lop3

	move.l	a2,end_of_samples	;
	rts

music	lea	mod(pc),a0
	addq.w	#$01,counter
	move.w	counter(pc),d0
	cmp.w	speed(pc),d0
	blt.s	nonew
	clr.w	counter
	bra	getnew

nonew	lea	voice1(pc),a4
	lea	aud1lc(pc),a3
	bsr	checkcom
	lea	voice2(pc),a4
	lea	aud2lc(pc),a3
	bsr	checkcom
	lea	voice3(pc),a4
	lea	aud3lc(pc),a3
	bsr	checkcom
	lea	voice4(pc),a4
	lea	aud4lc(pc),a3
	bsr	checkcom
	bra	endr

arpeggio
	moveq	#0,d0
	move.w	counter(pc),d0
	divs	#$03,d0
	swap	d0
	tst.w	d0
	beq.s	arp2
	cmp.w	#$02,d0
	beq.s	arp1

	moveq	#0,d0
	move.b	$03(a4),d0
	lsr.b	#4,d0
	bra.s	arp3

arp1	moveq	#0,d0
	move.b	$03(a4),d0
	and.b	#$0F,d0
	bra.s	arp3

arp2	move.w	$10(a4),d2
	bra.s	arp4

arp3	add.w	d0,d0
	moveq	#0,d1
	move.w	$10(a4),d1
	lea	periods(pc),a0
	moveq	#$24,d4
arploop	move.w	0(a0,d0.w),d2
	cmp.w	(a0),d1
	bge.s	arp4
	addq.l	#2,a0
	dbra	d4,arploop
	rts

arp4	move.w	d2,$06(a3)
	rts

getnew	lea	mod+$043C(pc),a0
	lea	-$043C+$0C(a0),a2
	lea	-$043C+$03B8(a0),a1

	moveq	#0,d0
	move.l	d0,d1
	move.b	songpos(pc),d0
	move.b	0(a1,d0.w),d1
	asl.l	#8,d1
	asl.l	#2,d1
	add.w	pattpos(pc),d1
	clr.w	dmacon

	lea	aud1lc(pc),a3
	lea	voice1(pc),a4
	bsr.s	playvoice
	lea	aud2lc(pc),a3
	lea	voice2(pc),a4
	bsr.s	playvoice
	lea	aud3lc(pc),a3
	lea	voice3(pc),a4
	bsr.s	playvoice
	lea	aud4lc(pc),a3
	lea	voice4(pc),a4
	bsr.s	playvoice
	bra	setdma

playvoice
	move.l	0(a0,d1.l),(a4)
	addq.l	#4,d1
	moveq	#0,d2
	move.b	$02(a4),d2
	and.b	#$F0,d2
	lsr.b	#4,d2
	move.b	(a4),d0
	and.b	#$F0,d0
	or.b	d0,d2
	tst.b	d2
	beq.s	setregs
	moveq	#0,d3
	lea	samplestarts(pc),a1
	move.l	d2,d4
	subq.l	#$01,d2
	asl.l	#2,d2
	mulu	#$1E,d4
	move.l	0(a1,d2.l),$04(a4)
	move.w	0(a2,d4.l),$08(a4)
	move.w	$02(a2,d4.l),$12(a4)
	move.w	$04(a2,d4.l),d3
	tst.w	d3
	beq.s	noloop
	move.l	$04(a4),d2
	add.w	d3,d3
	add.l	d3,d2
	move.l	d2,$0A(a4)
	move.w	$04(a2,d4.l),d0
	add.w	$06(a2,d4.l),d0
	move.w	d0,8(a4)
	move.w	$06(a2,d4.l),$0E(a4)
	move.w	$12(a4),$08(a3)
	bra.s	setregs

noloop	move.l	$04(a4),d2
	add.l	d3,d2
	move.l	d2,$0A(a4)
	move.w	$06(a2,d4.l),$0E(a4)
	move.w	$12(a4),$08(a3)
setregs	move.w	(a4),d0
	and.w	#$0FFF,d0
	beq	checkcom2
	move.b	$02(a4),d0
	and.b	#$0F,d0
	cmp.b	#$03,d0
	bne.s	setperiod
	bsr	setmyport
	bra	checkcom2

setperiod
	move.w	(a4),$10(a4)
	andi.w	#$0FFF,$10(a4)
	move.w	$14(a4),d0
	move.w	d0,dmactrl
	clr.b	$1B(a4)

	move.l	$04(a4),(a3)
	move.w	$08(a4),$04(a3)
	move.w	$10(a4),d0
	and.w	#$0FFF,d0
	move.w	d0,$06(a3)
	move.w	$14(a4),d0
	or.w	d0,dmacon
	bra	checkcom2

setdma	move.w	dmacon(pc),d0

	btst	#0,d0			;-------------------
	beq.s	wz_nch1			;
	move.l	aud1lc(pc),wiz1lc	;
	moveq	#0,d1			;
	moveq	#0,d2			;
	move.w	aud1len(pc),d1		;
	move.w	voice1+$0E(pc),d2	;
	add.l	d2,d1			;
	move.l	d1,wiz1len		;
	move.w	d2,wiz1rpt		;
	clr.w	wiz1pos			;

wz_nch1	btst	#1,d0			;
	beq.s	wz_nch2			;
	move.l	aud2lc(pc),wiz2lc	;
	moveq	#0,d1			;
	moveq	#0,d2			;
	move.w	aud2len(pc),d1		;
	move.w	voice2+$0E(pc),d2	;
	add.l	d2,d1			;
	move.l	d1,wiz2len		;
	move.w	d2,wiz2rpt		;
	clr.w	wiz2pos			;

wz_nch2	btst	#2,d0			;
	beq.s	wz_nch3			;
	move.l	aud3lc(pc),wiz3lc	;
	moveq	#0,d1			;
	moveq	#0,d2			;
	move.w	aud3len(pc),d1		;
	move.w	voice3+$0E(pc),d2	;
	add.l	d2,d1			;
	move.l	d1,wiz3len		;
	move.w	d2,wiz3rpt		;
	clr.w	wiz3pos			;

wz_nch3	btst	#3,d0			;
	beq.s	wz_nch4			;
	move.l	aud4lc(pc),wiz4lc	;
	moveq	#0,d1			;
	moveq	#0,d2			;
	move.w	aud4len(pc),d1		;
	move.w	voice4+$0E(pc),d2	;
	add.l	d2,d1			;
	move.l	d1,wiz4len		;
	move.w	d2,wiz4rpt		;
	clr.w	wiz4pos			;-------------------

wz_nch4	addi.w	#$10,pattpos
	cmpi.w	#$0400,pattpos
	bne.s	endr
nex	clr.w	pattpos
	clr.b	break
	addq.b	#1,songpos
	andi.b	#$7F,songpos
	move.b	songpos(pc),d1
	cmp.b	mod+$03B6(pc),d1
	bne.s	endr
	move.b	mod+$03B7(pc),songpos
endr:	tst.b	break
	bne.s	nex
	rts

setmyport
	move.w	(a4),d2
	and.w	#$0FFF,d2
	move.w	d2,$18(a4)
	move.w	$10(a4),d0
	clr.b	$16(a4)
	cmp.w	d0,d2
	beq.s	clrport
	bge.s	rt
	move.b	#$01,$16(a4)
	rts

clrport	clr.w	$18(a4)
rt	rts

myport	move.b	$03(a4),d0
	beq.s	myslide
	move.b	d0,$17(a4)
	clr.b	$03(a4)
myslide	tst.w	$18(a4)
	beq.s	rt
	moveq	#0,d0
	move.b	$17(a4),d0
	tst.b	$16(a4)
	bne.s	mysub
	add.w	d0,$10(a4)
	move.w	$18(a4),d0
	cmp.w	$10(a4),d0
	bgt.s	myok
	move.w	$18(a4),$10(a4)
	clr.w	$18(a4)

myok	move.w	$10(a4),$06(a3)
	rts

mysub	sub.w	d0,$10(a4)
	move.w	$18(a4),d0
	cmp.w	$10(a4),d0
	blt.s	myok
	move.w	$18(a4),$10(a4)
	clr.w	$18(a4)
	move.w	$10(a4),$06(a3)
	rts

vib	move.b	$03(a4),d0
	beq.s	vi
	move.b	d0,$1A(a4)

vi	move.b	$1B(a4),d0
	lea	sin(pc),a1
	lsr.w	#$02,d0
	and.w	#$1F,d0
	moveq	#0,d2
	move.b	0(a1,d0.w),d2
	move.b	$1A(a4),d0
	and.w	#$0F,d0
	mulu	d0,d2
	lsr.w	#$06,d2
	move.w	$10(a4),d0
	tst.b	$1B(a4)
	bmi.s	vibmin
	add.w	d2,d0
	bra.s	vib2

vibmin	sub.w	d2,d0
vib2	move.w	d0,$06(a3)
	move.b	$1A(a4),d0
	lsr.w	#$02,d0
	and.w	#$3C,d0
	add.b	d0,$1B(a4)
	rts

nop:	move.w	$10(a4),$06(a3)
	rts

checkcom
	move.w	$02(a4),d0
	and.w	#$0FFF,d0
	beq.s	nop
	move.b	$02(a4),d0
	and.b	#$0F,d0
	tst.b	d0
	beq	arpeggio
	cmp.b	#$01,d0
	beq.s	portup
	cmp.b	#$02,d0
	beq	portdown
	cmp.b	#$03,d0
	beq	myport
	cmp.b	#$04,d0
	beq	vib
	cmp.b	#$05,d0
	beq	port_toneslide
	cmp.b	#$06,d0
	beq	vib_toneslide
	move.w	$10(a4),$06(a3)
	cmp.b	#$0A,d0
	beq.s	volslide
	rts

volslide
	moveq	#0,d0
	move.b	$03(a4),d0
	lsr.b	#4,d0
	tst.b	d0
	beq.s	voldown
	add.w	d0,$12(a4)
	cmpi.w	#$40,$12(a4)
	bmi.s	vol2
	move.w	#$40,$12(a4)
vol2	move.w	$12(a4),$08(a3)
	rts

voldown	moveq	#0,d0
	move.b	$03(a4),d0
	and.b	#$0F,d0
	sub.w	d0,$12(a4)
	bpl.s	vol3
	clr.w	$12(a4)
vol3	move.w	$12(a4),$08(a3)
	rts

portup	moveq	#0,d0
	move.b	$03(a4),d0
	sub.w	d0,$10(a4)
	move.w	$10(a4),d0
	and.w	#$0FFF,d0
	cmp.w	#$71,d0
	bpl.s	por2
	andi.w	#$F000,$10(a4)
	ori.w	#$71,$10(a4)
por2	move.w	$10(a4),d0
	and.w	#$0FFF,d0
	move.w	d0,$06(a3)
	rts

port_toneslide
	bsr	myslide
	bra.s	volslide

vib_toneslide
	bsr	vi
	bra.s	volslide

portdown
	clr.w	d0
	move.b	$03(a4),d0
	add.w	d0,$10(a4)
	move.w	$10(a4),d0
	and.w	#$0FFF,d0
	cmp.w	#$0358,d0
	bmi.s	por3
	andi.w	#$F000,$10(a4)
	ori.w	#$0358,$10(a4)
por3	move.w	$10(a4),d0
	and.w	#$0FFF,d0
	move.w	d0,$06(a3)
	rts

checkcom2
	move.b	$02(a4),d0
	and.b	#$0F,d0
	cmp.b	#$0D,d0
	beq.s	pattbreak
	cmp.b	#$0B,d0
	beq.s	posjmp
	cmp.b	#$0C,d0
	beq.s	setvol
	cmp.b	#$0F,d0
	beq.s	setspeed
	rts

pattbreak
	st	break
	rts

posjmp	move.b	$03(a4),d0
	subq.b	#$01,d0
	move.b	d0,songpos
	st	break
	rts

setvol	moveq	#0,d0
	move.b	$03(a4),d0
	cmp.w	#$40,d0
	ble.s	vol4
	move.b	#$40,$03(a4)
vol4	move.b	$03(a4),$09(a3)
	move.b	$03(a4),$13(a4)
	rts

setspeed
	cmpi.b	#$1F,$03(a4)
	ble.s	sets
	move.b	#$1F,$03(a4)
sets	move.b	$03(a4),d0
	beq.s	rts2
	move.w	d0,speed
	clr.w	counter
rts2	rts




		ifeq	DOWNLOAD
*******************
   SECTION DATA
*******************
		endc



sin	DC.B $00,$18,$31,$4A,$61,$78,$8D,$A1,$B4,$C5,$D4,$E0,$EB,$F4,$FA,$FD
	DC.B $FF,$FD,$FA,$F4,$EB,$E0,$D4,$C5,$B4,$A1,$8D,$78,$61,$4A,$31,$18

periods	DC.W $0358,$0328,$02FA,$02D0,$02A6,$0280,$025C,$023A,$021A,$01FC,$01E0
	DC.W $01C5,$01AC,$0194,$017D,$0168,$0153,$0140,$012E,$011D,$010D,$FE
	DC.W $F0,$E2,$D6,$CA,$BE,$B4,$AA,$A0,$97,$8F,$87
	DC.W $7F,$78,$71,$00,$00

speed	DC.W $06
counter	DC.W $00
songpos	DC.B $00
break	DC.B $00
pattpos	DC.W $00

dmacon		DC.W $00
samplestarts	DS.L $1F

voice1	DS.W 10
	DC.W $01
	DS.W 3
voice2	DS.W 10
	DC.W $02
	DS.W 3
voice3	DS.W 10
	DC.W $04
	DS.W 3
voice4	DS.W 10
	DC.W $08
	DS.W 3

mod	INCBIN ronken.MOD

	DS.B	16384			; Workspace
workspc	DS.W	1

***mod bits end


	even




	ifne	DEVELOP
pic1		incbin	"develop\1.pi1"
pic2		incbin	"develop\2.pi1"
pic3		incbin	"develop\3.pi1"
pic4		incbin	"develop\4.pi1"
		endc


offset_pointer	dc.l	table1

table1		incbin	sine1.dat
		dc.l	-1

** table 2 is made up of word offsets (.w) then Y offset (.w)
table2_pointer	dc.l	table2
table2

;table two is made up of 2 words for each screen update.
; The first word is the X offset (0,2,4,6,8..38)
; The second word is the Y offset in lines where 100 is a whole screen
		dc.w	0,1,0,2,0,3,0,4,0,5,0,6
		dc.w	0,7,0,8,0,9,0,10,0,11,0,12,0,13,0,14,0,15,0,16,0,17,0,18,0,19
		dc.w	0,20,0,21,0,22,0,23,0,24,0,25,0,26,0,27,0,28
		dc.w	0,29,0,30,0,31,0,32,0,33,0,34,0,35,0,36,0,37
		dc.w	0,38,0,39,0,40,0,41,0,42,0,43,0,44,0,45,0,46
		dc.l	047,48,49,50,51,52,53,54,55,56,57,58,59
		dc.l	60,61,62,63,64,65,66,67,68,69
		dc.l	70,71,72,73,74,75,76,77,78,79
		dc.l	80,81,82,83,84,85,86,87,88,89
		dc.l	90,91,92,93,94,95,96,97,98,99
	;	dc.l	100
		dc.w	0,99,2,99,4,99,6,99,8,99,10,99,12,99,14,99,16,99,18,99
;move screen to left
	dc.w	20,99,22,99,24,99,26,99,28,99,30,99,32,99,34,99,36,99,38,99

;move screen down
	dc.w	38,98,00,97,00,96,00,95,00,94,00,93,00,92,00,91
	dc.w	00,90,00,89,00,88,00,87,00,86,00,85,00,84,00,83,00,82,00,81
	dc.w	00,80,00,79,00,78,00,77,00,76,00,75,00,74,00,73,00,72,00,71
	dc.w	00,70,00,69,00,68,00,67,00,66,00,65,00,64,00,63,00,62,00,61
	dc.w	00,60,00,59,00,58,00,57,00,56,00,55,00,54,00,53,00,52,00,51
	dc.w	00,50,00,49,00,48,00,47,00,46,00,45,00,44,00,43,00,42,00,41

	dc.w	38,40,36,40,34,40,32,40,30,40,28,40,26,40,24,40,22,40,20,40
	dc.w	18,40,16,40,14,40,12,40,10,40,08,40,06,40,04,40,02,40

	dc.w	02,40,04,39,06,38,08,37,10,36,12,35,14,34,16,33,18,32,20,31
	dc.w	22,30,24,29,26,28,28,27,30,26,32,25,34,24,36,23,38,22,00,21
	dc.w	02,20,04,19,06,18,08,17,10,16,12,15,14,14,16,13,18,12,20,11
	dc.w	22,10,24,09,26,08,28,07,30,06,32,05,34,04,36,03,38,02,00,01


	dc.l	-1

font	incbin	med_font.dat

		;12345678901234567890
ascii	dc.b	"   TCB DID IT WITH",10
	dc.b	" JUST SOFTWARE MANY",10
	dc.b	"      YEARS AGO",10,10
	dc.b	"I STARTED TO RUN OUT",10
	dc.b	"OF MEMORY AND I USE",10
	dc.b	"    HARDWARE AND",10
	dc.b	"  SOFTWARE SCROLL.",10,10
	dc.b	"NO RIPPED CODE, JUST",10
	dc.b	"    RIPPED GRAFIX.",10
	dc.b	"             RESPECT"
	dc.b	0
	even


	ifeq	DEVELOP
pic1		incbin	tcb1.pi1
pic2		incbin	tcb2.pi1
	endc













		ifeq	DOWNLOAD
*******************
   SECTION BSS
*******************
		endc
stack_save	ds.l	1

ste_flag	ds.w	1
screen_base	ds.l	1
original_rez	ds.w	1
old_st_palette	ds.w	16
scr_now		ds.l	1


vsync_flag		ds.w	1
old_vbl			ds.l	1
hard_addr		ds.l	1
offset_into_tables	ds.w	1

screen2_address		ds.l	1
screen2_pixel_offset	ds.w	1

pic2_data
;The following line is the official space needed for the demo
	;	ds.b	16*8*22*200	;22 words by 200 lines (20 words for screen then 1 word each side)
;but... you can get away with the following space due to the shift tables in this code
; if you change the code, you may have to use the above line
	ds.b	16*8*16*200



black		ds.w	16



**mod bits

oldtima		ds.L 1

vtab		DS.B 65*256
vtabend



**mod bits end



* screens are    1 2
*                3 4
		ds.b	256
screens		ds.b	32000
		ds.b	32000
		ds.b	32000
		ds.b	32000



		ifne	DOWNLOAD
Code_End
Code_Length	equ	Code_End-Code_Start
		endc
