	xdef	Start20
	xdef	Quicker20
	xdef	Quickest20
	xdef	CopyLen20
Quicker20	equ	Quicker-Start20
Quickest20	equ	Quickest-Start20
CopyLen20	equ	Stop20-Start20

Start20
	dc.l	'*Art'
Quicker:
	moveq	#16,d1
	cmp.l	d1,d0
	bcs.s	tinycpy
	move.w	a0,d1
	ror.l	#2,d1
	move.w	a1,d1
	rol.l	#2,d1
	andi.w	#15,d1
	beq.s	xa0la1l
	move.w	tbl(pc,d1.w*2),d1
	jmp	tbl(pc,d1.w)

	nop
	nop

tbl	dc.w	xa0la1l-tbl
	dc.w	xa0la11-tbl
	dc.w	xa0la1e-tbl
	dc.w	xa0la13-tbl
	dc.w	xa01a1l-tbl
	dc.w	xa01a11-tbl
	dc.w	xa01a1e-tbl
	dc.w	xa01a13-tbl
	dc.w	xa0ea1l-tbl
	dc.w	xa0ea11-tbl
	dc.w	xa0ea1e-tbl
	dc.w	xa0ea13-tbl
	dc.w	xa03a1l-tbl
	dc.w	xa03a11-tbl
	dc.w	xa03a1e-tbl
	dc.w	xa03a13-tbl

tloop1	move.b	(a0)+,(a1)+
tinycpy	dbf	d0,tloop1
	rts

xa01a13:
xa03a11:
xa03a13:
	move.b	(a0)+,(a1)+
	subq.l	#1,d0
	bra.s	xa0la1l

	nop
	nop
	nop
	nop
	nop

xa01a11:
	move.b	(a0)+,(a1)+
	subq.l	#1,d0
xa0ea1e:
	move.w	(a0)+,(a1)+
	subq.l	#2,d0
xa0la1l:
xa0la1e:
xa0ea1l:
	cmpi.l	#48*8,d0
	bcs.s	smlmov
	moveq	#48,d1		; 12 registers of 4 bytes
	sub.l	d1,d0
	movem.l	d2-d7/a2-a6,-(sp)
bigmov	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	moveq	#48,d1
	adda.l	d1,a1
	sub.l	d1,d0
	bcc.s	bigmov
	add.w	d1,d0
	movem.l	(sp)+,d2-d7/a2-a6
smlmov	lsr.w	#1,d0
	beq.s	even01
	bcs.s	sm13
	lsr.w	#1,d0
	beq.s	even2
	bcs.s	sm2
sm0	subq.w	#1,d0
loop0	move.l	(a0)+,(a1)+
	dbf	d0,loop0
even0	rts

even01	bcs.s	even1
	rts

sm3	subq.w	#1,d0
loop3	move.l	(a0)+,(a1)+
	dbf	d0,loop3
even3	move.w	(a0)+,(a1)+
even1	move.b	(a0),(a1)
	rts

sm13	lsr.w	#1,d0
	beq.s	even3
	bcs.s	sm3
sm1	subq.w	#1,d0
loop1	move.l	(a0)+,(a1)+
	dbf	d0,loop1
	move.b	(a0),(a1)
	rts

sm2	subq.w	#1,d0
loop2	move.l	(a0)+,(a1)+
	dbf	d0,loop2
even2	move.w	(a0),(a1)
	rts

xa0ea11:
xa0ea13:
	move.w	(a0)+,d1
	ror.w	#8,d1
	move.b	d1,(a1)+
	rol.w	#8,d1
	move.b	d1,(a1)+
	subq.l	#2,d0
	bra.s	xa0la11

xa01a1l:
xa01a1e:
	move.b	(a0)+,(a1)+
	move.b	(a0)+,(a1)+
	subq.l	#2,d0
xa03a1e:
xa03a1l:
	move.b	(a0)+,(a1)+
	subq.l	#1,d0
	bra.s	xa0la11

xa0la13:
xa0la11:

	moveq	#36,d1		; 8 regs of 4 bytes + roundoff bytes
	cmp.l	d1,d0
	bcs.s	tinycp2
* This is tricky!  They said it couldn't be done...
unevcpy	movem.l	a2-a4/d2-d7,-(sp)
	movea.w	d1,a4
	sub.l	d1,d0
	movea.l	d0,a2
	moveq	#32,d1		; 8 registers of 4 bytes
	movea.w	d1,a3
uloop	movem.l	(a0)+,d0-d7
	rol.l	#8,d0
	rol.l	#8,d1
	rol.l	#8,d2
	rol.l	#8,d3
	rol.l	#8,d4
	rol.l	#8,d5
	rol.l	#8,d6
	rol.l	#8,d7
	move.b	d0,(a1)+
	move.b	d1,d0
	move.b	d2,d1
	move.b	d3,d2
	move.b	d4,d3
	move.b	d5,d4
	move.b	d6,d5
	move.b	d7,d6
	move.b	(a0)+,d7
	movem.l	d0-d7,(a1)
	adda.l	a3,a1
	move.b	(a0)+,(a1)+	; even up to next word
	move.b	(a0)+,(a1)+
	move.b	(a0)+,(a1)+	; ... and to next longword
	suba.l	a4,a2
	move.l	a2,d0
	bpl.s	uloop
	add.w	a4,d0
	movem.l	(sp)+,a2-a4/d2-d7
;	subq.b	#1,d0
;	bcs.s	tdone
	bra.s	tinycp2
tloop2	move.b	(a0)+,(a1)+
tinycp2	dbf	d0,tloop2
tdone	rts

	nop
	nop
	nop
	nop
	nop
	nop
	dc.l	'*Art'
Quickest
	machine	mc68020
	bftst	d0{0:16}
	machine	mc68000
	bne.s	bigq
	lsr.w	#2,d0
	cmp.w	#96,d0
	bcs.s	smlmovQ
	moveq	#12,d1
	sub.w	d1,d0
	divu.w	d1,d0
	movem.l	d2-d7/a2-a6,-(sp)
bigmovQ	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	lea	48(a1),a1
	dbf	d0,bigmovQ
	swap	d0
	movem.l	(sp)+,d2-d7/a2-a6
	bra.s	smlmovQ
qloop	move.l	(a0)+,(a1)+
smlmovQ	dbf	d0,qloop
done	rts

bigq	lsr.l	#2,d0
	moveq	#48,d1
	sub.l	d1,d0
	nop
	machine	mc68020
	divul.l	d1,d1:d0
	machine	mc68000
	movem.l	d1-d7/a2-a6,-(sp)
bmovQ2	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	lea	48(a1),a1
	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	lea	48(a1),a1
	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	lea	48(a1),a1
	movem.l	(a0)+,d1-d7/a2-a6
	movem.l	d1-d7/a2-a6,(a1)
	lea	48(a1),a1
	dbf	d0,bmovQ2
	sub.l	#$10000,d0
	bcc.s	bmovQ2
	movem.l	(sp)+,d0/d2-d7/a2-a6
	bra.s	smlmovQ

Stop20
