
		include 'exec/types.i'
		include 'graphics/gfx.i'
		include 'hardware/custom.i'
		include 'hardware/blit.i'

			xdef	_blit_picture
			xdef	_blitmask_picture

			xref	_GfxBase
			xref	_LVOWaitBlit

ip_width	equ		8
ip_height	equ		10
ip_bmap		equ		12

* d0 - x
* d1 - y
* d2 - data_offset_y / data_offset_x
* d3 - height / width

_blit_picture			; a0 = source, a1 = bitmap, d0 = x d1 = y
		movem.l		a2-a6/d2-d7,-(sp)

		moveq		#0,d2					; init data_offset's
		move.w		ip_height(a0),d3		; get pic height
		swap		d3
		move.w		ip_width(a0),d3			; get pic width

		move.w		bm_BytesPerRow(a1),d4	; bitmap width
		move.l		d4,a3					; save it

		tst.w		d0						; if x < 0 ?
		bpl.s		1$						; no, so skip
		move.w		d0,d2
		neg.w		d2						; data_offset = -x
		add.w		d0,d3					; width += x
		moveq		#0,d0					; x = 0
		bra.s		2$
1$		lsl.w		#3,d4					; bpr = bitmap width >> 3
		sub.w		d0,d4					; bitmap width - x
		cmp.w		d3,d4					; is that less than pic width?
		bpl.s		2$						; no, so skip
		move.w		d4,d3					; width = bitmap width - x

2$		cmp.w		#0,d3
		ble			99$						; if width <= 0, out of clip

		swap		d2						; now do y
		swap		d3

		tst.w		d1						; if y < 0 ?
		bpl.s		3$						; no, so skip
		move.w		d1,d2
		neg.w		d2						; data_offset = -y
		add.w		d1,d3					; height += y
		moveq		#0,d1					; y = 0
		bra.s		4$
3$		move.w		bm_Rows(a1),d4			; bitmap height
		sub.w		d1,d4					; bitmap height - y
		cmp.w		d3,d4					; is that less than pic height?
		bpl.s		4$						; no, so skip
		move.w		d4,d3					; height = bitmap height - y

4$		cmp.w		#0,d3
		ble			99$						; if height <= 0, out of clip

		swap		d2						; x-vals in low word
		swap		d3

		move.w		d2,d5					; xorg = data_offset_x >> 3 & ~1
		lsr.w		#3,d5
		bclr		#0,d5

		move.w		ip_bmap+bm_BytesPerRow(a0),d6	; pic width
		move.l		d6,a5					; save it
		swap		d2						; data_offset_y
		mulu.w		d2,d6
		add.w		d5,d6					; offset2 =
											;	xorg+pic width*data_offset_y

		move.w		d0,d4					; x1 = x >> 3 & ~1
		lsr.w		#3,d4
		bclr		#0,d4

		swap		d2
		and.w		#15,d2					; if any shift, subtract 2
		beq.s		5$
		subq.w		#2,d4

5$		move.l		_GfxBase,a6				; wait for blitter free
		jsr			_LVOWaitBlit(a6)

		move.l		#$00dff000,a4			; custom chip base

		moveq		#0,d7
		move.w		d0,d7
		sub.w		d2,d7
		and.w		#15,d7
		swap		d7
		lsr.l		#4,d7					; x - doff & 15 << 12
		move.w		d7,bltcon1(a4)
		moveq		#0,d7					; init to 0 mask
		tst.w		d2						; does doff = 0 ?
		bne.s		6$
											; d2 now avaiable
		moveq		#-1,d7
		move.w		d0,d2
		and.w		#15,d2
		lsr.w		d2,d7					; mask = 0xffff >> (x & 15)
6$		move.w		d7,bltafwm(a4)

		moveq		#15,d5
		add.w		d0,d5
		add.w		d3,d5					; x + width + 15
		move.w		d5,d2					; save for later
		lsr.w		#3,d5
		bclr		#0,d5					; x2 = x + width + 15 >> 3 & ~1
		sub.w		d4,d5					; x2 - x1

		move.l		a5,d7					; saved pic width
		sub.w		d5,d7
		move.w		d7,bltbmod(a4)			; pic width - (x2 - x1)

		move.l		a3,d7					; saved dest width
		sub.w		d5,d7
		move.w		d7,bltcmod(a4)			; dest width - (x2 - x1)
		move.w		d7,bltdmod(a4)			; dest width - (x2 - x1)

		moveq		#-1,d7
		move.w		d7,bltadat(a4)			; bltadat = -1
		addq.w		#1,d2
		and.w		#15,d2					; w = x + width & 15 (really)
		beq.s		7$
		lsr.w		d2,d7					; $ffff >> w
		not.w		d7						; NOT ($ffff >> w)
7$		move.w		d7,bltalwm(a4)

		move.w		#SRCB|SRCC|DEST|ABC|ABNC|NABC|NANBC,bltcon0(a4)

		move.l		a3,d7
		mulu.w		d1,d7
		add.w		d4,d7					; offset = x1 + dest_width * y

		swap		d3
		lsl.w		#6,d3
		lsr.w		#1,d5
		add.w		d3,d5					; size = (x2-x1)>>1 + (height<<6)

		moveq		#0,d3
		move.b		ip_bmap+bm_Depth(a0),d3	; depth
		lea			bm_Planes(a1),a1
		lea			ip_bmap+bm_Planes(a0),a0
		bra.s		10$

9$		jsr			_LVOWaitBlit(a6)

8$		move.l		(a0)+,a3
		add.w		d6,a3
		move.l		a3,bltbpt(a4)
		move.l		(a1)+,a3
		add.w		d7,a3
		move.l		a3,bltcpt(a4)
		move.l		a3,bltdpt(a4)
		move.w		d5,bltsize(a4)
		dbra		d3,9$

