 	opt	c+,l-,d+

;COMMENTS
; This code is only for giving an example of COPPER skip's.
; COPPER interrupts.
; and the STOP instruction.

;REGISTER USAGE
;	main code		handler
; a4	-> $dff000
; a5	-> main
; a6	-> exec base	$dff180 (color0)

;INCLUDES/EQUATES
	incdir	"SYS:include/"
	include	exec/exec_lib.i
	include	exec/memory.i
	include	hardware/custom.i
	include	hardware/dmabits.i
	include	include/font.i
	include	include/FONTout.i

cop		set	copperEND-copperlist
scrTOP		set	$24
scrSTOP		set	250
_screenwidth	equ	608/8
_screenheight	equ	scrSTOP-scrTOP
_fontlinesqueeze	equ	0
_planesize	equ	_screenwidth*_screenheight
planes		equ	1
spdbarTOP		equ	scrTOP+31
clrBKG		equ	$40f	; background color
clrTXT		equ	$000	; text color
clrSPD1		equ	$fc0	; speed bar color
clrSPD2		equ	$090
clrSPD3		equ	$7a0
clrSPD4		equ	$fff
clrSYNC		equ	$f20

;CODE w/COMMENTS
main:	lea	$bfe001,a3
	lea	$dff000,a4
	lea	main(pc),a5
	move.l	$4.w,a6

	move.b	(a0),d0
	bclr	#5,d0
	cmp.b	#'C',d0		; did they type Chip?
	bne.s	main1
codealloc
	move.l	#(CODEEND-main)-1,d0	; looping!
	bsr	alloc
	move.l	d0,d1
	beq.s	exit
	move.l	codealloc+2(pc),d0
	movem.l	d0/a1,-(a7)
	pea.l	free(pc)
	move.l	a1,a2
	lea	main(pc),a0
codeal0	move.b	(a0)+,(a2)+	; relocate
	dbra	d0,codeal0
	move.l	a1,a5
	jmp	main1-main(a5)

main1:	move.l	buffersize(pc),d0
	bsr	alloc
	move.l	d0,bufferloc-main(a5)
	beq.s	exit
	move.l	buffersize(pc),d0
	movem.l	d0/a1,-(a7)
	pea.l	free(pc)

	bsr	setup
	pea.l	copperoff(pc)
	bsr	messageout
	bsr	copperon
	jsr	_LVOSuperState(a6)
	move.l	d0,-(a7)
	lea	color0(a4),a6
;		#%fedcba9876543210
wait:	stop	#%0010000000011111
	btst	#6,(a3)		; wait for them to want to leave
	bne.s	wait
	move.w	#$4000,intena(a4)	; NO INTERRUPTS!!!
	move.l	$4.w,a6
	move.l	(a7)+,d0
	jsr	_LVOUserState(a6)
exit	rts

alloc:	move.l	#MEMF_CHIP!MEMF_CLEAR,d1
	jmp	_LVOAllocMem(a6)		; allocate plane/copper
	
free:	movem.l	(a7)+,d0/a1
	jmp	_LVOFreeMem(a6)

setup	move.l	bufferloc(pc),a1
	add.l	#cop,a1
	move.l	a1,bufferBP-main(a5)
	lea	cEP(pc),a2		; get correct offset
	move.l	#_planesize,d1		; in copper list to insert
	moveq	#planes-1,d2
CSUL	move.l	a1,d0
	bsr.s	CSU
	add.l	d1,a1
	dbra	d2,CSUL
	lea	copperlist(pc),a0
	move.l	bufferloc(pc),a1
	moveq	#(cop/4)-1,d0
setupCML	move.l	(a0)+,(a1)+
	dbra	d0,setupCML
	rts

CSU	move.w	d0,6(a2)
	swap	d0
	move.w	d0,2(a2)
	addq.l	#8,a2
	rts


copperon	move.l	$6c.w,vector3-main(a5) ;store the SYSTEMs level 3
	bsr.s	WAITBLIT		; vector.  Wait for end of blits
	move.w	intenar(a4),d0	; then grab the enable mask and
;		#%fedcba9876543210
	move.w	#%0111111111111111,intena(a4)	; DISABLE ALL INTERRUPTS
	bset	#15,d0	; set the enable mask for SETTING
	swap	d0	
	move.w	dmaconr(a4),d0	; and get the DMA flags also
	bset	#15,d0		; and store the flags for
	move.l	d0,intflags-main(a5)	; restoring on exit

	move.l	bufferloc(pc),d0	; get the physical base for my
	moveq	#0,d1		; copperlists.
	move.w	#copperlist2-copperlist,d1
	add.l	d0,d1		; point d1 at copperlist2
	move.l	d0,cop1lc(a4) ; now set the copperlists into
	move.l	d1,cop2lc(a4) ; the copperlist pointers.

	lea	inter(pc),a0 ; now we put the interrupt handler
	move.l	a0,$6c.w	; into the level 3 vector
	move.w	#%1100000000010000,intena(a4)	; enable "COPPER"
;		#%fedcba9876543210		  interrupts 
	rts

WAITBLIT	btst	#14,dmaconr+$dff000	; typical wait blit.
	bne.s	WAITBLIT
	rts

copperoff
	RestoreCopper		; stop the copper interrupts
	tst.w	copjmp1(a4)
	move.w	#$4000,intena(a4)	; NO INTERRUPTS!
	move.w	#$7fff,intreq(a4)	; ZAP ALL INTERRUPTS!
	move.l	intflags(pc),d0
	move.w	d0,dmacon(a4)
	swap	d0
	move.w	d0,intena(a4)
	move.l	vector3(pc),$6c.w
	rts

messageout:
	lea	message(pc),a0
	move.l	bufferBP(pc),a1
