mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-14 21:29:53 +00:00
4325cdcc78
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.
888 lines
25 KiB
Plaintext
888 lines
25 KiB
Plaintext
;
|
|
; File: Util.m.a
|
|
;
|
|
; Contains: xxx put contents here (or delete the whole line) xxx
|
|
;
|
|
; Written by: xxx put name of writer here (or delete the whole line) xxx
|
|
;
|
|
; Copyright: © 1988-1990 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <2> 4/5/90 KON Add visRgnChanged call. For color machines it's in QDUtil.a.
|
|
; <1.1> 11/11/88 CCH Fixed Header.
|
|
; <1.0> 11/9/88 CCH Adding to EASE.
|
|
; <1.3> 10/12/88 CCH Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; <1.2> 5/18/88 BBM Really fixed include statement
|
|
; <1.1> 5/18/88 MSH Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; <1.0> 2/11/88 BBM Adding file for the first time into EASEÉ
|
|
;
|
|
; To Do:
|
|
;
|
|
|
|
;EASE$$$ READ ONLY COPY of file ÒUTIL.m.aÓ
|
|
; 1.1 CCH 11/11/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; OLD REVISIONS BELOW
|
|
; 1.3 CCH 10/12/1988 Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; 1.2 BBM 5/18/88 Really fixed include statement
|
|
; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
; END EASE MODIFICATION HISTORY
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
INCLUDE 'GRAFTYPES.m.a'
|
|
;-------------------------------------------------------------
|
|
;
|
|
; --> UTIL.TEXT
|
|
;
|
|
; SMALL UTILITY ROUTINES USED BY QuickDraw.
|
|
;
|
|
|
|
VisRgnChanged PROC EXPORT ;<5Apr90 KON>
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Procedure VisRgnChanged(thePort: GrafPort);
|
|
;
|
|
; This call will be needed for video windows so the mask plane
|
|
; for touchstone can be updated. Non-video QD simply returns.
|
|
;
|
|
move.l (a7)+,(a7)
|
|
rts
|
|
ENDPROC
|
|
|
|
|
|
BitNot FUNC EXPORT
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitNot(long: LongInt): LongInt;
|
|
;
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
NOT.L (SP) ;INVERT LONG
|
|
MOVE.L (SP)+,(SP) ;STORE INTO RESULT
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
BitAnd FUNC EXPORT
|
|
EXPORT BitXor,BitOr,BitShift
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitAnd(long1,long2: LongInt): LongInt;
|
|
;
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
AND.L (SP)+,D0 ;AND IT WITH THE OTHER
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitXor(long1,long2: LongInt): LongInt;
|
|
;
|
|
BitXor MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
MOVE.L (SP)+,D1 ;GET THE SECOND
|
|
EOR.L D1,D0 ;XOR BOTH
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitOr(long1,long2: LongInt): LongInt;
|
|
;
|
|
BitOr MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
OR.L (SP)+,D0 ;OR IT WITH THE OTHER
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitShift(long: LongInt; count: INTEGER): LongInt;
|
|
;
|
|
; positive count --> shift left.
|
|
; negative count --> shift right.
|
|
;
|
|
BitShift MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE (SP)+,D1 ;GET COUNT
|
|
BPL.S SHLEFT ;SHIFT LEFT IF POSITIVE
|
|
NEG D1 ;MAKE COUNT POSITIVE
|
|
MOVE.L (SP)+,D0 ;GET LONG
|
|
LSR.L D1,D0 ;SHIFT IT RIGHT
|
|
BRA.S DONE ;AND STORE RESULT
|
|
SHLEFT MOVE.L (SP)+,D0 ;GET LONG
|
|
LSL.L D1,D0 ;SHIFT IT LEFT
|
|
DONE MOVE.L D0,(SP) ;STORE THE RESULT
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
BitTst FUNC EXPORT
|
|
EXPORT BitSet,BitClr
|
|
;---------------------------------------------------------
|
|
;
|
|
; FUNCTION BitTst(bytePtr: Ptr; bitNum: LongInt): BOOLEAN;
|
|
;
|
|
BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BTST D0,0(A1,D1.L) ;TEST THE BIT
|
|
SNE (SP) ;SET OR CLEAR RESULT
|
|
NEG.B (SP) ;CONVERT -1 TO 1
|
|
JMP (A0) ;RETURN
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; PROCEDURE BitSet(bytePtr: Ptr; bitNum: LongInt);
|
|
;
|
|
BitSet BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BSET D0,0(A1,D1.L) ;SET THE BIT
|
|
JMP (A0)
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; PROCEDURE BitClr(bytePtr: Ptr; bitNum: LongInt);
|
|
;
|
|
BitClr BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BCLR D0,0(A1,D1.L) ;SET THE BIT
|
|
JMP (A0)
|
|
;
|
|
;
|
|
;
|
|
SHARE MOVE.L (A7)+,A1
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D1 ;GET BITNUM
|
|
MOVE D1,D0 ;COPY IT
|
|
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
|
NOT D0 ;REVERSE BIT SENSE
|
|
JMP (A1)
|
|
|
|
|
|
|
|
Random FUNC EXPORT
|
|
;--------------------------------------------------------------
|
|
;
|
|
; FUNCTION Random: INTEGER;
|
|
;
|
|
; returns a signed 16 bit number, and updates unsigned 32 bit randSeed.
|
|
;
|
|
; recursion is randSeed := (randSeed * 16807) MOD 2147483647.
|
|
;
|
|
; See paper by Linus Schrage, A More Portable Fortran Random Number Generator
|
|
; ACM Trans Math Software Vol 5, No. 2, June 1979, Pages 132-138.
|
|
;
|
|
; Clobbers D0-D2, A0
|
|
;
|
|
;
|
|
; GET LO 16 BITS OF SEED AND FORM LO PRODUCT
|
|
; xalo := A * LoWord(seed)
|
|
;
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE #16807,D0 ;GET A = 7^5
|
|
MOVE D0,D2 ;GET A = 7^5
|
|
MULU RANDSEED+2(A0),D0 ;CALC LO PRODUCT = XALO
|
|
;
|
|
; FORM 31 HIGHEST BITS OF LO PRODUCT
|
|
; fhi:=HiWord(seed) * ORD4(a) + HiWord(xalo);
|
|
;
|
|
MOVE.L D0,D1 ;COPY xalo
|
|
CLR.W D1
|
|
SWAP D1 ;GET HiWord(xalo) as a long
|
|
MULU RANDSEED(A0),D2 ;MULT BY HiWord(seed)
|
|
ADD.L D1,D2 ;ADD LEFTLO = FHI
|
|
;
|
|
; GET OVERFLOW PAST 31ST BIT OF FULL PRODUCT
|
|
; k:=fhi DIV 32768;
|
|
;
|
|
MOVE.L D2,D1 ;COPY FHI
|
|
ADD.L D1,D1 ;CALC 2 TIMES FHI
|
|
CLR.W D1
|
|
SWAP D1 ;CALC FHI SHIFTED RIGHT 15 FOR K
|
|
;
|
|
; ASSEMBLE ALL THE PARTS AND PRE-SUBTRACT P
|
|
; seed:=((BitAnd(XALO,$0000FFFF) - P) + BitAnd(fhi,$00007FFF) * b16) + K;
|
|
;
|
|
AND.L #$0000FFFF,D0 ;GET LO WORD XALO
|
|
SUB.L #$7FFFFFFF,D0 ;SUBTRACT P = 2^31-1
|
|
AND.L #$00007FFF,D2 ;BitAnd(fhi,$00007FFF)
|
|
SWAP D2 ;TIMES 64K
|
|
ADD.L D1,D2 ;PLUS K
|
|
ADD.L D2,D0 ;CALC TOTAL
|
|
;
|
|
; IF seed < 0 THEN seed:=seed+p;
|
|
;
|
|
BPL.S UPDATE
|
|
ADD.L #$7FFFFFFF,D0
|
|
UPDATE MOVE.L D0,RANDSEED(A0) ;UPDATE SEED
|
|
CMP.W #$8000,D0 ;IS NUMBER -32768 ?
|
|
BNE.S NUMOK ;NO, CONTINUE
|
|
CLR D0 ;YES, RETURN ZERO INSTEAD
|
|
NUMOK MOVE.W D0,4(SP) ;RETURN LO WORD AS RESULT
|
|
RTS
|
|
|
|
|
|
|
|
ForeColor PROC EXPORT
|
|
EXPORT BackColor,PortLong,ColorBit,PortWord
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ForeColor(color: LongInt);
|
|
;
|
|
MOVEQ #FGCOLOR,D0 ;GET OFFSET TO FGCOLOR
|
|
BRA.S PortLong ;INSTALL A LONG
|
|
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE BackColor(color: LongInt);
|
|
;
|
|
BackColor
|
|
MOVEQ #BKCOLOR,D0 ;GET OFFSET TO FGCOLOR
|
|
;
|
|
; FALL THRU INTO PORTLONG
|
|
;
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE PortLong(long: LongInt);
|
|
; INSTALL A LONG INTO CURRENT GRAFPORT. ENTER WITH OFFSET IN D0
|
|
;
|
|
PortLong
|
|
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
|
|
MOVE.L (SP)+,0(A0,D0) ;INSTALL WORD INTO THEPORT
|
|
JMP (A1) ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ColorBit(whichBit: INTEGER);
|
|
;
|
|
ColorBit
|
|
MOVEQ #COLRBIT,D0 ;GET OFFSET TO COLRBIT
|
|
;FALL THRU INTO PORTWORD
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE PortWord(word: INTEGER);
|
|
; INSTALL A WORD INTO CURRENT GRAFPORT. ENTER WITH OFFSET IN D0
|
|
;
|
|
PortWord
|
|
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
|
|
MOVE.W (SP)+,0(A0,D0) ;INSTALL WORD INTO THEPORT
|
|
JMP (A1) ;AND RETURN
|
|
|
|
|
|
|
|
GetMaskTab PROC EXPORT
|
|
EXPORT LeftMask,RightMask,BitMask,MaskTab
|
|
;----------------------------------------------------------
|
|
;
|
|
; ASSEMBLY LANGUAGE CALLABLE PROCEDURES LEFTMASK, RIGHTMASK, AND BITMASK:
|
|
;
|
|
; ENTER WITH COORDINATE IN D0, RETURNS WITH 16 BIT MASK IN D0
|
|
; NO OTHER REGISTERS ALTERED.
|
|
;
|
|
LEA MaskTab,A0 ;POINT TO MASK TABLE
|
|
RTS ;AND RETURN
|
|
|
|
LeftMask
|
|
AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB+32(D0),D0 ;GET LEFTMASK
|
|
RTS
|
|
|
|
RIGHTMASK
|
|
AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB(D0),D0 ;GET RIGHT MASK
|
|
RTS
|
|
|
|
BITMASK AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB+64(D0),D0 ;GET BITMASK
|
|
RTS
|
|
|
|
MASKTAB DC.W $0000,$8000,$C000,$E000 ;TABLE OF 16 RIGHT MASKS
|
|
DC.W $F000,$F800,$FC00,$FE00
|
|
DC.W $FF00,$FF80,$FFC0,$FFE0
|
|
DC.W $FFF0,$FFF8,$FFFC,$FFFE
|
|
|
|
DC.W $FFFF,$7FFF,$3FFF,$1FFF ;TABLE OF 16 LEFT MASKS
|
|
DC.W $0FFF,$07FF,$03FF,$01FF
|
|
DC.W $00FF,$007F,$003F,$001F
|
|
DC.W $000F,$0007,$0003,$0001
|
|
|
|
DC.W $8000,$4000,$2000,$1000 ;TABLE OF 16 BIT MASKS
|
|
DC.W $0800,$0400,$0200,$0100
|
|
DC.W $0080,$0040,$0020,$0010
|
|
DC.W $0008,$0004,$0002,$0001
|
|
|
|
|
|
|
|
|
|
PatExpand PROC EXPORT
|
|
;----------------------------------------------------------
|
|
;
|
|
; EXPAND AN 8 BYTE PATTERN OUT TO 16 LONGS.
|
|
;
|
|
; CALLED ONLY FROM BITBLT,RGNBLT,DRAWLINE,DRAWARC.
|
|
;
|
|
; INPUTS: A0: POINTS TO 8 BYTE PATTERN
|
|
; A1: POINTS TO 16 LONGS OF DESTINATION
|
|
; A5: PASCAL GLOBAL PTR
|
|
; D2: HORIZONTAL GLOBAL-LOCAL OFFSET USED FOR PRE-ROTATE
|
|
; D7: -1 TO INVERT, ELSE 0
|
|
; patStretch AND PATALIGN
|
|
;
|
|
; OUTPUTS: 16 LONGS OF EXPANDED PATTERN
|
|
;
|
|
; CLOBBERS: D0,D1,D2,A0,A1
|
|
;
|
|
PARAMSIZE EQU 0
|
|
TWOPAT EQU -16 ;ROOM FOR TWO COPIES OF PAT
|
|
VARSIZE EQU TWOPAT ;TOTAL BYTES OF LOCAL VARS
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVE.L A4,-(SP) ;SAVE REGS
|
|
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
|
;
|
|
; IF PATALIGN VERT NON-ZERO, COPY PAT TWICE AND REPLACE A0
|
|
;
|
|
MOVEQ #7,D0
|
|
AND PATALIGN(A4),D0 ;GET PATALIGN MOD 8
|
|
BEQ.S VERTOK ;SKIP IF ZERO
|
|
MOVE.L (A0),TWOPAT(A6) ;MAKE TWO COPIES OF PATTERN
|
|
MOVE.L (A0)+,TWOPAT+8(A6)
|
|
MOVE.L (A0),TWOPAT+4(A6)
|
|
MOVE.L (A0),TWOPAT+12(A6)
|
|
LEA TWOPAT(A6),A0
|
|
ADD D0,A0
|
|
VERTOK
|
|
ADD PATALIGN+H(A4),D2 ;ADJUST FOR PATALIGN HORIZ
|
|
MOVEQ #7,D1 ;INIT COUNT OF 8 BYTES
|
|
AND D1,D2 ;TREAT SHIFTCOUNT MOD 8
|
|
MOVE.L THEPORT(A4),A4 ;GET CURRENT GRAFPORT
|
|
MOVE patStretch(A4),D0 ;GET patStretch
|
|
CMP #2,D0 ;IS patStretch = 2 ?
|
|
BEQ.S DOUBLE ;YES, DOUBLE
|
|
CMP #-2,D0 ;IS PAT STRETCH = -2 ?
|
|
BEQ.S THIN ;YES, STRETCH THIN
|
|
;ANY OTHER, USE NORMAL
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; NORMAL PATTERN. SIMPLY REPLICATE THE 8 BY 8 PATTERN.
|
|
;
|
|
NORMAL MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
|
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
|
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
|
MOVE.B D0,(A1)+ ;PUT ONE BYTE
|
|
MOVE.B D0,(A1)+ ;PUT ANOTHER TO MAKE A WORD
|
|
MOVE.W -2(A1),(A1)+ ;STRETCH WORD OUT TO LONG
|
|
MOVE.L -4(A1),32-4(A1) ;DUPLICATE 8 SCANS LATER
|
|
DBRA D1,NORMAL ;LOOP ALL 8 INPUT BYTES
|
|
BRA.S DONE
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; STRETCHED BY TWO: DOUBLE EACH BIT HORIZONTALLY AND VERTICALLY
|
|
;
|
|
DOUBLE CLR D0 ;CLEAR OUT HI BYTE
|
|
DLOOP MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
|
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
|
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
|
MOVE.B D0,-(SP) ;STASH FOR A WHILE
|
|
LSR.B #4,D0 ;GET HI NIBBLE
|
|
MOVE.B STRETCH(D0),(A1)+ ;PUT ONE BYTE
|
|
MOVEQ #$F,D0 ;MASK FOR LO NIBBLE
|
|
AND.B (SP)+,D0 ;GET THE LO NIBBLE
|
|
MOVE.B STRETCH(D0),(A1)+ ;PUT ANOTHER TO MAKE A WORD
|
|
MOVE.W -2(A1),(A1)+ ;STRETCH WORD OUT TO LONG
|
|
MOVE.L -4(A1),(A1)+ ;STRETCH LONG TO TWO LONGS
|
|
DBRA D1,DLOOP ;LOOP ALL 8 INPUT BYTES
|
|
BRA.S DONE
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; STRETCH BY TWO AND THIN OUT THE BITS. ADD EXTRA WHITE DOTS.
|
|
;
|
|
THIN CLR D0 ;CLEAR OUT HI BYTE
|
|
THINLP MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
|
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
|
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
|
MOVE.B D0,-(SP) ;STASH FOR A WHILE
|
|
LSR.B #4,D0 ;GET HI NIBBLE
|
|
MOVE.B THINSTR(D0),(A1)+ ;PUT ONE BYTE
|
|
MOVEQ #$F,D0 ;MASK FOR LO NIBBLE
|
|
AND.B (SP)+,D0 ;GET THE LO NIBBLE
|
|
MOVE.B THINSTR(D0),(A1)+ ;PUT ANOTHER TO MAKE A WORD
|
|
MOVE.W -2(A1),(A1)+ ;STRETCH WORD OUT TO LONG
|
|
CLR.L (A1)+ ;STRETCH LONG TO TWO LONGS
|
|
DBRA D1,THINLP ;LOOP ALL 8 INPUT BYTES
|
|
|
|
DONE MOVE.L (SP)+,A4 ;RESTORE REG
|
|
UNLINK PARAMSIZE,'PATEXPAN'
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; BIT DOUBLING TABLE FOR 0..15 INPUT --> BYTE OUTPUT
|
|
;
|
|
STRETCH DC.B $00,$03,$0C,$0F,$30,$33,$3C,$3F
|
|
DC.B $C0,$C3,$CC,$CF,$F0,$F3,$FC,$FF
|
|
;
|
|
; TABLE FOR THIN DOUBLING.
|
|
;
|
|
THINSTR DC.B $00,$01,$04,$05,$10,$11,$14,$15
|
|
DC.B $40,$41,$44,$45,$50,$51,$54,$55
|
|
|
|
|
|
|
|
|
|
ColorMap PROC EXPORT
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ColorMap(mode: INTEGER, pat: Pattern);
|
|
;
|
|
; ADJUST INPUT MODE AND PATTERN TO ACCOMPLISH COLOR SEPARATION.
|
|
; Returns (altered) mode and pat on the stack where they were.
|
|
; PRESERVES ALL REGISTERS.
|
|
;
|
|
MOVEM.L D0-D3/A0,-(SP) ;SAVE REGS
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;GET CURRENT GRAFPORT
|
|
MOVE.L A0,D0 ;IS THEPORT NIL ?
|
|
BEQ.S COLOROK ;YES, LEAVE COLOR ALONE
|
|
BTST #0,D0 ;IS THEPORT ODD ?
|
|
BNE.S COLOROK ;YES, LEAVE COLOR ALONE
|
|
MOVE COLRBIT(A0),D2 ;GET COLOR BIT SELECT
|
|
BMI.S COLOROK ;COLORBIT NEG MEANS NO COLOR
|
|
MOVE 28(SP),D3 ;GET INPUT MODE
|
|
MOVEQ #3,D0 ;MASK FOR BOTTOM 2 BITS
|
|
AND D3,D0 ;GET 2 BITS OF MODE
|
|
BEQ.S COPY ;BR IF COPY MODE
|
|
;
|
|
; THE XOR MODES DEPEND ON NEITHER FOREGROUND OR BACKGROUND COLOR
|
|
;
|
|
CMP #2,D0 ;IS IT SOME KIND OF XOR ?
|
|
BEQ.S COLOROK ;YES, THEY DON'T CHANGE
|
|
BGT.S BICMODE ;BRANCH IF BIC
|
|
;ELSE MUST BE OR
|
|
;
|
|
; THE OR MODES DEPEND ONLY ON THE FOREGROUND COLOR
|
|
;
|
|
ORMODE MOVE.L FGCOLOR(A0),D1 ;GET FOREGROUND COLOR
|
|
SHARE BTST D2,D1 ;TEST FOREGROUND COLOR BIT
|
|
BNE.S COLOROK ;NO CHANGE IF FG TRUE
|
|
EOR #2,D3 ;ELSE INVERT MODE BIT 2
|
|
BRA.S NEWMODE ;UPDATE MODE AND QUIT
|
|
|
|
;
|
|
; THE BIC MODES DEPEND ONLY ON THE BACKGROUND COLOR
|
|
;
|
|
BICMODE MOVE.L BKCOLOR(A0),D1 ;GET BACKGROUND COLOR
|
|
NOT.L D1 ;INVERT IT
|
|
BRA SHARE ;AND SHARE CODE
|
|
|
|
;
|
|
; THE COPY MODES DEPEND ON BOTH FOREGOUND AND BACKGROUND
|
|
;
|
|
COPY MOVE.L FGCOLOR(A0),D0 ;GET FOREGROUND COLOR
|
|
MOVE.L BKCOLOR(A0),D1 ;GET BACKGROUND COLOR
|
|
BTST D2,D0 ;TEST FOREGROUND COLOR BIT
|
|
BEQ.S FORE0 ;BRANCH IF IT'S ZERO
|
|
|
|
FORE1 BTST D2,D1 ;TEST BACKGROUND COLOR BIT
|
|
BEQ.S COLOROK ;NO CHANGE IF BKGND FALSE
|
|
MOVEQ #8,D3 ;ELSE REPLACE MODE = PAT COPY
|
|
USEPAT MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
LEA BLACK(A0),A0 ;POINT TO BLACK PATTERN
|
|
MOVE.L A0,24(SP) ;REPLACE PATTERN WITH BLACK
|
|
BRA.S NEWMODE ;UPDATE MODE AND QUIT
|
|
|
|
FORE0 BTST D2,D1 ;TEST BACKGROUND COLOR BIT
|
|
BNE.S INVMODE ;IF BK TRUE, INVERT MODE
|
|
MOVEQ #12,D3 ;ELSE REPLACE MODE = NOTPAT COPY
|
|
BRA.S USEPAT ;AND PATTERN WITH BLACK
|
|
|
|
INVMODE EOR #4,D3 ;USE INVERSE OF MODE
|
|
NEWMODE MOVE D3,28(SP) ;CHANGE INPUT MODE
|
|
COLOROK MOVEM.L (SP)+,D0-D3/A0 ;RESTORE REGS
|
|
RTS ;AND RETURN
|
|
|
|
|
|
GetPixel FUNC EXPORT
|
|
IMPORT HideCursor,ShowCursor
|
|
;---------------------------------------------------------
|
|
;
|
|
; FUNCTION GetPixel(h,v: INTEGER): BOOLEAN;
|
|
;
|
|
; Returns TRUE if the pixel at (h,v) is set to black.
|
|
; h and v are in local coords of the current grafport.
|
|
;
|
|
; CLOBBERS A0,A1,D0,D1,D2
|
|
;
|
|
JSR HIDECURSOR ;GET RID OF CURSOR
|
|
MOVE.L (SP)+,D2 ;POP RETURN ADDR
|
|
MOVE.L GRAFGLOBALS(A5),A1 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A1),A1 ;GET THEPORT
|
|
MOVE (SP)+,D0 ;GET VERT COORD
|
|
SUB PORTBITS+BOUNDS+TOP(A1),D0 ;CONVERT TO GLOBAL COORDS
|
|
MOVE (SP)+,D1 ;GET HORIZ COORD
|
|
SUB PORTBITS+BOUNDS+LEFT(A1),D1 ;CONVERT TO GLOBAL
|
|
MULU PORTBITS+ROWBYTES(A1),D0 ;CALC VERT * ROWBYTES
|
|
MOVE.L PORTBITS+BASEADDR(A1),A1 ;GET BASEADDR
|
|
ADD.L D0,A1 ;ADD VERTICAL OFFSET
|
|
MOVE D1,D0 ;COPY HORIZ
|
|
NOT D0 ;INVERT FOR BIT INDEX
|
|
LSR #3,D1 ;CONVERT DOTS TO BYTES
|
|
BTST D0,0(A1,D1) ;TEST ONE SCREEN BIT
|
|
SNE (SP) ;SET BOOLEAN RESULT
|
|
NEG.B (SP) ;MAKE $FF --> $01
|
|
MOVE.L D2,-(SP) ;PUSH RETURN ADDR
|
|
JMP SHOWCURSOR ;RESTORE CURSOR AND RETURN
|
|
|
|
|
|
|
|
StuffHex PROC EXPORT
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE STUFFHEX(THINGPTR: WORDPTR; S: STR255);
|
|
;
|
|
; CONVENIENCE ROUTINE TO STUFF HEX INTO ANY VARIABLE.
|
|
; BEWARE, NO RANGE-CHECKING.
|
|
;
|
|
MOVE.L 4(SP),A0 ;A0:=ADDR OF STRING
|
|
MOVE.L 8(SP),A1 ;A1:=THINGPTR
|
|
MOVE.L (SP),8(SP) ;CLEAN OFF STACK
|
|
ADD #8,SP ;POINT TO RETURN ADDR
|
|
MOVE.B (A0)+,D2 ;GET STRING LENGTH
|
|
AND #$00FE,D2 ;TRUNCATE LENGTH TO EVEN
|
|
BEQ.S ENDHEX ;QUIT IF LENGTH = 0
|
|
HEXLOOP BSR.S NEXTHEX ;GET HEX DIGIT AND CONVERT TO BINARY
|
|
MOVE.B D0,D1 ;SAVE MOST SIG DIGIT
|
|
BSR.S NEXTHEX ;GET HEX DIGIT AND CONVERT TO BINARY
|
|
LSL.B #4,D1 ;SHIFT MOST SIG INTO PLACE
|
|
ADD.B D0,D1 ;FILL IN LS NIBBLE
|
|
MOVE.B D1,(A1)+ ;STUFF BYTE INTO THING
|
|
SUB #2,D2 ;2 LESS CHARS TO GO
|
|
BNE.S HEXLOOP ;LOOP FOR STRING LENGTH
|
|
ENDHEX RTS ;RETURN TO PASCAL
|
|
;
|
|
; LOCAL ROUTINE TO GET NEXT HEX DIGIT AND CONVERT ASCII TO BINARY
|
|
;
|
|
NEXTHEX MOVE.B (A0)+,D0 ;GET HEX DIGIT FROM STRING
|
|
CMP.B #$39,D0 ;IS IT GTR THAN '9' ?
|
|
BLE.S SMALL ;NO, DO IT
|
|
ADD.B #9,D0 ;YES, ADD CORRECTION
|
|
SMALL AND.B #$F,D0 ;TREAT MOD 16, EVEN LOWER CASE OK
|
|
RTS
|
|
|
|
|
|
|
|
XorSlab PROC EXPORT
|
|
IMPORT MaskTab
|
|
;-----------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE XorSlab(bufAddr: Ptr; left,right: INTEGER);
|
|
;
|
|
; Enter with:
|
|
;
|
|
; A0: bufAddr
|
|
; D3: left coord
|
|
; D4: right coord
|
|
;
|
|
; Clobbers: A0,D0,D1,D3,D4,D5,D6
|
|
;
|
|
;
|
|
; GET LEFTMASK AND RIGHTMASK
|
|
;
|
|
MOVE.L A0,D1 ;save bufAddr
|
|
LEA MASKTAB,A0 ;point to mask table
|
|
MOVEQ #$F,D0 ;get mask for 4 lo bits
|
|
|
|
MOVE D3,D5 ;COPY LEFT COORD
|
|
AND D0,D5 ;CALC LEFT MOD 16
|
|
ADD D5,D5 ;DOUBLE FOR TABLE INDEX
|
|
MOVE 0(A0,D5),D5 ;GET MASK FROM TABLE
|
|
NOT D5 ;INVERT FOR LEFTMASK
|
|
|
|
MOVE D4,D6 ;COPY RIGHT COORD
|
|
AND D0,D6 ;TREAT RIGHT MOD 16
|
|
ADD D6,D6 ;DOUBLE FOR TABLE INDEX
|
|
MOVE 0(A0,D6),D6 ;GET RIGHTMASK IN D6
|
|
MOVE.L D1,A0 ;RESTORE SAVED bufAddr
|
|
|
|
;
|
|
; CALC LEFTWORD, BUFPTR, WORDCOUNT
|
|
;
|
|
ASR #4,D3 ;CONVERT DOTS TO WORDS
|
|
ADD D3,A0 ;ADD TO bufAddr
|
|
ADD D3,A0 ;TWICE FOR BYTE OFFSET
|
|
ASR #4,D4 ;CALC RIGHT DIV 16
|
|
SUB D3,D4 ;WORDCOUNT:=RIGHTWORD-LEFTWORD
|
|
BGT.S NOTIN1 ;BR IF NOT ALL IN ONE
|
|
;
|
|
; LEFT AND RIGHT ARE ALL IN ONE WORD
|
|
;
|
|
AND D5,D6 ;COMBINE LEFT AND RIGHT MASKS
|
|
EOR D6,(A0) ;XOR RIGHTMASK INTO BUFFER
|
|
RTS ;AND RETURN
|
|
;
|
|
; NOT ALL IN ONE WORD. DO LEFT, MIDDLE IF ANY, THEN RIGHT
|
|
;
|
|
NOTIN1 EOR D5,(A0)+ ;XOR LEFTMASK INTO BUFFER
|
|
BRA.S TEST ;SEE IF ANY FULL WORDS
|
|
INVLONG NOT.L (A0)+ ;INVERT 2 WHOLE WORDS
|
|
TEST SUBQ #2,D4 ;ANY FULL WORDS LEFT ?
|
|
BGT INVLONG ;YES, AT LEAST 2
|
|
BLT.S ENDWORD ;NO, FINISH UP LAST WITH MASK
|
|
NOT (A0)+ ;YES, DO LAST FULL WORD
|
|
ENDWORD EOR D6,(A0) ;XOR RIGHTMASK INTO BUFFER
|
|
RTS
|
|
|
|
|
|
DrawSlab PROC EXPORT
|
|
EXPORT SlabMode,FastSlabMode
|
|
IMPORT MaskTab
|
|
;--------------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE DRAWSLAB
|
|
;
|
|
; INPUTS:
|
|
;
|
|
; D0: scratch A0: MASKTAB
|
|
; D1: left A1: DSTLEFT, clobbered
|
|
; D2: right A2: MASKBUF, clobbered
|
|
; D3: A3: MINRECT
|
|
; D4: A4: MODECASE
|
|
; D5: A5:
|
|
; D6: pattern A6:
|
|
; D7: A7: stack
|
|
;
|
|
; CLOBBERS: D0-D3,A1,A2
|
|
;
|
|
;
|
|
;
|
|
; CLIP LEFT AND RIGHT TO MINRECT:
|
|
;
|
|
CMP LEFT(A3),D1 ;IS LEFT < MINRECT.LEFT ?
|
|
BGE.S LEFTOK ;NO, CONTINUE
|
|
MOVE LEFT(A3),D1 ;YES, LEFT := MINRECT.LEFT
|
|
LEFTOK CMP RIGHT(A3),D2 ;IS RIGHT > MINRECT.RIGHT ?
|
|
BLE.S RIGHTOK ;NO, CONTINUE
|
|
MOVE RIGHT(A3),D2 ;YES, RIGHT := MINRECT.RIGHT
|
|
RIGHTOK CMP D2,D1 ;IS LEFT >= RIGHT ?
|
|
BGE.S DONESLAB ;YES, QUIT
|
|
|
|
;
|
|
; SET UP LEFTMASK AND RIGHTMASK: (A0 already points to MaskTab)
|
|
;
|
|
MOVEQ #$F,D3 ;get mask for 4 lo bits
|
|
MOVE D1,D0 ;COPY LEFT
|
|
AND D3,D1 ;TREAT LEFT MOD 16
|
|
ADD D1,D1 ;DOUBLE FOR TABLE
|
|
MOVE 32(A0,D1),D1 ;GET LEFTMASK IN D1
|
|
AND D2,D3 ;GET RIGHT MOD 16
|
|
ADD D3,D3 ;DOUBLE FOR TABLE
|
|
MOVE 0(A0,D3),D3 ;GET RIGHTMASK IN D3
|
|
|
|
;
|
|
; CALC WORDCOUNT, DSTPTR, MASKPTR, AND TAKE CASE JUMP
|
|
;
|
|
ASR #4,D2 ;CONVERT RIGHT TO WORDS
|
|
ASR #4,D0 ;CONVERT LEFT TO WORDS
|
|
SUB D0,D2 ;CALC WORD COUNT
|
|
ADD D0,D0 ;DOUBLE FOR BYTES
|
|
ADD D0,A1 ;OFFSET DSTPTR
|
|
ADD D0,A2 ;OFFSET MASKPTR
|
|
TST D2 ;SET Z-FLAG BASED ON WORDCOUNT
|
|
JMP (A4) ;TAKE MODECASE TO DRAW SLAB
|
|
DONESLAB RTS
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; INTERFACE TO EACH SCAN LINE ROUTINE:
|
|
;
|
|
; ENTER WITH Z-FLAG SET IF ALL IN ONE WORD
|
|
;
|
|
; INPUTS: A1: DSTPTR
|
|
; A2: MASKPTR
|
|
; D1: LEFTMASK
|
|
; D2: WORDCNT
|
|
; D3: RIGHTMASK
|
|
; D6: PATTERN
|
|
;
|
|
; CLOBBERS: D0,D1,D2,A1,A2
|
|
;
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 8 OR 12: PATTERN --> DST
|
|
;
|
|
END8 AND D3,D1 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT8 MOVE D6,D0 ;GET PATTERN DATA
|
|
AND (A2)+,D1 ;MERGE MASK AND CLIPRGN MASK
|
|
AND D1,D0 ;MASK PATTERN DATA
|
|
NOT D1 ;MAKE NOTMASK
|
|
AND (A1),D1 ;AND NOTMASK WITH OLD DST
|
|
OR D0,D1 ;FILL HOLE WITH PATTERN
|
|
MOVE D1,(A1)+ ;UPDATE DST
|
|
MOVEQ #-1,D1 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
MASK8 BGT NEXT8 ;LOOP FOR ALL WORDS IN ROW
|
|
BEQ END8 ;DO LAST WORD WITH MASK
|
|
RTS
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 9 OR 13: PATTERN OR DST --> DST
|
|
;
|
|
END9 AND D3,D1 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT9 AND D6,D1 ;GET PATTERN DATA
|
|
AND (A2)+,D1 ;MERGE MASK AND CLIPRGN MASK
|
|
OR D1,(A1)+ ;OR RESULT INTO DST
|
|
MOVEQ #-1,D1 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
MASK9 BGT NEXT9 ;LOOP FOR ALL WORDS IN ROW
|
|
BEQ END9 ;DO LAST WORD WITH MASK
|
|
RTS
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 10 OR 14: PATTERN XOR DST --> DST
|
|
;
|
|
END10 AND D3,D1 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT10 AND D6,D1 ;GET PATTERN DATA
|
|
AND (A2)+,D1 ;MERGE MASK AND CLIPRGN MASK
|
|
EOR D1,(A1)+ ;XOR RESULT INTO DST
|
|
MOVEQ #-1,D1 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
MASK10 BGT NEXT10 ;LOOP FOR ALL WORDS IN ROW
|
|
BEQ END10 ;DO LAST WORD WITH MASK
|
|
RTS
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 11 OR 15: PATTERN BIC DST --> DST
|
|
;
|
|
END11 AND D3,D1 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT11 AND D6,D1 ;GET PATTERN DATA
|
|
AND (A2)+,D1 ;MERGE MASK AND CLIPRGN MASK
|
|
NOT D1 ;INVERT FOR BIC
|
|
AND D1,(A1)+ ;BIC RESULT INTO DST
|
|
MOVEQ #-1,D1 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC WORD COUNT
|
|
MASK11 BGT NEXT11 ;LOOP FOR ALL WORDS IN ROW
|
|
BEQ END11 ;DO LAST WORD WITH MASK
|
|
RTS
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; PROCEDURE SlabMode
|
|
;
|
|
; INPUT: D2: MODE, CLOBBERED
|
|
; OUTPUT: A4: MODECASE
|
|
;
|
|
SlabMode
|
|
AND #$3,D2 ;GET LO 2 BITS OF MODE
|
|
LEA MODETAB,A4 ;POINT TO MODE TABLE
|
|
MOVE.B 0(A4,D2),D2 ;GET OFFSET FROM MODETAB
|
|
SUB D2,A4 ;GET CASE JUMP ADDRESS
|
|
RTS
|
|
|
|
MODETAB DC.B MODETAB-MASK8
|
|
DC.B MODETAB-MASK9
|
|
DC.B MODETAB-MASK10
|
|
DC.B MODETAB-MASK11
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; FAST LOOPS, OPTIMIZED FOR BLACK PATTERN AND RECTANGLE CLIPPED
|
|
;
|
|
; FAST BLACK SLAB:
|
|
;
|
|
FAST8 BEQ.S MERGE8 ;BR IF ALL IN ONE WORD
|
|
OR D1,(A1)+ ;OR LEFTMASK INTO DST
|
|
SUB #2,D2 ;ADJUST WORDCOUNT FOR DBRA
|
|
BLT.S LAST8 ;BR IF NO UNMASKED WORDS
|
|
MOVEQ #-1,D1 ;GET SOME BLACK
|
|
LOOP8 MOVE D1,(A1)+ ;WRITE A WORD OF BLACK
|
|
DBRA D2,LOOP8 ;LOOP ALL UNMASKED WORDS
|
|
MERGE8 AND D1,D3 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST8 OR D3,(A1)+ ;OR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
;
|
|
; FAST XOR SLAB:
|
|
;
|
|
FAST10 BEQ.S MERGE10 ;BR IF ALL IN ONE WORD
|
|
EOR D1,(A1)+ ;XOR LEFTMASK INTO DST
|
|
SUB #2,D2 ;ADJUST WORDCOUNT FOR DBRA
|
|
BLT.S LAST10 ;BR IF NO UNMASKED WORDS
|
|
LOOP10 NOT (A1)+ ;INVERT A WORD OF DST
|
|
DBRA D2,LOOP10 ;LOOP ALL UNMASKED WORDS
|
|
BRA.S LAST10 ;THEN FINISH UP LAST WITH MASK
|
|
MERGE10 AND D1,D3 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST10 EOR D3,(A1)+ ;XOR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
;
|
|
; FAST WHITE SLAB:
|
|
;
|
|
FAST11 BEQ.S MERGE11 ;BR IF ALL IN ONE WORD
|
|
NOT D1 ;FORM NOT LEFTMASK
|
|
AND D1,(A1)+ ;AND NOT LEFTMASK INTO DST
|
|
SUB #2,D2 ;ADJUST WORDCOUNT FOR DBRA
|
|
BLT.S LAST11 ;BR IF NO UNMASKED WORDS
|
|
LOOP11 CLR (A1)+ ;CLEAR A WORD OF DST
|
|
DBRA D2,LOOP11 ;LOOP ALL UNMASKED WORDS
|
|
BRA.S LAST11 ;THEN FINISH UP LAST WITH MASK
|
|
MERGE11 AND D1,D3 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST11 NOT D3 ;FORM NOT RIGHTMASK
|
|
AND D3,(A1)+ ;AND NOT RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE FastSlabMode, Call when rect clipped and pattern black.
|
|
;
|
|
; INPUT: D2: MODE, CLOBBERED mode 0=black, 1=xor, 2=white
|
|
; OUTPUT: A4: MODECASE
|
|
;
|
|
FastSlabMode
|
|
AND #$3,D2 ;GET LO 2 BITS OF MODE
|
|
LEA FASTTAB,A4 ;POINT TO MODE TABLE
|
|
MOVE.B 0(A4,D2),D2 ;GET OFFSET FROM FASTTAB
|
|
SUB D2,A4 ;GET CASE JUMP ADDRESS
|
|
RTS
|
|
|
|
FASTTAB DC.B FASTTAB-FAST8 ;BLACK
|
|
DC.B FASTTAB-FAST10 ;XOR
|
|
DC.B FASTTAB-FAST11 ;WHITE
|
|
DC.B 0 ; even pad
|
|
|
|
END
|
|
|
|
|
|
|
|
|