Annotation of ntddk/src/video/displays/s3/i386/lines.asm, revision 1.1

1.1     ! root        1: ;---------------------------Module-Header------------------------------;
        !             2: ; Module Name: lines.asm
        !             3: ;
        !             4: ; ASM version of the line DDA calculator.
        !             5: ;
        !             6: ; Copyright (c) 1992 Microsoft Corporation
        !             7: ;-----------------------------------------------------------------------;
        !             8: 
        !             9:         .386
        !            10: 
        !            11:         .model  small,c
        !            12: 
        !            13:         assume cs:FLAT,ds:FLAT,es:FLAT,ss:FLAT
        !            14:         assume fs:nothing,gs:nothing
        !            15: 
        !            16:         .xlist
        !            17:         include stdcall.inc             ;calling convention cmacros
        !            18:         include i386\strucs.inc
        !            19:         include i386\lines.inc
        !            20:         .list
        !            21: 
        !            22:         .data
        !            23: 
        !            24:         public gaflRoundTable
        !            25: gaflRoundTable       label  dword
        !            26:         dd      FL_H_ROUND_DOWN + FL_V_ROUND_DOWN       ; no flips
        !            27:         dd      FL_H_ROUND_DOWN + FL_V_ROUND_DOWN       ; D flip
        !            28:         dd      FL_H_ROUND_DOWN                         ; V flip
        !            29:         dd      FL_V_ROUND_DOWN                         ; D & V flip
        !            30:         dd      FL_V_ROUND_DOWN                         ; slope one
        !            31:         dd      0baadf00dh
        !            32:         dd      FL_H_ROUND_DOWN                         ; slope one & V flip
        !            33:         dd      0baadf00dh
        !            34: 
        !            35:         .code
        !            36: 
        !            37: ;--------------------------------Macro----------------------------------;
        !            38: ; testb ebx, <mask>
        !            39: ;
        !            40: ; Substitutes a byte compare if the mask is entirely in the lo-byte or
        !            41: ; hi-byte (thus saving 3 bytes of code space).
        !            42: ;
        !            43: ;-----------------------------------------------------------------------;
        !            44: 
        !            45: TESTB   macro   targ,mask,thirdarg
        !            46:         local   mask2,delta
        !            47: 
        !            48: ifnb <thirdarg>
        !            49:         .err    TESTB mask must be enclosed in brackets!
        !            50: endif
        !            51: 
        !            52:         delta = 0
        !            53:         mask2 = mask
        !            54: 
        !            55:         if mask2 AND 0ffff0000h
        !            56:             test targ,mask                      ; If bit set in hi-word,
        !            57:             exitm                               ; test entire dword
        !            58:         endif
        !            59: 
        !            60:         if mask2 AND 0ff00h
        !            61:             if mask2 AND 0ffh                   ; If bit set in lo-byte and
        !            62:                 test targ,mask                  ; hi-byte, test entire dword
        !            63:                 exitm
        !            64:             endif
        !            65: 
        !            66:             mask2 = mask2 SHR 8
        !            67:             delta = 1
        !            68:         endif
        !            69: 
        !            70: ifidni <targ>,<EBX>
        !            71:         if delta
        !            72:             test bh,mask2
        !            73:         else
        !            74:             test bl,mask2
        !            75:         endif
        !            76:         exitm
        !            77: endif
        !            78: 
        !            79:         .err    Too bad TESTB doesn't support targets other than ebx!
        !            80: endm
        !            81: 
        !            82: ;---------------------------Public-Routine------------------------------;
        !            83: ; bLines(ppdev, pptfxFirst, pptfxBuf, prun, cptfx, pls,
        !            84: ;        prclClip, apfn[], flStart)
        !            85: ;
        !            86: ; Handles lines with trivial or simple clipping.
        !            87: ;
        !            88: ;-----------------------------------------------------------------------;
        !            89: 
        !            90: cProc   bLines,36,< \
        !            91:     uses esi edi ebx,  \
        !            92:     ppdev:      ptr,   \
        !            93:     pptfxFirst: ptr,   \
        !            94:     pptfxBuf:   ptr,   \
        !            95:     prun:       ptr,   \
        !            96:     cptfx:      dword, \
        !            97:     pls:        ptr,   \
        !            98:     prclClip:   ptr,   \
        !            99:     apfn:       ptr,   \
        !           100:     flStart:    dword  >
        !           101: 
        !           102:         local pptfxBufEnd:           ptr   ; Last point in pptfxBuf
        !           103:         local M0:                    dword ; Normalized x0 in device coords
        !           104:         local dM:                    dword ; Delta-x in device coords
        !           105:         local N0:                    dword ; Normalized y0 in device coords
        !           106:         local dN:                    dword ; Delta-y in device coords
        !           107:         local fl:                    dword ; Flags for current line
        !           108:         local x:                     dword ; Normalized start pixel x-coord
        !           109:         local y:                     dword ; Normalized start pixel y-coord
        !           110:         local eqGamma_lo:            dword ; Upper 32 bits of Gamma
        !           111:         local eqGamma_hi:            dword ; Lower 32 bits of Gamma
        !           112:         local x0:                    dword ; Start pixel x-offset
        !           113:         local y0:                    dword ; Start pixel y-offset
        !           114:         local ulSlopeOneAdjustment:  dword ; Special offset if line of slope 1
        !           115:         local cStylePels:            dword ; # of pixels in line (before clip)
        !           116:         local xStart:                dword ; Start pixel x-offset before clip
        !           117:         local pfn:                   ptr   ; Pointer to strip drawing function
        !           118:         local cPels:                 dword ; # pixels to be drawn (after clip)
        !           119:         local i:                     dword ; # pixels in strip
        !           120:         local r:                     dword ; Remainder (or "error") term
        !           121:         local d_I:                   dword ; Delta-I
        !           122:         local d_R:                   dword ; Delta-R
        !           123:         local plStripEnd:            ptr   ; Last strip in buffer
        !           124:         local ptlStart[size POINTL]: byte  ; Unnormalized start coord
        !           125:         local dN_Original:           dword ; dN before half-flip
        !           126:         local xClipLeft:             dword ; Left side of clip rectangle
        !           127:         local xClipRight:            dword ; Right side of clip rectangle
        !           128:         local strip[size STRIPS]:    byte  ; Our strip buffer
        !           129: 
        !           130:         mov     ecx, cptfx
        !           131:         mov     edx, pptfxBuf
        !           132:         lea     eax, [edx + ecx * (size POINTL) - (size POINTL)]
        !           133:         mov     pptfxBufEnd, eax        ; pptfxBufEnd is inclusive of end point
        !           134: 
        !           135:         mov     eax, [edx].ptl_x        ; Load up end point (M1, N1)
        !           136:         mov     edi, [edx].ptl_y
        !           137: 
        !           138:         mov     edx, pptfxFirst         ; Load up start point (M0, N0)
        !           139:         mov     esi, [edx].ptl_x
        !           140:         mov     ecx, [edx].ptl_y
        !           141: 
        !           142:         mov     ebx, flStart
        !           143: 
        !           144: ;-----------------------------------------------------------------------;
        !           145: ; Flip to the first octant.                                             ;
        !           146: ;-----------------------------------------------------------------------;
        !           147: 
        !           148: ; Register state:       esi = M0
        !           149: ;                       ecx = N0
        !           150: ;                       eax = dM (M1)
        !           151: ;                       edi = dN (N1)
        !           152: ;                       ebx = fl
        !           153: 
        !           154: ; Make sure we go left to right:
        !           155: 
        !           156: the_main_loop:
        !           157:         cmp     esi, eax
        !           158:         jle     short is_left_to_right  ; skip if M0 <= M1
        !           159:         xchg    esi, eax                ; swap M0, M1
        !           160:         xchg    ecx, edi                ; swap N0, N1
        !           161:         or      ebx, FL_FLIP_H
        !           162: 
        !           163: is_left_to_right:
        !           164: 
        !           165: ; Compute the deltas, remembering that the DDI says we should get
        !           166: ; deltas less than 2^31.  If we get more, we ensure we don't crash
        !           167: ; later on by simply skipping the line:
        !           168: 
        !           169:         sub     eax, esi                ; eax = dM
        !           170:         jo      next_line               ; dM must be less than 2^31
        !           171:         sub     edi, ecx                ; edi = dN
        !           172:         jo      next_line               ; dN must be less than 2^31
        !           173: 
        !           174:         jge     short is_top_to_bottom  ; skip if dN >= 0
        !           175:         neg     ecx                     ; N0 = -N0
        !           176:         neg     edi                     ; N1 = -N1
        !           177:         or      ebx, FL_FLIP_V
        !           178: 
        !           179: is_top_to_bottom:
        !           180:         cmp     edi, eax
        !           181:         jb      short done_flips        ; skip if dN < dM
        !           182:         jne     short slope_more_than_one
        !           183: 
        !           184: ; We must special case slopes of one:
        !           185: 
        !           186:         or      ebx, FL_FLIP_SLOPE_ONE
        !           187:         jmp     short done_flips
        !           188: 
        !           189: slope_more_than_one:
        !           190:         xchg    eax, edi                ; swap dM, dN
        !           191:         xchg    esi, ecx                ; swap M0, N0
        !           192:         or      ebx, FL_FLIP_D
        !           193: 
        !           194: done_flips:
        !           195: 
        !           196:         mov     edx, ebx
        !           197:         and     edx, FL_ROUND_MASK
        !           198:         .errnz  FL_ROUND_SHIFT - 2
        !           199:         or      ebx, [gaflRoundTable + edx]  ; get our rounding flags
        !           200: 
        !           201:         mov     dM, eax                 ; save some info
        !           202:         mov     dN, edi
        !           203:         mov     fl, ebx
        !           204: 
        !           205:         mov     edx, esi                ; x = LFLOOR(M0)
        !           206:         sar     edx, FLOG2
        !           207:         mov     x, edx
        !           208: 
        !           209:         mov     edx, ecx                ; y = LFLOOR(N0)
        !           210:         sar     edx, FLOG2
        !           211:         mov     y, edx
        !           212: 
        !           213: ;-----------------------------------------------------------------------;
        !           214: ; Compute the fractional remainder term                                 ;
        !           215: ;-----------------------------------------------------------------------;
        !           216: 
        !           217:         public  compute_fractional
        !           218: compute_fractional:
        !           219:         and     esi, F - 1              ; M0 = FXFRAC(M0)
        !           220:         and     ecx, F - 1              ; N0 = FXFRAC(N0)
        !           221: 
        !           222:         mov     M0, esi                 ; save M0, N0 for later
        !           223:         mov     N0, ecx
        !           224: 
        !           225:         lea     edx, [ecx + F/2]
        !           226:         mul     edx                     ; [edx:eax] = dM * (N0 + F/2)
        !           227:         xchg    eax, edi
        !           228:         mov     ecx, edx                ; [ecx:edi] = dM * (N0 + F/2)
        !           229:                                         ; (we just nuked N0)
        !           230: 
        !           231:         mul     esi                     ; [edx:eax] = dN * M0
        !           232: 
        !           233: ; Now gamma = dM * (N0 + F/2) - dN * M0 - bRoundDown
        !           234: 
        !           235:         .errnz  FL_V_ROUND_DOWN - 8000h
        !           236:         ror     bh, 8
        !           237:         sbb     edi, eax
        !           238:         sbb     ecx, edx
        !           239: 
        !           240:         shrd    edi, ecx, FLOG2
        !           241:         sar     ecx, FLOG2              ; gamma = [ecx:edi] >>= 4
        !           242: 
        !           243:         mov     eqGamma_hi, ecx
        !           244:         mov     eqGamma_lo, edi
        !           245: 
        !           246:         mov     eax, N0
        !           247: 
        !           248: ; Register state:
        !           249: ;                       eax = N0
        !           250: ;                       ebx = fl
        !           251: ;                       ecx = eqGamma_hi
        !           252: ;                       edx = garbage
        !           253: ;                       esi = M0
        !           254: ;                       edi = eqGamma_lo
        !           255: 
        !           256:         testb   ebx, FL_FLIP_H
        !           257:         jnz     line_runs_right_to_left
        !           258: 
        !           259: ;-----------------------------------------------------------------------;
        !           260: ; Figure out which pixels are at the ends of a left-to-right line.      ;
        !           261: ;                               -------->                               ;
        !           262: ;-----------------------------------------------------------------------;
        !           263: 
        !           264:         public line_runs_left_to_right
        !           265: line_runs_left_to_right:
        !           266:         or      esi, esi
        !           267:         jz      short LtoR_check_slope_one
        !           268:                                         ; skip ahead if M0 == 0
        !           269:                                         ;   (in that case, x0 = 0 which is to be
        !           270:                                         ;   kept in esi, and is already
        !           271:                                         ;   conventiently zero)
        !           272: 
        !           273:         or      eax, eax
        !           274:         jnz     short LtoR_N0_not_zero
        !           275: 
        !           276:         .errnz  FL_H_ROUND_DOWN - 80h
        !           277:         ror     bl, 8
        !           278:         sbb     esi, -F/2
        !           279:         shr     esi, FLOG2
        !           280:         jmp     short LtoR_check_slope_one
        !           281:                                         ; esi = x0 = rounded M0
        !           282: 
        !           283: LtoR_N0_not_zero:
        !           284:         sub     eax, F/2
        !           285:         sbb     edx, edx
        !           286:         xor     eax, edx
        !           287:         sub     eax, edx
        !           288:         cmp     esi, eax
        !           289:         sbb     esi, esi
        !           290:         inc     esi                     ; esi = x0 = (abs(N0 - F/2) <= M0)
        !           291: 
        !           292:         public  LtoR_check_slope_one
        !           293: LtoR_check_slope_one:
        !           294:         mov     ulSlopeOneAdjustment, 0
        !           295:         mov     eax, ebx
        !           296:         and     eax, FL_FLIP_SLOPE_ONE + FL_H_ROUND_DOWN
        !           297:         cmp     eax, FL_FLIP_SLOPE_ONE + FL_H_ROUND_DOWN
        !           298:         jne     short LtoR_compute_y0_from_x0
        !           299: 
        !           300: ; We have to special case lines that are exactly of slope 1 or -1:
        !           301: 
        !           302:         mov     eax, N0
        !           303:         add     eax, dN
        !           304:         and     eax, F - 1              ; eax = N1
        !           305:         jz      short LtoR_slope_one_check_start_point
        !           306: 
        !           307:         mov     edx, M0
        !           308:         add     edx, dM
        !           309:         and     edx, F - 1              ; edx = M1
        !           310: 
        !           311:         add     eax, F/2
        !           312:         cmp     edx, eax                ; cmp M1, N1 + F/2
        !           313:         jne     short LtoR_slope_one_check_start_point
        !           314:         mov     ulSlopeOneAdjustment, -1
        !           315: 
        !           316: LtoR_slope_one_check_start_point:
        !           317:         mov     eax, M0
        !           318:         or      eax, eax
        !           319:         jz      short LtoR_compute_y0_from_x0
        !           320: 
        !           321:         add     eax, F/2
        !           322:         cmp     eax, N0                 ; cmp M0 + 8, N0
        !           323:         jne     short LtoR_compute_y0_from_x0
        !           324: 
        !           325:         xor     esi, esi                ; x0 = 0
        !           326: 
        !           327: LtoR_compute_y0_from_x0:
        !           328: 
        !           329: ; ecx = eqGamma_hi
        !           330: ; esi = x0
        !           331: ; edi = eqGamma_lo
        !           332: 
        !           333:         mov     eax, dN
        !           334:         mov     edx, dM
        !           335: 
        !           336:         mov     x0, esi
        !           337:         mov     y0, 0
        !           338:         cmp     ecx, 0
        !           339:         jl      short LtoR_compute_x1
        !           340: 
        !           341:         neg     esi
        !           342:         and     esi, eax
        !           343:         sub     edx, esi
        !           344:         cmp     edi, edx
        !           345:         mov     edx, dM
        !           346:         jl      short LtoR_compute_x1
        !           347:         mov     y0, 1                   ; y0 = floor((dN * x0 + eqGamma) / dM)
        !           348: 
        !           349: LtoR_compute_x1:
        !           350: 
        !           351: ; Register state:
        !           352: ;                       eax = dN
        !           353: ;                       ebx = fl
        !           354: ;                       ecx = garbage
        !           355: ;                       edx = dM
        !           356: ;                       esi = garbage
        !           357: ;                       edi = garbage
        !           358: 
        !           359:         mov     esi, M0
        !           360:         add     esi, edx
        !           361:         mov     ecx, esi
        !           362:         shr     esi, FLOG2
        !           363:         dec     esi                     ; x1 = ((M0 + dM) >> 4) - 1
        !           364:         add     esi, ulSlopeOneAdjustment
        !           365:         and     ecx, F-1                ; M1 = (M0 + dM) & 15
        !           366:         jz      done_first_pel_last_pel
        !           367: 
        !           368:         add     eax, N0
        !           369:         and     eax, F-1                ; N1 = (N0 + dN) & 15
        !           370:         jnz     short LtoR_N1_not_zero
        !           371: 
        !           372:         .errnz  FL_H_ROUND_DOWN - 80h
        !           373:         ror     bl, 8
        !           374:         sbb     ecx, -F/2
        !           375:         shr     ecx, FLOG2              ; ecx = LROUND(M1, fl & FL_ROUND_DOWN)
        !           376:         add     esi, ecx
        !           377:         jmp     done_first_pel_last_pel
        !           378: 
        !           379: LtoR_N1_not_zero:
        !           380:         sub     eax, F/2
        !           381:         sbb     edx, edx
        !           382:         xor     eax, edx
        !           383:         sub     eax, edx
        !           384:         cmp     eax, ecx
        !           385:         jg      done_first_pel_last_pel
        !           386:         inc     esi
        !           387:         jmp     done_first_pel_last_pel
        !           388: 
        !           389: ;-----------------------------------------------------------------------;
        !           390: ; Figure out which pixels are at the ends of a right-to-left line.      ;
        !           391: ;                               <--------                               ;
        !           392: ;-----------------------------------------------------------------------;
        !           393: 
        !           394: ; Compute x0:
        !           395: 
        !           396:         public  line_runs_right_to_left
        !           397: line_runs_right_to_left:
        !           398:         mov     x0, 1                   ; x0 = 1
        !           399:         or      eax, eax
        !           400:         jnz     short RtoL_N0_not_zero
        !           401: 
        !           402:         xor     edx, edx                ; ulDelta = 0
        !           403:         .errnz  FL_H_ROUND_DOWN - 80h
        !           404:         ror     bl, 8
        !           405:         sbb     esi, -F/2
        !           406:         shr     esi, FLOG2              ; esi = LROUND(M0, fl & FL_H_ROUND_DOWN)
        !           407:         jz      short RtoL_check_slope_one
        !           408: 
        !           409:         mov     x0, 2
        !           410:         mov     edx, dN
        !           411:         jmp     short RtoL_check_slope_one
        !           412: 
        !           413: RtoL_N0_not_zero:
        !           414:         sub     eax, F/2
        !           415:         sbb     edx, edx
        !           416:         xor     eax, edx
        !           417:         sub     eax, edx
        !           418:         add     eax, esi                ; eax = ABS(N0 - F/2) + M0
        !           419:         xor     edx, edx                ; ulDelta = 0
        !           420:         cmp     eax, F
        !           421:         jle     short RtoL_check_slope_one
        !           422: 
        !           423:         mov     x0, 2                   ; x0 = 2
        !           424:         mov     edx, dN                 ; ulDelta = dN
        !           425: 
        !           426:         public  RtoL_check_slope_one
        !           427: RtoL_check_slope_one:
        !           428:         mov     ulSlopeOneAdjustment, 0
        !           429:         mov     eax, ebx
        !           430:         and     eax, FL_FLIP_SLOPE_ONE + FL_H_ROUND_DOWN
        !           431:         cmp     eax, FL_FLIP_SLOPE_ONE
        !           432:         jne     short RtoL_compute_y0_from_x0
        !           433: 
        !           434: ; We have to special case lines that are exactly of slope 1 or -1:
        !           435: 
        !           436:         mov     eax, N0
        !           437:         add     eax, dN
        !           438:         and     eax, F - 1              ; eax = N1
        !           439:         jz      short RtoL_slope_one_check_start_point
        !           440: 
        !           441:         mov     esi, M0
        !           442:         add     esi, dM
        !           443:         and     esi, F - 1              ; esi = M1
        !           444: 
        !           445:         add     eax, F/2
        !           446:         cmp     esi, eax                ; cmp M1, N1 + F/2
        !           447:         jne     short RtoL_slope_one_check_start_point
        !           448:         mov     ulSlopeOneAdjustment, 1
        !           449: 
        !           450: RtoL_slope_one_check_start_point:
        !           451:         mov     eax, M0
        !           452:         or      eax, eax
        !           453:         jz      short RtoL_compute_y0_from_x0
        !           454: 
        !           455:         add     eax, F/2
        !           456:         cmp     eax, N0                 ; cmp M0 + 8, N0
        !           457:         jne     short RtoL_compute_y0_from_x0
        !           458: 
        !           459:         mov     x0, 2                   ; x0 = 2
        !           460:         mov     edx, dN                 ; ulDelta = dN
        !           461: 
        !           462: RtoL_compute_y0_from_x0:
        !           463: 
        !           464: ; eax = garbage
        !           465: ; ebx = fl
        !           466: ; ecx = eqGamma_hi
        !           467: ; edx = ulDelta
        !           468: ; esi = garbage
        !           469: ; edi = eqGamma_lo
        !           470: 
        !           471:         mov     eax, dN                 ; eax = dN
        !           472:         mov     y0, 0                   ; y0 = 0
        !           473: 
        !           474:         add     edi, edx
        !           475:         adc     ecx, 0                  ; eqGamma += ulDelta
        !           476:                                         ; NOTE: Setting flags here!
        !           477:         mov     edx, dM                 ; edx = dM
        !           478:         jl      short RtoL_compute_x1   ; NOTE: Looking at the flags here!
        !           479:         jg      short RtoL_y0_is_2
        !           480: 
        !           481:         lea     ecx, [edx + edx]
        !           482:         sub     ecx, eax                ; ecx = 2 * dM - dN
        !           483:         cmp     edi, ecx
        !           484:         jge     short RtoL_y0_is_2
        !           485: 
        !           486:         sub     ecx, edx                ; ecx = dM - dN
        !           487:         cmp     edi, ecx
        !           488:         jl      short RtoL_compute_x1
        !           489: 
        !           490:         mov     y0, 1
        !           491:         jmp     short RtoL_compute_x1
        !           492: 
        !           493: RtoL_y0_is_2:
        !           494:         mov     y0, 2
        !           495: 
        !           496: RtoL_compute_x1:
        !           497: 
        !           498: ; Register state:
        !           499: ;                       eax = dN
        !           500: ;                       ebx = fl
        !           501: ;                       ecx = garbage
        !           502: ;                       edx = dM
        !           503: ;                       esi = garbage
        !           504: ;                       edi = garbage
        !           505: 
        !           506:         mov     esi, M0
        !           507:         add     esi, edx
        !           508:         mov     ecx, esi
        !           509:         shr     esi, FLOG2              ; x1 = (M0 + dM) >> 4
        !           510:         add     esi, ulSlopeOneAdjustment
        !           511:         and     ecx, F-1                ; M1 = (M0 + dM) & 15
        !           512: 
        !           513:         add     eax, N0
        !           514:         and     eax, F-1                ; N1 = (N0 + dN) & 15
        !           515:         jnz     short RtoL_N1_not_zero
        !           516: 
        !           517:         .errnz  FL_H_ROUND_DOWN - 80h
        !           518:         ror     bl, 8
        !           519:         sbb     ecx, -F/2
        !           520:         shr     ecx, FLOG2              ; ecx = LROUND(M1, fl & FL_ROUND_DOWN)
        !           521:         add     esi, ecx
        !           522:         jmp     done_first_pel_last_pel
        !           523: 
        !           524: RtoL_N1_not_zero:
        !           525:         sub     eax, F/2
        !           526:         sbb     edx, edx
        !           527:         xor     eax, edx
        !           528:         sub     eax, edx
        !           529:         add     eax, ecx                ; eax = ABS(N1 - F/2) + M1
        !           530:         cmp     eax, F+1
        !           531:         sbb     esi, -1
        !           532: 
        !           533: done_first_pel_last_pel:
        !           534: 
        !           535: ; Register state:
        !           536: ;                       eax = garbage
        !           537: ;                       ebx = fl
        !           538: ;                       ecx = garbage
        !           539: ;                       edx = garbage
        !           540: ;                       esi = x1
        !           541: ;                       edi = garbage
        !           542: 
        !           543:         mov     ecx, x0
        !           544:         lea     edx, [esi + 1]
        !           545:         sub     edx, ecx                ; edx = x1 - x0 + 1
        !           546: 
        !           547:         jle     next_line
        !           548:         mov     cStylePels, edx
        !           549:         mov     xStart, ecx
        !           550: 
        !           551: ;-----------------------------------------------------------------------;
        !           552: ; See if clipping or styling needs to be done.                          ;
        !           553: ;-----------------------------------------------------------------------;
        !           554: 
        !           555:         testb   ebx, FL_CLIP
        !           556:         jnz     do_some_clipping
        !           557: 
        !           558: ; Register state:
        !           559: ;                       eax = garbage
        !           560: ;                       ebx = fl
        !           561: ;                       ecx = x0
        !           562: ;                       edx = garbage
        !           563: ;                       esi = x1
        !           564: ;                       edi = garbage
        !           565: 
        !           566: done_clipping:
        !           567:         mov     eax, y0
        !           568: 
        !           569:         sub     esi, ecx
        !           570:         inc     esi                     ; esi = cPels = x1 - x0 + 1
        !           571:         mov     cPels, esi
        !           572: 
        !           573:         add     ecx, x                  ; ecx = ptlStart.ptl_x
        !           574:         add     eax, y                  ; eax = ptlStart.ptl_y
        !           575: 
        !           576:         testb   ebx, FL_FLIP_D
        !           577:         jz      short do_v_unflip
        !           578:         xchg    ecx, eax
        !           579: 
        !           580: do_v_unflip:
        !           581:         testb   ebx, FL_FLIP_V
        !           582:         jz      short done_unflips
        !           583:         neg     eax
        !           584: 
        !           585: done_unflips:
        !           586:         testb   ebx, FL_STYLED
        !           587:         jnz     do_some_styling
        !           588: 
        !           589: done_styling:
        !           590:         lea     edx, [strip.ST_alStrips + (STRIP_MAX * 4)]
        !           591:         mov     plStripEnd, edx
        !           592: 
        !           593: ;-----------------------------------------------------------------------;
        !           594: ; Setup to do DDA.                                                      ;
        !           595: ;-----------------------------------------------------------------------;
        !           596: 
        !           597: ; Register state:
        !           598: ;                       eax = ptlStart.ptl_y
        !           599: ;                       ebx = fl
        !           600: ;                       ecx = ptlStart.ptl_x
        !           601: ;                       edx = garbage
        !           602: ;                       esi = garbage
        !           603: ;                       edi = garbage
        !           604: 
        !           605:         mov     strip.ST_ptlStart.ptl_x, ecx
        !           606:         mov     strip.ST_ptlStart.ptl_y, eax
        !           607: 
        !           608:         mov     eax, dM
        !           609:         mov     ecx, dN
        !           610:         mov     esi, eqGamma_lo
        !           611:         mov     edi, eqGamma_hi
        !           612: 
        !           613: 
        !           614: ; Register state:
        !           615: ;                       eax = dM
        !           616: ;                       ebx = fl
        !           617: ;                       ecx = dN
        !           618: ;                       edx = garbage
        !           619: ;                       esi = eqGamma_lo
        !           620: ;                       edi = eqGamma_hi
        !           621: 
        !           622:         lea     edx, [ecx + ecx]        ; if (2 * dN > dM)
        !           623:         cmp     edx, eax
        !           624:         mov     edx, y0                 ; Load y0 again
        !           625:         jbe     short after_half_flip
        !           626: 
        !           627:         test    ebx, (FL_STYLED + FL_DONT_DO_HALF_FLIP)
        !           628:         jnz     short after_half_flip
        !           629: 
        !           630:         or      ebx, FL_FLIP_HALF
        !           631:         mov     fl, ebx
        !           632: 
        !           633: ; Do a half flip!
        !           634: 
        !           635:         not     esi
        !           636:         not     edi
        !           637:         add     esi, eax
        !           638:         adc     edi, 0                  ; eqGamma = -eqGamma - 1 + dM
        !           639: 
        !           640:         neg     ecx
        !           641:         add     ecx, eax                ; dN = dM - dN
        !           642: 
        !           643:         neg     edx
        !           644:         add     edx, x0                 ; y0 = x0 - y0
        !           645: 
        !           646: after_half_flip:
        !           647:         mov     strip.ST_flFlips, ebx
        !           648:         mov     eax, dM
        !           649: 
        !           650: ; Register state:
        !           651: ;                       eax = dM
        !           652: ;                       ebx = fl
        !           653: ;                       ecx = dN
        !           654: ;                       edx = y0
        !           655: ;                       esi = eqGamma_lo
        !           656: ;                       edi = eqGamma_hi
        !           657: 
        !           658:         or      ecx, ecx
        !           659:         jz      short zero_slope
        !           660: 
        !           661: compute_dda_stuff:
        !           662:         inc     edx
        !           663:         mul     edx
        !           664:         stc                             ; set the carry to accomplish -1
        !           665:         sbb     eax, esi
        !           666:         sbb     edx, edi                ; (y0 + 1) * dM - eqGamma - 1
        !           667:         div     ecx
        !           668: 
        !           669:         mov     esi, eax                ; esi = i
        !           670:         mov     edi, edx                ; edi = r
        !           671: 
        !           672:         xor     edx, edx
        !           673:         mov     eax, dM
        !           674:         div     ecx                     ; edx = d_R, eax = d_I
        !           675:         mov     d_I, eax
        !           676: 
        !           677:         sub     esi, x0
        !           678:         inc     esi
        !           679: 
        !           680: done_dda_stuff:
        !           681: 
        !           682: ; Register state:
        !           683: ;                       eax = d_I
        !           684: ;                       ebx = fl
        !           685: ;                       ecx = dN
        !           686: ;                       edx = d_R
        !           687: ;                       esi = i
        !           688: ;                       edi = r
        !           689: 
        !           690: ; We're going to decide if we can call the short-vector routines.  They
        !           691: ; can only take strips that have a maximum length of 15 pixels each.
        !           692: ; We happen to know that the longest strip in our line could be is d_I + 1.
        !           693: 
        !           694:         and     ebx, FL_STRIP_MASK
        !           695:         mov     eax, apfn
        !           696: 
        !           697:         .errnz  FL_STRIP_SHIFT
        !           698:         lea     eax, [eax + ebx * 4]
        !           699: 
        !           700:         cmp     d_I, MAX_SHORT_STROKE_LENGTH
        !           701:         sbb     ebx, ebx                ; ffffffffh when < 15, 0 when >= 15
        !           702:         and     ebx, NUM_STRIP_DRAW_DIRECTIONS * 4
        !           703:                                         ; Look four entries further into table
        !           704: 
        !           705:         mov     eax, [eax + ebx]
        !           706:         mov     pfn, eax
        !           707: 
        !           708:         lea     eax, [strip.ST_alStrips]
        !           709:         mov     ebx, cPels
        !           710: 
        !           711: ;-----------------------------------------------------------------------;
        !           712: ; Do our main DDA loop.                                                 ;
        !           713: ;-----------------------------------------------------------------------;
        !           714: 
        !           715: ; Register state:
        !           716: ;                       eax = plStrip
        !           717: ;                       ebx = cPels
        !           718: ;                       ecx = dN
        !           719: ;                       edx = d_R
        !           720: ;                       esi = i
        !           721: ;                       edi = r
        !           722: 
        !           723: dda_loop:
        !           724:         sub     ebx, esi
        !           725:         jle     final_strip
        !           726: 
        !           727:         mov     [eax], esi
        !           728:         add     eax, 4
        !           729:         cmp     plStripEnd, eax
        !           730:         jbe     short output_strips
        !           731: 
        !           732: done_output_strips:
        !           733:         mov     esi, d_I
        !           734:         add     edi, edx
        !           735:         cmp     edi, ecx
        !           736:         jb      short dda_loop
        !           737: 
        !           738:         sub     edi, ecx
        !           739:         inc     esi
        !           740:         jmp     short dda_loop
        !           741: 
        !           742: zero_slope:
        !           743:         mov     esi, 7fffffffh          ; Make run maximum length (cPels
        !           744:                                         ;   actually decideds how long the line
        !           745:                                         ;   is)
        !           746:         mov     d_I, 7fffffffh          ; Make delta maximum length so that
        !           747:                                         ; we don't try to do short vectors
        !           748:         mov     eax, cPels              ; We need this when we decide if to do
        !           749:         dec     eax                     ;   short strip routines.
        !           750:         jmp     short done_dda_stuff
        !           751: 
        !           752: ;-----------------------------------------------------------------------;
        !           753: ; Empty strips buffer.                                                  ;
        !           754: ;-----------------------------------------------------------------------;
        !           755: 
        !           756: output_strips:
        !           757:         mov     d_R, edx
        !           758:         mov     cPels, ebx
        !           759:         mov     i, esi
        !           760:         mov     r, edi
        !           761:         mov     dN, ecx
        !           762: 
        !           763:         lea     edx, [strip.ST_alStrips]
        !           764:         sub     eax, edx
        !           765:         shr     eax, 2
        !           766:         mov     strip.ST_cStrips, eax
        !           767: 
        !           768:         mov     eax, ppdev
        !           769:         lea     edx, [strip]
        !           770:         mov     ecx, pls
        !           771: 
        !           772:         ptrCall <dword ptr pfn>, \
        !           773:                 <eax, edx, ecx>
        !           774: 
        !           775:         mov     esi, i
        !           776:         mov     edi, r
        !           777:         mov     ebx, cPels
        !           778:         mov     edx, d_R
        !           779:         mov     ecx, dN
        !           780:         lea     eax, [strip.ST_alStrips]
        !           781:         jmp     done_output_strips
        !           782: 
        !           783: ;-----------------------------------------------------------------------;
        !           784: ; Empty strips buffer and go on to next line.                           ;
        !           785: ;-----------------------------------------------------------------------;
        !           786: 
        !           787: final_strip:
        !           788:         add     ebx, esi
        !           789:         mov     [eax], ebx
        !           790:         add     eax, 4
        !           791: 
        !           792: very_final_strip:
        !           793:         lea     edx, [strip.ST_alStrips]
        !           794:         sub     eax, edx
        !           795:         shr     eax, 2
        !           796:         mov     strip.ST_cStrips, eax
        !           797: 
        !           798:         mov     eax, ppdev
        !           799:         lea     edx, [strip]
        !           800:         mov     ecx, pls
        !           801: 
        !           802:         ptrCall   <dword ptr pfn>, \
        !           803:                 <eax, edx, ecx>
        !           804: 
        !           805: next_line:
        !           806:         mov     ebx, flStart
        !           807:         testb   ebx, FL_COMPLEX_CLIP
        !           808:         jnz     short see_if_done_complex_clipping
        !           809: 
        !           810:         mov     edx, pptfxBuf
        !           811:         cmp     edx, pptfxBufEnd
        !           812:         je      short all_done
        !           813: 
        !           814:         mov     esi, [edx].ptl_x
        !           815:         mov     ecx, [edx].ptl_y
        !           816:         add     edx, size POINTL
        !           817:         mov     pptfxBuf, edx
        !           818:         mov     eax, [edx].ptl_x
        !           819:         mov     edi, [edx].ptl_y
        !           820:         jmp     the_main_loop
        !           821: 
        !           822: all_done:
        !           823:         mov     eax, 1
        !           824: 
        !           825:         cRet    bLines
        !           826: 
        !           827: see_if_done_complex_clipping:
        !           828:         mov     ebx, fl
        !           829:         dec     cptfx
        !           830:         jz      short all_done
        !           831:         jmp     continue_complex_clipping
        !           832: 
        !           833: ;---------------------------Private-Routine-----------------------------;
        !           834: ; do_some_styling
        !           835: ;
        !           836: ; Inputs:
        !           837: ;       eax = ptlStart.ptl_y
        !           838: ;       ebx = fl
        !           839: ;       ecx = ptlStart.ptl_x
        !           840: ; Preserves:
        !           841: ;       eax, ebx, ecx
        !           842: ; Output:
        !           843: ;       Exits to done_styling.
        !           844: ;
        !           845: ;-----------------------------------------------------------------------;
        !           846: 
        !           847: do_some_styling:
        !           848:         mov     ptlStart.ptl_x, ecx
        !           849: 
        !           850:         mov     esi, pls
        !           851:         mov     edi, [esi].LS_spNext    ; spThis
        !           852:         mov     edx, edi
        !           853:         add     edx, cStylePels         ; spNext
        !           854: 
        !           855: ; For styles, we don't bother to keep the style position normalized.
        !           856: ; (we do ensure that it's positive, though).  If a figure is over 2
        !           857: ; billion pels long, we'll be a pel off in our style state (oops!).
        !           858: 
        !           859:         and     edx, 7fffffffh
        !           860:         mov     [esi].LS_spNext, edx
        !           861:         mov     ptlStart.ptl_y, eax
        !           862: 
        !           863: ; Do arbitrary styles:
        !           864: 
        !           865: do_arbitrary_style:
        !           866:         testb   ebx, FL_FLIP_H
        !           867:         jz      short arbitrary_left_to_right
        !           868: 
        !           869:         sub     edx, x0
        !           870:         add     edx, xStart
        !           871:         mov     eax, edx
        !           872:         xor     edx, edx
        !           873:         div     [esi].LS_spTotal
        !           874: 
        !           875:         neg     edx
        !           876:         jge     short continue_right_to_left
        !           877:         add     edx, [esi].LS_spTotal
        !           878:         not     eax
        !           879: 
        !           880: continue_right_to_left:
        !           881:         mov     edi, dword ptr [esi].LS_jStartMask
        !           882:         not     edi
        !           883:         mov     ecx, [esi].LS_aspRtoL
        !           884:         jmp     short compute_arbitrary_stuff
        !           885: 
        !           886: arbitrary_left_to_right:
        !           887:         add     edi, x0
        !           888:         sub     edi, xStart
        !           889:         mov     eax, edi
        !           890:         xor     edx, edx
        !           891:         div     [esi].LS_spTotal
        !           892:         mov     edi, dword ptr [esi].LS_jStartMask
        !           893:         mov     ecx, [esi].LS_aspLtoR
        !           894: 
        !           895: compute_arbitrary_stuff:
        !           896: ;       eax = sp / spTotal
        !           897: ;       ebx = fl
        !           898: ;       ecx = pspStart
        !           899: ;       edx = sp % spTotal
        !           900: ;       esi = pla
        !           901: ;       edi = jStyleMask
        !           902: 
        !           903:         and     eax, [esi].LS_cStyle        ; if odd length style and second run
        !           904:         and     al, 1                       ; through style array, flip the
        !           905:         jz      short odd_style_array_done  ; meaning of the elements
        !           906:         not     edi
        !           907: 
        !           908: odd_style_array_done:
        !           909:         mov     [esi].LS_pspStart, ecx
        !           910:         mov     eax, [esi].LS_cStyle
        !           911:         lea     eax, [ecx + eax * 4 - 4]
        !           912:         mov     [esi].LS_pspEnd, eax
        !           913: 
        !           914: find_psp:
        !           915:         sub     edx, [ecx]
        !           916:         jl      short found_psp
        !           917:         add     ecx, 4
        !           918:         jmp     short find_psp
        !           919: 
        !           920: found_psp:
        !           921:         mov     [esi].LS_psp, ecx
        !           922:         neg     edx
        !           923:         mov     [esi].LS_spRemaining, edx
        !           924: 
        !           925:         sub     ecx, [esi].LS_pspStart
        !           926:         test    ecx, 4                  ; size STYLEPOS
        !           927:         jz      short done_arbitrary
        !           928:         not     edi
        !           929: 
        !           930: done_arbitrary:
        !           931:         mov     dword ptr [esi].LS_jStyleMask, edi
        !           932:         mov     eax, ptlStart.ptl_y
        !           933:         mov     ecx, ptlStart.ptl_x
        !           934:         jmp     done_styling
        !           935: 
        !           936: 
        !           937: ;---------------------------Private-Routine-----------------------------;
        !           938: ; do_some_clipping
        !           939: ;
        !           940: ; Inputs:
        !           941: ;       eax = garbage
        !           942: ;       ebx = fl
        !           943: ;       ecx = x0
        !           944: ;       edx = garbage
        !           945: ;       esi = x1
        !           946: ;       edi = garbage
        !           947: ;
        !           948: ; Decides whether to do simple or complex clipping.
        !           949: ;
        !           950: ;-----------------------------------------------------------------------;
        !           951: 
        !           952:         align 4
        !           953: 
        !           954:         public  do_some_clipping
        !           955: do_some_clipping:
        !           956:         testb   ebx, FL_COMPLEX_CLIP
        !           957:         jnz     initialize_complex_clipping
        !           958: 
        !           959: ;-----------------------------------------------------------------------;
        !           960: ; simple_clipping
        !           961: ;
        !           962: ; Inputs:
        !           963: ;       ebx = fl
        !           964: ;       ecx = x0
        !           965: ;       esi = x1
        !           966: ; Output:
        !           967: ;       ebx = fl
        !           968: ;       ecx = new x0 (stack variable updated too)
        !           969: ;       esi = new x1
        !           970: ;       y0 stack variable updated
        !           971: ; Uses:
        !           972: ;       All registers
        !           973: ; Exits:
        !           974: ;       to done_clipping
        !           975: ;
        !           976: ; This routine handles clipping the line to the clip rectangle (it's
        !           977: ; faster to handle this case in the driver than to call the engine to
        !           978: ; clip for us).
        !           979: ;
        !           980: ; Fractional end-point lines complicate our lives a bit when doing
        !           981: ; clipping:
        !           982: ;
        !           983: ; 1) For styling, we must know the unclipped line's length in pels, so
        !           984: ;    that we can correctly update the styling state when the line is
        !           985: ;    clipped.  For this reason, I do clipping after doing the hard work
        !           986: ;    of figuring out which pixels are at the ends of the line (this is
        !           987: ;    wasted work if the line is not styled and is completely clipped,
        !           988: ;    but I think it's simpler this way).  Another reason is that we'll
        !           989: ;    have calculated eqGamma already, which we use for the intercept
        !           990: ;    calculations.
        !           991: ;
        !           992: ;    With the assumption that most lines will not be completely clipped
        !           993: ;    away, this strategy isn't too painful.
        !           994: ;
        !           995: ; 2) x0, y0 are not necessarily zero, where (x0, y0) is the start pel of
        !           996: ;    the line.
        !           997: ;
        !           998: ; 3) We know x0, y0 and x1, but not y1.  We haven't needed to calculate
        !           999: ;    y1 until now.  We'll need the actual value, and not an upper bound
        !          1000: ;    like y1 = LFLOOR(dM) + 2 because we have to be careful when
        !          1001: ;    calculating x(y) that y0 <= y <= y1, otherwise we can cause an
        !          1002: ;    overflow on the divide (which, needless to say, is bad).
        !          1003: ;
        !          1004: ;-----------------------------------------------------------------------;
        !          1005: 
        !          1006:         public  simple_clipping
        !          1007: simple_clipping:
        !          1008:         mov     edi, prclClip           ; get pointer to normalized clip rect
        !          1009:         and     ebx, FL_RECTLCLIP_MASK  ;   (it's lower-right exclusive)
        !          1010: 
        !          1011:         .errnz  (FL_RECTLCLIP_SHIFT - 2); ((ebx AND FL_RECTLCLIP_MASK) shr
        !          1012:         .errnz  (size RECTL) - 16       ;   FL_RECTLCLIP_SHIFT) is our index
        !          1013:         lea     edi, [edi + ebx*4]      ;   into the array of rectangles
        !          1014: 
        !          1015:         mov     edx, [edi].xRight       ; load the rect coordinates
        !          1016:         mov     eax, [edi].xLeft
        !          1017:         mov     ebx, [edi].yBottom
        !          1018:         mov     edi, [edi].yTop
        !          1019: 
        !          1020: ; Translate to our origin and so some quick completely clipped tests:
        !          1021: 
        !          1022:         sub     edx, x
        !          1023:         cmp     ecx, edx
        !          1024:         jge     totally_clipped         ; totally clipped if x0 >= xRight
        !          1025: 
        !          1026:         sub     eax, x
        !          1027:         cmp     esi, eax
        !          1028:         jl      totally_clipped         ; totally clipped if x1 < xLeft
        !          1029: 
        !          1030:         sub     ebx, y
        !          1031:         cmp     y0, ebx
        !          1032:         jge     totally_clipped         ; totally clipped if y0 >= yBottom
        !          1033: 
        !          1034:         sub     edi, y
        !          1035: 
        !          1036: ; Save some state:
        !          1037: 
        !          1038:         mov     xClipRight, edx
        !          1039:         mov     xClipLeft, eax
        !          1040: 
        !          1041:         cmp     esi, edx                ; if (x1 >= xRight) x1 = xRight - 1
        !          1042:         jl      short calculate_y1
        !          1043:         lea     esi, [edx - 1]
        !          1044: 
        !          1045: calculate_y1:
        !          1046:         mov     eax, esi                ; y1 = (x1 * dN + eqGamma) / dM
        !          1047:         mul     dN
        !          1048:         add     eax, eqGamma_lo
        !          1049:         adc     edx, eqGamma_hi
        !          1050:         div     dM
        !          1051: 
        !          1052:         cmp     edi, eax                ; if (yTop > y1) clipped
        !          1053:         jg      short totally_clipped
        !          1054: 
        !          1055:         cmp     ebx, eax                ; if (yBottom > y1) know x1
        !          1056:         jg      short x1_computed
        !          1057: 
        !          1058:         mov     eax, ebx                ; x1 = (yBottom * dM + eqBeta) / dN
        !          1059:         mul     dM
        !          1060:         stc
        !          1061:         sbb     eax, eqGamma_lo
        !          1062:         sbb     edx, eqGamma_hi
        !          1063:         div     dN
        !          1064:         mov     esi, eax
        !          1065: 
        !          1066: ; At this point, we've taken care of calculating the intercepts with the
        !          1067: ; right and bottom edges.  Now we work on the left and top edges:
        !          1068: 
        !          1069: x1_computed:
        !          1070:         mov     edx, y0
        !          1071: 
        !          1072:         mov     eax, xClipLeft          ; don't have to compute y intercept
        !          1073:         cmp     eax, ecx                ;   at left edge if line starts to
        !          1074:         jle     short top_intercept     ;   right of left edge
        !          1075: 
        !          1076:         mov     ecx, eax                ; x0 = xLeft
        !          1077:         mul     dN                      ; y0 = (xLeft * dN + eqGamma) / dM
        !          1078:         add     eax, eqGamma_lo
        !          1079:         adc     edx, eqGamma_hi
        !          1080:         div     dM
        !          1081: 
        !          1082:         cmp     ebx, eax                ; if (yBottom <= y0) clipped
        !          1083:         jle     short totally_clipped
        !          1084: 
        !          1085:         mov     edx, eax
        !          1086:         mov     y0, eax
        !          1087: 
        !          1088: top_intercept:
        !          1089:         mov     ebx, fl                 ; get ready to leave
        !          1090:         mov     x0, ecx
        !          1091: 
        !          1092:         cmp     edi, edx                ; if (yTop <= y0) done clipping
        !          1093:         jle     done_clipping
        !          1094: 
        !          1095:         mov     eax, edi                ; x0 = (yTop * dM + eqBeta) / dN + 1
        !          1096:         mul     dM
        !          1097:         stc
        !          1098:         sbb     eax, eqGamma_lo
        !          1099:         sbb     edx, eqGamma_hi
        !          1100:         div     dN
        !          1101:         lea     ecx, [eax + 1]
        !          1102: 
        !          1103:         cmp     xClipRight, ecx         ; if (xRight <= x0) clipped
        !          1104:         jle     short totally_clipped
        !          1105: 
        !          1106:         mov     y0, edi                 ; y0 = yTop
        !          1107:         mov     x0, ecx
        !          1108:         jmp     done_clipping           ; all done!
        !          1109: 
        !          1110: totally_clipped:
        !          1111: 
        !          1112: ; The line is completely clipped.  See if we have to update our style state:
        !          1113: 
        !          1114:         mov     ebx, fl
        !          1115:         testb   ebx, FL_STYLED
        !          1116:         jz      next_line
        !          1117: 
        !          1118: ; Adjust our style state:
        !          1119: 
        !          1120:         mov     esi, pls
        !          1121:         mov     eax, [esi].LS_spNext
        !          1122:         add     eax, cStylePels
        !          1123:         mov     [esi].LS_spNext, eax
        !          1124: 
        !          1125:         cmp     eax, [esi].LS_spTotal2
        !          1126:         jb      next_line
        !          1127: 
        !          1128: ; Have to normalize first:
        !          1129: 
        !          1130:         xor     edx, edx
        !          1131:         div     [esi].LS_spTotal2
        !          1132:         mov     [esi].LS_spNext, edx
        !          1133: 
        !          1134:         jmp     next_line
        !          1135: 
        !          1136: ;-----------------------------------------------------------------------;
        !          1137: 
        !          1138: initialize_complex_clipping:
        !          1139:         mov     eax, dN                 ; save a copy of original dN
        !          1140:         mov     dN_Original, eax
        !          1141: 
        !          1142: ;---------------------------Private-Routine-----------------------------;
        !          1143: ; continue_complex_clipping
        !          1144: ;
        !          1145: ; Inputs:
        !          1146: ;       ebx = fl
        !          1147: ; Output:
        !          1148: ;       ebx = fl
        !          1149: ;       ecx = x0
        !          1150: ;       esi = x1
        !          1151: ; Uses:
        !          1152: ;       All registers.
        !          1153: ; Exits:
        !          1154: ;       to done_clipping
        !          1155: ;
        !          1156: ; This routine handles the necessary initialization for the next
        !          1157: ; run in the CLIPLINE structure.
        !          1158: ;
        !          1159: ; NOTE: This routine is jumped to from two places!
        !          1160: ;-----------------------------------------------------------------------;
        !          1161: 
        !          1162:         public  continue_complex_clipping
        !          1163: continue_complex_clipping:
        !          1164:         mov     edi, prun
        !          1165:         mov     ecx, xStart
        !          1166:         testb   ebx, FL_FLIP_H
        !          1167:         jz      short complex_left_to_right
        !          1168: 
        !          1169: complex_right_to_left:
        !          1170: 
        !          1171: ; Figure out x0 and x1 for right-to-left lines:
        !          1172: 
        !          1173:         add     ecx, cStylePels
        !          1174:         dec     ecx
        !          1175:         mov     esi, ecx                ; esi = ecx = xStart + cStylePels - 1
        !          1176:         sub     ecx, [edi].RUN_iStop    ; New x0
        !          1177:         sub     esi, [edi].RUN_iStart   ; New x1
        !          1178:         jmp     short complex_reset_variables
        !          1179: 
        !          1180: complex_left_to_right:
        !          1181: 
        !          1182: ; Figure out x0 and x1 for left-to-right lines:
        !          1183: 
        !          1184:         mov     esi, ecx                ; esi = ecx = xStart
        !          1185:         add     ecx, [edi].RUN_iStart   ; New x0
        !          1186:         add     esi, [edi].RUN_iStop    ; New x1
        !          1187: 
        !          1188: complex_reset_variables:
        !          1189:         mov     x0, ecx
        !          1190: 
        !          1191: ; The half flip mucks with some of our variables, and we have to reset
        !          1192: ; them every pass.  We would have to reset eqGamma too, but it never
        !          1193: ; got saved to memory in its modified form.
        !          1194: 
        !          1195:         add     edi, size RUN
        !          1196:         mov     prun, edi               ; Increment run pointer for next time
        !          1197: 
        !          1198:         mov     edi, pls
        !          1199:         mov     eax, [edi].LS_spComplex
        !          1200:         mov     [edi].LS_spNext, eax    ; pls->spNext = pls->spComplex
        !          1201: 
        !          1202:         mov     eax, dN_Original        ; dN = dN_Original
        !          1203:         mov     dN, eax
        !          1204: 
        !          1205:         mul     ecx
        !          1206:         add     eax, eqGamma_lo
        !          1207:         adc     edx, eqGamma_hi         ; [edx:eax] = dN*x0 + eqGamma
        !          1208: 
        !          1209:         div     dM
        !          1210:         mov     y0, eax
        !          1211:         jmp     done_clipping
        !          1212: 
        !          1213: endProc bLines
        !          1214:         end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.