mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
1780 lines
55 KiB
Plaintext
1780 lines
55 KiB
Plaintext
;
|
|
; File: DrawLine.a
|
|
;
|
|
; Copyright: © 1981-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM2> 6/11/92 stb <sm 6/9/92>stb Synched with QDciPatchROM.a; added comments to
|
|
; DrawLine, SkipSetup, FASTLINE, HTOGL, VLINE, FASTSLANT.
|
|
; <8> 12/13/90 SMC Refixed <7>. With KON.
|
|
; <7> 11/26/90 SMC Fixed call to StretchBits to use locmode with pattern bit
|
|
; forced. PnMode was being used. With BAL.
|
|
; <6> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
|
; <5> 9/17/90 BG Removed <3>. 040s are now behaving more reliably.
|
|
; <4> 7/20/90 gbm Change some identifiers to cease conflicting with interface
|
|
; files
|
|
; <3> 6/26/90 BG Added EclipseNOPs for flakey 040s.
|
|
; <2> 2/13/90 BAL Ensure that the initial bit offset is calculated in a long
|
|
; instead of a word so that lines drawn into really wide pixmaps
|
|
; don't freak out.
|
|
; <¥1.6> 7/14/89 BAL For Aurora: Final CQD
|
|
; <1.5> 6/30/89 BAL Cleared runBuf(a6) before calling getSeek
|
|
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
|
; <¥1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
|
|
; 1/22/89 BAL Made patVPos a long.
|
|
; 9/22/88 BAL Moved initialization of region state records into GetSeek.
|
|
; 9/19/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
|
; 9/18/88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed
|
|
; references to PIXSRC;
|
|
; 11/8/87 BAL Fixed computation of bufSize for more accurate region clipping
|
|
; at at depths greater than 1. <C954>
|
|
; 11/7/87 BAL Fixed ChkPat to handle new patterns. <C945>
|
|
; 6/4/87 CRC preserve hilite mode across calls to colormap; set patmode in
|
|
; case user forgot
|
|
; 1/3/87 CRC pass color param to stretch
|
|
; 12/12/86 CRC Added support for arithmetic modes
|
|
; 10/9/86 EHB Added mask parameters to stretchbits calls
|
|
; 7/29/86 EHB Allocate EXPAT buffer on stack so long aligned
|
|
; 7/26/86 EHB Added support for expanded patterns
|
|
; 7/22/86 EHB Pass MODE to PatExpand
|
|
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetMask
|
|
; 6/20/86 EHB New params to COLORMAP; Added FCOLOR and BCOLOR to stack frame
|
|
; 6/18/86 EHB Call StretchBits instead of RgnBlt
|
|
; 6/15/86 EHB Make sure stack is longword aligned (for fast buffers); If one
|
|
; 1-bit region, play directly into RGNBUFFER Convert BitsToPix and
|
|
; use pixelSize
|
|
; 6/14/86 EHB Call GetXRtn to set expand routine for SeekMask; Added DSTPIX to
|
|
; stack frame
|
|
; 6/13/86 EHB Updated SeekMask to check rgn changed flag Moved SeekMask to
|
|
; another file; Rearranged stack frame with SeekMask stuff at top
|
|
; 6/10/86 EHB Modified to use 32-bit DrawSlab
|
|
; 6/5/86 EHB Clear flag bits from all references to rowBytes
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
;-----------------------------------------------------------------
|
|
;
|
|
; --> DRAWLINE.TEXT
|
|
;
|
|
;------------------------------------------------------------------
|
|
|
|
DrawLine PROC EXPORT
|
|
IMPORT SHFTTBL
|
|
Export steepBlitTab,shallowBlitTab,FastLine,FastSlant
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DRAWLINE(P1,P2: POINT);
|
|
;
|
|
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
|
|
;
|
|
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
|
|
;
|
|
|
|
|
|
;------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 8 ;SIZE OF PARAMETERS
|
|
P1 EQU PARAMSIZE+8-4 ;POINT
|
|
P2 EQU P1-4 ;POINT
|
|
|
|
|
|
;-------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
|
;
|
|
; STACK FRAME VARS USED BY SEEKMASK (CALLED BY STRETCHBITS, RGNBLT, DRAWARC, DRAWLINE)
|
|
;
|
|
&CurFile SETC 'DRAWLINE'
|
|
|
|
INCLUDE 'DrawingVars.a'
|
|
|
|
;-------------------------------------------------
|
|
; includes fixes as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
|
|
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
|
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
|
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
|
|
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
|
|
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
|
|
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
|
|
BLT GOHOME ;YES, QUIT
|
|
MOVE.W PNMODE(A3),D1 ;get pen mode Start of <7>
|
|
_GetStreamMode ;strip off alpha bits
|
|
;this code moved up here from below at SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
|
BSET #3,D1 ;set the pattern bit in case the user forgot to
|
|
MOVEQ #$10,D0 ;1 past normal mode range
|
|
BTST #5,D1 ;arithmetic mode?
|
|
BEQ.S @noRith
|
|
CMP #$3A,D1 ;hilite?
|
|
BEQ.S @ok
|
|
MOVEQ #$30,D0 ;1 past arithmetic mode range
|
|
@noRith CMP D0,D1 ;greater than defined range?
|
|
BGT GOHOME
|
|
@ok MOVE D1,LOCMODE(A6) ;copy mode for colormap End of <7>
|
|
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
|
|
;
|
|
MOVE.L SP,D1 ;GET THE STACK POINTER
|
|
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
|
|
MOVE.L D1,SP ;USE IT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CONVERT DSTBITS TO PIXMAP
|
|
; (A5 must contain global ptr)
|
|
;
|
|
LEA PORTBITS(A3),A1 ;GET POINTER TO DSTBITS
|
|
LEA DSTPIX(A6),A2 ;USE DSTPIX IN ITS PLACE
|
|
_BitsToPix ;CONVERT BITMAP
|
|
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
|
|
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CONVERT PIXEL DEPTH TO SHIFT AMOUNT TO AVOID MULTIPLIES
|
|
;
|
|
LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
|
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
|
|
MOVEQ #0,D1 ;DEFAULT SHIFT = 0
|
|
MOVE.B 0(A0,D0),D1 ;GET SRC SHIFT
|
|
MOVE D1,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
|
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
|
|
;
|
|
LEA PNPAT(A3),A0 ;POINT TO THE PATTERN
|
|
MOVE.L A0,LOCPAT(A6) ;COPY PATTERN POINTER
|
|
TST PORTBITS+ROWBYTES(A3) ;IS THE DST OLD OR NEW?
|
|
;ciDrawLine from QDciPatchROM.a used to be right here
|
|
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; Check for color filtering. Alter mode and pattern accordingly.
|
|
;
|
|
MOVE.B HiliteMode,-(SP) ;preserve the hilite mode
|
|
CLR.B multiColor(A6) ;use fg/bg color
|
|
_COLORMAP ;CHECK AGAINST THECOLOR, THEFILTER
|
|
MOVE.B (SP)+,HiliteMode ;since stretch (and thus ColorMap) may be called later
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
|
|
;
|
|
MOVE.L A3,A5 ;PUT GRAFPTR IN A5
|
|
MOVE.L CLIPRGN(A5),A2 ;GET CLIPRGN HANDLE
|
|
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
|
|
MOVE.L VISRGN(A5),A3 ;GET VISRGN HANDLE
|
|
MOVE.L (A3),A3 ;GET VISRGN POINTER
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; SET UP LINERECT, THE RECTANGLE BOUNDING THE LINE AND PEN
|
|
;
|
|
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V1, D2=H1, D3=V2, D4=H2
|
|
CMP D3,D1 ;IS V1 > V2 ?
|
|
BLE.S VOK2 ;NO, CONTINUE
|
|
EXG D1,D3 ;YES, SWAP VERT
|
|
VOK2 CMP D4,D2 ;IS H1 > H2 ?
|
|
BLE.S HOK2 ;NO, CONTINUE
|
|
EXG D2,D4 ;NO SWAP HORIZ
|
|
HOK2 ADD PNSIZE+H(A5),D4 ;ADD PEN WIDTH TO RIGHT
|
|
ADD PNSIZE+V(A5),D3 ;ADD PEN HEIGHT TO BOTTOM
|
|
MOVEM.W D1/D2/D3/D4,LINERECT(A6) ;STORE TOP, LEFT, BOTTOM, RIGHT
|
|
|
|
|
|
;-----------------------------------------------------------------------
|
|
;
|
|
; CALC MINRECT, THE INTERSECTION OF LINERECT, BITMAP BOUNDS,
|
|
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
|
|
;
|
|
PEA LINERECT(A6) ;PUSH LINE RECT
|
|
PEA DSTPIX+BOUNDS(A6) ;PUSH PIXMAP BOUNDS
|
|
PEA RGNBBOX(A2) ;PUSH CLIPRGN BBOX
|
|
PEA RGNBBOX(A3) ;PUSH VISRGN BBOX
|
|
MOVE #4,-(SP) ;PUSH NRECTS=4
|
|
PEA MINRECT(A6) ;PUSH DST ADDR
|
|
_RSECT ;CALC INTERSECTION
|
|
BEQ GOHOME ;QUIT IF NO INTERSECT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT AND DST IS SCREEN.
|
|
; (A5 must contain global ptr)
|
|
;
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
|
|
BEQ.S NOTSCRN ;=>NO
|
|
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
|
|
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
|
|
_SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
|
|
NOTSCRN MOVE.L PORT(A6),A5 ;GET BACK THEPORT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; CHECK FOR BOTH VISRGN AND CLIPRGN RECTANGULAR
|
|
;
|
|
CLR.B FASTFLAG(A6) ;FASTFLAG := FALSE
|
|
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
|
|
BEQ.S CKPAT ;YES, CONTINUE
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; If only visRgn is non-rectangular, then check if
|
|
; its intersection with minrect would be rectangular.
|
|
; IF TrimRect(visRgn,minRect) then treat as rectangular.
|
|
;
|
|
MOVE.L visRgn(A5),-(SP) ;push rgnHandle
|
|
PEA minRect(A6) ;push addr of minRect
|
|
MOVE.W #-1,-(SP) ;pass Trim = True
|
|
_TrimRect ;call trimRect
|
|
BLT show ;quit if intersection empty
|
|
BGT.S FLAGOK ;continue if non-rectangular
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; CHECK FOR BLACK OR WHITE PATTERN
|
|
;
|
|
CKPAT BTST #5,LocMode+1(A6) ;an arithmetic mode?
|
|
BNE.S FlagOK ;skip fast case if so
|
|
|
|
MOVE.L LOCPAT(A6),A0 ;POINT TO PATTERN
|
|
TST.B NEWPATTERN(A6) ;is it a new pattern? <C945 07Nov87 BAL>
|
|
BEQ.S @oldPat ;=>no, skip pixpat fields <C945 07Nov87 BAL>
|
|
|
|
MOVE.L (a0),a0 ;get the pixpat handle <C945 07Nov87 BAL>
|
|
MOVE.L (a0),a0 ;get the pixpat pointer <C945 07Nov87 BAL>
|
|
TST PATTYPE(A0) ;is it an old-style pattern? <C945 07Nov87 BAL>
|
|
BNE.S FLAGOK ;=>no, skip fast case <C945 07Nov87 BAL>
|
|
|
|
MOVE.L patData(a0),a0 ;get handle to pattern data <C945 07Nov87 BAL>
|
|
MOVE.L (a0),a0 ;get pattern ptr <C945 07Nov87 BAL>
|
|
|
|
@oldPat MOVE.L (A0)+,D0 ;GET 1ST HALF OF PATTERN
|
|
CMP.L (A0)+,D0 ;IS IT SAME AS 2ND HALF ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
NOT.L D0 ;IS PATTERN BLACK ?
|
|
BEQ.S YESFLAG ;YES, WE MADE IT
|
|
NOT.L D0 ;IS PATTERN WHITE ?
|
|
BNE.S FLAGOK ;NO, CONTINUE
|
|
EOR #4,LOCMODE(A6) ;YES, ALTER MODE AS IF BLACK
|
|
YESFLAG ST FASTFLAG(A6) ;RECT CLIPPED AND BLACK
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; fast case: map mode into black,xor,white, or do-nothing
|
|
;
|
|
MOVEQ #7,D0 ;GET 3 BIT MASK
|
|
AND LOCMODE(A6),D0 ;GET 3 BITS OF MODE
|
|
MOVE.B MODEMAP(D0),D0 ;MAP TO BLACK,XOR,WHITE,NOP
|
|
BMI show ;QUIT IF DO-NOTHING MODE
|
|
MOVE D0,LOCMODE(A6) ;UPDATE MODE
|
|
BRA.S FLAGOK ;AND CONTINUE
|
|
MODEMAP DC.B 0,0,1,2,2,255,255,255
|
|
FLAGOK
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; GET THE TWO LINE ENDPOINTS INTO REGISTERS
|
|
; AND CHECK FOR HORIZONTAL OR VERTICAL LINE
|
|
;
|
|
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V2, D2=H2, D3=V1, D4=H1
|
|
CMP D2,D4 ;H1=H2 ?
|
|
BEQ.S HVLINE ;YES, DO VERTICAL LINE
|
|
CMP D1,D3 ;NO, IS V2 > V1 ?
|
|
BGT.S SLANTED ;YES, DRAW SLANTED LINE
|
|
BLT.S VSWAP ;SWAP POINTS AND DRAW SLANTED
|
|
;ELSE V1=V2, DO HORIZONTAL
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; LINE IS EITHER HORIZONTAL OR VERTICAL.
|
|
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND
|
|
; CLIPRGN AND VISRGN BOTH RECTANGULAR. IF SO, OPTIMIZE FAST LINES.
|
|
;
|
|
HVLINE TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BEQ.S NOTFAST ;NO, CONTINUE
|
|
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
|
bne.s NotFast ;NO, CONTINUE
|
|
_FastLineJmp ;YES, DO IT FAST !
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; NOT FASTLINE. PUSH PARAMS AND CALL STRETCHBITS FOR HORIZ OR VERT LINE.
|
|
;
|
|
NOTFAST PEA PORTBITS(A5) ;PUSH SRCBITS = PORTBITS
|
|
CLR.L -(SP) ;NO MASKBITS
|
|
PEA PORTBITS(A5) ;PUSH DSTPIX
|
|
PEA MINRECT(A6) ;PUSH SRCRECT = DSTRECT
|
|
CLR.L -(SP) ;NO MASKRECT
|
|
PEA MINRECT(A6) ;PUSH DSTRECT
|
|
MOVE PNMODE(A5),D0 ;GET MODE <8>
|
|
AND #$FCFF,D0 ;STRIP SOME BITS <8>
|
|
BSET #3,D0 ;set the pattern bit in case the user forgot to <8>
|
|
MOVE D0,-(SP) ;PUSH CLEANED MODE <8>
|
|
PEA PNPAT(A5) ;PUSH PATTERN
|
|
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIPRGN HANDLE
|
|
MOVE.L VISRGN(A5),-(SP) ;PUSH VISRGN HANDLE
|
|
MOVE.L BIGRGN(A6),-(SP) ;PUSH SAVED WIDEOPEN
|
|
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
CLR -(SP) ;pass multicolor flag false
|
|
_STRETCHBITS ;DRAW THE HORIZ OR VERT LINE
|
|
BRA show ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; THE LINE IS SLANTED. SORT VERTICALLY
|
|
; AND DRAW TOP TO BOTTOM AS HORIZONTAL SLABS.
|
|
;
|
|
VSWAP EXG D1,D3 ;SORT POINTS BY VERTICAL
|
|
EXG D2,D4 ;SWAP HORIZ TO MATCH
|
|
SLANTED MOVE D3,D0 ;COPY LINE BOTTOM
|
|
ADD PNSIZE+V(A5),D0 ;ADD PEN HEIGHT
|
|
CMP minRect+TOP(A6),D0 ;IS RESULT <= minRect TOP ? <07Jul89>
|
|
BLE show ;YES, RESTORE CURSOR AND QUIT
|
|
CMP minRect+BOTTOM(A6),D1 ;IS TOP >= minRect BOTTOM ? <07Jul89>
|
|
BGE show ;YES, RESTORE CURSOR AND QUIT
|
|
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; SET UP INITIAL FIXED POINT LEFTEDGE AND RIGHTEDGE
|
|
; AND CHECK FOR ZERO PENSIZE.
|
|
;
|
|
MOVE.W D2,LEFTEDGE(A6) ;LEFTEDGE.INT := TOP HORIZ
|
|
MOVE.W #$8000,LEFTEDGE+2(A6) ;LEFTEDGE.FRACT := 1/2
|
|
MOVE.L LEFTEDGE(A6),RIGHTEDGE(A6) ;RIGHTEDGE:=LEFTEDGE
|
|
MOVE PNSIZE+H(A5),D0 ;GET PEN WIDTH
|
|
BLE show ;QUIT IF PENWIDTH <= 0
|
|
ADD.W D0,RIGHTEDGE(A6) ;ADD TO RIGHTEDGE.INT
|
|
MOVE PNSIZE+V(A5),D6 ;GET PEN HEIGHT
|
|
BLE show ;QUIT IF PEN HEIGHT <= 0
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CALC FIXED POINT SLOPE = FixRatio(dh,dv);
|
|
;
|
|
SUB D2,D4 ;CALC DH
|
|
SUB D1,D3 ;CALC DV
|
|
ext.l D3
|
|
moveq #0,d7 ;clear out high word
|
|
move.w d4,d7 ;copy DH to d7
|
|
swap D7
|
|
DIVS.l D3,D7 ;CALC FIXED POINT SLOPE DH/DV
|
|
MOVE.L D7,SLOPE(A6) ;SAVE FOR LATER
|
|
|
|
;
|
|
; CALC adjust := pen height * slope
|
|
;
|
|
move.l d7,d5 ;assume height is 1
|
|
cmp.w #1,d6 ;is pen height 1
|
|
beq.s @gotAdjust
|
|
ext.l d6
|
|
MULS.L d6,d5 ;CALC FixMul(pnSize.v,slope)
|
|
|
|
|
|
@gotAdjust
|
|
;
|
|
; ADJUST LEFTEDGE AND RIGHTEDGE DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
|
|
; Set steepFlag in A2: 0->shallow; 1->down&right; -1->down&left
|
|
|
|
sub.l a2,a2 ;assume shallow
|
|
MOVE.L D7,D0 ;COPY SLOPE
|
|
ASR.L #1,D0 ;CALC SLOPE/2
|
|
ADD.L D0,LEFTEDGE(A6) ;ADD SLOPE/2 TO LEFT EDGE
|
|
ADD.L D0,RIGHTEDGE(A6) ;ADD SLOPE/2 TO RIGHT EDGE
|
|
|
|
TST.L D7 ;IS SLOPE NEGATIVE ?
|
|
BMI.S NEGSLOPE ;YES, CONTINUE
|
|
SUB.L D5,LEFTEDGE(A6) ;SUBTRACT ADJUST FROM LEFTEDGE
|
|
CMP.L #$00010000,D7 ;IS SLOPE < ONE ?
|
|
BGT.S LESSV1 ;NO, BRANCH
|
|
BEQ.S Pos45 ;NO, BRANCH
|
|
|
|
MOREV1 ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFTEDGE
|
|
addq #1,a2 ;remember steep and to right
|
|
BRA.S SLOPEOK ;CONTINUE
|
|
|
|
Pos45 addq #1,a2 ;remember 45¡
|
|
LESSV1 SUB.W #1,RIGHTEDGE(A6) ;RIGHTEDGE := RIGHTEDGE - 1
|
|
BRA.S SLOPEOK ;CONTINUE
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; SLOPE IS NEGATIVE
|
|
;
|
|
NEGSLOPE SUB.L D5,RIGHTEDGE(A6) ;SUBTRACT ADJUST FROM RIGHTEDGE
|
|
CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
|
|
BLT.S LESSV2 ;NO, CONTINUE
|
|
|
|
MOREV2 ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHTEDGE
|
|
subq #1,a2 ;remember steep and to left
|
|
BRA.S SLOPEOK
|
|
|
|
LESSV2 ADD.W #1,LEFTEDGE(A6) ;LEFTEDGE := LEFTEDGE + 1
|
|
|
|
|
|
|
|
SLOPEOK MOVEM.W MINRECT(A6),D1/D2/D3/D4 ;GET MINRECT TOP,LEFT,BOTTOM,RIGHT
|
|
;
|
|
; ADJUST LEFTEDGE AND RIGHTEDGE IF LINE WAS CLIPPED VERTICALLY
|
|
;
|
|
CMP LINERECT+TOP(A6),D1 ;DID TOP GET CLIPPED ?
|
|
BEQ.S TOPOK ;NO, CONTINUE
|
|
MOVE D1,D0
|
|
SUB LINERECT+TOP(A6),D0 ;CALC DISCARD AMOUNT
|
|
EXT.L D0 ;MAKE IT LONG
|
|
MOVE.L D7,D5 ;GET 32 BIT SLOPE
|
|
MULS.L D0,D5 ;SLOPE * SCANS CLIPPED
|
|
ADD.L D5,LEFTEDGE(A6) ;BUMP LEFTEDGE TO NEW TOP
|
|
ADD.L D5,RIGHTEDGE(A6) ;BUMP RIGHTEDGE TO NEW TOP
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; LINE IS SLANTED. IF |SLOPE| <= 1 THEN
|
|
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND CLIPRGN
|
|
; AND VISRGN BOTH RECTANGULAR. IF SO THEN OPTIMIZE.
|
|
;
|
|
TOPOK
|
|
; bchg #0,0 ;debugging code
|
|
; beq.s CalcBufLeft
|
|
|
|
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BEQ.S CalcBufLeft ;NO, CONTINUE
|
|
cmp.w LINERECT+left(a6),D2 ;is MinRect.Left>Line's left edge?
|
|
bgt.s CalcBufLeft ;horizontally clipped!
|
|
cmp.w LINERECT+right(a6),D4 ;is MinRect.Right<Line's right edge?
|
|
blt.s CalcBufLeft ;horizontally clipped!
|
|
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
|
|
bne.s CalcBufLeft ;no, continue
|
|
_FastSlantJmp ;YES, DO IT FAST !
|
|
;Assumes: D1,D2,D3,D4 = MinRect T,L,B,R
|
|
; D7 = slope (16.16)
|
|
CalcBufLeft
|
|
;-----------------------------------------------------------
|
|
;
|
|
; CALC BUFLEFT
|
|
;
|
|
;D2 = MINRECT LEFT
|
|
MOVE DSTSHIFT(A6),D5 ;GET SHIFT FOR PIXEL DEPTH
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL COORDS
|
|
ext.l d2 ;make it a long <BAL 17Jan89>
|
|
LSL.l D5,D2 ;CONVERT PIXELS TO BITS
|
|
AND.l #~$1f,D2 ;TRUNC TO MULT OF 32 BITS
|
|
MOVE.l D2,D1 ;GET BUFLEFT IN BITS
|
|
LSR.l #3,D1 ;CONVERT BITS TO BYTES
|
|
MOVE D1,PATHPOS(A6) ;AND SAVE AS HORIZONTAL PATTERN BASE
|
|
LSR.l D5,D2 ;CONVERT BITS TO PIXELS
|
|
ADD DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BACK TO GLOBAL
|
|
MOVE D2,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
|
;
|
|
; IF FASTFLAG, THEN SKIP REGION SETUP
|
|
;
|
|
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
|
|
BNE SKIPSETUP ;YES, DON'T WASTE TIME WITH SETUP
|
|
|
|
;_________________________________________________________________________________________
|
|
;
|
|
; CALC expansion buffer = [ (minRect.right-minRect.left) div 32 + 1 ] * pixelsize - 1
|
|
; CALC bufSize = [ (minRect.right-minRect.left) * pixelsize - 1 ] div 32 <C954> 08Nov87 BAL
|
|
;
|
|
;D4 = MINRECT RIGHT
|
|
SUB D2,D4 ;CALC MAXH-BUFLEFT
|
|
move d4,d0 ;save for expansion scanline buffer <C954>
|
|
|
|
ext.l d4 ;clear out high word <C954>
|
|
lsl.l d5,d4 ;convert to bits <C954>
|
|
subq.l #1,d4 ;force downward round <C954>
|
|
LSR.l #5,D4 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
|
|
MOVE D4,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
|
|
|
|
LSR #5,D0 ;get (pixels in scanbuf)/32 <C954>
|
|
ADDQ #1,D0 ;MAKE IT ONE BASED
|
|
LSL D5,D0 ;CONVERT PIXELS TO BITS
|
|
SUBQ #1,D0 ;MAKE 0 BASED AGAIN
|
|
;
|
|
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK
|
|
;
|
|
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR ONE LONG
|
|
DBRA D0,CLRMASK ;LOOP TILL DONE
|
|
MOVE.L SP,RGNBUFFER(A6) ;REMEMBER WHERE RGNBUFFER IS
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
|
|
; GET SEEK ROUTINE INTO SEEKMASK(A6)
|
|
; GET EXPAND ROUTINE INTO EXRTN(A6) FOR SEEK ROUTINE
|
|
; Clobbers: A0-A3, D0-D4
|
|
;
|
|
lea Show,a0 ;get go home routine
|
|
move.l a0,goShow(a6) ;pass to getSeek <BAL 21Mar89>
|
|
move.l maskbc,StackFree(a6) ;pretend lots of stack <BAL 21Mar89>
|
|
|
|
clr.l DstRow(a6) ;flag as seeking down
|
|
clr.l runBuf(a6) ;don't use run clipping <1.5> BAL
|
|
MOVE.L VISRGN(A5),-(SP) ;PUSH VIS RGNHANDLE
|
|
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIP RGNHANDLE
|
|
MOVE.L #1,-(SP) ;PUSH HANDLE COUNT - 1
|
|
_GETSEEK ;GET EXPAND ROUTINE INTO EXRTN(A6)
|
|
;AND SEEK ROUTINE INTO SEEKMASK(A6)
|
|
|
|
SKIPSETUP
|
|
|
|
;------------------------------------
|
|
;
|
|
; CALC STARTING DSTLEFT
|
|
;
|
|
;Êas seen in QDciPatchROM.a at TryLine, fixes both patches on _FastSlabMode and _GetSeek <sm 6/9/92>stb
|
|
|
|
MOVE MINRECT+TOP(A6),D1
|
|
SUB DSTPIX+BOUNDS+TOP(A6),D1 ;CONVERT MINV TO GLOBAL COORDS
|
|
MOVE DSTPIX+ROWBYTES(A6),D0 ;get dst rowbytes
|
|
AND #nuRBMask,D0 ;clear off flag bits
|
|
MOVE D0,DSTROW(A6) ;SAVE FOR LATER
|
|
MULS D0,D1 ;MULT BY DST ROWBYTES; BAL 02Dec88
|
|
ADD.L DSTPIX+BASEADDR(A6),D1 ;ADD START OF BITMAP
|
|
|
|
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT BUFLEFT TO GLOBAL
|
|
ext.l d2 ;clear out high end <BAL 13Feb90>
|
|
MOVE DSTSHIFT(A6),D7 ;GET PIXEL TO BIT SHIFT AMOUNT
|
|
LSL.L D7,D2 ;CONVERT PIXELS TO BITS <BAL 13Feb90>
|
|
LSR.L #3,D2 ;CONVERT BITS TO BYTES <BAL 13Feb90>
|
|
; EXT.L D2 ;CLR HI WORD <BAL 13Feb90>
|
|
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
|
|
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; MAKE LEFTEDGE,RIGHTEDGE,MINRECT RELATIVE TO BUFFER LEFT
|
|
;
|
|
MOVE BUFLEFT(A6),D1
|
|
SUB.W D1,LEFTEDGE(A6) ;ADJUST LEFTEDGE.INT
|
|
SUB.W D1,RIGHTEDGE(A6) ;ADJUST RIGHTEDGE.INT
|
|
SUB D1,MINRECT+LEFT(A6)
|
|
SUB D1,MINRECT+RIGHT(A6)
|
|
|
|
|
|
;------------------------------------------------------------
|
|
;
|
|
; TAKE FAST OR SLOW OUTER CONTROL LOOP FOR SLANTED LINES:
|
|
;
|
|
TST.B fastFlag(A6) ;ARE WE RECT CLIPPED BLACK ?
|
|
BEQ.S GOSLOW ;NO, CONTINUE
|
|
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
_FastSlabMode ;Get fast case jump in A4
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
|
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
|
MOVE.L FCOLOR(A6),D4 ;PASS FCOLOR
|
|
MOVE.L BCOLOR(A6),D5 ;AND BACKCOLOR
|
|
MOVE MINRECT+BOTTOM(A6),D6 ;GET MINRECT BOTTOM
|
|
SUB MINRECT+TOP(A6),D6 ;CALC HEIGHT
|
|
SUB #1,D6 ;MINUS 1 FOR DBRA COUNT
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
NXTFAST MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
|
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
|
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
|
MOVE.W DSTSHIFT(A6),D0 ;GET PIXEL TO BIT SHIFT AMOUNT
|
|
_DrawSlab ;DRAW ONE SLAB IN PENMODE
|
|
ADD DSTROW(A6),A5 ;BUMP DST TO NEXT ROW
|
|
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
|
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
|
DBRA D6,NXTFAST ;LOOP FOR ALL SCANLINES
|
|
BRA DONE ;AND QUIT
|
|
|
|
|
|
GOSLOW
|
|
;------------------------------------------------------------------
|
|
;
|
|
; SET INVERSE FLAG AND CALL PATEXPAND TO EXPAND PATTERN
|
|
;
|
|
CLR.L D7 ;SAY NOT INVERTED
|
|
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
BTST #5,D2 ;a new arithmetic mode?
|
|
BNE.S NOTINV ;if so, no invert bit to test
|
|
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
|
BEQ.S NOTINV ;SKIP IF NOT INVERTED
|
|
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
|
|
|
|
NOTINV MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
_PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
|
|
;SETUP PATROW,PATHMASK,PATVMASK
|
|
MOVE PATROW(A6),D1 ;GET THE PATTERN ROWBYTES
|
|
BNE.S DONEW ;=>NON-ZERO, IT'S A NEW PATTERN
|
|
|
|
MOVEQ #$F,D6 ;ELSE 16 ROWS OF PATTERN
|
|
MOVEQ #$4,D1 ;GET PATTERN ROWBYTES INTO D1
|
|
MOVE D1,PATROW(A6) ;AND SET PATTERN ROWBYTES
|
|
MOVE #$3,PATHMASK(A6) ;HORIZONTAL MASK FOR PATTERN
|
|
MOVE #$3F,PATVMASK(A6) ;VERTICAL MASK FOR PATTERN
|
|
BRA.S DOOLD ;=>GO GET STARTING OFFSET INTO PATTERN
|
|
|
|
; NEW PATTERN. SET STARTING VERT POSITION.
|
|
|
|
DONEW MOVEQ #0,D6 ;CLEAR HIGH WORD
|
|
MOVE PATVMASK(A6),D6 ;GET VERTICAL MASK
|
|
ADDQ #1,D6 ;CONVERT TO COUNT
|
|
DIVU PATROW(A6),D6 ;DIVIDE BY ROWSIZE
|
|
SUBQ #1,D6 ;GET ROWS OF PATTERN
|
|
|
|
DOOLD AND MINRECT+TOP(A6),D6 ;GET TOP VERT LOCAL COORD
|
|
MULU D1,D6 ;CALC OFFSET INTO PATTERN
|
|
MOVE.l D6,PATVPOS(A6) ;SAVE AS PATVPOS <BAL 22Jan89>
|
|
|
|
; GET SLOW SLABMODE IN A4 (RELIES ON PATROW, SET UP BY PATEXPAND)
|
|
|
|
MOVE LOCMODE(A6),D2 ;GET (ALTERED) PEN MODE
|
|
_SlabMode ;GET DrawSlab CASE JUMP IN A4
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
; FOR EACH SLAB, MAKE MASK BUFFER CURRENT AND DRAW SLAB
|
|
|
|
MOVE MINRECT+TOP(A6),VERT(A6) ;INIT CURRENT VERT:=MINV
|
|
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
|
|
MOVE.L FCOLOR(A6),D4 ;PASS FCOLOR
|
|
MOVE.L BCOLOR(A6),D5 ;AND BACKCOLOR
|
|
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
|
|
NXTMASK JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
|
LEA MINRECT(A6),A3 ;POINT TO MINRECT
|
|
LEA ([EXPAT,A6],D6.l),A0 ;GET pointer to THIS ROW'S PATTERN
|
|
MOVE.L (A0),D6 ;set up the pattern
|
|
MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
|
|
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
|
|
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
|
|
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR TO LEFT
|
|
MOVE.W DSTSHIFT(A6),D0 ;GET SHIFT FOR PIXEL DEPTH
|
|
_DrawSlab ;DRAW ONE SLAB IN PENMODE
|
|
MOVE.l PATVPOS(A6),D6 ;GET PATVPOS <BAL 22Jan89>
|
|
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
|
AND PATVMASK(A6),D6 ;WRAP AT END OF PATTERN
|
|
MOVE.l D6,PATVPOS(A6) ;SAVE PATVPOS FOR DRAWSLAB <BAL 22Jan89>
|
|
ADD DSTROW(A6),A5 ;BUMP DST TO NEXT ROW
|
|
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
|
|
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
|
|
ADD #1,VERT(A6) ;BUMP CURRENT VERT FOR SEEKMASK
|
|
MOVE VERT(A6),D0 ;GET CURRENT VERT
|
|
CMP MINRECT+BOTTOM(A6),D0 ;AT BOTTOM YET ?
|
|
BLT NXTMASK ;NO, LOOP ALL SCAN LINES
|
|
|
|
|
|
DONE move.b MMUsave(a6),d0 ;get previous MMU state in d0
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
SHOW MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
|
|
TST.B CRSRFLAG(A6) ;DRAWING TO SCREEN?
|
|
BEQ.S GOHOME ;=>NO, JUST RETURN
|
|
_SHOWCURSOR ;RESTORE CURSOR
|
|
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
|
|
MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
|
|
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
|
UNLINK PARAMSIZE,'DRAWLINE'
|
|
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
|
|
;
|
|
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
FASTLINE
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
move.w d1,-(sp) ;save a register
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
|
move.w (sp)+,d1 ;restore d1
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
MOVE.L alphaMask(A6),D4 ;get alpha mask <6>
|
|
CMP D1,D3 ;IS LINE HORIZONTAL ?
|
|
BNE VLINE ;NO, MUST BE VERTICAL
|
|
BSR HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
|
MOVEQ #-1,D6 ;GET ONES IN D6
|
|
LSR.L D0,D6 ;CONVERT TO LEFTMASK
|
|
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL
|
|
EXT.L D2 ;MAKE IT LONG
|
|
LSL.L D3,D2 ;CONVERT PIXELS TO BITS
|
|
MOVEQ #$1F,D0 ;NEED RIGHT MOD 32
|
|
AND.L D2,D0 ;MAKE A COPY OF RIGHT
|
|
MOVEQ #-1,D3 ;GET ONES IN D3
|
|
LSR.L D0,D3 ;SHIFT IN 0'S FOR LEFTMASK
|
|
NOT.L D3 ;CONVERT TO RIGHTMASK
|
|
AND.L D4,D6 ;clip left mask with alpha mask <6>
|
|
AND.L D4,D3 ;clip right mask with alpha mask <6>
|
|
LSR.L #5,D2 ;CONVERT BITS TO LONGS
|
|
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S HSET ;BR IF FOREGROUND
|
|
BEQ.S HTOGL ;BR IF XOR
|
|
;ELSE BACKGROUND
|
|
|
|
;------------------------------------------------------
|
|
;
|
|
; DRAW A HORIZONTAL LINE IN THE BACKGROUND COLOR (NORMALLY WHITE)
|
|
;
|
|
MOVE.L BCOLOR(A6),D5 ;GET THE COLOR
|
|
BRA.S HDRAW
|
|
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; DRAW A HORIZONTAL LINE IN THE FOREGROUND COLOR (NORMALLY BLACK)
|
|
;
|
|
HSET MOVE.L FCOLOR(A6),D5 ;GET THE FOREGROUND COLOR
|
|
HDRAW SUB D1,D2 ;CALC LONG COUNT
|
|
BEQ.S ALLONE ;BR IF ALL IN ONE LONG
|
|
|
|
MOVE.L D5,D1 ;COPY COLOR
|
|
AND.L D6,D1 ;MASK COLOR FOR LEFT EDGE
|
|
NOT.L D6 ;GET NOT LEFTMASK
|
|
AND.L (A4),D6 ;PUNCH HOLE IN DEST
|
|
OR.L D1,D6 ;COMBINE SRC AND DST
|
|
MOVE.L D6,(A4)+ ;AND DROP COLOR IN
|
|
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
BEQ.S DOEND ;BR IF NO UNMASKED LONG
|
|
|
|
NOT.L D4 ;reverse alpha mask <6>
|
|
BEQ.S DOONE ;use normal loops if all ones <6>
|
|
;
|
|
; <6> Draw horizontal line using alpha mask
|
|
;
|
|
ALPHALINE
|
|
MOVE.L (A4),D0 ;get long of dst
|
|
EOR.L D5,D0 ;apply color
|
|
AND.L D4,D0 ;mask with alpha mask
|
|
EOR.L D5,D0 ;reapply color
|
|
MOVE.L D0,(A4)+ ;put result to dst
|
|
DBRA D2,ALPHALINE ;do another long
|
|
BRA.S DOEND ;all done
|
|
|
|
DOTWO MOVE.L D5,(A4)+ ;FILL A LONG WITH COLOR
|
|
DOONE MOVE.L D5,(A4)+ ;FILL ANOTHER LONG
|
|
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
|
DOMORE BGT DOTWO ;YES, AT LEAST TWO LONGS
|
|
BEQ DOONE ;YES, FINISH UP LAST LONG
|
|
DOEND AND.L D3,D5 ;MASK SOURCE FOR RIGHT EDGE
|
|
NOT.L D3 ;GET NOTMASK
|
|
AND.L (A4),D3 ;PUNCH HOLE IN DST DATA
|
|
OR.L D5,D3 ;COMBINE SRC AND DST
|
|
MOVE.L D3,(A4) ;AND DROP COLOR IN
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
ALIGN Alignment
|
|
|
|
ALLONE AND.L D3,D6 ;COMBINE LEFT AND RIGHT MASKS
|
|
AND.L D6,D5 ;GET MASKED COLOR
|
|
NOT.L D6 ;GET NOTMASK
|
|
AND.L (A4),D6 ;PUNCH OUT DESTINATION
|
|
OR.L D5,D6 ;COMBINE SRC AND DST
|
|
MOVE.L D6,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
;--------------------------------------------------
|
|
;
|
|
; DRAW AN XOR HORIZONTAL LINE
|
|
;
|
|
HTOGL SUB D1,D2 ;CALC LONGCOUNT
|
|
BEQ.S ONETOGL ;BR IF ALL IN ONE LONG
|
|
EOR.L D6,(A4)+ ;DO LEFT LONG WITH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
BEQ.S ENDTOGL ;BR IF NO UNMASKED LONGS
|
|
BRA.S TOGLONE ;SEE IF ANY LONGS LEFT TO DO
|
|
TOGLTWO EOR.L D4,(A4)+ ;INVERT A LONG <6>
|
|
TOGLONE EOR.L D4,(A4)+ ;INVERT ANOTHER LONG <6>
|
|
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
|
|
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
|
|
BEQ TOGLONE ;YES, FINISH UP LAST LONG
|
|
ENDTOGL EOR.L D3,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
ONETOGL AND.L D3,D6 ;COMBINE LEFT AND RIGHT MASK
|
|
EOR.L D6,(A4) ;DRAW LINE
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;Êas seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
;-------------------------------------------------------
|
|
;
|
|
; DRAW A ONE PIXEL WIDE VERTICAL LINE.
|
|
;
|
|
VLINE BSR.S HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
|
|
MOVEQ #-1,D2 ;GET ONES IN D2
|
|
LSR.L D0,D2 ;CONVERT TO LEFTMASK (LEFT MOD 32 IN D0)
|
|
MOVE.L D2,D0 ;GET LEFTMASK
|
|
MOVE DSTPIX+PIXELSIZE(A6),D1 ;GET PIXEL SIZE
|
|
LSR.L D1,D0 ;SHIFT BY PIXEL SIZE FOR RIGHT EDGE
|
|
NOT.L D0 ;MAKE IT A RIGHTMASK
|
|
AND.L D0,D2 ;AND RIGHTMASK INTO LEFTMASK
|
|
AND.L D4,D2 ;MASK WITH ALPHA MASK <6>
|
|
MOVE MINRECT+BOTTOM(A6),D1 ;GET BOTTOM
|
|
SUB MINRECT+TOP(A6),D1 ;CALC HEIGHT
|
|
SUB #1,D1 ;INIT HEIGHT COUNT
|
|
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S VSET ;BR IF FOREGROUND
|
|
BEQ.S VTOGL ;BR IF XOR
|
|
|
|
VCLR MOVE.L BCOLOR(A6),D5 ;GET BACKGROUND COLOR
|
|
BRA.S VDRAW ;=>AND DO LINE
|
|
|
|
VSET MOVE.L FCOLOR(A6),D5 ;GET FOREGROUND COLOR
|
|
VDRAW BEQ.S VAND ;COLOR IS ALL 0's SO JUST AND
|
|
MOVE.L D5,D0 ;COPY COLOR
|
|
NOT.L D0 ;WAS IT ALL 1's?
|
|
BEQ.S VOR ;YES, JUST NEED TO OR
|
|
AND.L D2,D5 ;GET DATA TO WRITE
|
|
NOT.L D2 ;MAKE NOTMASK
|
|
|
|
NXTV MOVE.L D2,D3 ;GET NOTMASK
|
|
AND.L (A4),D3 ;PUNCH A HOLE IN THE DST
|
|
OR.L D5,D3 ;COMBINE SRC AND DST
|
|
MOVE.L D3,(A4) ;AND PUT TO DST
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,NXTV ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
ALIGN Alignment
|
|
|
|
VTOGL EOR.L D2,(A4) ;TOGGLE ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,VTOGL ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
ALIGN Alignment
|
|
|
|
VOR OR.L D2,(A4) ;TOGGLE ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,VOR ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
ALIGN Alignment
|
|
|
|
VAND NOT.L D2 ;MAKE INTO CLEARING MASK
|
|
@AND AND.L D2,(A4) ;TOGGLE ONE DOT
|
|
ADD D7,A4 ;BUMP TO NEXT ROW
|
|
DBRA D1,@AND ;LOOP ALL DOTS
|
|
BRA.S DONE ;RESTORE CURSOR AND QUIT
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;------------------------------------------------------------------------
|
|
;
|
|
; LOCAL ROUTINE TO SET UP POINTER TO FIRST WORD, BIT INDEX, AND ROWBYTES
|
|
;
|
|
; INPUTS: MINRECT
|
|
; A5: thePort
|
|
;
|
|
; OUTPUTS: D0: LEFT MOD 32 (for getting mask)
|
|
; D1: LEFT DIV 32 (for long position)
|
|
; D3: DSTSHIFT
|
|
; D7: ROWBYTES
|
|
; A4: POINTER TO FIRST WORD
|
|
;
|
|
; CLOBBERS: D0,D1,D7,A0,A4
|
|
;
|
|
HVSETUP MOVE.L DSTPIX+BASEADDR(A6),A4 ;GET BITMAP START
|
|
MOVE MINRECT+TOP(A6),D0 ;GET STARTING VERT
|
|
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL
|
|
MOVE DSTPIX+ROWBYTES(A6),D7 ;GET ROWBYTES
|
|
AND #nuRBMask,D7 ;clear off flag bits
|
|
MULS D7,D0 ;MULT TOP BY ROWBYTES; BAL 02Dec88
|
|
ADD.L D0,A4 ;ADD TO BASEADDR
|
|
MOVE MINRECT+LEFT(A6),D0 ;GET STARTING HORIZ
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D0 ;CONVERT TO GLOBAL
|
|
EXT.L D0 ;MAKE IT LONG
|
|
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
|
EXT.L D3 ;MAKE IT LONG
|
|
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
|
MOVE.L D0,D1 ;MAKE A COPY
|
|
LSR.L #5,D1 ;CONVERT BITS TO LONGS
|
|
LEA (A4,D1*4),A4 ;add in byte cnt
|
|
AND #$1F,D0 ;TREAT LEFT MOD 32
|
|
RTS
|
|
|
|
ALIGN 4
|
|
|
|
;-------------------------------------------------------
|
|
|
|
SteepBlitTab
|
|
DC.L steepCopy1-SteepBlitTab
|
|
DC.L steepCopy2-SteepBlitTab
|
|
DC.L steepCopy4-SteepBlitTab
|
|
DC.L steepCopy8-SteepBlitTab
|
|
DC.L steepCopy16-SteepBlitTab
|
|
DC.L steepCopy32-SteepBlitTab
|
|
|
|
SteepBlitXorTab
|
|
DC.L steepXor1-SteepBlitTab
|
|
DC.L steepXor2-SteepBlitTab
|
|
DC.L steepXor4-SteepBlitTab
|
|
DC.L steepXor8-SteepBlitTab
|
|
DC.L steepXor16-SteepBlitTab
|
|
DC.L steepXor32-SteepBlitTab
|
|
|
|
;-------------------------------------------------------
|
|
|
|
ShallowBlitTab
|
|
DC.L shallowCopy1-ShallowBlitTab
|
|
DC.L shallowCopy2-ShallowBlitTab
|
|
DC.L shallowCopyN-ShallowBlitTab
|
|
DC.L shallowCopyN-ShallowBlitTab
|
|
DC.L shallowCopyN-ShallowBlitTab
|
|
DC.L done-ShallowBlitTab ;never used
|
|
|
|
ShallowBlitXorTab
|
|
DC.L shallowXor1-ShallowBlitTab
|
|
DC.L shallowXor2-ShallowBlitTab
|
|
DC.L shallowXorN-ShallowBlitTab
|
|
DC.L shallowXorN-ShallowBlitTab
|
|
DC.L shallowXorN-ShallowBlitTab
|
|
DC.L done-ShallowBlitTab ;never used
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; SET UP AND DRAW A FAST SLANTED LINE.
|
|
; Only steep lines are currently implemented: (45¡<=¿<=135¡)
|
|
;
|
|
; Assumes: D1,D2,D3,D4 = MinRect top,left,bottom,right
|
|
; D7 = slope (16.16)
|
|
|
|
FASTSLANT
|
|
|
|
;------------------------------------------------------------------------
|
|
;
|
|
; SET UP REGISTERS FOR FAST SLANT LOOPS
|
|
;
|
|
; INPUTS: MINRECT, DSTPIX, SLOPE
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 =
|
|
; a1 = d1 = fgColor/bkColor
|
|
; a2 = d2 = dst pixel size (bit width)
|
|
; a3 = rowBytes d3 = dstShift
|
|
; a4 = dstPtr d4 = bit offset to pixel left
|
|
; a5 = d5 = leftEdge (16.16)
|
|
; a6 = locals d6 = scan count (zero based)
|
|
; a7^= d7 = slope (16.16)
|
|
;-------------------------------------------------------
|
|
; includes fix as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
SLANTSETUP
|
|
TST.B alphaMode(A6) ;if alphamode == 0, stay in all cases <6>
|
|
BEQ.S @stay ; <6>
|
|
TST A2 ;leave if shallow and alphamode != 0 <6>
|
|
BEQ goBack ; <6>
|
|
MOVE LOCMODE(A6),D0 ;get the local mode <6>
|
|
ADDQ #1,D0 ;convert from xor=1 to xor=srcXor <6>
|
|
CMP #srcXor,D0 ; <6>
|
|
BNE goBack ;if copying, leave because alphamode != 0
|
|
@stay MOVE.L DSTPIX+BASEADDR(A6),A4 ;GET BITMAP START
|
|
MOVE D1,D0 ;GET STARTING VERT
|
|
SUB DSTPIX+BOUNDS+TOP(A6),D0 ;CONVERT TO GLOBAL
|
|
MOVE DSTPIX+ROWBYTES(A6),D6 ;GET ROWBYTES
|
|
AND #nuRBMask,D6 ;clear off flag bits
|
|
MULS D6,D0 ;MULT TOP BY ROWBYTES
|
|
MOVE D6,A3 ;REMEMBER ROWBYTES
|
|
ADD.L D0,A4 ;ADD TO BASEADDR
|
|
tst.w a2 ;taller or wider?
|
|
beq Shallow
|
|
SUB D1,D3 ;CALC HEIGHT
|
|
MOVEQ #-1,D6 ;
|
|
ADD D3,D6 ;D6 IS HEIGHT-1
|
|
MOVE.L LEFTEDGE(A6),D5 ;GET LEFTEDGE
|
|
|
|
MOVE.L D5,D2 ;Get LeftEdge.int
|
|
SWAP D2
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D2 ;CONVERT TO GLOBAL
|
|
EXT.L D2 ;MAKE IT LONG
|
|
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
|
LSL.L D3,D2 ;CONVERT PIXELS TO BITS
|
|
MOVE.L D2,D4 ;MAKE A COPY
|
|
LSR.L #5,D2 ;CONVERT BITS TO LONGS
|
|
LSL.L #2,D2 ;Convert back to bytes
|
|
ADD.L D2,A4 ;ADD TO RUNNING TOTAL
|
|
AND #$1F,D4 ;TREAT LEFT MOD 32
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
_rSwapMMUMode ;(can trash a0/a1/a2, d0/d1/d2)
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
tst.l d7 ;are we going right to left
|
|
bpl.s @toRight ;fractions ok
|
|
neg.w d7 ;make fraction positive
|
|
not.w d5 ;measure distance from right
|
|
;(plus one for boundary cases)
|
|
@toRight
|
|
tst.w d7 ;are we ± 45¡?
|
|
bne.s @not45 ;FOR REED:
|
|
not.w d7 ;hack slope and fraction so that
|
|
move.w d7,d5 ;every scanline generates a carry
|
|
@not45
|
|
MOVE DSTPIX+PIXELSIZE(A6),D2 ;GET DST PIXEL SIZE
|
|
MOVE.L FCOLOR(A6),D1 ;ASSUME FOREGROUND COLOR
|
|
moveq #0,d0 ;init zero register for loops
|
|
LEA SteepBlitTab,a0 ;point to mode table
|
|
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S @useFG ;BR IF FOREGROUND
|
|
BEQ.S @doXor ;BR IF XOR
|
|
;ELSE BACKGROUND
|
|
MOVE.L BCOLOR(A6),D1 ;GET THE COLOR
|
|
@useFG ADD.L (A0,D3*4),A0 ;GET MODECASE
|
|
JMP (A0) ;GO THERE
|
|
|
|
@doXor MOVE.L alphaMask(A6),D1 ;get xoring mask
|
|
ADD.L SteepBlitXorTab-SteepBlitTab(A0,D3*4),A0 ;Adjusted modecase
|
|
JMP (A0) ;GO THERE
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; DRAW ONE PIXEL WIDE STEEP SLANTED LINES
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = zero
|
|
; a1 = d1 = fgColor/bkColor/(-1 for xor)
|
|
; a2 = d2 = dst pixel size (bit width)
|
|
; a3 = rowBytes d3 = dstShift
|
|
; a4 = dstPtr d4 = bit offset to pixel left
|
|
; a5 = d5 = leftEdge (16.16)
|
|
; a6 = locals d6 = scan count (zero based)
|
|
; a7^= d7 = slope (16.16)
|
|
;-------------------------------------------------------
|
|
steepCopy1
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfins d1,(a4){d4:d2} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfins d1,(a4){d4:d2} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepCopy2
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfins d1,(a4){d4:2} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2 ;get a one or zero
|
|
add.l d2,d4 ;bump a bit
|
|
add.l d2,d4 ;bump a bit
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfins d1,(a4){d4:2} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2
|
|
sub.l d2,d4 ;bump a bit
|
|
sub.l d2,d4 ;bump a bit
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepCopy4
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfins d1,(a4){d4:4} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2 ;get a one or zero
|
|
lsl.l #2,d2 ;scale up by bit depth
|
|
add.l d2,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfins d1,(a4){d4:4} ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2
|
|
lsl.l #2,d2 ;scale up by bit depth
|
|
sub.l d2,d4 ;bump a pixel
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepCopy8
|
|
lsr.l #3,d4 ;convert bit offset to byte offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
move.b d1,(a4,d4) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
move.b d1,(a4,d4) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepCopy16
|
|
lsr.l #4,d4 ;convert bit offset to word offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
move.w d1,(a4,d4*2) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
move.w d1,(a4,d4*2) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepCopy32
|
|
lsr.l #5,d4 ;convert bit offset to long offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
move.l d1,(a4,d4*4) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
move.l d1,(a4,d4*4) ;blit one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; XOR ONE PIXEL WIDE STEEP SLANTED LINES
|
|
;
|
|
;-------------------------------------------------------
|
|
steepXor1
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfchg (a4){d4:d2} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfchg (a4){d4:d2} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepXor2
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfchg (a4){d4:2} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2 ;get a one or zero
|
|
add.l d2,d4 ;bump a bit
|
|
add.l d2,d4 ;bump a bit
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfchg (a4){d4:2} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2
|
|
sub.l d2,d4 ;bump a bit
|
|
sub.l d2,d4 ;bump a bit
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepXor4
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
bfchg (a4){d4:4} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2 ;get a one or zero
|
|
lsl.l #2,d2 ;scale up by bit depth
|
|
add.l d2,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
bfchg (a4){d4:4} ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d0,d2 ;start with zero
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d2
|
|
lsl.l #2,d2 ;scale up by bit depth
|
|
sub.l d2,d4 ;bump a pixel
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepXor8
|
|
lsr.l #3,d4 ;convert bit offset to byte offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
eor.b d1,(a4,d4) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
eor.b d1,(a4,d4) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepXor16
|
|
lsr.l #4,d4 ;convert bit offset to word offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
eor.w d1,(a4,d4*2) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
eor.w d1,(a4,d4*2) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
steepXor32
|
|
lsr.l #5,d4 ;convert bit offset to long offset
|
|
tst.l d7 ;are we backwards
|
|
bmi.s @toLeft
|
|
|
|
@toRight
|
|
eor.l d1,(a4,d4*4) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
addx.l d0,d4 ;bump a pixel
|
|
dbra d6,@toRight
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft
|
|
eor.l d1,(a4,d4*4) ;toggle one pixel
|
|
add.l a3,a4 ;bump to next row
|
|
add.w d7,d5 ;add fractions
|
|
subx.l d0,d4
|
|
dbra d6,@toLeft
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; DRAW ONE PIXEL WIDE Shallow SLANTED LINES
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = actual slab width
|
|
; a1 = d1 = fgColor/bkColor/(-1 for xor)
|
|
; a2 = |dx/dy| d2 = zero
|
|
; a3 = rowBytes d3 = dstShift
|
|
; a4 = dstPtr d4 = bit offset to pixel left
|
|
; a5 = bits to right d5 = integer slab width
|
|
; a6 = locals d6 = scan count (zero based)
|
|
; a7^= d7 = (high)slope,(low)rightEdge
|
|
;-------------------------------------------------------
|
|
goBack
|
|
; move.w minRect+left(a6),d2 ;restore minRect left
|
|
; move.w minRect+right(a6),d4 ;restore minRect right
|
|
bra CalcBufLeft
|
|
|
|
Shallow
|
|
cmp.w lineRect+top(a6),d1 ;was top clipped?
|
|
bgt.s goBack ;yes, take slow case
|
|
cmp.w lineRect+bottom(a6),d3 ;is bottom clipped?
|
|
blt.s goBack ;yes, take slow case
|
|
SUB D1,D3 ;CALC HEIGHT
|
|
MOVEQ #-2,D6 ;
|
|
ADD D3,D6 ;D6 IS HEIGHT-2
|
|
|
|
move.w d2,d0 ;assume left to right
|
|
tst.l d7 ;dx/dy < 0?
|
|
bpl.s @useLeft ;yes, left to right
|
|
move.w d4,d0 ;no, MinRect.right instead
|
|
@useLeft
|
|
SUB DSTPIX+BOUNDS+LEFT(A6),D0 ;CONVERT MinRect.Left TO GLOBAL
|
|
EXT.L D0 ;MAKE IT LONG
|
|
MOVE DSTSHIFT(A6),D3 ;GET DSTSHIFT
|
|
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
|
MOVE.L D0,D1 ;MAKE A COPY
|
|
LSR.L #5,D0 ;CONVERT BITS TO LONGS
|
|
LSL.L #2,D0 ;Convert back to bytes
|
|
ADD.L D0,A4 ;ADD TO RUNNING TOTAL
|
|
AND #$1F,D1 ;TREAT LEFT MOD 32
|
|
|
|
move.l d7,d5 ;copy slope
|
|
bpl.s @notNeg
|
|
neg.l d5 ;get |slope|
|
|
@notNeg move.l d5,a2 ;copy |slope| for later
|
|
cmp.l #$10800,d5 ;is it nearly 45¡?
|
|
blt.s goBack ;yes, can't be as inaccurate as before
|
|
clr.w d5
|
|
swap d5 ;|slope|.int
|
|
lsl.l d3,d5 ;|slope|.int * pixelSize
|
|
cmp.w #32,d5 ;does max slab fit in a long?
|
|
bge.s goBack ;no, punt for now
|
|
|
|
SUB D2,D4 ;get pixel width
|
|
move.w rightEdge+2(a6),d7 ;get rightEdge.frac
|
|
LSL.L D3,D4 ;CONVERT PIXELS TO BITS
|
|
ADD D1,D4 ;D4 is bit offset to rightedge of last slab
|
|
MOVE.W D4,A5 ;save for later
|
|
MOVE.L D1,D4 ;save initial bit offset
|
|
tst.l d7 ;right to left?
|
|
bpl.s @widthOK
|
|
SUB D1,A5 ;undo the damage
|
|
SUB D1,A5 ;do it right
|
|
|
|
@widthOK
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
_rSwapMMUMode ;(can trash a0/a1/a2, d0/d1/d2)
|
|
move.b d0,MMUsave(a6) ;save previous state for later
|
|
|
|
moveq #0,d0 ;compute first (clipped) slab width in d0
|
|
move.w minrect+right(a6),d0 ;get right clip
|
|
sub.w leftEdge(a6),d0 ;get initial slab width
|
|
tst.l d7 ;right to left?
|
|
bmi.s @yesNeg ;yes, all ok
|
|
move.w rightEdge(a6),d0 ;get rightEdge.int
|
|
sub.w minrect+left(a6),d0 ;get initial slab width
|
|
@yesNeg LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
|
moveq #0,d2 ;get a useful constant
|
|
MOVE.L FCOLOR(A6),D1 ;ASSUME FOREGROUND COLOR
|
|
LEA ShallowBlitTab,a0 ;point to mode table
|
|
CMP #1,LOCMODE(A6) ;WHICH MODIFIED MODE ?
|
|
BLT.S @useFG ;BR IF FOREGROUND
|
|
BEQ.S @doXor ;BR IF XOR
|
|
;ELSE BACKGROUND
|
|
MOVE.L BCOLOR(A6),D1 ;GET THE COLOR
|
|
@useFG ADD.L (A0,D3*4),A0 ;GET MODECASE
|
|
JMP (A0) ;GO THERE
|
|
|
|
@doXor ;Use alternate table
|
|
ADD.L ShallowBlitXorTab-ShallowBlitTab(A0,D3*4),A0 ;Adjusted modecase
|
|
JMP (A0) ;GO THERE
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowCopy1 ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.w d5,d0 ;prime slab width with slope.int
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add one
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.w d5,d0 ;prime slab width with slope.int
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add one
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowCopy2 ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
add.l d0,d0 ;double it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
add.l d0,d0 ;double it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowCopyN ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
lsl.l d3,d0 ;quad it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
lsl.l d3,d0 ;quad it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfins d1,(a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowXor1 ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.w d5,d0 ;prime slab width with slope.int
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add one
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.w d5,d0 ;prime slab width with slope.int
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add one
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowXor2 ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
add.l d0,d0 ;double it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
add.l d0,d0 ;double it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
|
|
shallowXorN ;start with first clipped slab
|
|
tst.l d7 ;slope negative?
|
|
bmi.s @toLeft ;draw from right to left
|
|
|
|
@midR bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
add.l d0,d4 ;bump offset by slab width
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
lsl.l d3,d0 ;quad it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midR
|
|
sub d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
ALIGN Alignment
|
|
|
|
@toLeft ;start with first clipped slab
|
|
@midL sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit a slab
|
|
add.l a3,a4 ;bump to next row
|
|
move.l d2,d0 ;zero working register
|
|
add.w a2,d7 ;add fractions
|
|
addx.l d2,d0 ;conditionally add 1
|
|
lsl.l d3,d0 ;quad it
|
|
add.l d5,d0 ;add in base slab width (slope.int)
|
|
dbra d6,@midL
|
|
add d4,a5 ;compute width of last slab
|
|
move a5,d0
|
|
sub.l d0,d4 ;bump offset by slab width
|
|
bfchg (a4){d4:d0} ;blit last slab
|
|
bra done
|
|
|
|
;-------------------------------------------------------
|
|
|
|
ENDPROC
|
|
|
|
|