;	jmp	$30000
;	org	$30000
;	load	$30000	

	SECTION	"UB-DEMO-ANVIL",CODE_C

* CREDITS: ALL CODING BY ANVIL/CYTAX	; (27/28-JAN-91)+(01/02-MAR-91)

* THIS IS A PRODUCTION FOR ICE (International Computer Entertainment)
* ICE IS A TRADEMARK OF CYTAX INC.
* ALL RIGHTS RESERVED 

; -------------------------------

BUFFERS:	EQU	7
PLANES:		EQU	3			; 1-5
BITPLANES:	EQU	$40000
PLANEWIDTH:	EQU	40
PLANEHIGH:	EQU	256
PLANESIZE:	EQU	PLANEWIDTH*PLANEHIGH	; WIDTH IN WORDS*HIGH
BITPLANESIZE:	EQU	PLANEWIDTH*PLANES*PLANEHIGH

; -------------------------------

PROGSTART:

* JUMP INTO THE SUPERVISOR STATE MODE BY USING THE TRAP VECTORS


	MOVEM.L	D0-D7/A0-A6,-(A7)		; SAVE REGISTERS

	MOVE.L	$80,D0
	LEA	TRAP0VEC_BUF(PC),A0		; SAVE TRAP 0 VECTOR
	MOVE.L	D0,(A0)
	LEA	START(PC),A0			; START OF PRG TO A0
	MOVE.L	A0,$80				; MY PROGRAMM BEGIN
	TRAP	#0				; DO TRAP
	MOVE.L	TRAP0VEC_BUF(PC),$80		; RESTORE TRAP 0 VECTOR
	MOVEM.L	(A7)+,D0-D7/A0-A6		; LOAD REGISTERS
	MOVEQ.L	#0,D0				; CLEAR D0
	RTS					; RETURN
		
; -------------------------------

START:

	LEA.L	$DFF000,A5			; DMA BASIS ADR IN A5

	BSR.W	INSTALL
	
; -------------------------------

MAIN:

	BTST	#2,$16(A5)			; TEST IF RIGHT MOUSEBUTTON
	BEQ.W	RIGHTBUTTON

RIGHTBUTTON:

	BTST	#$6,$BFE001			; TEST LEFT MOUSEBUTTON
	BEQ.S	FINI				; IF PRESSED THEN END

	BRA.W	MAIN				; GOTO MAIN 

; ===============================

FINI:

	BSR.W	RESET

	RTE					; RETURN FROM SUPERVISOR MODE

; ===============================

; -------------------------------
; *** VARIABLES AND KONSTANTS ***
; -------------------------------

TRAP0VEC_BUF:	DC.L	0

IRQ_PLAIN3SAVE:	DC.L	0

DMACON_BUF:	DC.W	0
INTENA_BUF:	DC.W	0
WHICH_PLANE:	DC.W	6			; THE LAST ONE -> NO DELAY

YPOS:		DC.W	0
XPOS:		DC.W	0

BLTCON0BOB:	DC.W	%0000111111000010
BLTCON1BOB:	DC.W	%0000000000000000

STATUS:		DC.B	0
GFXNAME:	DC.B	"graphics.library",0	; GFX NAME

	EVEN					; MAKE PC EVEN

; -------------------------------
; ********* SUBROUTINES *********
; -------------------------------

; -------------------------------

NEXT_BOB:

	MOVEM.L	D0-D7/A0-A6,-(A7)		; SAVE REGISTERS
	MOVE	WHICH_PLANE(PC),D0		; PLANECOUNT -> D0
	ADDQ	#1,D0				; +1
	CMP.W	#BUFFERS,D0			; IF 7
	BNE.S	ALL_RIGHT			; IF NOT ...
	MOVEQ	#0,D0				; CLEAR D0

