mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-24 17:32:59 +00:00
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
|
|
|
|
|
|
|
|
|