; SetBlock.asm implements inner loop of /SetBlock routine

;~~~~~~ THE BCPL ROUTINE IMPLEMENTED IS ~~~~~~~~

; PaintBlock(height) be
;
[
;
let Cnt = 0
;
let Ptr = SetBPtr; SetBptr = SetBPtr+1
;
[
;
if OnBits then @Ptr = @Ptr % (SetBMask & OnBits!(Cnt&3))
;
if OffBits then @Ptr = @Ptr & not (SetBMask & OffBits!(Cnt&1))
;
Ptr=Ptr+Nwrds
;
Cnt=Cnt+1
;
if Cnt ge height then return
;
] repeat
;
]

;width = width-16
;if width le 0 then break
;SetBMask= width ls 16? MaskTable!width, -1

.srel
PaintBlock: PntBl
.bextz SetBPtr,OnBits,OffBits,SetBMask,MaskTable,Mag
.bext PaintBlock, PaintBits

.nrel
SavedAC2:
0
SavedAC3:
0
height:
0
width:
0
Nwrds:
44
Minus16:
177760
Cnt:
0


PntBl:
sta 2 SavedAC2
sta 3 SavedAC3
sta 0 height
sta 1 width
movl 1 1 SZC
jmp exit;return if width is negative

Xloop:
sub 0 0
sta 0 Cnt
lda 3 SetBPtr,0
inc 3 2
sta 2 SetBPtr,0

YLoop:
lda 2 OnBits,0
mov 2 2 SNR
jmp SkpOn
lda 1 Cnt
subzl 0 0;make the constant 1
movol 0 0;make it a 3
and 0 1
add 1 2
lda 2 0,2;get the OnBits from table
lda 1 SetBMask,0
and 1 2
SkpOn:
lda 0 0,3
com 2 2
and 2 0
adc 2 0;leave result in AC0

PntOff:
lda 2 OffBits,0
mov 2 2 SNR
jmp PntDn
lda 1 Cnt
movr# 1 1 SZC
inc 2 2
lda 2 0,2;get the OnBits from table
lda 1 SetBMask,0
and 2 1
com 1 1
and 1 0

PntDn:
sta 0 0,3
lda 2 Nwrds
add 2 3
lda 2 height
lda 1 Cnt
inc 1 1
sta 1 Cnt
subo 2 1 SEZ
jmp YLoop

lda 1 Minus16
lda 0 width;compute width-16
addz 1 0 SBN;jump to exit if the result is le 0
jmp exit
sta 0 width
adc 2 2
addz 0 1 SZC
jmp SetMsk
lda 2 MaskTable,0
add 0 2
lda 2 0,2
SetMsk:
sta 2 SetBMask,0
jmp Xloop


exit:
lda 2 SavedAC2
lda 3 SavedAC3
jmp 1 3




.end

;