ALL_RIGHT:

	LEA	WHICH_PLANE(PC),A0
	MOVE.W	D0,(A0)				; SAVE PLANECOUNT
	
	MOVE.L	#BITPLANESIZE,D1			
	MULU.W	D0,D1				; CALC NEW PLANE ADDRESS 
	MOVE.L	D1,D0	

	MOVE.L	#BITPLANES,D1			; BITPLANE ADDRESS IN D1
	ADD.L	D0,D1
	
	MOVEQ	#PLANES-1,D4			; COUNT OF PLANES - 1
	LEA.L	COP_PLANE(PC),A0		; COPPERLIST
	MOVE.W	#$00E0,D3			; BPL1PTH -> D3
	
INST_BOBPLANES:

	MOVE.W	D3,(A0)+			; BPLXPTH IN COPPERLIST
	ADDQ.W	#2,D3				; NEXT REGISTER
	SWAP	D1				; CHANGE LOW/HIGH WORD
	MOVE.W	D1,(A0)+			; HI-WORD IN COPPERLIST
	MOVE.W	D3,(A0)+			; BPLXPTL IN COPPERLIST
	ADDQ.W	#2,D3				; NEXT REGISTER	
	SWAP	D1				; CHANGE LOW/HIGH WORD
	MOVE.W	D1,(A0)+			; LO-WORD IN COPPERLIST
	ADD.W	#PLANEWIDTH,D1			; CALC NEXT PLANEADRESS
	DBF	D4,INST_BOBPLANES

	MOVE.W	WHICH_PLANE(PC),D0		; PLANECOUNT -> D0
	MOVE.W	#BUFFERS,D2
CONT:
	ADDQ	#1,D0				; +1
	CMP.W	#BUFFERS,D0			; IF 7
	BNE.S	ALL_RIGHT2			; IF NOT ...

	MOVEQ	#0,D0				; CLEAR D0

ALL_RIGHT2:

	MOVEM.L	D0-D7/A0-A6,-(A7)		; SAVE REGISTERS
	BSR	DOBOBY
	MOVEM.L	(A7)+,D0-D7/A0-A6		; RESTORE REGISTERS

	DBF	D2,CONT

	MOVEM.L	(A7)+,D0-D7/A0-A6		; RESTORE REGISTERS

	RTS

; -------------------------------

DOBOBY:

	MOVE.L	#BITPLANESIZE,D1			
	MULU.W	D0,D1				; CALC NEW PLANE ADDRESS 
	MOVE.L	D1,D0	

	LEA.L	BITPLANES,A0			; BITPLANE ADDRESS IN D1
	ADD.L	D0,A0

	MOVEQ	#0,D0				; CLEAR D0
	LEA.L	COSINTABX(PC),A1		; COSINUS TABLE TO A1
	LEA.L	XPOS(PC),A2			; MY XPOS COUNTER IN A2
	ADD.W	(A2),A1	
	ADD.W	#2,(A2)				; NEXT POS
	LEA.L	COSINTABXEND-4(PC),A3		; END OF COSINUSTABLE -> A3
 	CMP.L	A3,A1				; TEST IF EO TABLE REACHED
	BLS.S	NOCOSTABEND2			; IF NOT THEN ...
	MOVE.W	#4,(A2)				; WRITE 4 IN XPOS

NOCOSTABEND2:
	
	MOVE.W	(A1),D0				; WRITE NEW XPOSITION IN D0

NOMIN1:

	BSR.W	FINESCROLL

	MOVEQ	#0,D1				; CLEAR D1
	LEA.L	SINTABY(PC),A1			; SINUS TABLE TO A1
	LEA.L	YPOS(PC),A2			; YPOS COUNTER IN A2
	ADD.W	(A2),A1				
	ADD.W	#2,(A2)				; NEXT POS
	LEA.L	SINTABYEND-4(PC),A3		; END OF SINUSTABLE -> A3
	CMP.L	A3,A1				; TEST IF EO TABLE REACHED
	BLS.S	NOSINTABYEND			; IF NOT THEN ...
	MOVE.W	#0,(A2)				; MUST BE ZERO !

NOSINTABYEND:
	
	MOVE.W	(A1),D1				; WRITE NEW YPOITION IN D1

	ADD.L	D0,D1				; ADD THE WORDS OF XPOS TO

	LEA.L	BOBDATA(PC),A1			; BOB GFX ADR -> A1
	LEA.L	BOBMASK(PC),A2			; BOB MASK TO A2

	BSR.S	INSERT_BOB			; COPY BOB ON PLANE

	RTS