cputext:	SCF			;a0 msg/a1 bitplane ptr

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; serve up those juicey interrupts.
inter:
	move.w	#clrSPD1,(a6)		; 0
;		#%fedcba9876543210
	move.w	#%0000000000010000,intreq(a4)	; 16	16
; as fast as possible....
	move.l	#2159,d0
	muls	#29127,d0
	move.w	#clrSPD2,(a6)
	move.w	#clrSPD3,(a6)
	move.w	#clrSPD4,(a6)
	move.w	#clrSPD3,(a6)
	move.w	#clrSPD2,(a6)
	move.w	#clrBKG,(a6)	; 16	100 cycles...!
VBexit	rte

;CONSTANTS
message
 dc.b 'Amiga Speed odometer',10,10
 dc.b '  0   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18',10
 dc.b '  | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |',10
 dc.b 'The red zone represents the time for the cpu to respond to the interrupt',10
 dc.b 'request.',10
 dc.b 'The yellow zone is the time requiered to calculate 2159 * 29127',10
 dc.b 'Then GREEN/BROWN/WHITE/BROWN/GREEN are moved onto the screen.',10,10
 dc.b 'USAGE - speedtest [CHIP]',10
 dc.b 'where CHIP will force the program to run in CHIP memory',10,10
 dc.b 'ATP Research and Development',10
 dc.b ' 326 Spring Street',10
 dc.b '  NY, NY 10013',10,10
 dc.b 'All rights reversed. $25 for commented 68000 source code.',10
 dc.b	0				;done
 even

copperlist
	dc.w	bpl1mod,$0		; no modula on screen
	dc.w	bpl2mod,$0		; YET...
	dc.w	diwstrt,$41+(scrTOP*$100)	; normal NTSC display
	dc.w	diwstop,$d1+(scrSTOP*$100)
	dc.w	ddfstrt,$38		; normal data fetching
	dc.w	ddfstop,$38+(8*18)
		;       %fedcba9876543210
	dc.w	bplcon0,%1001001000000000	; set it as high-res/1 bitplane/color burst
	dc.w	bplcon1,0
	NOSPRITES
cEP	dc.w	bpl1pth,0			; here is where we get the bit
	dc.w	bpl1ptl,0			; plane pointers
	dc.w	color0,clrBKG		; base colors
	dc.w	color1,clrTXT
	dc.w	(spdbarTOP)*$100+1,$fffe	;wait
	dc.w	copjmp2,0		; do the second copperlist
	ENDCOPPER			; just in case? case of what?
; wait for 0 raster point... at all lines...

copperlist2
 dc.w $0141,$01fe	;wait for sync point on odd raster line
 dc.w color0,clrSYNC	; set color
 dc.w intreq,$8010		; request interrupt
 dc.w $01e3,$01f0		; wait for end of same line
 dc.w $0041,$01f0,color0,clrSYNC,intreq,$8010,$00e3,$01f0 ; EVEN
 dc.w $0141,$01fe,color0,clrSYNC,intreq,$8010,$01e3,$01f0 ; ODD
 dc.w $0041,$01f0,color0,clrSYNC,intreq,$8010,$00e3,$01f0 ; EVEN
 dc.w $0141,$01fe,color0,clrSYNC,intreq,$8010,$01e3,$01f0 ; ODD
 dc.w $0041,$01f0,color0,clrSYNC,intreq,$8010,$00e3,$01f0 ; EVEN
 dc.w $0141,$01fe,color0,clrSYNC,intreq,$8010,$01e3,$01f0 ; ODD
; next we turn off the screen/audio/disk dma for the next 'speed bar'
 dc.w dmacon,DMAF_CLR!DMAF_RASTER!DMAF_AUDIO!DMAF_DISK
 dc.w (spdbarTOP+10)*$100+1,$ff01	; and until we pass this raster
 dc.w copjmp2,$0			; we loop copperlist2
 dc.w (spdbarTOP+25)*$100+1,$fffe	; wait for a good point in the
; raster before turning the DMA back on.. [might not be needed]
 dc.w dmacon,DMAF_SET!DMAF_RASTER!DMAF_AUDIO!DMAF_DISK
 dc.w intreq,$0010		;clear out the interrupt request because we might
 dc.w color0,clrBKG		; we may have an over burdened irq handler.

 dc.w (scrTOP+93*$100)+1,$fffe ;now we change the colors on the text
 dc.w color1,clrSYNC
 dc.w (scrTOP+113*$100)+1,$fffe
 dc.w color1,clrSPD1
 dc.w (scrTOP+123*$100)+1,$fffe
 dc.w color1,clrSPD2
 dc.w (scrTOP+125*$100)+1,$fffe
 dc.w color1,clrSPD3
 dc.w (scrTOP+127*$100)+1,$fffe
 dc.w color1,clrSPD4
 dc.w (scrTOP+129*$100)+1,$fffe
 dc.w color1,clrSPD3
 dc.w (scrTOP+131*$100)+1,$fffe
 dc.w color1,clrSPD2
 dc.w (scrTOP+133*$100)+1,$fffe
 dc.w color1,$0ff
 dc.w (scrTOP+173*$100)+1,$fffe
 dc.w color1,$ff0
 dc.w (scrTOP+187*$100)+1,$fffe
 dc.w color1,$cc0
 dc.w (scrTOP+203*$100)+1,$fffe
 dc.w color1,clrTXT
	ENDCOPPER
copperEND	dc.l	0

;NONE REGISTER VARIABLES
bufferloc	dc.l	0
bufferBP	dc.l	0		; = bufferloc+cop...
buffersize
	dc.l	planes*_planesize+cop
vector3	dc.l	0
intflags	dc.l	0	; also holding the dmaflags.

CODEEND	dc.l	0
