NEW
  AUTO 3,1
*--------------------------------------
* BitBlt
*  S.CB.X1 : Destination X (screen)
*  S.CB.Y1 : Destination Y (screen)
*  S.CB.DstX : X1 in bitmap/mask
*  S.CB.DstY : Y1 in bitmap/mask
*  S.CB.SrcW : width in bitmap/mask
*  S.CB.SrcH : height in bitmap/mask
*  S.CB.SrcPtr : pointer to S.BM
*  S.CB.SrcPtr+1 = 0, Aux hMem in S.CB.SrcPtr 
*  S.CB.DstPtr : pointer to Save/restore Buffer
*--------------------------------------
BITBLT			>LDYA CB.Cache+S.CB.X1
				jsr LBUF.SetBounds1YA
				stx BLT.ScrBitOfs
				
				lda CB.Cache+S.CB.X1
				clc
				adc CB.Cache+S.CB.SrcW
				tay
				lda CB.Cache+S.CB.X1+1
				adc CB.Cache+S.CB.SrcW+1
				pha
				tya
				sbc #0
				tay
				pla
				sbc #0
				
				jsr LBUF.SetBounds2YA
				
				lda CB.Cache+S.CB.SrcH
				sta ZPTmpByte
*--------------------------------------
				lda CB.Cache+S.CB.OP
				bit #S.CB.OP.RESTORE
				beq BITBLT.0

				ldy CB.Cache+S.CB.DstPtr
				lda CB.Cache+S.CB.DstPtr+1
				bne .1
				
				sta SETREADAUX			DstPtr is AUX hMem
				tya
				>SYSCALL2 GetMemPtr
				
.1				>STYA ZPBMSavePtr

				ldy CB.Cache+S.CB.Y1

.2				lda BASEL,y				setup line Base Ptr
				sta ZPBasePtr
				lda BASEH,y
				sta ZPBasePtr+1

				iny
				phy

				ldx LBUF.C1

.3				ldy COL.BANK,x
				sta $C000,y
				txa
				lsr
				tay

				lda (ZPBMSavePtr)
				sta (ZPBasePtr),y
				inc ZPBMSavePtr
				bne .4

				inc ZPBMSavePtr+1

.4				cpx LBUF.C2
				inx
				bcc .3
				
				ply
				dec ZPTmpByte
				bne .2

				sta CLRREADAUX
BITBLT.RTS		rts
*--------------------------------------
BITBLT.0		bit #S.CB.OP.SAVE
				beq BITBLT.1

				ldy CB.Cache+S.CB.DstPtr
				lda CB.Cache+S.CB.DstPtr+1
				bne .1
				
				tya						DstPtr is AUX hMem
				>SYSCALL2 GetStkObjPtr
				
				sta SETWRITEAUX
				
.1				>STYA ZPBMSavePtr

				ldy CB.Cache+S.CB.Y1

.2				lda BASEL,y				setup line Base Ptr
				sta ZPBasePtr
				lda BASEH,y
				sta ZPBasePtr+1

				iny
				phy
				
				ldx LBUF.C1

.3				ldy COL.BANK,x
				sta $C000,y
				txa
				lsr
				tay

				lda (ZPBasePtr),y
				sta (ZPBMSavePtr)
				inc ZPBMSavePtr
				bne .4

				inc ZPBMSavePtr+1

.4				cpx LBUF.C2
				inx
				bcc .3

				ply
				dec ZPTmpByte
				bne .2

				sta CLRWRITEAUX

				lda CB.Cache+S.CB.OP
*--------------------------------------
BITBLT.1		and #$0F
				beq BITBLT.RTS
				
				ldy CB.Cache+S.CB.SrcPtr
				lda CB.Cache+S.CB.SrcPtr+1
				bne .4

				sta SETREADAUX			SrcPtr is AUX hMem

				tya
				>SYSCALL2 GetMemPtr

.4				>STYA ZPBMDataPtr
*--------------------------------------
BITBLT.2		ldy #S.BM-1

.1				lda (ZPBMDataPtr),y
				sta BM.Cache,y
				dey
				bpl .1

				ldx #0

				lda BM.Cache+S.BM.F
				cmp #S.BM.F.BBP1
				beq .11

				ldx #$80

.11				stx BLT.CMASK
				lda ZPBMDataPtr
				clc
				adc BM.Cache+S.BM.MASK.OFS
				sta ZPBMMaskPtr
				lda ZPBMDataPtr+1
				adc BM.Cache+S.BM.MASK.OFS+1
				sta ZPBMMaskPtr+1

				lda ZPBMDataPtr
				clc
				adc #S.BM
				sta ZPBMDataPtr
				bcc .2
				inc ZPBMDataPtr+1
	