; -------------------------------

INSERT_BOB:

	BSR.S	BLITTER_WAIT			; TEST IF BLITTER FINISHED

* A0 BITPLANE ADDRESS
* A1 BOBIMAGEDATA	
* A2 BOBDATAMASK
* D0 X-POSITION	
* D1 Y-POSITION	

	ADD.L	D1,A0				; ADD YPOS + XPOS(WORDS) TO A0

	MOVE.L	A1,$050(A5)			; BLTAPTH
	MOVE.L	A2,$04C(A5)			; BLTBPTH
	MOVE.L	A0,$048(A5)			; BLTCPTH
	MOVE.L	A0,$054(A5)			; BLTDPTH

	MOVE.L	#$FFFFFFFF,$044(A5)		; BLTAFWM

	MOVE.W	BLTCON0BOB(PC),$40(A5)		; BLTCON0
	MOVE.W	BLTCON1BOB(PC),$42(A5)		; BLTCON1
	MOVE.W	#0,$64(A5)			; BLTAMOD
	MOVE.W	#0,$62(A5)			; BLTBMOD
	MOVE.W	#PLANEWIDTH-4,$60(A5)		; BLTCMOD
	MOVE.W	#PLANEWIDTH-4,$66(A5)		; BLTDMOD
	MOVE.W	#(PLANES*16)*64+2,$58(A5)	; BLTSIZE

	RTS

; -------------------------------
		
FINESCROLL:
	
	MOVE.W	d0,d1				; COPY D0 TO D1
	LSR.W	#4,d0				; >> 4 D0 
	LSL.W	#1,d0				; << 1 D0

	ANDI.W	#%0000000000001111,d1		; ONLY LAST FOUR BITS !!!
	LSL.W	#8,d1				; << 8 D1
	LSL.W	#4,d1				; << 4 D1
	LEA.L	BLTCON1BOB(PC),A2		; ADR OF ... IN A2 
	MOVE.W	D1,(A2)				; WRITE D1 IN BLTCON1BOB

	ORI.W	#%0000111111100010,d1		; THE MASK WHICH MUST BE SET !
	LEA.L	BLTCON0BOB(PC),A2		; ADR OF ... IN A2
	MOVE.W	d1,(a2)				; WRITE D1 IN BLTCON0BOB
	RTS					; RETURN

; -------------------------------

BLITTER_WAIT:

	BTST	#14,$002(A5)			; DMACONR
	BNE.S	BLITTER_WAIT			; NOT SET THEN ...
	RTS					; RETURN

; -------------------------------

RESET:

	BSR.W	RESET_PLANES
	BSR.W	RESET_IRQ
	BSR.W	RESET_COPPER

	RTS					; RETURN

; ===============================

INSTALL:

	BSR.S	INST_PLANES
	BSR.S	INST_COPPER
	BSR.S	INST_IRQ			; INSTALL IRQ'S

	RTS					; RETURN

; -------------------------------

INST_IRQ:

	MOVE.W	$01C(A5),D0			; INTENAR TO D0
	ORI.W	#$8000,D0			; SET SET/CLR BIT
	LEA	INTENA_BUF(PC),A0		; SAVE INTENA REGISTER
	MOVE.W	D0,(A0)				; D0 IN INTENA_BUF

	MOVE.W	#$7FFF,$09A(A5)			; FORBID ALL IRQ'S IN INTENA

	BSR.W	INST_PLAIN3IRQ			; INSTALL PLAIN 3 IRQ

	RTS					; RETURN

; -------------------------------

