.IMPORT pre_cosin ; array of 2*ITRIGO_ARRAY_SIZE longs .IMPORT pre_loffset ; long* .EXPORT bh_xd, bh_yd, bh_rd2 ; long .EXPORT bh_xs, bh_ys, bh_ref ; long .EXPORT bh_xc, bh_yc ; long .EXPORT bh_out_w, bh_out_h ; short .EXPORT bh_in_w, bh_in_h ; short .EXPORT bh_out_x, bh_out_y ; short .EXPORT BHL32_68030,BHL16_68030,BHLInd_68030 .EXPORT BHL32_F68030,BHL16_F68030,BHLInd_F68030 .EXPORT lcosin_fpu ITRIGO_ARRAY_SIZE EQU (1 << 14) ITRIGO_ANGLE_MAX EQU (ITRIGO_ARRAY_SIZE-1) QUARTER EQU (ITRIGO_ARRAY_SIZE/4) ; The black hole transformation consists of: ; Rotate the destination pixel around the black hole center ; The closest we are to the black hole, the bigger the rotation angle is ; We have 2 or 3 parts of computation angle for black hole transformation: ; 1: Just before dividing the maximum possible angle (depending on LDV paramter Rotation angle) by: ; CPU: the square of distance to black hole center ; FPU: the distance to black hole center; here we need 68881 instruction FSQRT ; So there are 3 parts in macro calculations: ; 1. Before dividing by distance or its square ; 1a. (FPU only) Compute distance ; 3. Divide by either distance or its square and state if the resulting pixel is in source image ; Dividing by distance instead of its square gives better visual results MACRO BH_COMP_1 MOVE.L A6,D0 ; Remember A6=bh_xd ADD.L D0,D0 ADDQ.L #1,D0 MOVE.L A5,D1 ; Remember A5=bh_rd2 ADD.L D0,D1 ; bh_rd2(D1)=1+2*bh_xd(D0) MOVE.L bh_ref(PC),D2 MOVE.L D1,A5 ; Save bh_rd2, free D1 ADDQ.L #1,D1 ; We need bh_rd2+1 for divide ENDM MACRO BH_COMP_2 bail_out_addr DIVU.L D1,D2 ; alpha(D2)=bh_ref/(1+bh_rd2) ANDI.L #ITRIGO_ANGLE_MAX,D2 ; alpha &= ITRIGO_ANGLE_MAX LSL.L #3,D2 ; D2=offset for pre_cosin array MOVE.L A6,D0 ; D0=bh_xd MOVE.L bh_yd(PC),D1 ; D1=bh_yd MOVE.L 4(A2,D2.L),D3 ; A2->pre_cosin, D3.L=SIN(alpha) MOVE.L (A2,D2.L),D2 ; A2->pre_cosin, D2.L=COS(alpha) MOVEQ.L #16,D6 ; Prepare shifts/assume not in range MOVE.L D0,D4 MULS.L D2,D4 ; D4=bh_xd * pre_cos[alpha] MOVE.L D1,D5 MULS.L D3,D5 ; D5=bh_yd * pre_sin[alpha] SUB.L D5,D4 ; D4=bh_xd * pre_cos[alpha] - bh_yd * pre_sin[alpha] ASR.L D6,D4 ADD.L bh_xc(PC),D4 ; D6=16, assume pixel not in range BLT.S bail_out_addr ; xs < 0: not in range CMP.W bh_in_w(PC),D4 BGE.S bail_out_addr ; xs >= bh_in_w: not in range MOVE.L D4,A3 ; A3=bh_xs= (D4 >> 16) MOVE.L D0,D4 MULS.L D3,D4 ; D4=bh_xd * pre_sin[alpha] MOVE.L D1,D5 MULS.L D2,D5 ; D5=bh_yd * pre_cos[alpha] ADD.L D5,D4 ; D4=bh_xd * pre_sin[alpha] + bh_yd * pre_cos[alpha] ASR.L D6,D4 ADD.L bh_yc(PC),D4 ; D4.L=bh_ys BLT.S bail_out_addr ; ys < 0: not in range CMP.W bh_in_h(PC),D4 BGE.S bail_out_addr ; ys >= bh_in_h: not in range MOVEQ.L #0,D6 ; pixel in range ENDM ; Macro for CPU 68030 MACRO BH_COMPUTE_CPU bail_out_addr BH_COMP_1 BH_COMP_2 bail_out_addr ENDM ; Macro for using FPU ; What we do with FPU is to compute the square root of D1 which ; Is then the distance to the back hole center instead of its square MACRO BH_COMPUTE_FPU bail_out_addr BH_COMP_1 FMOVE.L D1,FP0 FSQRT FP0 FMOVE.L FP0,D1 BH_COMP_2 bail_out_addr ENDM ; Init parameters valid for the entire call MACRO INIT_BHL MOVE.L pre_cosin,A2 MOVE.L pre_loffset,A4 ; A4-->preoffset MOVE.L bh_rd2(PC),A5 ; A5=bh_rd2 MOVE.L bh_xd(PC),A6 ; A6=bh_xd MOVE.W bh_out_w(PC),D7 SUBQ.W #1,D7 ; For DBF ENDM MACRO INIT_BHL_SYM MOVE.L pre_cosin,A2 MOVE.L pre_loffset,A4 ; A4-->preoffset MOVE.L bh_rd2(PC),A5 ; A5=bh_rd2 MOVE.L bh_xd(PC),A6 ; A6=bh_xd MOVE.W bh_out_w(PC),D7 LSR.W #1,D7 ; loop to bh_out_w/2 counts ADD.W A6,D7 ; starting from bh_xd MOVE.W D7,last_xd ENDM ; Get pixel TC32 -->dest (Dx) ; A4-->pre_loffset MACRO GET_TCPIXEL32 p,x,y,dest MOVE.L (A4,y.L*4),dest ADD.L x,dest MOVE.L (p,dest.L*4),dest ENDM ; Set pixel TC32 val(Dx) -->dest ; A4-->pre_loffset ; scratch_Dx scratch variable MACRO SET_TCPIXEL32 p,x,y,val,scratch_Dx MOVE.L (A4,y.L*4),scratch_Dx ADD.L x,scratch_Dx MOVE.L val,(p,scratch_Dx.L*4) ENDM ; Get pixel TC16 -->dest (Dx) ; A4-->pre_loffset MACRO GET_TCPIXEL16 p,x,y,dest MOVE.L (A4,y.L*4),dest ADD.L x,dest MOVE.W (p,dest.L*2),dest ENDM ; Set pixel TC16 val(Dx) -->dest ; A4-->pre_loffset ; scratch_Dx scratch variable MACRO SET_TCPIXEL16 p,x,y,val,scratch_Dx MOVE.L (A4,y.L*4),scratch_Dx ADD.L x,scratch_Dx MOVE.W val,(p,scratch_Dx.L*2) ENDM ; Rotate 90 ; x,y,scratch_Dx : registers, y has to be Dx ; #define R90(x,y) { long _x=x; x=-y; y=_x; } MACRO R90 x,y,scratch_Dx MOVE.L x,scratch_Dx NEG.L y MOVE.L y,x MOVE.L scratch_Dx,y ENDM MACRO PIXINIMG x,y,w,h,bailout TST.W x BLT.S bailout TST.W y BLT.S bailout CMP.W w,x BGE.S bailout CMP.W h,y BGE.S bailout ENDM ; On sample file 00_1480ms.jpg, Aranym 32bit: ; BHL32_68000 takes about 1450ms ; BHL32_68030 takes about 740ms ; 68030 routine for True Color 32bit ; BHL32_68030(short use_sym, void* in, void* out) ; D0, A0 A1 BHL32_68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context TST.W D0 BNE BHL32_68030_sym MOVEQ.L #0,D7 MOVE.W bh_out_x(PC),D7 LSL.L #2,D7 ADD.L D7,A1 ; A1-->&out[bh_out_x] INIT_BHL bhl32_l030: BH_COMPUTE_CPU bhl32_tpir_030 ; -->D6=0:pixel in range bhl32_tpir_030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl32_setpix_030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) MOVE.L (A0,D0.L*4),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhl32_setpix_030: MOVE.L D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhl32_l030 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS BHL32_68030_sym: INIT_BHL_SYM bhl32_l030_sym: BH_COMPUTE_CPU bhl32_tpir_030_sym ; -->D6=0:pixel in range bhl32_tpir_030_sym: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl32_setpix_030_sym GET_TCPIXEL32 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) bhl32_setpix_030_sym: MOVE.L A6,-(SP) ; Save bh_xd MOVE.L bh_xc(PC),D2 ; D2=bh_xc MOVE.L bh_yc(PC),D3 ; D3=bh_yc ADD.L D2,A6 ; A6=bh_xd+bh_xc MOVE.L bh_yd(PC),D7 ADD.L D3,D7 ; D7=bh_yd+bh_yc SET_TCPIXEL32 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) MOVEQ.L #2,D1 ; 3 loops, -1 for DBF deduc32_030: SUB.L D2,A3 ; We need now bh_xs(A3) and bh_ys(D4) relative to SUB.L D3,D4 ; Black Hole center to use R90 SUB.L D2,A6 ; We need now bh_xd(A6) and bh_yd(D7) relative to SUB.L D3,D7 ; Black Hole center to use R90 R90 A6,D7,D0 ; Rotate (xd,yd) by PI/4 R90 A3,D4,D0 ; Rotate (xs,ys) by PI/4 ADD.L D2,A3 ; Now we need coords in image raster ADD.L D3,D4 ADD.L D2,A6 ADD.L D3,D7 PIXINIMG A6,D7,bh_in_w(PC),bh_in_h(PC),dnotinimg32_030 ; Check if pixel in dest is within bounds MOVEQ.L #-1,D0 ; Assume out of range PIXINIMG A3,D4,bh_in_w(PC),bh_in_h(PC),plotdest32_030 ; Check if pixel in src is within bounds GET_TCPIXEL32 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) plotdest32_030: SET_TCPIXEL32 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) dnotinimg32_030: DBF D1,deduc32_030 MOVE.L (SP)+,A6 ; Restore bh_xd ADD.L #1,A6 ; bh_xd++ CMP.W last_xd(PC),A6 BLE bhl32_l030_sym MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS ; 68030 routine for True Color 16bit ; BHL16_68030(short use_sym, void* in, void* out) ; D0, A0 A1 BHL16_68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context TST.W D0 BNE BHL16_68030_sym MOVEQ.L #0,D7 MOVE.W bh_out_x(PC),D7 ADD.L D7,D7 ADD.L D7,A1 ; A1-->&out[bh_out_x] INIT_BHL bhl16_l030: BH_COMPUTE_CPU bhl16_tpir_030 ; -->D6=0:pixel in range bhl16_tpir_030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl16_setpix_030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) MOVE.W (A0,D0.L*2),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhl16_setpix_030: MOVE.W D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhl16_l030 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS BHL16_68030_sym: INIT_BHL_SYM bhl16_l030_sym: BH_COMPUTE_CPU bhl16_tpir_030_sym ; -->D6=0:pixel in range bhl16_tpir_030_sym: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl16_setpix_030_sym GET_TCPIXEL16 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) bhl16_setpix_030_sym: MOVE.L A6,-(SP) ; Save bh_xd MOVE.L bh_xc(PC),D2 ; D2=bh_xc MOVE.L bh_yc(PC),D3 ; D3=bh_yc ADD.L D2,A6 ; A6=bh_xd+bh_xc MOVE.L bh_yd(PC),D7 ADD.L D3,D7 ; D7=bh_yd+bh_yc SET_TCPIXEL16 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) MOVEQ.L #2,D1 ; 3 loops, -1 for DBF deduc16_030: SUB.L D2,A3 ; We need now bh_xs(A3) and bh_ys(D4) relative to SUB.L D3,D4 ; Black Hole center to use R90 SUB.L D2,A6 ; We need now bh_xd(A6) and bh_yd(D7) relative to SUB.L D3,D7 ; Black Hole center to use R90 R90 A6,D7,D0 ; Rotate (xd,yd) by PI/4 R90 A3,D4,D0 ; Rotate (xs,ys) by PI/4 ADD.L D2,A3 ; Now we need coords in image raster ADD.L D3,D4 ADD.L D2,A6 ADD.L D3,D7 PIXINIMG A6,D7,bh_in_w(PC),bh_in_h(PC),dnotinimg16_030 ; Check if pixel in dest is within bounds MOVEQ.L #-1,D0 ; Assume out of range PIXINIMG A3,D4,bh_in_w(PC),bh_in_h(PC),plotdest16_030 ; Check if pixel in src is within bounds GET_TCPIXEL16 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) plotdest16_030: SET_TCPIXEL16 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) dnotinimg16_030: DBF D1,deduc16_030 MOVE.L (SP)+,A6 ; Restore bh_xd ADD.L #1,A6 ; bh_xd++ CMP.W last_xd(PC),A6 BLE bhl16_l030_sym MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS ; 68030 routine for bitplances images, converted to indexes ; BHLInd_68030(short use_sym, void* in, void* out) ; D0, A0 A1 BHLInd_68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context INIT_BHL bhlind_l030: BH_COMPUTE_CPU bhlind_tpir_030 ; -->D6=0:pixel in range bhlind_tpir_030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhlind_setpix_030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) MOVE.B (A0,D0.L),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhlind_setpix_030: MOVE.B D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhlind_l030 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS .EVEN bh_xd: DC.L 0 bh_yd: DC.L 0 bh_rd2: DC.L 0 bh_xs: DC.L 0 bh_ys: DC.L 0 bh_ref: DC.L 0 bh_xc: DC.L 0 bh_yc: DC.L 0 bh_out_w: DC.W 0 bh_out_h: DC.W 0 bh_in_w: DC.W 0 bh_in_h: DC.W 0 bh_out_x: DC.W 0 bh_out_y: DC.W 0 last_xd: DC.W 0 ; 68030/FPU routine for True Color 32bit ; BHL32_F68030(short use_sym, void* in, void* out) ; D0, A0 A1 ;BHL32_F68030: ; MOVEM.L D0-D7/A2-A6,-(SP) ; Save context ; FMOVE.X FP0,-(SP) ; ; INIT_BHL ;bhl32_lf030: ; BH_COMPUTE_FPU bhl32_tpir_f030 ; -->D6=0:pixel in range ;bhl32_tpir_f030: ; MOVEQ.L #-1,D0 ; Assume out of range ; TST.W D6 ; BNE.S bhl32_setpix_f030 ; MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ; ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) ; MOVE.L (A0,D0.L*4),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] ;bhl32_setpix_f030: ; MOVE.L D0,(A1)+ ; ADD.L #1,A6 ; bh_xd++ ; DBF D7,bhl32_lf030 ; ; FMOVE.X (SP)+,FP0 ; MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context ; RTS BHL32_F68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context FMOVE.X FP0,-(SP) TST.W D0 BNE BHL32_F68030_sym MOVEQ.L #0,D7 MOVE.W bh_out_x(PC),D7 LSL.L #2,D7 ADD.L D7,A1 ; A1-->&out[bh_out_x] INIT_BHL bhl32_lf030: BH_COMPUTE_FPU bhl32_tpir_f030 ; -->D6=0:pixel in range bhl32_tpir_f030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl32_setpix_f030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) MOVE.L (A0,D0.L*4),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhl32_setpix_f030: MOVE.L D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhl32_lf030 FMOVE.X (SP)+,FP0 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS BHL32_F68030_sym: INIT_BHL_SYM bhl32_lf030_sym: BH_COMPUTE_FPU bhl32_tpir_f030_sym ; -->D6=0:pixel in range bhl32_tpir_f030_sym: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl32_setpix_f030_sym GET_TCPIXEL32 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) bhl32_setpix_f030_sym: MOVE.L A6,-(SP) ; Save bh_xd MOVE.L bh_xc(PC),D2 ; D2=bh_xc MOVE.L bh_yc(PC),D3 ; D3=bh_yc ADD.L D2,A6 ; A6=bh_xd+bh_xc MOVE.L bh_yd(PC),D7 ADD.L D3,D7 ; D7=bh_yd+bh_yc SET_TCPIXEL32 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) MOVEQ.L #2,D1 ; 3 loops, -1 for DBF deduc32_f030: SUB.L D2,A3 ; We need now bh_xs(A3) and bh_ys(D4) relative to SUB.L D3,D4 ; Black Hole center to use R90 SUB.L D2,A6 ; We need now bh_xd(A6) and bh_yd(D7) relative to SUB.L D3,D7 ; Black Hole center to use R90 R90 A6,D7,D0 ; Rotate (xd,yd) by PI/4 R90 A3,D4,D0 ; Rotate (xs,ys) by PI/4 ADD.L D2,A3 ; Now we need coords in image raster ADD.L D3,D4 ADD.L D2,A6 ADD.L D3,D7 PIXINIMG A6,D7,bh_in_w(PC),bh_in_h(PC),dnotinimg32_f030 ; Check if pixel in dest is within bounds MOVEQ.L #-1,D0 ; Assume out of range PIXINIMG A3,D4,bh_in_w(PC),bh_in_h(PC),plotdest32_f030 ; Check if pixel in src is within bounds GET_TCPIXEL32 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) plotdest32_f030: SET_TCPIXEL32 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) dnotinimg32_f030: DBF D1,deduc32_f030 MOVE.L (SP)+,A6 ; Restore bh_xd ADD.L #1,A6 ; bh_xd++ CMP.W last_xd(PC),A6 BLE bhl32_lf030_sym FMOVE.X (SP)+,FP0 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS BHL16_F68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context FMOVE.X FP0,-(SP) TST.W D0 BNE BHL16_f68030_sym MOVEQ.L #0,D7 MOVE.W bh_out_x(PC),D7 ADD.L D7,D7 ADD.L D7,A1 ; A1-->&out[bh_out_x] INIT_BHL bhl16_lf030: BH_COMPUTE_FPU bhl16_tpir_f030 ; -->D6=0:pixel in range bhl16_tpir_f030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl16_setpix_f030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs(A3) MOVE.W (A0,D0.L*2),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhl16_setpix_f030: MOVE.W D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhl16_lf030 FMOVE.X (SP)+,FP0 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS BHL16_f68030_sym: INIT_BHL_SYM bhl16_lf030_sym: BH_COMPUTE_FPU bhl16_tpir_f030_sym ; -->D6=0:pixel in range bhl16_tpir_f030_sym: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhl16_setpix_f030_sym GET_TCPIXEL16 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) bhl16_setpix_f030_sym: MOVE.L A6,-(SP) ; Save bh_xd MOVE.L bh_xc(PC),D2 ; D2=bh_xc MOVE.L bh_yc(PC),D3 ; D3=bh_yc ADD.L D2,A6 ; A6=bh_xd+bh_xc MOVE.L bh_yd(PC),D7 ADD.L D3,D7 ; D7=bh_yd+bh_yc SET_TCPIXEL16 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) MOVEQ.L #2,D1 ; 3 loops, -1 for DBF deduc16_f030: SUB.L D2,A3 ; We need now bh_xs(A3) and bh_ys(D4) relative to SUB.L D3,D4 ; Black Hole center to use R90 SUB.L D2,A6 ; We need now bh_xd(A6) and bh_yd(D7) relative to SUB.L D3,D7 ; Black Hole center to use R90 R90 A6,D7,D0 ; Rotate (xd,yd) by PI/4 R90 A3,D4,D0 ; Rotate (xs,ys) by PI/4 ADD.L D2,A3 ; Now we need coords in image raster ADD.L D3,D4 ADD.L D2,A6 ADD.L D3,D7 PIXINIMG A6,D7,bh_in_w(PC),bh_in_h(PC),dnotinimg16_f030 ; Check if pixel in dest is within bounds MOVEQ.L #-1,D0 ; Assume out of range PIXINIMG A3,D4,bh_in_w(PC),bh_in_h(PC),plotdest16_f030 ; Check if pixel in src is within bounds GET_TCPIXEL16 A0,A3,D4,D0 ; A0-->in_ptr, A3=bh_xs+bh_xc, D4=bh_ys+bh_yc ; D0=GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc) plotdest16_f030: SET_TCPIXEL16 A1,A6,D7,D0,D5 ; SET_TCPIXEL(out_ptr, bh_xd+bh_xc, bh_yd+bh_yc, GET_TCPIXEL(in_ptr, bh_xs+bh_xc, bh_ys+bh_yc)) dnotinimg16_f030: DBF D1,deduc16_f030 MOVE.L (SP)+,A6 ; Restore bh_xd ADD.L #1,A6 ; bh_xd++ CMP.W last_xd(PC),A6 BLE bhl16_lf030_sym FMOVE.X (SP)+,FP0 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS ; 68030/FPU routine for bitplances images, converted to indexes ; BHLInd_F68030(short use_sym, void* in, void* out) ; D0, A0 A1 BHLInd_F68030: MOVEM.L D0-D7/A2-A6,-(SP) ; Save context FMOVE.X FP0,-(SP) INIT_BHL bhlInd_lf030: BH_COMPUTE_FPU bhlInd_tpir_f030 ; -->D6=0:pixel in range bhlInd_tpir_f030: MOVEQ.L #-1,D0 ; Assume out of range TST.W D6 BNE.S bhlInd_setpix_f030 MOVE.L (A4,D4.L*4),D0 ; D4=bh_ys, D0=pre_loffset[bh_ys] ADD.L A3,D0 ; D0=pre_loffset[bh_ys] + bh_xs MOVE.B (A0,D0.L),D0 ; D0=in_ptr[pre_loffset[bh_ys] + bh_xs] bhlInd_setpix_f030: MOVE.B D0,(A1)+ ADD.L #1,A6 ; bh_xd++ DBF D7,bhlInd_lf030 FMOVE.X (SP)+,FP0 MOVEM.L (SP)+,D0-D7/A2-A6 ; Restore context RTS ; Pre-calculation of cosinus/sinus table using FPU ; void lcosin_fpu(long i, long* pcs) ; D0 A0 ; double angle = i*ANGLE_ADD ; ; pcs[0] = 65536.0 * cos( angle ) ; ; pcs[1] = 65536.0 * sin( angle ) ; lcosin_fpu: FMOVEM.X FP0-FP2,-(SP) FMOVE D0,FP0 ; 3.8349519697141030742952189737299e-4=M_PI/2.0/(double)QUARTER ; For some reason, I did not manage to use EQU with floating point constants FMUL.X #3.8349519697141030742952189737299e-4,FP0 FSINCOS.X FP0,FP1:FP2 FMUL.X #65536.0,FP1 FMUL.X #65536.0,FP2 FMOVE.L FP1,(A0)+ FMOVE.L FP2,(A0) FMOVEM.X (SP)+,FP0-FP2 RTS