/[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 287 - (show annotations)
Sun Feb 14 22:35:27 2010 UTC (9 years, 9 months ago) by thrust26
File size: 11174 byte(s)
bugfix for single pixel clipped lines
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 ; 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
72 ; initialize with 'not clipped'
73 lda #0 ; 2
74
75 ldy _LargeY0+0,x ; 4
76 #if CLIP_TOP <> 0
77 cpy #CLIP_TOP ; 2 == 0
78 bcc clip_top ; 2/3
79 #endif
80 cpy #(CLIP_BOTTOM+1); 2
81 bcc end_top_bottom ; 2/3
82 clip_bottom
83 lda #1 ; 2 means (y > CLIP_BOTTOM)
84 bne end_top_bottom ; 3
85
86 clip_top
87 lda #2 ; 2 means (y < CLIP_TOP)
88 end_top_bottom ; = 23 (A==0)
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 ; 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
99 ldy _LargeX0+0,x ; 4
100 #if CLIP_LEFT <> 0
101 cpy #CLIP_LEFT ; 2
102 bcc clip_left ; 2/3
103 #endif
104 cpy #(CLIP_RIGHT+1) ; 2
105 bcc end_left_right ; 2/3
106 clip_right
107 ora #4 ; 2 means (x > CLIP_RIGHT)
108 bne end_left_right ; 3
109
110 clip_left
111 ora #8 ; 2 means (x < CLIP_LEFT)
112 end_left_right ; = 21 (A==0)
113 sta _ClipCode0,x ; 4
114 rts ; 6 = 10
115 .)
116
117
118 _ClipComputeMidPoint
119 .(
120 ; xc=(x0+x1)>>1;
121 clc
122 #ifdef USE_ACCURATE_CLIPPING
123 lda _ClipX0-1 ; 3
124 adc _ClipX1-1 ; 3
125 sta _ClipXc-1 ; 3
126 #endif
127 lda _ClipX0+0 ; 3
128 adc _ClipX1+0 ; 3
129 sta _ClipXc+0 ; 3
130
131 lda _ClipX0+1 ; 3
132 adc _ClipX1+1 ; 3
133 ; divide by 2:
134 cmp #$80 ; 2
135 ror ; 2
136 sta _ClipXc+1 ; 3
137 ror _ClipXc+0 ; 5
138 #ifdef USE_ACCURATE_CLIPPING
139 ror _ClipXc-1 ; 5 = 41
140 #endif
141
142 ; yc=(y0+y1)>>1;
143 clc
144 #ifdef USE_ACCURATE_CLIPPING
145 lda _ClipY0-1 ; 3
146 adc _ClipY1-1 ; 3
147 sta _ClipYc-1 ; 3
148 #endif
149 lda _ClipY0+0 ; 3
150 adc _ClipY1+0 ; 3
151 sta _ClipYc+0 ; 3
152
153 lda _ClipY0+1 ; 3
154 adc _ClipY1+1 ; 3
155 ; divide by 2:
156 cmp #$80 ; 2
157 ror ; 2
158 sta _ClipYc+1 ; 3
159 ror _ClipYc+0 ; 5
160 #ifdef USE_ACCURATE_CLIPPING
161 ror _ClipYc-1 ; 5 = 41
162 #endif
163 rts ; 6 = 6
164 ; total: 88
165 .)
166
167
168 _ClipSetNormalStartPoints
169 .(
170 ; x0=LargeX0;
171 ; y0=LargeY0;
172 lda _LargeX0+0
173 sta _ClipX0+0
174 lda _LargeX0+1
175 sta _ClipX0+1
176
177 lda _LargeY0+0
178 sta _ClipY0+0
179 lda _LargeY0+1
180 sta _ClipY0+1
181
182 ; x1=LargeX1;
183 ; y1=LargeY1;
184 lda _LargeX1+0
185 sta _ClipX1+0
186 lda _LargeX1+1
187 sta _ClipX1+1
188
189 lda _LargeY1+0
190 sta _ClipY1+0
191 lda _LargeY1+1
192 sta _ClipY1+1
193
194 rts
195 .)
196
197 _ClipSetInvertedStartPoints
198 .(
199 ; x0=LargeX1;
200 ; y0=LargeY1;
201 lda _LargeX1+0
202 sta _ClipX0+0
203 lda _LargeX1+1
204 sta _ClipX0+1
205
206 lda _LargeY1+0
207 sta _ClipY0+0
208 lda _LargeY1+1
209 sta _ClipY0+1
210
211 ; 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 .)
225
226
227 _ClipMoveP1
228 .(
229 ; x1=xc;
230 lda _ClipXc+0 ; 3
231 sta _ClipX1+0 ; 3
232 lda _ClipXc+1 ; 3
233 sta _ClipX1+1 ; 3
234 #ifdef USE_ACCURATE_CLIPPING
235 lda _ClipXc-1 ; 3
236 sta _ClipX1-1 ; 3
237 #endif
238
239 ; y1=yc;
240 lda _ClipYc+0 ; 3
241 sta _ClipY1+0 ; 3
242 lda _ClipYc+1 ; 3
243 sta _ClipY1+1 ; 3
244 #ifdef USE_ACCURATE_CLIPPING
245 lda _ClipYc-1 ; 3
246 sta _ClipY1-1 ; 3
247 #endif
248 rts ; 6
249 ; 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 _ClipDichoTopBottom
279 .(
280 .(
281 ; if (LargeY0==CLIP_TOP/BOTTOM)
282 cpy _LargeY0+0
283 bne skip
284 lda _LargeY0+1
285 bne skip
286 cpx #OFS_PT0
287 bne copy
288 rts
289
290 copy:
291 ; special case: XY0 == XY1
292 jmp _ClipReturnP0
293 skip
294 .)
295
296 .(
297 ; if (LargeY1==CLIP_TOP/BOTTOM)
298 cpy _LargeY1+0
299 bne skip
300 lda _LargeY1+1
301 bne skip
302 cpx #OFS_PT1
303 bne copy
304 rts
305
306 copy:
307 ; special case: XY0 == XY1
308 jmp _ClipReturnP1
309 skip
310 .)
311
312 sec
313 lda _LargeY0+0
314 sbc _LargeY1+0
315 lda _LargeY0+1
316 sbc _LargeY1+1
317 bmi label4
318
319 label3
320 ; (LargeY0>=LargeY1)
321 jsr _ClipSetInvertedStartPoints
322 jmp end_swap
323
324 label4
325 ; (LargeY0<LargeY1)
326 jsr _ClipSetNormalStartPoints
327
328 end_swap
329
330 #ifdef USE_ACCURATE_CLIPPING
331 lda #0
332 sta _ClipX0-1
333 sta _ClipY0-1
334 sta _ClipX1-1
335 sta _ClipY1-1
336 #endif
337
338 loop
339 jsr _ClipComputeMidPoint; 94 (ClipXY0+ClipXY1)/2
340
341 ; if (yc==CLIP_TOP/BOTTOM)
342 sec
343 tya
344 sbc _ClipYc+0
345 beq done_lo
346 lda #0
347 sbc _ClipYc+1
348 not_done_hi
349 bmi replace_first
350
351 replace_second
352 ; if (yc<CLIP_TOP/BOTTOM)
353 jsr _ClipMoveP0 ;48
354 jmp loop ; 3
355
356 replace_first
357 ; if (yc>CLIP_TOP/BOTTOM)
358 jsr _ClipMoveP1 ;48
359 jmp loop ; 3
360
361 done_lo
362 lda #0
363 sbc _ClipYc+1
364 bne not_done_hi
365 jmp _ClipReturnPc
366 .)
367
368
369 _ClipDichoLeftRight
370 .(
371 .(
372 ; if (LargeX0==CLIP_LEFT/RIGHT)
373 cpy _LargeX0+0
374 bne skip
375 lda _LargeX0+1
376 bne skip
377 cpx #OFS_PT0
378 bne copy
379 rts
380
381 copy:
382 ; special case: XY0 == XY1
383 jmp _ClipReturnP0
384 skip
385 .)
386
387 .(
388 ; if (LargeX1==CLIP_LEFT/RIGHT)
389 cpy _LargeX1+0
390 bne skip
391 lda _LargeX1+1
392 bne skip
393 cpx #OFS_PT1
394 bne copy
395 rts
396
397 copy:
398 ; special case: XY0 == XY1
399 jmp _ClipReturnP1
400 skip
401 .)
402
403 sec
404 lda _LargeX0+0
405 sbc _LargeX1+0
406 lda _LargeX0+1
407 sbc _LargeX1+1
408 bmi label4
409
410 label3
411 ; (LargeX0>=LargeX1)
412 jsr _ClipSetInvertedStartPoints
413 jmp end_swap
414
415 label4
416 ; (LargeX0<LargeX1)
417 jsr _ClipSetNormalStartPoints
418
419 end_swap
420
421 #ifdef USE_ACCURATE_CLIPPING
422 lda #0
423 sta _ClipX0-1
424 sta _ClipY0-1
425 sta _ClipX1-1
426 sta _ClipY1-1
427 #endif
428
429 ; loop until clip point reached:
430 loop
431 jsr _ClipComputeMidPoint ;94
432
433 ; if (xc==CLIP_LEFT/RIGHT)
434 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 not_done_hi
441 bmi replace_first ; 2/3= 7/8
442
443 replace_second
444 ; if (xc<CLIP_LEFT/RIGHT)
445 jsr _ClipMoveP0 ;48
446 jmp loop ; 3
447
448 replace_first
449 ; if (xc>CLIP_LEFT/RIGHT)
450 jsr _ClipMoveP1 ;48
451 jmp loop ; 3
452 ; loop total: 161.5
453
454 done_lo
455 lda #0 ; 2
456 sbc _ClipXc+1 ; 3
457 bne not_done_hi ; 2/3
458 jmp _ClipReturnPc ; 3
459 .)
460
461 _ClipReturnPc
462 .(
463 ; LargeX0/1=ClipXc;
464 lda _ClipXc+0
465 sta _LargeX0+0,x
466 lda _ClipXc+1
467 sta _LargeX0+1,x
468
469 ; LargeY/1=ClipYc;
470 lda _ClipYc+0
471 sta _LargeY0+0,x
472 lda _ClipYc+1
473 sta _LargeY0+1,x
474
475 rts
476 .)
477
478 _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 _DrawClippedLine
514 .(
515 ; The region outcodes for the the endpoints
516 ; Compute the outcode for the first point
517 ldx #OFS_PT0 ; 2 XY0
518 jsr _ClipFindRegion ;60 A==0
519 ; Compute the outcode for the second point
520 ldx #OFS_PT1 ; 2 XY1
521 clip_loop
522 jsr _ClipFindRegion ;60 A==0
523
524 ; In theory, this can never end up in an infinite loop,
525 ; it'll always come in one of the trivial cases eventually
526
527 lda _ClipCode0
528 ora _ClipCode1
529 bne end_trivial_draw
530
531 ; /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 end_trivial_draw
544
545 lda _ClipCode0
546 and _ClipCode1
547 beq end_invisible_line
548 ; The line isn't visible on screen, trivial reject
549 rts
550
551 end_invisible_line
552 .(
553 ; 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 skip
560
561 lsr
562 bcc end_clip_bottom
563 ; Clip bottom
564 ldy #CLIP_BOTTOM
565 jsr _ClipDichoTopBottom
566 jmp clip_loop
567 end_clip_bottom
568
569 lsr
570 bcc end_clip_top
571 ; Clip top
572 ldy #CLIP_TOP
573 jsr _ClipDichoTopBottom
574 jmp clip_loop
575 end_clip_top
576
577 lsr
578 bcc end_clip_right
579 ; Clip right
580 ldy #CLIP_RIGHT
581 jsr _ClipDichoLeftRight
582 jmp clip_loop
583 end_clip_right
584
585 lsr
586 bcc clip_loop
587 ; Clip left
588 ldy #CLIP_LEFT
589 jsr _ClipDichoLeftRight
590 jmp clip_loop
591 .)
592 .)
593

  ViewVC Help
Powered by ViewVC 1.1.26