INST_COPPER:

	MOVE.W	$002(A5),D0			; DMACONR TO D0
	ORI.W	#$8000,D0			; CLEAR/SET BIT
	LEA	DMACON_BUF(PC),A0		; DMACON_BUF TO A0
	MOVE.W	D0,(A0)				; D0 IN DMACON_BUF

	MOVE.W	#$05E0,$096(A5)			; COP+BLT+SPR+BPL DMA OUT
	LEA	COPPERLIST(PC),A0		; COPPERL. ADR IN A0
	MOVE.L	A0,$080(A5)			; NEW COPPERLIST TO COP1LCH
	MOVE.W	#$0000,$088(A5)			; CLEAR COPJMP COUNTER
	MOVE.W	#$8380,$096(A5)			; ALLOW DMA:COPPER+PLANES
	MOVE.W	#$8040,$096(A5)			; ALLOW BLITTER DMA

	RTS					; RETURN

; -------------------------------

INST_PLANES:

	MOVEQ	#PLANES-1,D4			; COUNT OF PLANES - 1
	LEA.L	COP_PLANE(PC),A0		; COPPERLIST
	MOVE.L	#BITPLANES,D1			; BITPLANE ADRESS IN D1
	MOVE.W	#$00E0,D3			; BPL1PTH -> D3
	
INST_PLANES_1:

	MOVE.W	D3,(A0)+			; BPLxPTH IN COPPERLIST
	ADDQ.W	#2,D3				; NEXT REGISTER
	SWAP	D1				; CHANGE LOW/HIGH WORD
	MOVE.W	D1,(A0)+			; HI-WORD IN COPPERLIST
	MOVE.W	D3,(A0)+			; BPLxPTL IN COPPERLIST
	ADDQ.W	#2,D3				; NEXT REGISTER	
	SWAP	D1				; CHANGE LOW/HIGH WORD
	MOVE.W	D1,(A0)+			; LO-WORD IN COPPERLIST
	ADD.W	#PLANEWIDTH,D1			; CALC NEXT PLANEADRESS
	DBF	D4,INST_PLANES_1

CLEAR_PLANES_1:
	
	LEA.L	BITPLANES,A0			; BITPLANEADRESS TO A0
	MOVE.w	#PLANES,D2			; HOW MANY PLANES ? -> D2
	ADD.W	#BUFFERS,D2			; HOW MANY BITPLANES ADD -> D2

CLEAR_PLANES_2:
	
	MOVE.W	#PLANESIZE-1,D1			; SIZE OF PLANES IN D1
	
CLEAR_PLANES_3:
	
	MOVE.W	#0,(A0)+			; CLEAR PLANES	

	DBF	D1,CLEAR_PLANES_3
	DBF	D2,CLEAR_PLANES_2

	RTS					; RETURN

; -------------------------------

RESET_PLANES:

	RTS					; RETURN

; -------------------------------

RESET_IRQ:

	MOVE.L	IRQ_PLAIN3SAVE(PC),$6C		; RESTORE IRQ VECTOR PLAIN 3

	MOVE.W	INTENA_BUF(PC),$09A(A5)		; RESTORE INTENA

	RTS					; RETURN

; -------------------------------

RESET_COPPER:

	LEA.L	GFXNAME(PC),a1			; "graphics.library" TO A1
	MOVEQ.L	#0,D0				; CLEAR D0
	MOVEA.L	$4,A6				; EXECBASE TO A6
	JSR	-$228(A6)			; OPEN GRAPHICS LIBRARY
	MOVEA.L	D0,A4				; WRITE GFXBASE IN A4
	MOVE.L	38(A4),$080(A5)			; GFX+38 = SYSTEMCOPPERLIST
	MOVE.W	#$0000,$088(A5)			; WRITE SOMETHING IN COPJMP
	MOVE.W	DMACON_BUF(PC),$096(A5)		; RESTORE DMACON

	RTS					; RETURN

; ===============================

INST_PLAIN3IRQ:

	MOVE.L	$6C,D0				; VECTOR PLAIN 3 TO D0
	LEA	IRQ_PLAIN3SAVE(PC),A0		; SAVE IRQ VEC-LEVEL3
	MOVE.L	D0,(A0)	
	LEA	PLAIN3_IRQ(PC),A0		; IRQ ADRESS TO A0
	MOVE.L	A0,$6C				; NEW ADRESS TO IRQ-LEV2-VEC

	MOVE.W	#$C030,$09A(A5)			; ALLOW IRQ'S IN INTENA

