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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 282 by thrust26, Sat Feb 13 23:24:23 2010 UTC revision 283 by thrust26, Sun Feb 14 19:45:17 2010 UTC
# Line 1  Line 1 
1  ; without, trivial, -1, 7331 clipping  ; History of linebench timings...
2  ; 451, 466, 636 (initial version)  ; without, trivial, worst case, 7331 clipping
3    ; 451, 466, 636,  -  (initial version)
4  ; 451, 459, 624, 424  ; 451, 459, 624, 424
5    ; 451; 459, 614, 422
6    ; 451; 459, 609, 418
7    
8  #include "params.h"  #include "params.h"
9    
   
10      .zero      .zero
11    
12  ; 5 bytes for point 0  ; 5 bytes for point 0
# Line 16  _LargeX1        .dsb 2 Line 18  _LargeX1        .dsb 2
18  _LargeY1        .dsb 2  _LargeY1        .dsb 2
19  _ClipCode1      .dsb 1  _ClipCode1      .dsb 1
20    
 _LargeX         .dsb 2  
 _LargeY         .dsb 2  
   
21  #ifdef USE_ACCURATE_CLIPPING  #ifdef USE_ACCURATE_CLIPPING
22                  .dsb 1                  .dsb 1
23  #endif  #endif
# Line 44  _ClipXc         .dsb 2 Line 43  _ClipXc         .dsb 2
43  #endif  #endif
44  _ClipYc         .dsb 2  _ClipYc         .dsb 2
45    
46      .text  #define OFS_PT0 0
47    #define OFS_PT1 (_LargeX1-_LargeX0)
48    
49        .text
50    
51  _Break  _Break
52      jmp _Break      jmp _Break
53      rts      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  _ClipComputeMidPoint
119  .(  .(
# Line 68  _ClipComputeMidPoint Line 130  _ClipComputeMidPoint
130    
131      lda _ClipX0+1      lda _ClipX0+1
132      adc _ClipX1+1      adc _ClipX1+1
133      sta _ClipXc+1  ; divide by 2:
   
     lda _ClipXc+1  
134      cmp #$80      cmp #$80
135      ror _ClipXc+1      ror
136        sta _ClipXc+1
137      ror _ClipXc+0      ror _ClipXc+0
138  #ifdef USE_ACCURATE_CLIPPING  #ifdef USE_ACCURATE_CLIPPING
139      ror _ClipXc-1      ror _ClipXc-1
# Line 91  _ClipComputeMidPoint Line 152  _ClipComputeMidPoint
152    
153      lda _ClipY0+1      lda _ClipY0+1
154      adc _ClipY1+1      adc _ClipY1+1
155      sta _ClipYc+1  ; divide by 2:
   
     lda _ClipYc+1  
156      cmp #$80      cmp #$80
157      ror _ClipYc+1      ror
158        sta _ClipYc+1
159      ror _ClipYc+0      ror _ClipYc+0
160  #ifdef USE_ACCURATE_CLIPPING  #ifdef USE_ACCURATE_CLIPPING
161      ror _ClipYc-1      ror _ClipYc-1
# Line 103  _ClipComputeMidPoint Line 163  _ClipComputeMidPoint
163      rts      rts
164  .)  .)
165    
 _ClipMoveP1  
 .(  
     ; x1=xc;  
     lda _ClipXc+0  
     sta _ClipX1+0  
     lda _ClipXc+1  
     sta _ClipX1+1  
 #ifdef USE_ACCURATE_CLIPPING  
     lda _ClipXc-1  
     sta _ClipX1-1  
 #endif  
   
     ; y1=yc;  
     lda _ClipYc+0  
     sta _ClipY1+0  
     lda _ClipYc+1  
     sta _ClipY1+1  
 #ifdef USE_ACCURATE_CLIPPING  
     lda _ClipYc-1  
     sta _ClipY1-1  
 #endif  
     rts  
 .)  
   
 _ClipMoveP0  
 .(  
     ; x0=xc;  
     lda _ClipXc+0  
     sta _ClipX0+0  
     lda _ClipXc+1  
     sta _ClipX0+1  
 #ifdef USE_ACCURATE_CLIPPING  
     lda _ClipXc-1  
     sta _ClipX0-1  
 #endif  
   
     ; y0=yc;  
     lda _ClipYc+0  
     sta _ClipY0+0  
     lda _ClipYc+1  
     sta _ClipY0+1  
 #ifdef USE_ACCURATE_CLIPPING  
     lda _ClipYc-1  
     sta _ClipY0-1  
 #endif  
     rts  
 .)  
   
   
 _ClipReturnPc  
 .(  
     ; LargeX=ClipXc;  
     lda _ClipXc+0  
     sta _LargeX+0  
     lda _ClipXc+1  
     sta _LargeX+1  
   
     ; LargeY=ClipYc;  
     lda _ClipYc+0  
     sta _LargeY+0  
     lda _ClipYc+1  
     sta _LargeY+1  
   
     rts  
 .)  
   
 _ClipReturnP0  
 .(  
     ; LargeX=LargeX0;  
     lda _LargeX0+0  
     sta _LargeX+0  
     lda _LargeX0+1  
     sta _LargeX+1  
   
     ; LargeY=LargeY0;  
     lda _LargeY0+0  
     sta _LargeY+0  
     lda _LargeY0+1  
     sta _LargeY+1  
   
     rts  
 .)  
   
 _ClipReturnP1  
 .(  
     ; LargeX=LargeX1;  
     lda _LargeX1+0  
     sta _LargeX+0  
     lda _LargeX1+1  
     sta _LargeX+1  
   
     ; LargeY=LargeY1;  
     lda _LargeY1+0  
     sta _LargeY+0  
     lda _LargeY1+1  
     sta _LargeY+1  
   
     rts  
 .)  
