/[projet1]/public/oric/routines/rasterization/linebench/clip.s
Defence Force logotype

Contents of /public/oric/routines/rasterization/linebench/clip.s

Parent Directory Parent Directory | Revision Log Revision Log


Revision 283 - (show annotations)
Sun Feb 14 19:45:17 2010 UTC (9 years, 10 months ago) by thrust26
File size: 9154 byte(s)
bugfix
451, 459, 609, 418
1 ; History of linebench timings...
2 ; without, trivial, worst case, 7331 clipping
3 ; 451, 466, 636, - (initial version)
4 ; 451, 459, 624, 424
5 ; 451; 459, 614, 422
6 ; 451; 459, 609, 418
7
8 #include "params.h"
9
10 .zero
11
12 ; 5 bytes for point 0
13 _LargeX0 .dsb 2
14 _LargeY0 .dsb 2
15 _ClipCode0 .dsb 1
16 ; 5 bytes for point 1
17 _LargeX1 .dsb 2
18 _LargeY1 .dsb 2
19 _ClipCode1 .dsb 1
20
21 #ifdef USE_ACCURATE_CLIPPING
22 .dsb 1
23 #endif
24 _ClipX0 .dsb 2
25 #ifdef USE_ACCURATE_CLIPPING
26 .dsb 1
27 #endif
28 _ClipY0 .dsb 2
29 #ifdef USE_ACCURATE_CLIPPING
30 .dsb 1
31 #endif
32 _ClipX1 .dsb 2
33 #ifdef USE_ACCURATE_CLIPPING
34 .dsb 1
35 #endif
36 _ClipY1 .dsb 2
37 #ifdef USE_ACCURATE_CLIPPING
38 .dsb 1
39 #endif
40 _ClipXc .dsb 2
41 #ifdef USE_ACCURATE_CLIPPING
42 .dsb 1
43 #endif
44 _ClipYc .dsb 2
45
46 #define OFS_PT0 0
47 #define OFS_PT1 (_LargeX1-_LargeX0)
48
49 .text
50
51 _Break
52 jmp _Break
53 rts
54
55
56 ;
57 ; In this code, we assume that the CLIP_ values are fitting
58 ; the resolution of an Oric screen, so they will never be out
59 ; of a 240x200 screen resolution, fit in an unsigned byte.
60 ;
61 _ClipFindRegion
62 .(
63 ; yHi >= $01 -> clip_bottom
64 ; yHi == $00 -> check yLo
65 ; yHi <= $ff -> clip_top
66
67 ; top/bottom test
68 ldy _LargeY0+1,x ;
69 bmi clip_top ; if Y-Hi <= -1, clip top
70 bne clip_bottom ; else, if Y-Hi != 0, clip bottom
71
72 ; initialize with 'not clipped'
73 lda #0
74
75 ldy _LargeY0+0,x
76 #if CLIP_TOP <> 0
77 cpy #CLIP_TOP ; = 5
78 bcc clip_top
79 #endif
80 cpy #(CLIP_BOTTOM+1); = 194
81 bcc end_top_bottom
82 clip_bottom
83 lda #1 ; means (y > CLIP_BOTTOM)
84 bne end_top_bottom
85
86 clip_top
87 lda #2 ; means (y < CLIP_TOP)
88 end_top_bottom
89
90 ; xHi >= $01 -> clip_right
91 ; xHi == $00 -> check xLo
92 ; xHi <= $ff -> clip_left
93
94 ; left/right test
95 ldy _LargeX0+1,x
96 bmi clip_left ; if X-Hi <=- 1, clip left
97 bne clip_right ; else, if X-Hi != 0, clip bottom
98
99 ldy _LargeX0+0,x
100 #if CLIP_LEFT <> 0
101 cpy #CLIP_LEFT
102 bcc clip_left
103 #endif
104 cpy #(CLIP_RIGHT+1)
105 bcc end_left_right
106 clip_right
107 ora #4 ; means (x > CLIP_RIGHT)
108 bne end_left_right ; 3
109
110 clip_left
111 ora #8 ; means (x < CLIP_LEFT)
112 end_left_right
113 sta _ClipCode0,x
114 rts
115 .)
116
117
118 _ClipComputeMidPoint
119 .(
120 ; xc=(x0+x1)>>1;
121 clc
122 #ifdef USE_ACCURATE_CLIPPING
123 lda _ClipX0-1
124 adc _ClipX1-1
125 sta _ClipXc-1
126 #endif
127 lda _ClipX0+0
128 adc _ClipX1+0
129 sta _ClipXc+0
130
131 lda _ClipX0+1
132 adc _ClipX1+1
133 ; divide by 2:
134 cmp #$80
135 ror
136 sta _ClipXc+1
137 ror _ClipXc+0
138 #ifdef USE_ACCURATE_CLIPPING
139 ror _ClipXc-1
140 #endif
141
142 ; yc=(y0+y1)>>1;
143 clc
144 #ifdef USE_ACCURATE_CLIPPING
145 lda _ClipY0-1
146 adc _ClipY1-1
147 sta _ClipYc-1
148 #endif
149 lda _ClipY0+0
150 adc _ClipY1+0
151 sta _ClipYc+0
152
153 lda _ClipY0+1
154 adc _ClipY1+1
155 ; divide by 2:
156 cmp #$80
157 ror
158 sta _ClipYc+1
159 ror _ClipYc+0
160 #ifdef USE_ACCURATE_CLIPPING
161 ror _ClipYc-1
162 #endif
163 rts
164 .)
165
166
167 _ClipSetNormalStartPoints
168 .(
169 ; x0=LargeX0;
170 ; y0=LargeY0;
171 lda _LargeX0+0
172 sta _ClipX0+0
173 lda _LargeX0+1
174 sta _ClipX0+1
175
176 lda _LargeY0+0
177 sta _ClipY0+0
178 lda _LargeY0+1
179 sta _ClipY0+1
180
181 ; x1=LargeX1;
182 ; y1=LargeY1;
183 lda _LargeX1+0
184 sta _ClipX1+0
185 lda _LargeX1+1
186 sta _ClipX1+1
187
188 lda _LargeY1+0
189 sta _ClipY1+0
190 lda _LargeY1+1
191 sta _ClipY1+1
192
193 rts
194 .)
195
196 _ClipSetInvertedStartPoints
197 .(
198 ; x0=LargeX1;
199 ; y0=LargeY1;
200 lda _LargeX1+0
201 sta _ClipX0+0
202 lda _LargeX1+1
203 sta _ClipX0+1
204
205 lda _LargeY1+0
206 sta _ClipY0+0
207 lda _LargeY1+1
208 sta _ClipY0+1
209
210 ; x1=LargeX0;
211 ; y1=LargeY0;
212 lda _LargeX0+0
213 sta _ClipX1+0
214 lda _LargeX0+1
215 sta _ClipX1+1
216
217 lda _LargeY0+0
218 sta _ClipY1+0
219 lda _LargeY0+1
220 sta _ClipY1+1
221
222 rts
223 .)
224
225
226 _ClipMoveP1
227 .(
228 ; x1=xc;
229 lda _ClipXc+0
230 sta _ClipX1+0
231 lda _ClipXc+1
232 sta _ClipX1+1
233 #ifdef USE_ACCURATE_CLIPPING
234 lda _ClipXc-1
235 sta _ClipX1-1
236 #endif
237
238 ; y1=yc;
239 lda _ClipYc+0
240 sta _ClipY1+0
241 lda _ClipYc+1
242 sta _ClipY1+1
243 #ifdef USE_ACCURATE_CLIPPING
244 lda _ClipYc-1
245 sta _ClipY1-1
246 #endif
247 rts
248 ; total: 42
249 .)
250
251 _ClipMoveP0
252 .(
253 ; x0=xc;
254 lda _ClipXc+0
255 sta _ClipX0+0
256 lda _ClipXc+1
257 sta _ClipX0+1
258 #ifdef USE_ACCURATE_CLIPPING
259 lda _ClipXc-1
260 sta _ClipX0-1
261 #endif
262
263 ; y0=yc;
264 lda _ClipYc+0
265 sta _ClipY0+0
266 lda _ClipYc+1
267 sta _ClipY0+1
268 #ifdef USE_ACCURATE_CLIPPING
269 lda _ClipYc-1
270 sta _ClipY0-1
271 #endif
272 ; total: 42
273 rts
274 .)
275
276
277 _ClipDichoTopBottom
278 .(
279 .(
280 ; if (LargeY0==CLIP_TOP/BOTTOM)
281 cpy _LargeY0+0
282 bne skip
283 lda _LargeY0+1
284 bne skip
285 rts
286 skip
287 .)
288
289 .(
290 ; if (LargeY1==CLIP_TOP/BOTTOM)
291 cpy _LargeY1+0
292 bne skip
293 lda _LargeY1+1
294 bne skip
295 rts
296 skip
297 .)
298
299 sec
300 lda _LargeY0+0
301 sbc _LargeY1+0
302 lda _LargeY0+1
303 sbc _LargeY1+1
304 bmi label4
305
306 label3
307 ; (LargeY0>=LargeY1)
308 jsr _ClipSetInvertedStartPoints
309 jmp end_swap
310
311 label4
312 ; (LargeY0<LargeY1)
313 jsr _ClipSetNormalStartPoints
314
315 end_swap
316
317 #ifdef USE_ACCURATE_CLIPPING
318 lda #0
319 sta _ClipX0-1
320 sta _ClipY0-1
321 sta _ClipX1-1
322 sta _ClipY1-1
323 #endif
324
325 loop
326 jsr _ClipComputeMidPoint ; (ClipXY0+ClipXY1)/2
327
328 ; if (yc==CLIP_TOP/BOTTOM)
329 sec
330 tya
331 sbc _ClipYc+0
332 beq done_lo
333 lda #0
334 sbc _ClipYc+1
335 not_done_hi
336 bmi replace_first
337
338 replace_second
339 ; if (yc<CLIP_TOP/BOTTOM)
340 jsr _ClipMoveP0
341 jmp loop
342
343 replace_first
344 ; if (yc>CLIP_TOP/BOTTOM)
345 jsr _ClipMoveP1
346 jmp loop
347
348 done_lo
349 lda #0
350 sbc _ClipYc+1
351 bne not_done_hi
352 jmp _ClipReturnPc
353 .)
354
355
356 _ClipDichoLeftRight
357 .(
358 .(
359 ; if (LargeX0==CLIP_LEFT/RIGHT)
360 cpy _LargeX0+0
361 bne skip
362 lda _LargeX0+1
363 bne skip
364 rts
365 skip
366 .)
367
368 .(
369 ; if (LargeX1==CLIP_LEFT/RIGHT)
370 cpy _LargeX1+0
371 bne skip
372 lda _LargeX1+1
373 bne skip
374 rts
375 skip
376 .)
377
378 sec
379 lda _LargeX0+0
380 sbc _LargeX1+0
381 lda _LargeX0+1
382 sbc _LargeX1+1
383 bmi label4
384
385 label3
386 ; (LargeX0>=LargeX1)
387 jsr _ClipSetInvertedStartPoints
388 jmp end_swap
389
390 label4
391 ; (LargeX0<LargeX1)
392 jsr _ClipSetNormalStartPoints
393
394 end_swap
395
396 #ifdef USE_ACCURATE_CLIPPING
397 lda #0
398 sta _ClipX0-1
399 sta _ClipY0-1
400 sta _ClipX1-1
401 sta _ClipY1-1
402 #endif
403
404 ; loop until clip point reached:
405 loop
406 jsr _ClipComputeMidPoint
407
408 ; if (xc==CLIP_LEFT/RIGHT)
409 sec
410 tya
411 sbc _ClipXc+0
412 beq done_lo
413 lda #0
414 sbc _ClipXc+1
415 not_done_hi
416 bmi replace_first
417
418 replace_second
419 ; if (xc<CLIP_LEFT/RIGHT)
420 jsr _ClipMoveP0
421 jmp loop
422
423 replace_first
424 ; if (xc>CLIP_LEFT/RIGHT)
425 jsr _ClipMoveP1
426 jmp loop
427
428 done_lo
429 lda #0
430 sbc _ClipXc+1
431 bne not_done_hi
432 jmp _ClipReturnPc
433 .)
434
435 _ClipReturnPc
436 .(
437 ; LargeX0/1=ClipXc;
438 lda _ClipXc+0
439 sta _LargeX0+0,x
440 lda _ClipXc+1
441 sta _LargeX0+1,x
442
443 ; LargeY/1=ClipYc;
444 lda _ClipYc+0
445 sta _LargeY0+0,x
446 lda _ClipYc+1
447 sta _LargeY0+1,x
448
449 rts
450 .)
451
452 _DrawClippedLine
453 .(
454 ; The region outcodes for the the endpoints
455 ; Compute the outcode for the first point
456 ldx #OFS_PT0 ; XY0
457 jsr _ClipFindRegion
458 ; Compute the outcode for the second point
459 ldx #OFS_PT1 ; XY1
460 clip_loop
461 jsr _ClipFindRegion
462
463 ; In theory, this can never end up in an infinite loop,
464 ; it'll always come in one of the trivial cases eventually
465
466 lda _ClipCode0
467 ora _ClipCode1
468 bne end_trivial_draw
469
470 ; /accept because both endpoints are in screen or on the border,
471 ; trivial accept
472 lda _LargeX0
473 sta _CurrentPixelX
474 lda _LargeY0
475 sta _CurrentPixelY
476 lda _LargeX1
477 sta _OtherPixelX
478 lda _LargeY1
479 sta _OtherPixelY
480 jmp _DrawLine8
481
482 end_trivial_draw
483
484 lda _ClipCode0
485 and _ClipCode1
486 beq end_invisible_line
487 ; The line isn't visible on screen, trivial reject
488 rts
489
490 end_invisible_line
491 .(
492 ; if no trivial reject or accept, continue the loop
493 ldx #OFS_PT0
494 lda _ClipCode0
495 bne skip
496 ldx #OFS_PT1
497 lda _ClipCode1
498 skip
499
500 lsr
501 bcc end_clip_bottom
502 ; Clip bottom
503 ldy #CLIP_BOTTOM
504 jsr _ClipDichoTopBottom
505 jmp clip_loop
506 end_clip_bottom
507
508 lsr
509 bcc end_clip_top
510 ; Clip top
511 ldy #CLIP_TOP
512 jsr _ClipDichoTopBottom
513 jmp clip_loop
514 end_clip_top
515
516 lsr
517 bcc end_clip_right
518 ; Clip right
519 ldy #CLIP_RIGHT
520 jsr _ClipDichoLeftRight
521 jmp clip_loop
522 end_clip_right
523
524 lsr
525 bcc clip_loop
526 ; Clip left
527 ldy #CLIP_LEFT
528 jsr _ClipDichoLeftRight
529 jmp clip_loop
530 .)
531 .)
532

  ViewVC Help
Powered by ViewVC 1.1.26