; INCLUSIV BLITTER FINISH: $C070
	
	RTS

; ===============================

PLAIN3_IRQ:

	MOVEM.L	D0-D7/A0-A6,-(A7)		; SAVE REGISTERS

	MOVE.W	$01E(A5),D0			; COPY INTREQR TO D0
	MOVE.W	D0,D1				; COPY D0 TO D1

	BTST	#5,D0				; TEST IF VERTIKALB IRQ
	BEQ.S	NO_VERTB_IRQ

	BRA.S	NO_COPPER_IRQ

NO_VERTB_IRQ:

	BTST	#4,D0				; TEST IF COPPER IRQ
	BEQ.W	NO_COPPER_IRQ

	BSR.W	NEXT_BOB

NO_COPPER_IRQ:

	MOVEM.L	(A7)+,D0-D7/A0-A6		; RESTORE REGISTERS

	MOVE.W	#$0030,$09C(A5)			; SET BACK IN INTREQ
	MOVE.W	#$2000,$09C(A5)			; SET BIT IN INTREQ BACK

	RTE					; RETURN FROM IRQ
	
; ===============================

COPPERLIST:

	DC.W	$010F,$FFFE
	DC.W	$008E,$2981,$0090,$29C1
	DC.W	$0092,$0038,$0094,$00D0
	
	DC.W	$0100,$0200

col1:	dc.w	$0180,$0000
	dc.w	$0182,$0260
	dc.w	$0184,$0472
	dc.w	$0186,$0CFC
	dc.w	$0188,$0AC9
	dc.w	$018a,$08B7
	dc.w	$018c,$06A4
	dc.w	$018e,$0582

	DC.W	$0144,$0000,$0146,$0000

	dc.w	$0108,$0000+((PLANES-1)*PLANEWIDTH)
	dc.w	$010a,$0000+((PLANES-1)*PLANEWIDTH)

COP_PLANE:	
	
	DCB.W	PLANES*4,$0000

	DC.W	$260F,$FFFE,$0180,$000F,$270F,$FFFE,$0180,$0000

	DC.W	$280F,$FFFE

	DC.W	$0100,$0200+(PLANES<<12)

	DC.W	$FFDD,$FFFE,$100F,$FFFE
	DC.W	$2a0F,$FFFE,$0180,$000f,$2b0F,$FFFE,$0180,$0000
	DC.W	$0100,$0200
	DC.W	$009C,%1000000000010000		; INTREQ
	DC.W	$FFFF,$FFFE

; ===============================

COSINTABX:

  dc.w  304,304,304,304,304,303,303,303,303,302,302,301,301,300,299,299
  dc.w  298,297,297,296,295,294,293,292,291,290,289,287,286,285,284,282
  dc.w  281,279,278,277,275,273,272,270,268,267,265,263,261,259,258,256
  dc.w  254,252,250,248,246,243,241,239,237,235,233,230,228,226,223,221
  dc.w  219,216,214,211,209,206,204,201,199,196,194,191,189,186,184,181
  dc.w  178,176,173,171,168,165,163,160,157,155,152,149,147,144,141,139
  dc.w  136,133,131,128,126,123,120,118,115,113,110,108,105,103,100,98
  dc.w  95,93,90,88,85,83,81,78,76,74,71,69,67,65,63,61
  dc.w  58,56,54,52,50,48,46,45,43,41,39,37,36,34,32,31
  dc.w  29,27,26,25,23,22,20,19,18,17,15,14,13,12,11,10
  dc.w  9,8,7,7,6,5,5,4,3,3,2,2,1,1,1,1
  dc.w  0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3
  dc.w  3,4,5,5,6,7,7,8,9,10,11,12,13,14,15,17
  dc.w  18,19,20,22,23,25,26,27,29,31,32,34,36,37,39,41
  dc.w  43,45,46,48,50,52,54,56,58,61,63,65,67,69,71,74
  dc.w  76,78,81,83,85,88,90,93,95,98,100,103,105,108,110,113
  dc.w  115,118,120,123,126,128,131,133,136,139,141,144,147,149,152,155
  dc.w  157,160,163,165,168,171,173,176,178,181,184,186,189,191,194,196
  dc.w  199,201,204,206,209,211,214,216,219,221,223,226,228,230,233,235
  dc.w  237,239,241,243,246,248,250,252,254,256,258,259,261,263,265,267
  dc.w  268,270,272,273,275,277,278,279,281,282,284,285,286,287,289,290
  dc.w  291,292,293,294,295,296,297,297,298,299,299,300,301,301,302,302
  dc.w  303,303,303,303,304,304,304,304

