Annotation of ntddk/src/video/displays/s3/i386/lines.asm, revision 1.1.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.