.2				>LDYA CB.Cache+S.CB.SrcY
				ldx BM.Cache+S.BM.RowBytes
				jsr YAMultX
				pha
				tya
				clc
				adc ZPBMDataPtr
				sta BLT.BMDataPtr
				pla
				pha
				adc ZPBMDataPtr+1
				sta BLT.BMDataPtr+1
				tya
				adc ZPBMMaskPtr
				sta BLT.BMMaskPtr
				pla 
				adc ZPBMMaskPtr+1
				sta BLT.BMMaskPtr+1
				lda CB.Cache+S.CB.SrcX
				pha
				and #7
				sta BLT.BMBitOfs
				pla
				lsr CB.Cache+S.CB.SrcX+1
				ror
				lsr CB.Cache+S.CB.SrcX+1
				ror
				lsr CB.Cache+S.CB.SrcX+1
				ror
				pha
				clc
				adc BLT.BMDataPtr
				sta BLT.BMDataPtr
				bcc .3

				inc BLT.BMDataPtr+1
				clc

.3				pla
				adc BLT.BMMaskPtr
				sta BLT.BMMaskPtr
				bcc .4

				inc BLT.BMMaskPtr+1

.4				lda BM.Cache+S.BM.H
				cmp CB.Cache+S.CB.SrcH
				bcs .5
				
				sta CB.Cache+S.CB.SrcH
				
.5				ldx BLT.ScrBitOfs
				bne BITBLT.LOOPx

*------------  Shift 0

BITBLT.LOOP0	lda CB.Cache+S.CB.OP
				bit #S.CB.OP.MASK
				beq .2

				>LDYA BLT.BMMaskPtr
				>STYA ZPBMDataPtr

				lda BLT.BMBitOfs
				sta BLT.BMBitOfsL
				ldx LBUF.C1
				stx BLT.ScrColIdx

.1				jsr BLT.Get7BMBits		we have 0xxxxxxxx in A

				ldx BLT.ScrColIdx
				sta LBUF.MASK,x
				inc BLT.ScrColIdx
				cpx LBUF.C2
				bne .1

.2				>LDYA BLT.BMDataPtr
				>STYA ZPBMDataPtr

				lda BLT.BMBitOfs
				sta BLT.BMBitOfsL
				ldx LBUF.C1
				stx BLT.ScrColIdx

.3				jsr BLT.Get7BMBits		we have 0xxxxxxxx in A

				ora BLT.CMASK
				ldx BLT.ScrColIdx
				sta LBUF.DATA,x
				inc BLT.ScrColIdx
				cpx LBUF.C2
				bne .3

				ldy CB.Cache+S.CB.Y1
				jsr LBUF.DrawAtY

				inc CB.Cache+S.CB.Y1
				dec CB.Cache+S.CB.SrcH
				beq .8

				lda CB.Cache+S.CB.OP
				bit #S.CB.OP.MASK
				beq .4

				lda BLT.BMMaskPtr
				clc
				adc BM.Cache+S.BM.RowBytes
				sta BLT.BMMaskPtr
				bcc .4

				inc BLT.BMMaskPtr+1

.4				lda BLT.BMDataPtr
				clc
				adc BM.Cache+S.BM.RowBytes
				sta BLT.BMDataPtr
				bcc BITBLT.LOOP0

				inc BLT.BMDataPtr+1

				bra BITBLT.LOOP0

.8				sta CLRREADAUX
				rts
*--------------------------------------
BITBLT.LOOPx	ldy Shift.L.LO-1,x		X = 1->6
				sty ZPScrShiftPtr
				ldy Shift.L.HI-1,x		X = 1->6
				sty ZPScrShiftPtr+1
				lda Shift7BitsCol1,x	get #%00001111, BM bits that go in Col1
				sta BITBLT.LOOPx.2+1
				sta BITBLT.LOOPx.6+1
				lda Shift7BitsCol2,x	get #%01110000, BM bits that go in Col2
				sta BITBLT.LOOPx.3+1
				sta BITBLT.LOOPx.7+1

*------------  Shift 1->6				Comment : SCRBitOfs=X=3

BITBLT.LOOPx.0	lda CB.Cache+S.CB.OP	X = BLT.ScrBitOfs
				bit #S.CB.OP.MASK
				beq BITBLT.LOOPx.4

				>LDYA BLT.BMMaskPtr
				>STYA ZPBMDataPtr

				lda BLT.BMBitOfs
				sta BLT.BMBitOfsL
				ldx LBUF.C1
				stx BLT.ScrColIdx
				stz LBUF.MASK,x			make sure C1 not ORed with trash in "ora LBUF.DATA,x"	

BITBLT.LOOPx.1	jsr BLT.Get7BMBits		we have c6543210 in A, destination : COL=3210xxx, COL+1=xxxx654
				pha						save BM byte for 2nd col
BITBLT.LOOPx.2	and #$ff				SELF MODIFIED : MASK WITH #%00001111, keep col1 bits only
				tay
				lda (ZPScrShiftPtr),y	make 0000dddd Shift left 3 :  0dddd000
				ldx BLT.ScrColIdx		Get actual COL index
				ora LBUF.MASK,x			Light proper bits : 0dddd???
				sta LBUF.MASK,x			store  0xdddd???
				pla						Get back BM Byte