COSINTABXEND:

; ------------------------

SINTABY:

  dc.w  14400,14640,14880,15120,15360,15600,15960,16200,16440,16680,16920
  dc.w  17160,17400,17640,17880,18120,18360,18600,18840,19080,19320,19560
  dc.w  19800,20040,20280,20520,20760,20880,21120,21360,21600,21840,22080
  dc.w  22200,22440,22680,22920,23040,23280,23520,23640,23880,24000,24240
  dc.w  24360,24600,24720,24960,25080,25320,25440,25560,25800,25920,26040
  dc.w  26160,26280,26520,26640,26760,26880,27000,27120,27240,27360,27480
  dc.w  27600,27600,27720,27840,27960,27960,28080,28200,28200,28320,28320
  dc.w  28440,28440,28560,28560,28680,28680,28680,28680,28800,28800,28800
  dc.w  28800,28800,28800,28800,28800,28800,28800,28800,28680,28680,28680
  dc.w  28680,28560,28560,28440,28440,28320,28320,28200,28200,28080,27960
  dc.w  27960,27840,27720,27600,27600,27480,27360,27240,27120,27000,26880
  dc.w  26760,26640,26520,26280,26160,26040,25920,25800,25560,25440,25320
  dc.w  25080,24960,24720,24600,24360,24240,24000,23880,23640,23520,23280
  dc.w  23040,22920,22680,22440,22200,22080,21840,21600,21360,21120,20880
  dc.w  20760,20520,20280,20040,19800,19560,19320,19080,18840,18600,18360
  dc.w  18120,17880,17640,17400,17160,16920,16680,16440,16200,15960,15600
  dc.w  15360,15120,14880,14640,14400,14160,13920,13680,13440,13200,12840
  dc.w  12600,12360,12120,11880,11640,11400,11160,10920,10680,10440,10200
  dc.w  9960,9720,9480,9240,9000,8760,8520,8280,8040,7920,7680
  dc.w  7440,7200,6960,6720,6600,6360,6120,5880,5760,5520,5280
  dc.w  5160,4920,4800,4560,4440,4200,4080,3840,3720,3480,3360
  dc.w  3240,3000,2880,2760,2640,2520,2280,2160,2040,1920,1800
  dc.w  1680,1560,1440,1320,1200,1200,1080,960,840,840,720
  dc.w  600,600,480,480,360,360,240,240,120,120,120
  dc.w  120,0,0,0,0,0,0,0,0,0,0
  dc.w  0,120,120,120,120,240,240,360,360,480,480
  dc.w  600,600,720,840,840,960,1080,1200,1200,1320,1440
  dc.w  1560,1680,1800,1920,2040,2160,2280,2520,2640,2760,2880
  dc.w  3000,3240,3360,3480,3720,3840,4080,4200,4440,4560,4800
  dc.w  4920,5160,5280,5520,5760,5880,6120,6360,6600,6720,6960
  dc.w  7200,7440,7680,7920,8040,8280,8520,8760,9000,9240,9480
  dc.w  9720,9960,10200,10440,10680,10920,11160,11400,11640,11880,12120
  dc.w  12360,12600,12840,13200,13440,13680,13920,14160

SINTABYEND:

; ===============================

; * PLACE FOR GFX, SOUND ETC... *

; ===============================

BOBDATA:	INCBIN	"DF0:DATA/SINGLEBOB+MODULO.MSS"
BOBMASK:	INCBIN	"DF0:DATA/BOBMASK+MODULO.BIN"

; ===============================

PROGEND:

	END

