161 lines
4.4 KiB
Plaintext
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
|
|
|