BITBLT.LOOPx.3	and #$ff				SELF MODIFIED : #%01110000 get only col2 bites 
				tay
				lda (ZPScrShiftPtr),y	shift right 4 (=shift left 3!!!) : 00000ddd
				sta LBUF.MASK+1,x
				inc BLT.ScrColIdx
				cpx LBUF.C2
				bne BITBLT.LOOPx.1

BITBLT.LOOPx.4	>LDYA BLT.BMDataPtr
				>STYA ZPBMDataPtr

				lda BLT.BMBitOfs
				sta BLT.BMBitOfsL
				ldx LBUF.C1
				stx BLT.ScrColIdx
				stz LBUF.DATA,x			make sure C1 not ORed with trash in "ora LBUF.DATA,x"	

BITBLT.LOOPx.5	jsr BLT.Get7BMBits		we have c6543210 in A, destination : COL=3210xxx, COL+1=xxxx654
				pha						save BM byte for 2nd col
BITBLT.LOOPx.6	and #$ff				SELF MODIFIED : MASK WITH #%00001111, keep col1 bits only
				tay
				lda (ZPScrShiftPtr),y	make 0000dddd Shift left 3 :  0dddd000
				ora BLT.CMASK

				ldx BLT.ScrColIdx		Get actual COL index
				ora LBUF.DATA,x			Light proper bits : 0dddd???
				sta LBUF.DATA,x			store  0xdddd???
				pla						Get back BM Byte
BITBLT.LOOPx.7	and #$ff				SELF MODIFIED : #%01110000 get only col2 bites 
				tay
				lda (ZPScrShiftPtr),y	shift right 4 (=shift left 3!!!) : 00000ddd
				ora BLT.CMASK
				sta LBUF.DATA+1,x
				inc BLT.ScrColIdx
				cpx LBUF.C2
				bne BITBLT.LOOPx.5

				ldy CB.Cache+S.CB.Y1
				jsr LBUF.DrawAtY

				inc CB.Cache+S.CB.Y1
				dec CB.Cache+S.CB.SrcH
				beq .8

				lda CB.Cache+S.CB.OP
				bit #S.CB.OP.MASK
				beq .1

				lda BLT.BMMaskPtr
				clc
				adc BM.Cache+S.BM.RowBytes
				sta BLT.BMMaskPtr
				bcc .1

				inc BLT.BMMaskPtr+1

.1				lda BLT.BMDataPtr
				clc
				adc BM.Cache+S.BM.RowBytes
				sta BLT.BMDataPtr
				bcc .2

				inc BLT.BMDataPtr+1

.2				jmp BITBLT.LOOPx.0

.8				sta CLRREADAUX
				rts
*--------------------------------------
* BM Data/Mask bits :
* 76543210 76543210
*    ^
*  BMBitOfsL (0->7)
* LBUF DATA/MASK Bits
* c6543210 c6543210
*      ^
*--------------------------------------
BLT.Get7BMBits	ldx BLT.BMBitOfsL
				beq BLT.Get7BMBits0		OFS=0, done! and no need to advance ZPBMDataPtr

				dex						OFS 0->6
				beq BLT.Get7BMBits1		OFS was 1....done and go to next byte, OFS=0

				lda Shift.R.LO-1,x		X = 1->6
				sta ZPBMShiftPtr
				lda Shift.R.HI-1,x		X = 1->6
				sta ZPBMShiftPtr+1

				lda (ZPBMDataPtr)
				lsr						OFS=1->7, shift one (Range 0->127)
				and Mask7BitsH,x		Get only left upper X bits
				tay						xxxxx000
				lda (ZPBMShiftPtr),y	shift'em RIGHT 000xxxxx
				pha
				inc ZPBMDataPtr			Next BM data byte
				bne .1

				inc ZPBMDataPtr+1

.1				lda (ZPBMDataPtr)		get next byte
				and Mask7BitsL,x		only first Y bits 000000yy	
				tay
				pla						get back right part bits 000xxxxx
				ora (ZPBMShiftPtr),y	shift right 000000yy and ORA with 000xxxxx=0yyxxxxx
				dec BLT.BMBitOfsL		X = 1->6, ADD 7 MOD 8.....
				rts

BLT.Get7BMBits0	lda #7
				sta BLT.BMBitOfsL		Was 0, add 7 bits
				lda (ZPBMDataPtr)
				and #%01111111			Get only 7 needed bits
				rts

BLT.Get7BMBits1	lda (ZPBMDataPtr)
				lsr						OFS=1->7, shift one (Range 0->127)

				stz BLT.BMBitOfsL		LSR did already 0xxxxxxx, Was 1, add 7 bits, MOD 8=0

				inc ZPBMDataPtr			go to next byte in BM line
				bne .8
				inc ZPBMDataPtr+1			
.8				rts
*--------------------------------------
MAN
SAVE usr/src/drv/dhgr.drv.s.blt
LOAD usr/src/drv/dhgr.drv.s
ASM