99$		movem.l		(sp)+,a2-a6/d2-d7
		rts

10$		dbra		d3,8$
		bra.s		99$

_blitmask_picture	; a0 = source, a1 = bitmap, d0 = x d1 = y, a2 = mask
		movem.l		a2-a6/d2-d7,-(sp)		; a2 at 24

		moveq		#0,d2					; init data_offset's
		move.w		ip_height(a0),d3		; get pic height
		swap		d3
		move.w		ip_width(a0),d3			; get pic width

		move.w		bm_BytesPerRow(a1),d4	; bitmap width
		move.l		d4,a3					; save it

		tst.w		d0						; if x < 0 ?
		bpl.s		1$						; no, so skip
		move.w		d0,d2
		neg.w		d2						; data_offset = -x
		add.w		d0,d3					; width += x
		moveq		#0,d0					; x = 0
		bra.s		2$
1$		lsl.w		#3,d4					; bpr = bitmap width >> 3
		sub.w		d0,d4					; bitmap width - x
		cmp.w		d3,d4					; is that less than pic width?
		bpl.s		2$						; no, so skip
		move.w		d4,d3					; width = bitmap width - x

2$		cmp.w		#0,d3
		ble			99$						; if width <= 0, out of clip

		swap		d2						; now do y
		swap		d3

		tst.w		d1						; if y < 0 ?
		bpl.s		3$						; no, so skip
		move.w		d1,d2
		neg.w		d2						; data_offset = -y
		add.w		d1,d3					; height += y
		moveq		#0,d1					; y = 0
		bra.s		4$
3$		move.w		bm_Rows(a1),d4			; bitmap height
		sub.w		d1,d4					; bitmap height - y
		cmp.w		d3,d4					; is that less than pic height?
		bpl.s		4$						; no, so skip
		move.w		d4,d3					; height = bitmap height - y

4$		cmp.w		#0,d3
		ble			99$						; if height <= 0, out of clip

		swap		d2						; x-vals in low word
		swap		d3

		move.w		d2,d5					; xorg = data_offset_x >> 3 & ~1
		lsr.w		#3,d5
		bclr		#0,d5

		move.w		ip_bmap+bm_BytesPerRow(a0),d6	; pic width
		move.l		d6,a5					; save it
		swap		d2						; data_offset_y
		mulu.w		d2,d6
		add.w		d5,d6					; offset2 =
											;	xorg+pic width*data_offset_y

		move.w		d0,d4					; x1 = x >> 3 & ~1
		lsr.w		#3,d4
		bclr		#0,d4

		swap		d2
		and.w		#15,d2					; if any shift, subtract 2
		beq.s		5$
		subq.w		#2,d4

5$		move.l		_GfxBase,a6				; wait for blitter free
		jsr			_LVOWaitBlit(a6)

		move.l		#$00dff000,a4			; custom chip base

		moveq		#0,d7
		move.w		d0,d7
		sub.w		d2,d7
		and.w		#15,d7
		swap		d7
		lsr.l		#4,d7					; x - doff & 15 << 12
		move.w		d7,bltcon1(a4)

		or.w		#SRCA|SRCB|SRCC|DEST|ABC|ABNC|NABC|NANBC,d7
		move.w		d7,bltcon0(a4)

		moveq		#0,d7					; init to 0 mask
		tst.w		d2						; does doff = 0 ?
		bne.s		6$
											; d2 now avaiable
		moveq		#-1,d7
6$		move.w		d7,bltafwm(a4)

		moveq		#15,d5
		add.w		d0,d5
		add.w		d3,d5					; x + width + 15
		move.w		d5,d2					; save in d2 for later
		lsr.w		#3,d5
		bclr		#0,d5					; x2 = x + width + 15 >> 3 & ~1
		sub.w		d4,d5					; x2 - x1

		move.l		a5,d7					; saved pic width
		sub.w		d5,d7
		move.w		d7,bltbmod(a4)			; pic width - (x2 - x1)

		move.w		d7,bltamod(a4)			; mask width - (x2 - x1)

		move.l		a3,d7					; saved dest width
		sub.w		d5,d7
		move.w		d7,bltcmod(a4)			; dest width - (x2 - x1)
		move.w		d7,bltdmod(a4)			; dest width - (x2 - x1)

		moveq		#-1,d7
		addq.w		#1,d2
		and.w		#15,d2					; w = x + width & 15 (really)
		beq.s		7$
		moveq		#0,d7
7$		move.w		d7,bltalwm(a4)

		move.l		a3,d7
		mulu.w		d1,d7
		add.w		d4,d7					; offset = x1 + dest_width * y

		swap		d3
		lsl.w		#6,d3
		lsr.w		#1,d5
		add.w		d3,d5					; size = (x2-x1)>>1 + (height<<6)

		move.l		24(sp),a5				; get saved mask pointer
		move.l		ip_bmap+bm_Planes(a5),a5	; get first plane
		add.w		d6,a5					; add offset2

		moveq		#0,d3
		move.b		ip_bmap+bm_Depth(a0),d3	; depth
		lea			bm_Planes(a1),a1
		lea			ip_bmap+bm_Planes(a0),a0
		bra.s		10$

9$		jsr			_LVOWaitBlit(a6)

8$		move.l		a5,bltapt(a4)
		move.l		(a0)+,a3
		add.w		d6,a3
		move.l		a3,bltbpt(a4)
		move.l		(a1)+,a3
		add.w		d7,a3
		move.l		a3,bltcpt(a4)
		move.l		a3,bltdpt(a4)
		move.w		d5,bltsize(a4)
		dbra		d3,9$

99$		movem.l		(sp)+,a2-a6/d2-d7
		rts

10$		dbra		d3,8$
		bra.s		99$