166    
167  _ClipSetNormalStartPoints  _ClipSetNormalStartPoints
168  .(  .(
# Line 262  _ClipSetInvertedStartPoints Line 223  _ClipSetInvertedStartPoints
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  _ClipDichoTopBottom
278  .(  .(
279      .(      .(
280      ; if (LargeY0==CLIP_TOP)      ; if (LargeY0==CLIP_TOP/BOTTOM)
281      cpx _LargeY0+0      cpy _LargeY0+0
282      bne skip      bne skip
283      lda _LargeY0+1      lda _LargeY0+1
284      bne skip      bne skip
285      jmp _ClipReturnP0      rts
286  skip  skip
287      .)      .)
288    
289      .(      .(
290      ; if (LargeY1==CLIP_TOP)      ; if (LargeY1==CLIP_TOP/BOTTOM)
291      cpx _LargeY1+0      cpy _LargeY1+0
292      bne skip      bne skip
293      lda _LargeY1+1      lda _LargeY1+1
294      bne skip      bne skip
295      jmp _ClipReturnP1      rts
296  skip  skip
297      .)      .)
298    
# Line 311  end_swap Line 323  end_swap
323  #endif  #endif
324    
325  loop  loop
326      jsr _ClipComputeMidPoint      jsr _ClipComputeMidPoint ; (ClipXY0+ClipXY1)/2
   
     ;   if (yc==CLIP_TOP)  
     cpx _ClipYc+0  
     bne not_done  
     lda _ClipYc+1  
     beq done  
   
 not_done  
327    
328        ;   if (yc==CLIP_TOP/BOTTOM)
329      sec      sec
330      txa      tya
331      sbc _ClipYc+0      sbc _ClipYc+0
332        beq done_lo
333      lda #0      lda #0
334      sbc _ClipYc+1      sbc _ClipYc+1
335    not_done_hi
336      bmi replace_first      bmi replace_first
337    
338  replace_second  replace_second
339      ; if (yc<CLIP_TOP)      ; if (yc<CLIP_TOP/BOTTOM)
340      jsr _ClipMoveP0      jsr _ClipMoveP0
341      jmp loop      jmp loop
342    
343  replace_first  replace_first
344      ; if (yc>CLIP_TOP)      ; if (yc>CLIP_TOP/BOTTOM)
345      jsr _ClipMoveP1      jsr _ClipMoveP1
346      jmp loop      jmp loop
347    
348  done  done_lo
349      ; Finished !      lda #0
350        sbc _ClipYc+1
351        bne not_done_hi
352      jmp _ClipReturnPc      jmp _ClipReturnPc
353  .)  .)
354    
# Line 348  _ClipDichoLeftRight Line 357  _ClipDichoLeftRight
357  .(  .(
358      .(      .(
359      ; if (LargeX0==CLIP_LEFT/RIGHT)      ; if (LargeX0==CLIP_LEFT/RIGHT)
360      cpx _LargeX0+0      cpy _LargeX0+0
361      bne skip      bne skip
362      lda _LargeX0+1      lda _LargeX0+1
363      bne skip      bne skip
364      jmp _ClipReturnP0      rts
365  skip  skip
366      .)      .)
367    
368      .(      .(
369      ; if (LargeX1==CLIP_LEFT/RIGHT)      ; if (LargeX1==CLIP_LEFT/RIGHT)
370      cpx _LargeX1+0      cpy _LargeX1+0
371      bne skip      bne skip
372      lda _LargeX1+1      lda _LargeX1+1
373      bne skip      bne skip
374      jmp _ClipReturnP1      rts
375  skip  skip
376      .)      .)
377    
# Line 392  end_swap Line 401  end_swap
401      sta _ClipY1-1      sta _ClipY1-1
402  #endif  #endif
403    
404    ; loop until clip point reached:
405  loop  loop
406      jsr _ClipComputeMidPoint      jsr _ClipComputeMidPoint
407    
408      ;   if (xc==CLIP_LEFT/RIGHT)      ;   if (xc==CLIP_LEFT/RIGHT)
     cpx _ClipXc+0  
     bne not_done  
     lda _ClipXc+1  
     beq done  
   
 not_done  
   
409      sec      sec
410      txa      tya
411      sbc _ClipXc+0      sbc _ClipXc+0
412        beq done_lo
413      lda #0      lda #0
414      sbc _ClipXc+1      sbc _ClipXc+1
415    not_done_hi
416      bmi replace_first      bmi replace_first
417    
418  replace_second  replace_second
# Line 420  replace_first Line 425  replace_first
425      jsr _ClipMoveP1      jsr _ClipMoveP1
426      jmp loop      jmp loop
427    
428  done  done_lo
429      ; Finished !      lda #0
430        sbc _ClipXc+1
431        bne not_done_hi
432      jmp _ClipReturnPc      jmp _ClipReturnPc
433  .)  .)
434    
435    _ClipReturnPc
   
   
 ;  
 ; In this code, we assume that the CLIP_ values are fitting  
 ; the resolution of an Oric screen, so they will never be out  
 ; of a 240x200 screen resolution, fit in an unsigned byte.  
 ;  
 _ClipFindRegion0  
     ldx #0  
 _ClipFindRegion  
436  .(  .(
437  ; yHi >= $01 -> clip_bottom      ; LargeX0/1=ClipXc;
438  ; yHi == $00 -> check      lda _ClipXc+0
439  ; yHi <= $ff -> clip_top      sta _LargeX0+0,x
440        lda _ClipXc+1
441  ; top/bottom test      sta _LargeX0+1,x
     ldy _LargeY0+1,x    ;  
     bmi clip_top        ;       if Y-Hi <= -1, clip top  
     bne clip_bottom     ;       else, if Y-Hi != 0, clip bottom  
   
 ; initialize with 'not clipped'  
     lda #0  
   
     ldy _LargeY0+0,x  
 #if CLIP_TOP <> 0  
     cpy #CLIP_TOP       ;       = 5  
     bcc clip_top  
 #endif  
     cpy #(CLIP_BOTTOM+1);       = 194  
     bcc end_top_bottom  
 clip_bottom  
     lda #1              ;       means (y > CLIP_BOTTOM)  
     bne end_top_bottom  
   
 clip_top  
     lda #2              ;       means (y < CLIP_TOP)  
 end_top_bottom  
   
 ; xHi >= $01 -> clip_right  
 ; xHi == $00 -> check  
 ; xHi <= $ff -> clip_left  
   
 ; left/right test  
     ldy _LargeX0+1,x  
     bmi clip_left       ;       if X-Hi <=- 1, clip left  
     bne clip_right      ;       else, if X-Hi != 0, clip bottom  
442    
443      ldy _LargeX0+0,x      ; LargeY/1=ClipYc;
444  #if CLIP_LEFT <> 0      lda _ClipYc+0
445      cpy #CLIP_LEFT      sta _LargeY0+0,x
446      bcc clip_left      lda _ClipYc+1
447  #endif      sta _LargeY0+1,x
     cpy #(CLIP_RIGHT+1)  
     bcc end_left_right  
 clip_right  
     ora #4              ;       means (x > CLIP_RIGHT)  
     bne end_left_right  ; 3  
448    
 clip_left  
     ora #8              ;       means (x < CLIP_LEFT)  
 end_left_right  
     sta _ClipCode0,x  
449      rts      rts
450  .)  .)
451    
# Line 495  _DrawClippedLine Line 453  _DrawClippedLine
453  .(  .(
454  ; The region outcodes for the the endpoints  ; The region outcodes for the the endpoints
455  ; Compute the outcode for the first point  ; Compute the outcode for the first point
456      jsr _ClipFindRegion0      ldx #OFS_PT0        ; XY0
457        jsr _ClipFindRegion
458  ; Compute the outcode for the second point  ; Compute the outcode for the second point
459  clip_loop1      ldx #OFS_PT1        ; XY1
460      ldx #_LargeY1-_LargeY0      ; XY1  clip_loop
461      jsr _ClipFindRegion      jsr _ClipFindRegion
462    
463      ; In theory, this can never end up in an infinite loop, it'll always come in one of the trivial cases eventually  ; In theory, this can never end up in an infinite loop,
464  clip_loop  ; it'll always come in one of the trivial cases eventually
465    
466      lda _ClipCode0      lda _ClipCode0
467      ora _ClipCode1      ora _ClipCode1
468      bne end_trivial_draw      bne end_trivial_draw
     .(  
         ; /accept because both endpoints are in screen or on the border, trivial accept  
         lda _LargeX0  
         sta _CurrentPixelX  
         lda _LargeY0  
         sta _CurrentPixelY  
         lda _LargeX1  
         sta _OtherPixelX  
         lda _LargeY1  
         sta _OtherPixelY  
469    
470          jmp _DrawLine8  ; /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  end_trivial_draw
483    
484      lda _ClipCode0      lda _ClipCode0
485      and _ClipCode1      and _ClipCode1
486      beq end_invisible_line      beq end_invisible_line
487      .(  ; The line isn't visible on screen, trivial reject
488          ; The line isn't visible on screen, trivial reject      rts
         rts  
     .)  
 end_invisible_line  
489    
490    end_invisible_line
491      .(      .(
492          ; if no trivial reject or accept, continue the loop  ; if no trivial reject or accept, continue the loop
493          .(      ldx #OFS_PT0
494          lda _ClipCode0      lda _ClipCode0
495          bne skip      bne skip
496          lda _ClipCode1      ldx #OFS_PT1
497        lda _ClipCode1
498  skip  skip
         .)  
499    
500          lsr      lsr
501          bcc end_clip_bottom      bcc end_clip_bottom
502          ; Clip bottom  ; Clip bottom
503          ldx #CLIP_BOTTOM      ldy #CLIP_BOTTOM
504          jsr _ClipDichoTopBottom      jsr _ClipDichoTopBottom
505          jmp end_clip_switch      jmp clip_loop
506  end_clip_bottom  end_clip_bottom
507    
508          lsr      lsr
509          bcc end_clip_top      bcc end_clip_top
510          ; Clip top  ; Clip top
511          ldx #CLIP_TOP      ldy #CLIP_TOP
512          jsr _ClipDichoTopBottom      jsr _ClipDichoTopBottom
513          jmp end_clip_switch      jmp clip_loop
514  end_clip_top  end_clip_top
515    
516          lsr      lsr
517          bcc end_clip_right      bcc end_clip_right
518          ; Clip right  ; Clip right
519          ldx #CLIP_RIGHT      ldy #CLIP_RIGHT
520          jsr _ClipDichoLeftRight      jsr _ClipDichoLeftRight
521          jmp end_clip_switch      jmp clip_loop
522  end_clip_right  end_clip_right
523    
524          lsr      lsr
525          bcc end_clip_left      bcc clip_loop
526          ; Clip left  ; Clip left
527          ldx #CLIP_LEFT      ldy #CLIP_LEFT
528          jsr _ClipDichoLeftRight      jsr _ClipDichoLeftRight
         jmp end_clip_switch  
 end_clip_left  
   
 end_clip_switch  
   
     lda _ClipCode0  
     beq clip_second_point  
   
 clip_first_point  
     ; First endpoint was clipped  
     lda _LargeX+0  
     sta _LargeX0+0  
     lda _LargeX+1  
     sta _LargeX0+1  
   
     lda _LargeY+0  
     sta _LargeY0+0  
     lda _LargeY+1  
     sta _LargeY0+1  
   
     jsr _ClipFindRegion0  
   
529      jmp clip_loop      jmp clip_loop
   
 clip_second_point  
     ; Second endpoint was clipped  
     lda _LargeX+0  
     sta _LargeX1+0  
     lda _LargeX+1  
     sta _LargeX1+1  
   
     lda _LargeY+0  
     sta _LargeY1+0  
     lda _LargeY+1  
     sta _LargeY1+1  
   
     jmp clip_loop1  
   
530      .)      .)
   
     ; Not supposed to arrive here :p  
     rts  
531  .)  .)
532    

Legend:
Removed from v.282  
changed lines
  Added in v.283

  ViewVC Help
Powered by ViewVC 1.1.26