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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26