Files
2017-04-17 00:10:12 +02:00

161 lines
4.4 KiB
Plaintext

; File pixelpacker.a
;
; void __asm packPixels(register __a0 unsigned char *bytemap,
; register __a1 struct BitMap *bitmap,
; register __d4 int left,
; register __d5 int top,
; register __d6 int width,
; register __d7 int height);
;
; Copies bytemap to bitmap.
; Assumes width is divisible by 16 and bitmap depth is 5.
; Warning: This looks weird, but it is quite a bit faster
; than doing it by shifting. Adds take 2 clocks, but shifts
; take 6.
xdef _packPixels
section code
_packPixels:
movem.L d2/d3/a2-a6,-(sp) ;save registers on the stack
suba.L #8,sp
move.L d7,(sp)
clr.L d0
move.W (a1),d0
asl.L #3,d0
movea.L d0,a5
suba.L d6,a5 ;a5 = bytemap skip = 8*BytesPerRow - width
asr.L #3,d6
movea.W (a1),a4
suba.L d6,a4 ;a4 = bitmap skip = BytesPerRow - width/8
asr.L #1,d6 ;d6 = width/16 = number of writes per row
move.L d6,4(a7) ;save number of writes per row on the stack
muls.W (a1),d5
asl.L #3,d5
add.L d5,d4
adda.L d4,a0 ;a0 = left + 8*top*BytesPerRow = initial bytemap addr
asr.L #3,d4
movea.L d4,a6 ;a6 = left/8 + top*BytesPerRow = initial bitmap disp
adda.L #8,a1 ;a1 = plane pointer array
;d0-d4 are the output words
;d5 is the input long, (read 4 times per output)
;d6 is the counter for the row loop = width/16
;d7 is an accumulator
;a5 is used to save the count during the inner loop
;rows are counted in the height argument on the stack
bigloop: ;do one row
clr.L d0
clr.L d1
clr.L d2
clr.L d3
clr.L d4
clr.L d7
movea.L d6,a3 ;save the row count in a3
moveq.L #4,d6 ;use d6 to count to 4
loop: ;execute 4 times and write 16 pixels
move.L (a0)+,d5 ;load next 4 bytes of input data
move.L d5,d7 ;bitplane 0 for 4 pixels
andi.L #$01010101,d7
or.B d7,d0
lsr.L #7,d7
or.B d7,d0
lsr.L #7,d7
or.B d7,d0
lsr.L #7,d7
or.B d7,d0
lsr.L #1,d5
move.L d5,d7 ;bitplane 1 for 4 pixels
andi.L #$01010101,d7
or.B d7,d1
lsr.L #7,d7
or.B d7,d1
lsr.L #7,d7
or.B d7,d1
lsr.L #7,d7
or.B d7,d1
lsr.L #1,d5
move.L d5,d7 ;bitplane 2 for 4 pixels
andi.L #$01010101,d7
or.B d7,d2
lsr.L #7,d7
or.B d7,d2
lsr.L #7,d7
or.B d7,d2
lsr.L #7,d7
or.B d7,d2
lsr.L #1,d5
move.L d5,d7 ;bitplane 3 for 4 pixels
andi.L #$01010101,d7
or.B d7,d3
lsr.L #7,d7
or.B d7,d3
lsr.L #7,d7
or.B d7,d3
lsr.L #7,d7
or.B d7,d3
lsr.L #1,d5
move.L d5,d7 ;bitplane 4 for 4 pixels
andi.L #$01010101,d7
or.B d7,d4
lsr.L #7,d7
or.B d7,d4
lsr.L #7,d7
or.B d7,d4
lsr.L #7,d7
or.B d7,d4
subq.L #1,d6
beq store
lsl.L #4,d0
lsl.L #4,d1
lsl.L #4,d2
lsl.L #4,d3
lsl.L #4,d4
jmp loop
store: ;a2 points into the bitplanes
move.L a3,d6 ;put the row count back in d6
movea.L a1,a3 ;a3 points into the array of planepointers
movea.L (a3)+,a2 ;a6 is the bitmap displacement
move.W d0,(a2,a6.L) ;write to plane 0
movea.L (a3)+,a2
move.W d1,(a2,a6.L) ;write to plane 1
movea.L (a3)+,a2
move.W d2,(a2,a6.L) ;write to plane 2
movea.L (a3)+,a2
move.W d3,(a2,a6.L) ;write to plane 3
movea.L (a3),a2
move.W d4,(a2,a6.L) ;write to plane 4
adda.L #2,a6 ;increment bitmap displacement
subq.L #1,d6 ;decrement count
bgt bigloop
;done with a row
move.L (sp),d7
subq.L #1,d7 ;decrement row count
beq done
move.L d7,(sp)
move.L 4(a7),d6 ;reset write counter
adda.L a4,a6 ;add bitmap skip to bitmap displacement
adda.L a5,a0 ;add bytemap skip to bytemap address
jmp bigloop
done:
adda #8,sp
movem.L (sp)+,d2/d3/a2-a6 ;restore registers
rts
END