This repository has been archived by the owner on Nov 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSeekRgn.a
192 lines (163 loc) · 7.72 KB
/
SeekRgn.a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
.INCLUDE GRAFTYPES.TEXT
;------------------------------------------------------------------
;
; --> SEEKRGN.TEXT
;
; Routines to play back a region into a scanline buffer.
;
;
.PROC INITRGN,0
;------------------------------------------------------
;
; INPUTS: A0: RGNPTR
; A1: STATE RECORD
; D0: MINH
; D1: MAXH
; D2: BUFLEFT
;
; OUTPUTS: ALL FIELDS OF STATE RECORD,
; SCANBUF ALLOCATED ON STACK
;
; CLOBBERS: D0,D1,A0
;
MOVE D0,MINH(A1) ;INSTALL MINH
MOVE D1,MAXH(A1) ;INSTALL MAXH
MOVE D2,LEFTH(A1) ;INSTALL LEFTH
MOVE.L A0,RGNPTR(A1) ;INSTALL RGNPTR
MOVE #-32767,THISV(A1) ;THISV := -32767
MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := RGN BBOX TOP
LEA RGNDATA(A0),A0 ;POINT TO FIRST DATA
MOVE.L A0,DATAPTR(A1) ;INIT DATAPTR
MOVE.L (SP)+,A0 ;POP RETURN ADDR
SUB D2,D1 ;CALC BUFFER WIDTH IN DOTS
LSR #5,D1 ;DIV BY 32 FOR #LONGS-1
MOVE D1,SCANSIZE(A1) ;SAVE SCANSIZE FOR LATER
CLRLOOP CLR.L -(SP) ;ALLOCATE AND CLEAR BUFFER
DBRA D1,CLRLOOP
MOVE.L SP,SCANBUF(A1) ;REMEMBER BUFFER START
JMP (A0) ;RETURN
.PROC SEEKRGN,0
.REF MaskTab
;------------------------------------------------------------------
;
; SeekRgn(rgnState,vert);
;
; ROUTINE TO PLAY BACK A REGION FORWARD OR BACKWARD UNTIL ITS SCAN
; BUFFER CONTAINS THE BITMAP FOR THE GIVEN VERTICAL COORDINATE.
;
; INPUTS: A1 POINTS TO A REGION STATE RECORD
; DO CONTAINS THE DESIRED VERTICAL COORD
;
; OUTPUTS: UPDATES THISV, NEXTV, DATAPTR, AND SCANBUF^ OF STATE RECORD
; D1-->1 IF CHANGE, 0 IF NO CHANGE. (Z-FLAG SET IF NO CHANGE)
;
; CLOBBERS: A0,D1.
;
;----------------------------------------------------
;
; RETURN QUICKLY IF SCANBUF IS ALREADY CURRENT.
;
CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ?
BGE.S DOWN ;YES, BUMP DOWNWARD
CMP THISV(A1),D0 ;IS DESIRED VERT < CURRENT VERT ?
BLT.S UP ;YES, BUMP UPWARD
CLR D1 ;ELSE REPORT NO CHANGES
RTS ;AND RETURN
;-----------------------------------------------------
;
; TO MOVE UPWARDS, JUST RESET TO START AND MOVE DOWN.
;
UP MOVE.L SCANBUF(A1),A0 ;POINT TO SCANBUF
MOVE SCANSIZE(A1),D1 ;GET BUFFER SIZE
CLRLP CLR.L (A0)+ ;CLEAR A LONG
DBRA D1,CLRLP ;LOOP ENTIRE SCANBUF
MOVE.L RGNPTR(A1),A0 ;GET RGNPTR
MOVE RGNBBOX+TOP(A0),NEXTV(A1) ;NEXTV := TOP VERT
MOVE #-32767,THISV(A1) ;RESET THISV TO -32767
LEA RGNDATA(A0),A0 ;POINT TO START OF REGION DATA
MOVE.L A0,DATAPTR(A1) ;RESET DATAPTR
CMP NEXTV(A1),D0 ;IS DESIRED VERT >= NEXTV ?
BLT DONE ;NO, QUIT
;------------------------------------------------------
;
; WHILE DESIRED VERT >= NEXTV DO BUMP DOWN.
;
DOWN MOVEM.L D0-D6/A2-A3,-(SP) ;SAVE REGS
MOVE D0,D2 ;SAVE VERT
MOVE.L DATAPTR(A1),A2 ;POINT TO VERT COORD
DOWN1 MOVE (A2)+,THISV(A1) ;UPDATE CURRENT VERT
;-------------------------------------------------
;
; GET LEFT AND RIGHT HORIZ COORDS
; AND TRIM AGAINST MINH AND MAXH
;
NEXTHOR MOVE (A2)+,D3 ;GET LEFT COORD
CMP #32767,D3 ;IS IT A TERMINATOR ?
BEQ.S DONE1 ;YES, QUIT
MOVE (A2)+,D4 ;GET RIGHT COORD
CMP MINH(A1),D4 ;IS RIGHT <= MINH ?
BLE NEXTHOR ;YES, IGNORE ON LEFT
CMP MAXH(A1),D3 ;IS LEFT >= MAXH ?
BGE NEXTHOR ;YES, IGNORE ON RIGHT
CMP MINH(A1),D3 ;IS LEFT < MINH ?
BGE.S LOK ;NO, CONTINUE
MOVE MINH(A1),D3 ;YES, TRIM LEFT
LOK CMP MAXH(A1),D4 ;IS RIGHT > MAXH ?
BLE.S ROK ;NO, CONTINUE
MOVE MAXH(A1),D4 ;YES, TRIM RIGHT
ROK SUB LEFTH(A1),D3 ;MAKE COORDS REL TO BUFFER
SUB LEFTH(A1),D4
;------------------------------------------
;
; GET LEFTMASK AND RIGHTMASK
;
LEA MASKTAB,A0 ;POINT TO MASK TABLE
MOVEQ #$F,D0 ;GET MASK FOR LO 4 BITS
MOVE D3,D5 ;COPY LEFT COORD
AND D0,D5 ;CALC LEFT MOD 16
ADD D5,D5 ;DOUBLE FOR INDEX
MOVE 0(A0,D5),D5 ;GET MASK FROM TABLE
NOT D5 ;INVERT FOR LEFTMASK
MOVE D4,D6 ;COPY RIGHT COORD
AND D0,D6 ;CALC RIGHT MOD 16
ADD D6,D6 ;DOUBLE FOR INDEX
MOVE 0(A0,D6),D6 ;GET RIGHTMASK IN D6
;------------------------------------------
;
; CALC LEFTWORD, BUFPTR, WORDCOUNT
;
LSR #4,D3 ;CONVERT DOTS TO WORDS
MOVE.L SCANBUF(A1),A3 ;COPY BUFSTART
ADD D3,A3
ADD D3,A3 ;INIT BUFPTR TO LEFTWORD
LSR #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,(A3) ;XOR COMBINATION INTO BUFFER
BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN
;------------------------------------------
;
; NOT ALL IN ONE WORD. DO LEFT, MIDDLE IF ANY, THEN RIGHT
;
NOTIN1 EOR D5,(A3)+ ;XOR LEFTMASK INTO BUFFER
BRA.S TEST ;SEE IF ANY FULL WORDS
INVLONG NOT.L (A3)+ ;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 (A3)+ ;YES, DO LAST FULL WORD
ENDWORD EOR D6,(A3) ;XOR RIGHTMASK INTO BUFFER
BRA NEXTHOR ;GO FOR MORE DH'S THIS SCAN
DONE1 MOVE.L A2,DATAPTR(A1) ;UPDATE DATAPTR
MOVE (A2),NEXTV(A1) ;UPDATE NEXT VERT
CMP NEXTV(A1),D2 ;IS DESIRED VERT >= NEXTV ?
BGE DOWN1 ;YES, BUMP DOWN SOME MORE
MOVEM.L (SP)+,D0-D6/A2-A3 ;RESTORE REGS
DONE MOVEQ #1,D1 ;REPORT SCANLINE CHANGED
RTS ;AND RETURN
.END