
#include "asm_mac.i"

func clearBitmapBuffer
    move.l 4(%sp),%a0           // a0 = buffer
    lea 20480(%a0),%a0          // a0 = buffer end

    movm.l %d2-%d7/%a2-%a6,-(%sp)

    // the function consume about 43200 cycles to clear the whole bitmap buffer

    moveq #0,%d1
    move.l %d1,%d2
    move.l %d1,%d3
    move.l %d1,%d4
    move.l %d1,%d5
    move.l %d1,%d6
    move.l %d1,%d7
    move.l %d1,%a1
    move.l %d1,%a2
    move.l %d1,%a3
    move.l %d1,%a4
    move.l %d1,%a5
    move.l %d1,%a6

    moveq #38,%d0

.L01:
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    dbra %d0,.L01

    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a6,-(%a0)
    movm.l %d1-%d7/%a1-%a4,-(%a0)

    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts


func copyBitmapBuffer
    move.l 4(%sp),%a0           // a0 = src
    move.l 8(%sp),%a1           // a1 = dest

    movm.l %d2-%d7/%a2-%a6,-(%sp)

    // first 32 bytes transfer
    // remaing 20448 bytes to copy
    // the function consume about 92000 cycles to copy the whole bitmap buffer

    lea 20480(%a1),%a1          // a1 = dest end

    movm.l 20448(%a0),%d1-%d7/%a2
    movm.l %d1-%d7/%a2,-(%a1)

    lea    20400(%a0),%a0       // a0 = src end - (48 + 32)

    moveq #41,%d0               // 42 * (48 bytes * 10) = 42 * 480 = 20160 (/20448)

.L02:
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)       // 216 cycles for 48 bytes copy
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)

    dbra %d0,.L02

    // 288 bytes remaining = 6 * 48

    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    lea    -48(%a0),%a0
    movm.l %d1-%d7/%a2-%a6,-(%a1)
    movm.l (%a0),%d1-%d7/%a2-%a6
    movm.l %d1-%d7/%a2-%a6,-(%a1)

    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts


func BMP_setPixelFastA
    moveq   #-1,%d1                         // d1 = 0xFFFFFFFF
    move.w  6(%sp),%d0                      // d0 = X
    move.w  10(%sp),%d1                     // d1 = Y

.spf_01:
    lsl.w   #7,%d1
    lsr.w   #1,%d0
    jcs     .spf_x_odd

.spf_x_even:
    add.w   %d0,%d1
    add.w   bmp_buffer_write+2,%d1
    move.l  %d1,%a0                         // a0 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.b  15(%sp),%d1                     // d1 = col

    move.b  (%a0),%d0                       // d0 = *dst
    and.b   #0x0F,%d0
    and.b   #0xF0,%d1
    or.b    %d1,%d0
    move.b  %d0,(%a0)                       // *dst = (*dst & 0x0F) // (col & 0xF0);

    rts

.spf_x_odd:
    add.w   %d0,%d1
    add.w   bmp_buffer_write+2,%d1
    move.l  %d1,%a0                         // a0 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.b  15(%sp),%d1                     // d1 = col

    move.b  (%a0),%d0                       // d0 = *dst
    and.b   #0xF0,%d0
    and.b   #0x0F,%d1
    or.b    %d1,%d0
    move.b  %d0,(%a0)                       // *dst = (*dst & 0xF0) // (col & 0x0F);

    rts


func BMP_setPixelA
    moveq   #-1,%d1                         // d1 = 0xFFFFFFFF
    move.w  6(%sp),%d0                      // d0.w = X
    move.w  10(%sp),%d1                     // d1.w = Y

    cmp.w   #256,%d0
    jcc     .sp_01
    cmp.w   #160,%d1
    jcs     .spf_01

.sp_01:
    rts


func BMP_setPixelsFast_V2D
    move.l  4(%sp),%a0                      // a0 = crd
    move.b  11(%sp),%d1                     // d1 = col
    move.w  14(%sp),%d0                     // d0 = num
    subq.w  #1,%d0

    movem.l %d2-%d6/%a2,-(%sp)

    move.l  bmp_buffer_write,%a2            // a2 = bmp_buffer_write
    move.b  #0x0F,%d3
    move.b  #0xF0,%d4
    move.b  %d1,%d5
    move.b  %d1,%d6
    and.b   %d3,%d5                         // d5 = col & 0x0F = cd
    and.b   %d4,%d6                         // d6 = col & 0xF0 = cu

.spsfv_loop:
    move.w  (%a0)+,%d1                      // d1 = X
    move.w  (%a0)+,%d2                      // d2 = Y

    lsl.w   #7,%d2
    lsr.w   #1,%d1
    jcs     .spsfv_x_odd

.spsfv_x_even:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d3,%d2
    or.b    %d6,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // cu;

    dbra.w  %d0,.spsfv_loop

    movem.l (%sp)+,%d2-%d6/%a2
    rts

.spsfv_x_odd:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d4,%d2
    or.b    %d5,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0xF0) // cd;

    dbra.w  %d0,.spsfv_loop

    movem.l (%sp)+,%d2-%d6/%a2
    rts


func BMP_setPixels_V2D
    move.l  4(%sp),%a0                      // a0 = crd
    move.b  11(%sp),%d1                     // d1 = col
    move.w  14(%sp),%d0                     // d0 = num
    subq.w  #1,%d0

    movem.l %d2-%d6/%a2-%a4,-(%sp)

    move.l  bmp_buffer_write,%a2            // a2 = bmp_buffer_write
    move.b  #0x0F,%d3
    move.b  #0xF0,%d4
    move.b  %d1,%d5
    move.b  %d1,%d6
    and.b   %d3,%d5                         // d5 = col & 0x0F = cd
    and.b   %d4,%d6                         // d6 = col & 0xF0 = cu
    move.w  #256,%a3
    move.w  #160,%a4

.spsv_loop:
    move.w  (%a0)+,%d1                      // d1 = X
    move.w  (%a0)+,%d2                      // d2 = Y

    cmp.w   %a3,%d1
    jcc     .spsv_01
    cmp.w   %a4,%d2
    jcs     .spsv_02

.spsv_01:
    dbra.w  %d0,.spsv_loop

    movem.l (%sp)+,%d2-%d6/%a2-%a4
    rts

.spsv_02:
    lsl.w   #7,%d2
    lsr.w   #1,%d1
    jcs     .spsv_x_odd

.spsv_x_even:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d3,%d2
    or.b    %d6,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // cu;

    dbra.w  %d0,.spsv_loop

    movem.l (%sp)+,%d2-%d6/%a2-%a4
    rts

.spsv_x_odd:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d4,%d2
    or.b    %d5,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0xF0) // cd;

    dbra.w  %d0,.spsv_loop

    movem.l (%sp)+,%d2-%d6/%a2-%a4
    rts


func BMP_setPixelsFast
    move.l  4(%sp),%a0                      // a0 = pixels
    move.w  10(%sp),%d0                     // d0 = num
    subq.w  #1,%d0

    movem.l %d2-%d4/%a2,-(%sp)

    move.l  bmp_buffer_write,%a2            // a2 = bmp_buffer_write
    move.b  #0x0F,%d3
    move.b  #0xF0,%d4

.spsf_loop:
    move.w  (%a0)+,%d1                      // d1 = X
    move.w  (%a0)+,%d2                      // d2 = Y

    lsl.w   #7,%d2
    lsr.w   #1,%d1
    jcs     .spsf_x_odd

.spsf_x_even:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.w  (%a0)+,%d1                      // d1 = col

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d3,%d2
    and.b   %d4,%d1
    or.b    %d1,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // (col & 0xF0);

    dbra.w  %d0,.spsf_loop

    movem.l (%sp)+,%d2-%d4/%a2
    rts

.spsf_x_odd:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.w  (%a0)+,%d1                      // d1 = col

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d4,%d2
    and.b   %d3,%d1
    or.b    %d1,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // (col & 0xF0);

    dbra.w  %d0,.spsf_loop

    movem.l (%sp)+,%d2-%d4/%a2
    rts


func BMP_setPixels
    move.l  4(%sp),%a0                      // a0 = pixels
    move.w  10(%sp),%d0                     // d0 = num
    subq.w  #1,%d0

    movem.l %d2-%d6/%a2,-(%sp)

    move.l  bmp_buffer_write,%a2            // a2 = bmp_buffer_write
    move.b  #0x0F,%d3
    move.b  #0xF0,%d4
    move.w  #256,%d5
    move.w  #160,%d6

.sps_loop:
    move.w  (%a0)+,%d1                      // d1 = X
    move.w  (%a0)+,%d2                      // d2 = Y

    cmp.w   %d5,%d1
    jcc     .sps_01
    cmp.w   %d6,%d2
    jcs     .sps_02

.sps_01:
    move.w  (%a0)+,%d1                      // d1 = col (ignore)
    dbra.w  %d0,.sps_loop

    movem.l (%sp)+,%d2-%d6/%a2
    rts

.sps_02:
    lsl.w   #7,%d2
    lsr.w   #1,%d1
    jcs     .sps_x_odd

.sps_x_even:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.w  (%a0)+,%d1                      // d1 = col

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d3,%d2
    and.b   %d4,%d1
    or.b    %d1,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // (col & 0xF0);

    dbra.w  %d0,.sps_loop

    movem.l (%sp)+,%d2-%d6/%a2
    rts

.sps_x_odd:
    add.w   %d1,%d2
    lea.l   (%a2,%d2.w),%a1                 // a1 = dst = &bmp_buffer_write[(y * BMP_PITCH) + (x >> 1)]
    move.w  (%a0)+,%d1                      // d1 = col

    move.b  (%a1),%d2                       // d2 = *dst
    and.b   %d4,%d2
    and.b   %d3,%d1
    or.b    %d1,%d2
    move.b  %d2,(%a1)                       // *dst = (*dst & 0x0F) // (col & 0xF0);

    dbra.w  %d0,.sps_loop

    movem.l (%sp)+,%d2-%d6/%a2
    rts


func BMP_clipLine
    movm.l %d2-%d7,-(%sp)

    move.l 28(%sp),%a0          // a0 = &line

    movm.w (%a0),%d2-%d5        // d2 = x1, d3 = y1, d4 = x2, d5 = y2

    move.w #255,%d0             // d0 = BMP_WIDTH - 1
    move.w #159,%d1             // d1 = BMP_HEIGHT - 1

    cmp.w %d0,%d2               // if (((u16) x1 < BMP_WIDTH) &&
    jhi .L50
    cmp.w %d0,%d4               //     ((u16) x2 < BMP_WIDTH) &&
    jhi .L50
    cmp.w %d1,%d3               //     ((u16) y1 < BMP_HEIGHT) &&
    jhi .L50
    cmp.w %d1,%d5               //     ((u16) y2 < BMP_HEIGHT))
    jhi .L50

    movm.w %d2-%d5,(%a0)        //   update line
    moveq #1,%d0                //   return 1;
    movm.l (%sp)+,%d2-%d7
    rts

.L60:
    move.w %d4,%d6
    sub.w %d2,%d6               // d6 = dx = x2 - x1;
    move.w %d5,%d7
    sub.w %d3,%d7               // d7 = dy = y2 - y1;

    tst.w %d2                   // if (x1 < 0)
    jge .L38                    // {

    muls.w %d7,%d2              //   y1 -= (x1 * dy) / dx;
    divs.w %d6,%d2
    sub.w %d2,%d3
    moveq #0,%d2                //   x1 = 0;
    jra .L39                    // }

.L38:
    cmp.w %d0,%d2               // else if (x1 >= BMP_WIDTH)
    jle .L39                    // {

    sub.w %d0,%d2
    muls.w %d7,%d2              //   y1 -= ((x1 - (BMP_WIDTH - 1)) * dy) / dx;
    divs.w %d6,%d2
    sub.w %d2,%d3
    move.w %d0,%d2              //   x1 = BMP_WIDTH - 1;
                                // }
.L39:
    tst.w %d4                   // if (x2 < 0)
    jge .L41                    // {

    muls.w %d7,%d4              //   y2 -= (x2 * dy) / dx;
    divs.w %d6,%d4
    sub.w %d4,%d5
    moveq #0,%d4                //   x2 = 0;
    jra .L42                    // }

.L41:
    cmp.w %d0,%d4               // else if (x2 >= BMP_WIDTH)
    jle .L42                    // {

    sub.w %d0,%d4
    muls.w %d7,%d4              //   y2 -= ((x2 - (BMP_WIDTH - 1)) * dy) / dx;
    divs.w %d6,%d4
    sub.w %d4,%d5
    move.w %d0,%d4              //   x2 = BMP_WIDTH - 1;
                                // }
.L42:
    tst.w %d3                   // if (y1 < 0)
    jge .L44                    // {

    muls.w %d6,%d3              //   x1 -= (y1 * dx) / dy;
    divs.w %d7,%d3
    sub.w %d3,%d2
    moveq #0,%d3                //   y1 = 0;
    jra .L45                    // }

.L44:
    cmp.w %d1,%d3               // else if (y1 >= BMP_HEIGHT)
    jle .L45                    // {

    sub.w %d1,%d3
    muls.w %d6,%d3              //   x1 -= ((y1 - (BMP_HEIGHT - 1)) * dx) / dy;
    divs.w %d7,%d3
    sub.w %d3,%d2
    move.w %d1,%d3              //   y1 = BMP_HEIGHT - 1;

.L45:                            // }
    tst.w %d5                   // if (y2 < 0)
    jge .L47                    // {

    muls.w %d6,%d5              //   x2 -= (y2 * dx) / dy;
    divs.w %d7,%d5
    sub.w %d5,%d4
    moveq #0,%d5                //   y2 = 0;
    jra .L48                    // }

.L47:
    cmp.w %d1,%d5               // else if (y2 >= BMP_HEIGHT)
    jle .L48                    // {

    sub.w %d1,%d5
    muls.w %d6,%d5              //   x2 -= ((y2 - (BMP_HEIGHT - 1)) * dx) / dy;
    divs.w %d7,%d5
    sub.w %d5,%d4
    move.w %d1,%d5              //   y2 = BMP_HEIGHT - 1;
                                // }
.L48:
    cmp.w %d0,%d2               // if (((u16) x1 < BMP_WIDTH) &&
    jhi .L50
    cmp.w %d0,%d4               //     ((u16) x2 < BMP_WIDTH) &&
    jhi .L50
    cmp.w %d1,%d3               //     ((u16) y1 < BMP_HEIGHT) &&
    jhi .L50
    cmp.w %d1,%d5               //     ((u16) y2 < BMP_HEIGHT))
    jhi .L50                    // {

    movm.w %d2-%d5,(%a0)        //   update line
    moveq #1,%d0                //   return 1;
    movm.l (%sp)+,%d2-%d7
    rts                         // }

.L50:
    tst.w %d2                   // if (((x1 < 0) && (x2 < 0)) ////
    jge .L53
    tst.w %d4
    jlt .L52

.L53:
    cmp.w %d0,%d2               //     ((x1 >= BMP_WIDTH) && (x2 >= BMP_WIDTH)) ////
    jle .L54
    cmp.w %d0,%d4
    jgt .L52

.L54:
    tst.w %d3                   //     ((y1 < 0) && (y2 < 0)) ////
    jge .L55
    tst.w %d5
    jlt .L52

.L55:
    cmp.w %d1,%d3               //     ((y1 >= BMP_HEIGHT) && (y2 >= BMP_HEIGHT)))
    jle .L60
    cmp.w %d1,%d5
    jle .L60

.L52:
    moveq #0,%d0                //   return 0;
    movm.l (%sp)+,%d2-%d7
    rts


func BMP_drawLine
    movem.l %d2-%d7/%a2-%a5,-(%sp)

    move.l  44(%sp),%a0     // a0 = &line
    movem.w (%a0)+,%d2-%d6  // d2 = x1, d3 = y1, d4 = x2, d5 = y2, d6 = col

.dl_start:
    moveq   #1,%d0          // d0 = stepx = 1
    move.w  #128,%d1        // d1 = stepy = BMP_PITCH;

    sub.w   %d2,%d4         // d4 = deltax
    jge     .dl_01          // {

    neg.w   %d4             //     deltax = -deltax;
    neg.w   %d0             //     stepx = -stepx;
                            // }
.dl_01:
    sub.w   %d3,%d5         // d5 = deltay
    jge     .dl_02          // {

    neg.w   %d5             //     deltay = -deltay;
    neg.w   %d1             //     stepy = -stepy;
                            // }
.dl_02:                     //
    move.w  %d0,%a2         // a2 = stepx
    move.w  %d1,%a3         // a3 = stepy
    move.w  %d4,%a4         // a4 = dx
    move.w  %d5,%a5         // a5 = dy

    move.l  bmp_buffer_write,%d7
    lsl.w   #7,%d3
    add.w   %d3,%d7         // d7.l = &bmp_buffer_write[y1 * BMP_PITCH]
    move.l  %d7,%a0         // a0 = *dst = &bmp_buffer_write[y1 * BMP_PITCH]

    moveq   #-0x10,%d0      // d0 = mu = 0xF0
    moveq   #0x0F,%d1       // d1 = md = 0x0F
    move.b  %d6,%d7
    and.b   %d0,%d6         // d6 = cu = col & mu
    and.b   %d1,%d7         // d7 = cd = col & md


    cmp.w   %d4,%d5         // if (deltax < deltay)
    jge     .dl_on_dy       // {

.dl_on_dx:
    move.w  %d4,%d3         //   d2 = x
    asr.w   #1,%d3          //   d3 = delta = dx >> 1
                            //   d4 = cnt = dx

.dl_dx_loop:                //   while(cnt--)
    move.w  %d2,%d5         //   {
    lsr.w   #1,%d5          //     d5 = x >> 1
    jcs     .dl_dx_odd      //     if (x & 1)
                            //     {
.dl_dx_even:
    lea     (%a0,%d5.w),%a1 //       a1 = d = dst + (x >> 1)

    move.b  (%a1),%d5
    and.b   %d1,%d5
    or.b    %d6,%d5
    move.b  %d5,(%a1)       //       *d = (*d & md) // cu

    add.w   %a2,%d2         //       x += stepx
    sub.w   %a5,%d3         //       if ((delta -= dy) < 0)
    jpl     .dl_dx_even_1   //       {

    add.w   %a3,%a0         //         dst += stepy; (can be 16 bits as dst is in RAM)
    add.w   %a4,%d3         //         delta += dx;

.dl_dx_even_1:              //       }
    dbra    %d4,.dl_dx_loop //     }

.dl_end:
    movem.l (%sp)+,%d2-%d7/%a2-%a5
    rts
                            //     else
.dl_dx_odd:                 //     {
    lea     (%a0,%d5.w),%a1 //       a1 = d = dst + (x >> 1)

    move.b  (%a1),%d5
    and.b   %d0,%d5
    or.b    %d7,%d5
    move.b  %d5,(%a1)       //       *d = (*d & mu) // cd

    add.w   %a2,%d2         //       x += stepx
    sub.w   %a5,%d3         //       if ((delta -= dy) < 0)
    jpl     .dl_dx_odd_1    //       {

    add.w   %a3,%a0         //           dst += stepy; (can be 16 bits as dst is in RAM)
    add.w   %a4,%d3         //           delta += dx;

.dl_dx_odd_1:               //       }
    dbra    %d4,.dl_dx_loop //     }

    movem.l (%sp)+,%d2-%d7/%a2-%a5
    rts

.dl_on_dy:
    move.w  %d5,%d3         //   d2 = x
    asr.w   #1,%d3          //   d3 = delta = dy >> 1
    move.w  %d5,%d4         //   d4 = cnt = dy

.dl_dy_loop:                //   while(cnt--)
    move.w  %d2,%d5         //   {
    lsr.w   #1,%d5          //     d5 = x >> 1
    jcs     .dl_dy_odd      //     if (x & 1)
                            //     {
.dl_dy_even:
    lea     (%a0,%d5.w),%a1 //       a1 = d = dst + (x >> 1)

    move.b  (%a1),%d5
    and.b   %d1,%d5
    or.b    %d6,%d5
    move.b  %d5,(%a1)       //       *d = (*d & md) // cu

    add.w   %a3,%a0         //       dst += stepy; (can be 16 bits as dst is in RAM)
    sub.w   %a4,%d3         //       if ((delta -= dx) < 0)
    jpl     .dl_dy_even_1   //       {

    add.w   %a2,%d2         //         x += stepx
    add.w   %a5,%d3         //         delta += dy;

.dl_dy_even_1:              //       }
    dbra    %d4,.dl_dy_loop //     }

    movem.l (%sp)+,%d2-%d7/%a2-%a5
    rts
                            //     else
.dl_dy_odd:                 //     {
    lea     (%a0,%d5.w),%a1 //       a1 = d = dst + (x >> 1)

    move.b  (%a1),%d5
    and.b   %d0,%d5
    or.b    %d7,%d5
    move.b  %d5,(%a1)       //       *d = (*d & mu) // cd

    add.w   %a3,%a0         //       dst += stepy; (can be 16 bits as dst is in RAM)
    sub.w   %a4,%d3         //       if ((delta -= dx) < 0)
    jpl     .dl_dy_odd_1    //       {

    add.w   %a2,%d2         //         x += stepx
    add.w   %a5,%d3         //         delta += dy;

.dl_dy_odd_1:               //       }
    dbra    %d4,.dl_dy_loop //     }

    movem.l (%sp)+,%d2-%d7/%a2-%a5
    rts


func BMP_isPolygonCulled
    movm.l %d2-%d5,-(%sp)

    move.l 20(%sp),%a1          // a1 = pts
    movm.w (%a1),%d0-%d5        // d0 = pts[0].x, d1 = pts[0].y, d2 = pts[1].x, d3 = pts[1].y, d4 = pts[2].x, d5 = pts[2].y

    sub.w %d0,%d4               // d4 = x2 - x0
    sub.w %d1,%d3               // d3 = y1 - y0
    muls.w %d4,%d3

    sub.w %d0,%d2               // d2 = x1 - x0
    sub.w %d1,%d5               // d5 = y2 - y0
    muls.w %d5,%d2

    cmp.l %d3,%d2               // culling test
    jge .L11                    // if (d4 * d3 < d5 * d2)

    moveq #1,%d0                //     return 1;
    movm.l (%sp)+,%d2-%d5
    rts

.L11:
    moveq #0,%d0                //     return 0;
    movm.l (%sp)+,%d2-%d5
    rts


    // internal use only
    // -----------------
    // IN:
    // d0 = dx
    // d1 = dy
    // d7 = x
    // a1 = dst
    //
    // OUT:
    // d0 = ?
    // d1 = dy * 4
    // d7 = ?
    // a1 = dst (updated)
    // a6 = ?
fillEdge:
    ext.l %d0               // if (dx == 0)
    jeq fillEdgeFast        //   goto fillEdgeFast

    asl.l #7,%d0            // d0 = dx << 7
    divs.w %d1,%d0          // d0 = (dx << 7) / dy
    ext.l %d0
    ror.l #7,%d0            // d0 = step x

    swap %d7
    move.w #0x8000, %d7
    swap %d7                // d7 = x 32 bits extended

    add.w %d1,%d1
    add.w %d1,%d1           // d1 = dy * 4 (for jump table)
    andi #0,%ccr            // clear X flag

.fe_fill_base2:
    move.l (.fe_fill_table-.fe_fill_base2)-2(%pc,%d1.w),%a6
    jmp (%a6)

    .align 4
.fe_fill_table:
    .long .fe_fill_0
    .long .fe_fill_1
    .long .fe_fill_2
    .long .fe_fill_3
    .long .fe_fill_4
    .long .fe_fill_5
    .long .fe_fill_6
    .long .fe_fill_7
    .long .fe_fill_8
    .long .fe_fill_9
    .long .fe_fill_10
    .long .fe_fill_11
    .long .fe_fill_12
    .long .fe_fill_13
    .long .fe_fill_14
    .long .fe_fill_15
    .long .fe_fill_16
    .long .fe_fill_17
    .long .fe_fill_18
    .long .fe_fill_19
    .long .fe_fill_20
    .long .fe_fill_21
    .long .fe_fill_22
    .long .fe_fill_23
    .long .fe_fill_24
    .long .fe_fill_25
    .long .fe_fill_26
    .long .fe_fill_27
    .long .fe_fill_28
    .long .fe_fill_29
    .long .fe_fill_30
    .long .fe_fill_31
    .long .fe_fill_32
    .long .fe_fill_33
    .long .fe_fill_34
    .long .fe_fill_35
    .long .fe_fill_36
    .long .fe_fill_37
    .long .fe_fill_38
    .long .fe_fill_39
    .long .fe_fill_40
    .long .fe_fill_41
    .long .fe_fill_42
    .long .fe_fill_43
    .long .fe_fill_44
    .long .fe_fill_45
    .long .fe_fill_46
    .long .fe_fill_47
    .long .fe_fill_48
    .long .fe_fill_49
    .long .fe_fill_50
    .long .fe_fill_51
    .long .fe_fill_52
    .long .fe_fill_53
    .long .fe_fill_54
    .long .fe_fill_55
    .long .fe_fill_56
    .long .fe_fill_57
    .long .fe_fill_58
    .long .fe_fill_59
    .long .fe_fill_60
    .long .fe_fill_61
    .long .fe_fill_62
    .long .fe_fill_63
    .long .fe_fill_64
    .long .fe_fill_65
    .long .fe_fill_66
    .long .fe_fill_67
    .long .fe_fill_68
    .long .fe_fill_69
    .long .fe_fill_70
    .long .fe_fill_71
    .long .fe_fill_72
    .long .fe_fill_73
    .long .fe_fill_74
    .long .fe_fill_75
    .long .fe_fill_76
    .long .fe_fill_77
    .long .fe_fill_78
    .long .fe_fill_79
    .long .fe_fill_80
    .long .fe_fill_81
    .long .fe_fill_82
    .long .fe_fill_83
    .long .fe_fill_84
    .long .fe_fill_85
    .long .fe_fill_86
    .long .fe_fill_87
    .long .fe_fill_88
    .long .fe_fill_89
    .long .fe_fill_90
    .long .fe_fill_91
    .long .fe_fill_92
    .long .fe_fill_93
    .long .fe_fill_94
    .long .fe_fill_95
    .long .fe_fill_96
    .long .fe_fill_97
    .long .fe_fill_98
    .long .fe_fill_99
    .long .fe_fill_100
    .long .fe_fill_101
    .long .fe_fill_102
    .long .fe_fill_103
    .long .fe_fill_104
    .long .fe_fill_105
    .long .fe_fill_106
    .long .fe_fill_107
    .long .fe_fill_108
    .long .fe_fill_109
    .long .fe_fill_110
    .long .fe_fill_111
    .long .fe_fill_112
    .long .fe_fill_113
    .long .fe_fill_114
    .long .fe_fill_115
    .long .fe_fill_116
    .long .fe_fill_117
    .long .fe_fill_118
    .long .fe_fill_119
    .long .fe_fill_120
    .long .fe_fill_121
    .long .fe_fill_122
    .long .fe_fill_123
    .long .fe_fill_124
    .long .fe_fill_125
    .long .fe_fill_126
    .long .fe_fill_127
    .long .fe_fill_128
    .long .fe_fill_129
    .long .fe_fill_130
    .long .fe_fill_131
    .long .fe_fill_132
    .long .fe_fill_133
    .long .fe_fill_134
    .long .fe_fill_135
    .long .fe_fill_136
    .long .fe_fill_137
    .long .fe_fill_138
    .long .fe_fill_139
    .long .fe_fill_140
    .long .fe_fill_141
    .long .fe_fill_142
    .long .fe_fill_143
    .long .fe_fill_144
    .long .fe_fill_145
    .long .fe_fill_146
    .long .fe_fill_147
    .long .fe_fill_148
    .long .fe_fill_149
    .long .fe_fill_150
    .long .fe_fill_151
    .long .fe_fill_152
    .long .fe_fill_153
    .long .fe_fill_154
    .long .fe_fill_155
    .long .fe_fill_156
    .long .fe_fill_157
    .long .fe_fill_158
    .long .fe_fill_159
    .long .fe_fill_160

.fe_fill_160:
    move.w %d7,(%a1)+           // *src++ = F16_toInt(x);
    addx.l %d0,%d7              //  x += step;
.fe_fill_159:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_158:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_157:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_156:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_155:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_154:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_153:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_152:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_151:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_150:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_149:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_148:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_147:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_146:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_145:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_144:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_143:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_142:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_141:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_140:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_139:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_138:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_137:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_136:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_135:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_134:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_133:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_132:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_131:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_130:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_129:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_128:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_127:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_126:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_125:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_124:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_123:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_122:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_121:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_120:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_119:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_118:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_117:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_116:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_115:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_114:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_113:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_112:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_111:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_110:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_109:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_108:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_107:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_106:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_105:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_104:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_103:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_102:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_101:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_100:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_99:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_98:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_97:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_96:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_95:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_94:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_93:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_92:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_91:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_90:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_89:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_88:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_87:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_86:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_85:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_84:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_83:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_82:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_81:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_80:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_79:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_78:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_77:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_76:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_75:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_74:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_73:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_72:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_71:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_70:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_69:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_68:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_67:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_66:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_65:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_64:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_63:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_62:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_61:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_60:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_59:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_58:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_57:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_56:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_55:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_54:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_53:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_52:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_51:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_50:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_49:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_48:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_47:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_46:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_45:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_44:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_43:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_42:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_41:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_40:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_39:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_38:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_37:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_36:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_35:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_34:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_33:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_32:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_31:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_30:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_29:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_28:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_27:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_26:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_25:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_24:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_23:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_22:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_21:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_20:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_19:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_18:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_17:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_16:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_15:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_14:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_13:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_12:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_11:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_10:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_9:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_8:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_7:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_6:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_5:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_4:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_3:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_2:
    move.w %d7,(%a1)+
    addx.l %d0,%d7
.fe_fill_1:
    move.w %d7,(%a1)+
.fe_fill_0:
    rts


    // internal use only
    // -----------------
    // IN:
    // d7 = x
    // d1 = dy
    // a1 = dst
    //
    // OUT:
    // d7 = ?
    // d1 = dy * 4
    // a1 = dst (updated)
    // a6 = ?
fillEdgeFast:
    move.w %d7,%a6
    swap %d7
    move.w %a6,%d7              // d7 = x = (x1 << 16) // x1

    add.w %d1,%d1
    add.w %d1,%d1               // for jump table

.fef_fill_base:
    move.l (.fef_fill_table-.fef_fill_base)-2(%pc,%d1.w),%a6
    jmp (%a6)

    .align 4
.fef_fill_table:
    .long .fef_fill_0
    .long .fef_fill_1
    .long .fef_fill_2
    .long .fef_fill_3
    .long .fef_fill_4
    .long .fef_fill_5
    .long .fef_fill_6
    .long .fef_fill_7
    .long .fef_fill_8
    .long .fef_fill_9
    .long .fef_fill_10
    .long .fef_fill_11
    .long .fef_fill_12
    .long .fef_fill_13
    .long .fef_fill_14
    .long .fef_fill_15
    .long .fef_fill_16
    .long .fef_fill_17
    .long .fef_fill_18
    .long .fef_fill_19
    .long .fef_fill_20
    .long .fef_fill_21
    .long .fef_fill_22
    .long .fef_fill_23
    .long .fef_fill_24
    .long .fef_fill_25
    .long .fef_fill_26
    .long .fef_fill_27
    .long .fef_fill_28
    .long .fef_fill_29
    .long .fef_fill_30
    .long .fef_fill_31
    .long .fef_fill_32
    .long .fef_fill_33
    .long .fef_fill_34
    .long .fef_fill_35
    .long .fef_fill_36
    .long .fef_fill_37
    .long .fef_fill_38
    .long .fef_fill_39
    .long .fef_fill_40
    .long .fef_fill_41
    .long .fef_fill_42
    .long .fef_fill_43
    .long .fef_fill_44
    .long .fef_fill_45
    .long .fef_fill_46
    .long .fef_fill_47
    .long .fef_fill_48
    .long .fef_fill_49
    .long .fef_fill_50
    .long .fef_fill_51
    .long .fef_fill_52
    .long .fef_fill_53
    .long .fef_fill_54
    .long .fef_fill_55
    .long .fef_fill_56
    .long .fef_fill_57
    .long .fef_fill_58
    .long .fef_fill_59
    .long .fef_fill_60
    .long .fef_fill_61
    .long .fef_fill_62
    .long .fef_fill_63
    .long .fef_fill_64
    .long .fef_fill_65
    .long .fef_fill_66
    .long .fef_fill_67
    .long .fef_fill_68
    .long .fef_fill_69
    .long .fef_fill_70
    .long .fef_fill_71
    .long .fef_fill_72
    .long .fef_fill_73
    .long .fef_fill_74
    .long .fef_fill_75
    .long .fef_fill_76
    .long .fef_fill_77
    .long .fef_fill_78
    .long .fef_fill_79
    .long .fef_fill_80
    .long .fef_fill_81
    .long .fef_fill_82
    .long .fef_fill_83
    .long .fef_fill_84
    .long .fef_fill_85
    .long .fef_fill_86
    .long .fef_fill_87
    .long .fef_fill_88
    .long .fef_fill_89
    .long .fef_fill_90
    .long .fef_fill_91
    .long .fef_fill_92
    .long .fef_fill_93
    .long .fef_fill_94
    .long .fef_fill_95
    .long .fef_fill_96
    .long .fef_fill_97
    .long .fef_fill_98
    .long .fef_fill_99
    .long .fef_fill_100
    .long .fef_fill_101
    .long .fef_fill_102
    .long .fef_fill_103
    .long .fef_fill_104
    .long .fef_fill_105
    .long .fef_fill_106
    .long .fef_fill_107
    .long .fef_fill_108
    .long .fef_fill_109
    .long .fef_fill_110
    .long .fef_fill_111
    .long .fef_fill_112
    .long .fef_fill_113
    .long .fef_fill_114
    .long .fef_fill_115
    .long .fef_fill_116
    .long .fef_fill_117
    .long .fef_fill_118
    .long .fef_fill_119
    .long .fef_fill_120
    .long .fef_fill_121
    .long .fef_fill_122
    .long .fef_fill_123
    .long .fef_fill_124
    .long .fef_fill_125
    .long .fef_fill_126
    .long .fef_fill_127
    .long .fef_fill_128
    .long .fef_fill_129
    .long .fef_fill_130
    .long .fef_fill_131
    .long .fef_fill_132
    .long .fef_fill_133
    .long .fef_fill_134
    .long .fef_fill_135
    .long .fef_fill_136
    .long .fef_fill_137
    .long .fef_fill_138
    .long .fef_fill_139
    .long .fef_fill_140
    .long .fef_fill_141
    .long .fef_fill_142
    .long .fef_fill_143
    .long .fef_fill_144
    .long .fef_fill_145
    .long .fef_fill_146
    .long .fef_fill_147
    .long .fef_fill_148
    .long .fef_fill_149
    .long .fef_fill_150
    .long .fef_fill_151
    .long .fef_fill_152
    .long .fef_fill_153
    .long .fef_fill_154
    .long .fef_fill_155
    .long .fef_fill_156
    .long .fef_fill_157
    .long .fef_fill_158
    .long .fef_fill_159
    .long .fef_fill_160

.fef_fill_160:
    move.l %d7,(%a1)+
.fef_fill_158:
    move.l %d7,(%a1)+
.fef_fill_156:
    move.l %d7,(%a1)+
.fef_fill_154:
    move.l %d7,(%a1)+
.fef_fill_152:
    move.l %d7,(%a1)+
.fef_fill_150:
    move.l %d7,(%a1)+
.fef_fill_148:
    move.l %d7,(%a1)+
.fef_fill_146:
    move.l %d7,(%a1)+
.fef_fill_144:
    move.l %d7,(%a1)+
.fef_fill_142:
    move.l %d7,(%a1)+
.fef_fill_140:
    move.l %d7,(%a1)+
.fef_fill_138:
    move.l %d7,(%a1)+
.fef_fill_136:
    move.l %d7,(%a1)+
.fef_fill_134:
    move.l %d7,(%a1)+
.fef_fill_132:
    move.l %d7,(%a1)+
.fef_fill_130:
    move.l %d7,(%a1)+
.fef_fill_128:
    move.l %d7,(%a1)+
.fef_fill_126:
    move.l %d7,(%a1)+
.fef_fill_124:
    move.l %d7,(%a1)+
.fef_fill_122:
    move.l %d7,(%a1)+
.fef_fill_120:
    move.l %d7,(%a1)+
.fef_fill_118:
    move.l %d7,(%a1)+
.fef_fill_116:
    move.l %d7,(%a1)+
.fef_fill_114:
    move.l %d7,(%a1)+
.fef_fill_112:
    move.l %d7,(%a1)+
.fef_fill_110:
    move.l %d7,(%a1)+
.fef_fill_108:
    move.l %d7,(%a1)+
.fef_fill_106:
    move.l %d7,(%a1)+
.fef_fill_104:
    move.l %d7,(%a1)+
.fef_fill_102:
    move.l %d7,(%a1)+
.fef_fill_100:
    move.l %d7,(%a1)+
.fef_fill_98:
    move.l %d7,(%a1)+
.fef_fill_96:
    move.l %d7,(%a1)+
.fef_fill_94:
    move.l %d7,(%a1)+
.fef_fill_92:
    move.l %d7,(%a1)+
.fef_fill_90:
    move.l %d7,(%a1)+
.fef_fill_88:
    move.l %d7,(%a1)+
.fef_fill_86:
    move.l %d7,(%a1)+
.fef_fill_84:
    move.l %d7,(%a1)+
.fef_fill_82:
    move.l %d7,(%a1)+
.fef_fill_80:
    move.l %d7,(%a1)+
.fef_fill_78:
    move.l %d7,(%a1)+
.fef_fill_76:
    move.l %d7,(%a1)+
.fef_fill_74:
    move.l %d7,(%a1)+
.fef_fill_72:
    move.l %d7,(%a1)+
.fef_fill_70:
    move.l %d7,(%a1)+
.fef_fill_68:
    move.l %d7,(%a1)+
.fef_fill_66:
    move.l %d7,(%a1)+
.fef_fill_64:
    move.l %d7,(%a1)+
.fef_fill_62:
    move.l %d7,(%a1)+
.fef_fill_60:
    move.l %d7,(%a1)+
.fef_fill_58:
    move.l %d7,(%a1)+
.fef_fill_56:
    move.l %d7,(%a1)+
.fef_fill_54:
    move.l %d7,(%a1)+
.fef_fill_52:
    move.l %d7,(%a1)+
.fef_fill_50:
    move.l %d7,(%a1)+
.fef_fill_48:
    move.l %d7,(%a1)+
.fef_fill_46:
    move.l %d7,(%a1)+
.fef_fill_44:
    move.l %d7,(%a1)+
.fef_fill_42:
    move.l %d7,(%a1)+
.fef_fill_40:
    move.l %d7,(%a1)+
.fef_fill_38:
    move.l %d7,(%a1)+
.fef_fill_36:
    move.l %d7,(%a1)+
.fef_fill_34:
    move.l %d7,(%a1)+
.fef_fill_32:
    move.l %d7,(%a1)+
.fef_fill_30:
    move.l %d7,(%a1)+
.fef_fill_28:
    move.l %d7,(%a1)+
.fef_fill_26:
    move.l %d7,(%a1)+
.fef_fill_24:
    move.l %d7,(%a1)+
.fef_fill_22:
    move.l %d7,(%a1)+
.fef_fill_20:
    move.l %d7,(%a1)+
.fef_fill_18:
    move.l %d7,(%a1)+
.fef_fill_16:
    move.l %d7,(%a1)+
.fef_fill_14:
    move.l %d7,(%a1)+
.fef_fill_12:
    move.l %d7,(%a1)+
.fef_fill_10:
    move.l %d7,(%a1)+
.fef_fill_8:
    move.l %d7,(%a1)+
.fef_fill_6:
    move.l %d7,(%a1)+
.fef_fill_4:
    move.l %d7,(%a1)+
.fef_fill_2:
    move.l %d7,(%a1)+
.fef_fill_0:
    rts

.fef_fill_159:
    move.l %d7,(%a1)+
.fef_fill_157:
    move.l %d7,(%a1)+
.fef_fill_155:
    move.l %d7,(%a1)+
.fef_fill_153:
    move.l %d7,(%a1)+
.fef_fill_151:
    move.l %d7,(%a1)+
.fef_fill_149:
    move.l %d7,(%a1)+
.fef_fill_147:
    move.l %d7,(%a1)+
.fef_fill_145:
    move.l %d7,(%a1)+
.fef_fill_143:
    move.l %d7,(%a1)+
.fef_fill_141:
    move.l %d7,(%a1)+
.fef_fill_139:
    move.l %d7,(%a1)+
.fef_fill_137:
    move.l %d7,(%a1)+
.fef_fill_135:
    move.l %d7,(%a1)+
.fef_fill_133:
    move.l %d7,(%a1)+
.fef_fill_131:
    move.l %d7,(%a1)+
.fef_fill_129:
    move.l %d7,(%a1)+
.fef_fill_127:
    move.l %d7,(%a1)+
.fef_fill_125:
    move.l %d7,(%a1)+
.fef_fill_123:
    move.l %d7,(%a1)+
.fef_fill_121:
    move.l %d7,(%a1)+
.fef_fill_119:
    move.l %d7,(%a1)+
.fef_fill_117:
    move.l %d7,(%a1)+
.fef_fill_115:
    move.l %d7,(%a1)+
.fef_fill_113:
    move.l %d7,(%a1)+
.fef_fill_111:
    move.l %d7,(%a1)+
.fef_fill_109:
    move.l %d7,(%a1)+
.fef_fill_107:
    move.l %d7,(%a1)+
.fef_fill_105:
    move.l %d7,(%a1)+
.fef_fill_103:
    move.l %d7,(%a1)+
.fef_fill_101:
    move.l %d7,(%a1)+
.fef_fill_99:
    move.l %d7,(%a1)+
.fef_fill_97:
    move.l %d7,(%a1)+
.fef_fill_95:
    move.l %d7,(%a1)+
.fef_fill_93:
    move.l %d7,(%a1)+
.fef_fill_91:
    move.l %d7,(%a1)+
.fef_fill_89:
    move.l %d7,(%a1)+
.fef_fill_87:
    move.l %d7,(%a1)+
.fef_fill_85:
    move.l %d7,(%a1)+
.fef_fill_83:
    move.l %d7,(%a1)+
.fef_fill_81:
    move.l %d7,(%a1)+
.fef_fill_79:
    move.l %d7,(%a1)+
.fef_fill_77:
    move.l %d7,(%a1)+
.fef_fill_75:
    move.l %d7,(%a1)+
.fef_fill_73:
    move.l %d7,(%a1)+
.fef_fill_71:
    move.l %d7,(%a1)+
.fef_fill_69:
    move.l %d7,(%a1)+
.fef_fill_67:
    move.l %d7,(%a1)+
.fef_fill_65:
    move.l %d7,(%a1)+
.fef_fill_63:
    move.l %d7,(%a1)+
.fef_fill_61:
    move.l %d7,(%a1)+
.fef_fill_59:
    move.l %d7,(%a1)+
.fef_fill_57:
    move.l %d7,(%a1)+
.fef_fill_55:
    move.l %d7,(%a1)+
.fef_fill_53:
    move.l %d7,(%a1)+
.fef_fill_51:
    move.l %d7,(%a1)+
.fef_fill_49:
    move.l %d7,(%a1)+
.fef_fill_47:
    move.l %d7,(%a1)+
.fef_fill_45:
    move.l %d7,(%a1)+
.fef_fill_43:
    move.l %d7,(%a1)+
.fef_fill_41:
    move.l %d7,(%a1)+
.fef_fill_39:
    move.l %d7,(%a1)+
.fef_fill_37:
    move.l %d7,(%a1)+
.fef_fill_35:
    move.l %d7,(%a1)+
.fef_fill_33:
    move.l %d7,(%a1)+
.fef_fill_31:
    move.l %d7,(%a1)+
.fef_fill_29:
    move.l %d7,(%a1)+
.fef_fill_27:
    move.l %d7,(%a1)+
.fef_fill_25:
    move.l %d7,(%a1)+
.fef_fill_23:
    move.l %d7,(%a1)+
.fef_fill_21:
    move.l %d7,(%a1)+
.fef_fill_19:
    move.l %d7,(%a1)+
.fef_fill_17:
    move.l %d7,(%a1)+
.fef_fill_15:
    move.l %d7,(%a1)+
.fef_fill_13:
    move.l %d7,(%a1)+
.fef_fill_11:
    move.l %d7,(%a1)+
.fef_fill_9:
    move.l %d7,(%a1)+
.fef_fill_7:
    move.l %d7,(%a1)+
.fef_fill_5:
    move.l %d7,(%a1)+
.fef_fill_3:
    move.l %d7,(%a1)+
.fef_fill_1:
    move.w %d7,(%a1)+
    rts


    // edges calculation
    // -----------------
    //
    // d0 = dx / free use
    // d1 = dy / free use
    // d2 = yMin / x0
    // d3 = yMax / y0
    // d4 = xMin / x1
    // d5 = xMax / y1
    // d6 = BMP_HEIGHT-1/ymax
    // d7 = x / free use
    // a0 = pt / pt1
    // a1 = edge / pt0
    // a2 = ptYMin
    // a3 = BMP_WIDTH-1
    // a4 = ptFirst
    // a5 = ptLast
    // a6 = free use
    // 0(sp) = left edge
    // 320(sp) = right edge
    // 640(sp) = left Ymin
    // 642(sp) = right Ymin
    //
    // polygon drawing
    // ---------------
    //
    // d0 = current col (32 bits extended)
    // d1 = other col (32 bits extended)
    // d2 = xl
    // d3 = xr
    // d4 = free use
    // d5 = free use
    // d6 = len
    // a0 = buf = &bmp_buffer_write[y]
    // a1 = &buf[x]
    // a2 = leftEdge
    // a3 = rightEdge
    // a4 = free use

func BMP_drawPolygon
    movm.l %d2-%d7/%a2-%a6,-(%sp)

    move.l 48(%sp),%a0      // a0 = pt = &pts[0]
    move.w 54(%sp),%d1      // d1 = num

    move.w %d1,%d0
    add.w %d0,%d0
    add.w %d0,%d0           // d0 = num * 4
    move.l %a0,%a4          // a4 = ptFirt
    lea (%a0,%d0.w),%a5     // a5 = ptLast

    move.l (%a0)+,%d0       // d0.w = y = pt->y; pt++;

    move.l %a0,%a2          // a2 = ptYMin = &pts[1]
    move.w %d0,%d2          // d2.w = yMin = y
    move.w %d0,%d3          // d3.W = yMax = y
    swap %d0
    move.w %d0,%d4          // d4.w = xMin = x
    move.w %d0,%d5          // d5.W = xMax = x

    subq.w #2,%d1           // d1 = cnt = num - 2

.DP_pts_loop:               // while (cnt--) {
    move.l (%a0)+,%d0       //   y = pt->y; pt++;

    cmp.w %d2,%d0           //   if (y < yMin)
    jge .DP_find_ymax       //   {

    move.w %d0,%d2          //     yMin = y
    move.l %a0,%a2          //     ptYMin = pt + 1

    swap %d0                //     d0 = x

    cmp.w %d4,%d0           //     if (x < xMin)
    jge .DP_find_xmax       //     {

    move.w %d0,%d4          //       xMin = x
    dbra %d1,.DP_pts_loop   //       continue
    jra .DP_pts_loop_done   //     }
                            //   }
.DP_find_ymax:
    cmp.w %d3,%d0           //   if (y > yMax)
    jle .DP_find_xmin       //   {

    move.w %d0,%d3          //     yMax = y
                            //   }
.DP_find_xmin:
    swap %d0                //   d0 = x

    cmp.w %d4,%d0           //   if (x < xMin)
    jge .DP_find_xmax       //   {

    move.w %d0,%d4          //     xMin = x
    dbra %d1,.DP_pts_loop   //     continue
    jra .DP_pts_loop_done   //   }

.DP_find_xmax:
    cmp.w %d5,%d0           //   if (x > xMax)
    jle .DP_pts_loop_next   //   {

    move.w %d0,%d5          //       xMax = x
                            //
.DP_pts_loop_next:          //   }
    dbra %d1,.DP_pts_loop   // }

.DP_pts_loop_done:
    subq.l #4,%a2           // fix ptYMin

    tst.w %d3               // if (yMax <= 0)        // we use <= as it is simpler to ignore case where ymax = 0 here
    jle .DP_end0            //   return 0
    tst.w %d5               // if (xMax < 0)
    jlt .DP_end0            //   return 0

    move.l #159,%d6         // d6 = BMP_HEIGHT-1

    cmp.w %d6,%d2           // if (yMin > BMP_HEIGHT)
    jgt .DP_end0            //   return 0

    move.l #255,%a3         // a3 = BMP_WIDTH-1

    cmp.w %a3,%d4           // if (xMin > BMP_WIDTH)
    jgt .DP_end0            //   return 0

    lea -644(%sp),%sp       // reserve memory for edge table and others

    cmp.w %d3,%d2           // if (yMin == yMax)
    jne .DP_no_single_line  // {

    tst.w %d4               //   if (xmin < 0)
    jge .DP_sl_xmin_ok

    moveq #0,%d4            //     xmin = 0

.DP_sl_xmin_ok:
    cmp.w %a3,%d5           //   if (xmax >= BMP_WIDTH)
    jle .DP_sl_xmax_ok

    move.w %a3,%d5          //     xmax = BMP_WIDTH - 1

.DP_sl_xmax_ok:
    move.w %d3,%d6          //   d6 = maxY

    add.w %d3,%d3
    lea 0(%sp,%d3.w),%a0

    move.w %d4,(%a0)        //   leftEdge[yMin] = xmin
    move.w %d5,320(%a0)     //   rightEdge[yMin] = xmax

    jra .drawPolygon_SL     //   draw polygon now (d2 = minY and d6 = maxY)
                            // }

.DP_end0:
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts


.DP_no_single_line:
    cmp.w %d6,%d3           // if (ymax < BMP_HEIGHT)
    jge .DP_ymax_ok

    move.w %d3,%d6          //   d6 = ymax

.DP_ymax_ok:
    tst.w %d4               // if (xmin < 0)
    jlt .DP_XClip           //   goto XClip
    cmp.w %a3,%d5           // if (xmax >= BMP_WIDTH)
    jgt .DP_XClip           //   goto XClip


    // LEFT NO X CLIP
    // --------------

    move.l %a2,%a0          // a0 = pt = ptYMin

    move.l (%a0),%d2        // d2.wl = y0   d2.wh = x0
    cmp.l %a4,%a0           // if (pt == ptFirst)
    jne .DP_lnc_first

    move.l %a5,%a0          //   pt = ptLast

.DP_lnc_first:
    move.l -(%a0),%d4       // d4.wl = y1   d4.wh = x1

    tst.w %d4               // while (y1 <= 0)
    jgt .DP_lnc_y1l_ok      // {

.DP_lnc_y1l_loop:
    move.l %d4,%d2          //   d2.wl = y0   d2.wh = x0
    cmp.l %a4,%a0           //   if (pt == ptFirst)
    jne .DP_lnc_y1l_next

    move.l %a5,%a0          //     pt = ptLast

.DP_lnc_y1l_next:
    move.l -(%a0),%d4       //   d4.wl = y1   d4.wh = x1
    tst.w %d4               // }
    jle .DP_lnc_y1l_loop

.DP_lnc_y1l_ok:
    move.w %d2,%d3          // d3 = y0
    swap %d2                // d2 = x0
    move.w %d4,%d5          // d5 = y1
    swap %d4                // d4 = x1

    // Clip Y0

    tst.w %d3               // if (y0 < 0)
    jge .DP_lnc_y0_ok       // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    muls.w %d3,%d0
    divs.w %d1,%d0          //   d0 = adj = (y0 * dx) / dy
    sub.w %d0,%d2           //   x0 -= adj
    moveq #0,%d3            //   y0 = 0
                            // }
.DP_lnc_y0_ok:
    move.w %d3,640(%sp)     // minYL = y0
    move.l %sp,%d0
    add.w %d3,%d0
    add.w %d3,%d0
    move.l %d0,%a1          // a1 = edge = &leftEdge[minYL]

.DP_lnc_loop:

    // Clip Y1

    cmp.w %d6,%d5           // if (y1 >= ymax)
    jlt .DP_lnc_y1h_ok      // {
                            //   if (y1 > ymax)
    jeq .DP_lnc_y1h_nc      //   {

    move.w %d5,%d1
    sub.w %d3,%d1           //     d1 = dy
    move.w %d4,%d0
    sub.w %d2,%d0           //     d0 = dx

    sub.w %d6,%d5
    muls.w %d5,%d0
    divs.w %d1,%d0          //     d0 = adj = ((y1 - ymax) * dx) / dy
    sub.w %d0,%d4           //     x1 -= adj
    move.w %d6,%d5          //     y1 = ymax
                            //   }
.DP_lnc_y1h_nc:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jeq .DP_lnc_done

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x

    pea .DP_lnc_done        //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
    jra fillEdge            //   goto lnc_done
                            // }

.DP_lnc_end0:
    lea 644(%sp),%sp        // release memory for edge table and others
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

.DP_lnc_y1h_ok:
    move.w %d5,%d1
    sub.w %d3,%d1           // d1 = dy
    jlt .DP_lnc_end0        // if (dy < 0) return 0
    jeq .DP_lnc_next        // if (dy)
                            // {
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x
    jsr fillEdge            //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
                            // }
.DP_lnc_next:
    move.w %d4,%d2          // x0 = x1
    move.w %d5,%d3          // y0 = y1
    cmp.l %a4,%a0           // if (pt == ptFirst)
    jne .DP_lnc_next_ok

    move.l %a5,%a0          //   pt = ptLast

.DP_lnc_next_ok:
    move.w -(%a0),%d5       // y1 = pt->y
    move.w -(%a0),%d4       // x1 = pt->x
    jra .DP_lnc_loop

.DP_lnc_done:

    // RIGHT NO X CLIP
    // ---------------

    move.l %a2,%a0          // a0 = pt = ptYMin

    move.l (%a0)+,%d2       // d2.wl = y0   d2.wh = x0
    cmp.l %a5,%a0           // if (pt == ptLast)
    jne .DP_rnc_first

    move.l %a4,%a0          //   pt = ptFirst

.DP_rnc_first:
    move.l (%a0)+,%d4       // d4.wl = y1   d4.wh = x1

    tst.w %d4               // while (y1 <= 0)
    jgt .DP_rnc_y1l_ok      // {

.DP_rnc_y1l_loop:
    move.l %d4,%d2          //   d2.wl = y0   d2.wh = x0
    cmp.l %a5,%a0           //   if (pt == ptLast)
    jne .DP_rnc_y1l_next

    move.l %a4,%a0          //     pt = ptFirst

.DP_rnc_y1l_next:
    move.l (%a0)+,%d4       //   d4.wl = y1   d4.wh = x1
    tst.w %d4               // }
    jle .DP_rnc_y1l_loop

.DP_rnc_y1l_ok:
    move.w %d2,%d3          // d3 = y0
    swap %d2                // d2 = x0
    move.w %d4,%d5          // d5 = y1
    swap %d4                // d4 = x1

    // Clip Y0

    tst.w %d3               // if (y0 < 0)
    jge .DP_rnc_y0_ok       // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    muls.w %d3,%d0
    divs.w %d1,%d0          //   d0 = adj = (y0 * dx) / dy
    sub.w %d0,%d2           //   x0 -= adj
    moveq #0,%d3            //   y0 = 0
                            // }
.DP_rnc_y0_ok:
    move.w %d3,642(%sp)     // minYR = y0
    lea 320(%sp),%a1        // a1 = &rightEdge[0]
    add.w %d3,%a1
    add.w %d3,%a1           // a1 = edge = &rightEdge[minYR]

.DP_rnc_loop:

    // Clip Y1

    cmp.w %d6,%d5           // if (y1 >= ymax)
    jlt .DP_rnc_y1h_ok      // {
                            //   if (y1 > ymax)
    jeq .DP_rnc_y1h_nc      //   {

    move.w %d4,%d0
    sub.w %d2,%d0           //     d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //     d1 = dy

    sub.w %d6,%d5
    muls.w %d5,%d0
    divs.w %d1,%d0          //     d0 = adj = ((y1 - ymax) * dx) / dy
    sub.w %d0,%d4           //     x1 -= adj
    move.w %d6,%d5          //     y1 = ymax
                            //   }
.DP_rnc_y1h_nc:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jeq .DP_rnc_done

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x

    pea .DP_rnc_done        //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
    jra fillEdge            //   goto rnc_done
                            // }

.DP_rnc_end0:
    lea 644(%sp),%sp        // release memory for edge table and others
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

.DP_rnc_y1h_ok:
    move.w %d5,%d1
    sub.w %d3,%d1           // d1 = dy

    jlt .DP_rnc_end0        // if (dy < 0) return 0
    jeq .DP_rnc_next        // if (dy)
                            // {
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x
    jsr fillEdge            //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
                            // }
.DP_rnc_next:
    move.w %d4,%d2          // x0 = x1
    move.w %d5,%d3          // y0 = y1
    cmp.l %a5,%a0           // if (pt == ptLast)
    jne .DP_rnc_next_ok

    move.l %a4,%a0          //   pt = ptFirst

.DP_rnc_next_ok:
    move.w (%a0)+,%d4       // x1 = pt->x
    move.w (%a0)+,%d5       // y1 = pt->y
    jra .DP_rnc_loop

.DP_rnc_done:
    move.w 642(%sp),%d2     // d2 = minYR, d6 = maxY
    move.w 640(%sp),%d3     // d3 = minYL

    cmp.w %d2,%d3           // if (minYL > minYR)
    jle .drawPolygon

    move.w %d3,%d2          // d2 = minYL
    jra .drawPolygon



.DP_XClip:

    // LEFT WITH X CLIP
    // ----------------

    move.l %a2,%a0          // a0 = pt = ptYMin

    move.l (%a0),%d2        // d2.wl = y0   d2.wh = x0
    cmp.l %a4,%a0           // if (pt == ptFirst)
    jne .DP_l_first

    move.l %a5,%a0          //   pt = ptLast

.DP_l_first:
    move.l -(%a0),%d4       // d4.wl = y1   d4.wh = x1

    tst.w %d4               // while (y1 <= 0)
    jgt .DP_l_y1l_ok        // {

.DP_l_y1l_loop:
    move.l %d4,%d2          //   d2.wl = y0   d2.wh = x0
    cmp.l %a4,%a0           //   if (pt == ptFirst)
    jne .DP_l_y1l_next

    move.l %a5,%a0          //     pt = ptLast

.DP_l_y1l_next:
    move.l -(%a0),%d4       //   d4.wl = y1   d4.wh = x1
    tst.w %d4               // }
    jle .DP_l_y1l_loop

.DP_l_y1l_ok:
    move.w %d4,%d5          // d5 = y1
    swap %d4                // d4 = x1
    move.w %d2,%d3          // d3 = y0
    swap %d2                // d2 = x0

    // Clip Y0

    tst.w %d3               // if (y0 < 0)
    jge .DP_l_y0_ok         // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    muls.w %d3,%d0
    divs.w %d1,%d0          //   d0 = adj = (y0 * dx) / dy
    sub.w %d0,%d2           //   x0 -= adj
    moveq #0,%d3            //   y0 = 0
                            // }
.DP_l_y0_ok:

    // Clip X BEFORE

    cmp.w %a3,%d2           // if (x0 >= BMP_WIDTH)
    jle .DP_l_xl_ok         // {
    cmp.w %a3,%d4           //   while (x1 >= BMP_WIDTH)
    jle .DP_l_x0_clip       //   {

.DP_l_xl_loop:
    cmp.w %d4,%d2           //     if (x0 < x1)
    jlt .DP_l_end0          //       return 0
    cmp.w %d6,%d5           //     if (y1 >= ymax)
    jge .DP_l_end0          //       return 0

    move.w %d4,%d2          //     x0 = x1
    move.w %d5,%d3          //     y0 = y1
    cmp.l %a4,%a0           //     if (pt == ptFirst)
    jne .DP_l_xl_next

    move.l %a5,%a0          //       pt = ptLast

.DP_l_xl_next:
    move.w -(%a0),%d5       //     y1 = pt->y
    move.w -(%a0),%d4       //     x1 = pt->x
    cmp.w %a3,%d4           //
    jgt .DP_l_xl_loop       //   }

.DP_l_x0_clip:
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    sub.w %a3,%d2
    muls.w %d2,%d1
    divs.w %d0,%d1          //   d1 = adj = ((x0 - (BMP_WIDTH - 1)) * dy) / dx
    sub.w %d1,%d3           //   y0 -= adj

    cmp.w %d6,%d3           //   if (y0 > ymax)
    jgt .DP_l_end0          //     return 0

    move.w %a3,%d2          //   x0 = BMP_WIDTH - 1
                            // }

.DP_l_xl_ok:
    move.w %d3,640(%sp)     // minYL = y0
    move.l %sp,%d0
    add.w %d3,%d0
    add.w %d3,%d0
    move.l %d0,%a1          // a1 = edge = &leftEdge[minYL]

.DP_l_loop:

    // Clip Y1 against ymax

    cmp.w %d6,%d5           // if (y1 > ymax)
    jle .DP_l_y1_ok         // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    sub.w %d6,%d5
    muls.w %d5,%d0
    divs.w %d1,%d0          //   d0 = adj = ((y1 - ymax) * dx) / dy
    sub.w %d0,%d4           //   x1 -= adj
    move.w %d6,%d5          //   y1 = ymax
                            // }

    // clip X0 < 0

.DP_l_y1_ok:
    tst.w %d2               // if (x0 < 0)
    jge .DP_l_x0p           // {
    move.w %d4,%d0          //   if (x1 < 0)
    jge .DP_l_x0n_x1p       //   {

    move.w %d5,%d1
    sub.w %d3,%d1           //     d1 = dy = len
    jlt .DP_l_end0          //     if (dy < 0) return 0

    jeq .DP_l_next          //     if (dy)
                            //     {
    moveq #0,%d7            //       d7 = x
    pea .DP_l_next          //       fillEdgeFast
    jra fillEdgeFast        //     }

                            //     goto next
                            //   }
.DP_l_x0n_x1p:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_l_end0          //   if (dy < 0) return 0

    sub.w %d2,%d0           //   d0 = dx

    muls.w %d2,%d1
    moveq #0,%d2            //   d1 = adj = (x0 * dy) / dx
    divs.w %d0,%d1          //   x0 = 0

    jeq .DP_l_test_x1p      //   if (adj)
                            //   {
    sub.w %d1,%d3           //     y0 -= adj
    neg.w %d1               //     d1 = -adj = len
    moveq #0,%d7            //     d7 = x

    pea .DP_l_test_x1p      //     fillEdgeFast
    jra fillEdgeFast        //   }

                            //   goto test X1 >= BMP_WIDTH
                            // }

.DP_l_end0:
    lea 644(%sp),%sp        // release memory for edge table and others
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts


    // clip X1 < 0

.DP_l_x0p:
    cmp.w %a3,%d4           // if (x1 < 0)
    jls .DP_l_x1_ok         // {
    jgt .DP_l_x1p

    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_l_end0          //   if (dy < 0) return 0

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx

    move.w %d1,%d3
    muls.w %d4,%d3
    divs.w %d0,%d3          //   d3 = adj = (x1 * dy) / dx

    sub.w %d3,%d1           //   dy -= adj
    jeq .DP_l_x1n_1         //   if (dy)
                            //   {
    moveq #0,%d0
    sub.w %d2,%d0           //     d0 = new dx
    move.w %d2,%d7          //     d7 = x

    jsr fillEdge            //     fillEdge
                            //   }
.DP_l_x1n_1:
    tst.w %d3               //
    jeq .DP_l_next          //   if (adj)
                            //   {
    move.w %d3,%d1          //     d1 = dy
    moveq #0,%d7            //     d7 = x

    pea .DP_l_next          //     fillEdgeFast
    jra fillEdgeFast        //   }

                            //   goto next
                            // }

   // clip x1 >= BMP_WIDTH

.DP_l_test_x1p:
    cmp.w %a3,%d4           // if (x1 >= BMP_WIDTH)
    jle .DP_l_x1_ok         // {

.DP_l_x1p:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_l_end0          //   if (dy < 0) return 0

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx

    sub.w %a3,%d4
    muls.w %d1,%d4
    divs.w %d0,%d4          //   d4 = adj = ((x1 - (BMP_WIDTH - 1)) * dy) / dx

    sub.w %d4,%d5           //   y1 -= adj
    move.w %d5,%d6          //   ymax = y1

    sub.w %d4,%d1           //   d1 = dy = (dy - adj)
    jeq .DP_l_done          //   if (dy)
                            //   {
    move.w %a3,%d0
    sub.w %d2,%d0           //     d0 = dx
    move.w %d2,%d7          //     d7 = x
                            //
    pea .DP_l_done          //     fillEdge        //; d7.w = x; d0 = dx; d1 = dy
    jra fillEdge            //   }

                            //   goto done
                            // }

.DP_l_x1_ok:
    move.w %d5,%d1
    sub.w %d3,%d1           // d1 = dy
    jlt .DP_l_end0          // if (dy < 0) return 0

    jeq .DP_l_next          // if (dy)
                            // {
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x

    jsr fillEdge            //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
                            // }
.DP_l_next:
    cmp.w %d6,%d5           // if (y1 >= ymax)
    jge .DP_l_done          //   goto DP_l_done

    move.w %d4,%d2          // x0 = x1
    move.w %d5,%d3          // y0 = y1
    cmp.l %a4,%a0           // if (pt == ptFirst)
    jne .DP_l_next_ok

    move.l %a5,%a0          //   pt = ptLast

.DP_l_next_ok:
    move.w -(%a0),%d5       // y1 = pt->y
    move.w -(%a0),%d4       // x1 = pt->x
    jra .DP_l_loop


.DP_l_done:

    // RIGHT WITH X CLIP
    // -----------------

    move.l %a2,%a0          // a0 = pt = ptYMin

    move.l (%a0)+,%d2       // d2.wl = y0   d2.wh = x0
    cmp.l %a5,%a0           // if (pt == ptLast)
    jne .DP_r_first

    move.l %a4,%a0          //   pt = ptFirst

.DP_r_first:
    move.l (%a0)+,%d4       // d4.wl = y1   d4.wh = x1

    tst.w %d4               // while (y1 <= 0)
    jgt .DP_r_y1l_ok        // {

.DP_r_y1l_loop:
    move.l %d4,%d2          //   d2.wl = y0   d2.wh = x0
    cmp.l %a5,%a0           //   if (pt == ptLast)
    jne .DP_r_y1l_next

    move.l %a4,%a0          //     pt = ptFirst

.DP_r_y1l_next:
    move.l (%a0)+,%d4       //   d4.wl = y1   d4.wh = x1
    tst.w %d4               // }
    jle .DP_r_y1l_loop

.DP_r_y1l_ok:
    move.w %d2,%d3          // d3 = y0
    swap %d2                // d2 = x0
    move.w %d4,%d5          // d5 = y1
    swap %d4                // d4 = x1

    // Clip Y0

    tst.w %d3               // if (y0 < 0)
    jge .DP_r_y0_ok         // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    muls.w %d3,%d0
    divs.w %d1,%d0          //   d0 = adj = (y0 * dx) / dy
    sub.w %d0,%d2           //   x0 -= adj
    moveq #0,%d3            //   y0 = 0
                            // }
.DP_r_y0_ok:

    // Clip X BEFORE

    tst.w %d2               // if (x0 < 0)
    jge .DP_r_xl_ok         // {
    tst.w %d4               //   while (x1 < 0)
    jge .DP_r_x0_clip       //   {

.DP_r_xl_loop:
    cmp.w %d4,%d2           //     if (x0 > x1)
    jgt .DP_r_end0          //       return 0
    cmp.w %d6,%d5           //     if (y1 >= ymax)
    jge .DP_r_end0          //       return 0

    move.w %d4,%d2          //     x0 = x1
    move.w %d5,%d3          //     y0 = y1
    cmp.l %a5,%a0           //     if (pt == ptLast)
    jne .DP_r_xl_next

    move.l %a4,%a0          //     pt = ptFirst

.DP_r_xl_next:
    move.w (%a0)+,%d4       //     x1 = pt->x
    move.w (%a0)+,%d5       //     y1 = pt->y
    tst.w %d4
    jlt .DP_r_xl_loop       //   }

.DP_r_x0_clip:
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    muls.w %d2,%d1
    divs.w %d0,%d1          //   d1 = adj = (x0 * dy) / dx
    sub.w %d1,%d3           //   y0 -= adj

    cmp.w %d6,%d3           //   if (y0 > ymax)
    jgt .DP_r_end0          //     return 0

    moveq #0,%d2            //   x0 = 0
                            // }

.DP_r_xl_ok:
    move.w %d3,642(%sp)     // minYR = y0
    lea 320(%sp),%a1        // a1 = &rightEdge[0]
    add.w %d3,%a1
    add.w %d3,%a1           // a1 = edge = &rightEdge[minYR]

.DP_r_loop:

    // Clip Y1 against ymax

    cmp.w %d6,%d5           // if (y1 > ymax)
    jle .DP_r_y1_ok         // {

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy

    sub.w %d6,%d5
    muls.w %d5,%d0
    divs.w %d1,%d0          //   d0 = adj = ((y1 - ymax) * dx) / dy
    sub.w %d0,%d4           //   x1 -= adj
    move.w %d6,%d5          //   y1 = ymax
                            // }

    // clip X0 >= BMP_WIDTH

.DP_r_y1_ok:
    cmp.w %a3,%d2           // if (x0 >= BMP_WIDTH)
    jle .DP_r_x0p           // {
    cmp.w %a3,%d4           //   if (x1 >= BMP_WIDTH)
    jle .DP_r_x0n_x1p       //   {

    move.w %d5,%d1
    sub.w %d3,%d1           //     d1 = dy = len
    jlt .DP_r_end0          //     if (dy < 0) return 0

    jeq .DP_r_next          //     if (dy)
                            //     {
    move.w %a3,%d7          //       d7 = x
    pea .DP_r_next          //       fillEdgeFast
    jra fillEdgeFast        //     }

                            //     goto next
                            //   }
.DP_r_x0n_x1p:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_r_end0          //   if (dy < 0) return 0

    move.w %d2,%d0
    sub.w %d4,%d0           //   d0 = -dx

    sub.w %a3,%d2           //   d2 = x0 - (BMP_WIDTH - 1)
    muls.w %d2,%d1
    move.w %a3,%d2          //   d1 = adj = (((BMP_WIDTH - 1) - x0) * dy) / dx
    divs.w %d0,%d1          //   x0 = BMP_WIDTH - 1

    jeq .DP_r_test_x1p      //   if (adj)
                            //   {
    add.w %d1,%d3           //     y0 += adj
    move.w %a3,%d7          //     d7 = x

    pea .DP_r_test_x1p      //     fillEdgeFast
    jra fillEdgeFast        //   }

                            //   goto test X1 >= BMP_WIDTH
                            // }

.DP_r_end0:
    lea 644(%sp),%sp        // release memory for edge table and others
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts


    // clip X1 >= BMP_WIDTH

.DP_r_x0p:
    cmp.w %a3,%d4           // if (x1 >= BMP_WIDTH)
    jls .DP_r_x1_ok         // {
    jle .DP_r_x1p

    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_r_end0          //   if (dy < 0) return 0

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx

    move.w %d4,%d7
    sub.w %a3,%d7           //   d7 = x1 - (BMP_WIDTH - 1)
    move.w %d1,%d3          //   d3 = dy

    muls.w %d7,%d3
    divs.w %d0,%d3          //   d3 = adj = ((x1 - (BMP_WIDTH - 1)) * dy) / dx

    sub.w %d3,%d1           //   dy -= adj
    jeq .DP_r_x1n_1         //   if (dy)
                            //   {
    move.w %a3,%d0
    sub.w %d2,%d0           //     d0 = new dx
    move.w %d2,%d7          //     d7 = x

    jsr fillEdge            //     fillEdge
                            //   }
.DP_r_x1n_1:
    tst.w %d3               //
    jeq .DP_r_next          //   if (adj)
                            //   {
    move.w %d3,%d1          //     d1 = dy
    move.w %a3,%d7          //     d7 = x

    pea .DP_r_next          //     fillEdgeFast
    jra fillEdgeFast        //   }

                            //   goto next
                            // }

   // clip x1 < 0

.DP_r_test_x1p:
    tst.w %d4               // if (x1 < 0)
    jge .DP_r_x1_ok         // {

.DP_r_x1p:
    move.w %d5,%d1
    sub.w %d3,%d1           //   d1 = dy
    jlt .DP_r_end0         	//   if (dy < 0) return 0

    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx

    muls.w %d1,%d4
    divs.w %d0,%d4          //   d4 = adj = (x1 * dy) / dx

    sub.w %d4,%d5           //   y1 -= adj
    cmp.w %d6,%d5           //   if (y1 < ymax)
    jge .DP_r_ymax_ok

    move.w %d5,%d6          //     ymax = y1

.DP_r_ymax_ok:
    sub.w %d4,%d1           //   d1 = dy = (dy - adj)
    jeq .DP_r_done          //   if (dy)
                            //   {
    moveq #0,%d0
    sub.w %d2,%d0           //     d0 = dx
    move.w %d2,%d7          //     d7 = x

    pea .DP_r_done          //     fillEdge        //; d7.w = x; d0 = dx; d1 = dy
    jra fillEdge            //   }

                            //   goto done
                            // }

.DP_r_x1_ok:
    move.w %d5,%d1
    sub.w %d3,%d1           // d1 = dy
    jlt .DP_r_end0          // if (dy < 0) return 0

    jeq .DP_r_next          // if (dy)
                            // {
    move.w %d4,%d0
    sub.w %d2,%d0           //   d0 = dx
    move.w %d2,%d7          //   d7 = x

    jsr fillEdge            //   fillEdge        //; d7.w = x; d0 = dx; d1 = dy
                            // }
.DP_r_next:
    cmp.w %d6,%d5           // if (y1 >= ymax)
    jge .DP_r_done          //   goto DP_r_done

    move.w %d4,%d2          // x0 = x1
    move.w %d5,%d3          // y0 = y1
    cmp.l %a5,%a0           // if (pt == ptLast)
    jne .DP_r_next_ok

    move.l %a4,%a0          //     pt = ptFirst

.DP_r_next_ok:
    move.w (%a0)+,%d4       // x1 = pt->x
    move.w (%a0)+,%d5       // y1 = pt->y
    jra .DP_r_loop


.DP_r_done:
    move.w 642(%sp),%d2     // d2 = minYR, d6 = maxY
    move.w 640(%sp),%d3     // d3 = minYL

    cmp.w %d2,%d3           // if (minYL > minYR)
    jle .drawPolygon

    move.w %d3,%d2          // d2 = minYL

    // polygon drawing
    // ---------------

.drawPolygon:
    subq.w #1,%d6               // we do not draw the last line (simpler)

.drawPolygon_SL:
    sub.w %d2,%d6               // d6 = len = maxY - minY
    jlt .dp_end0                // < 0 = nothing to draw --> exit

    move.b 644+59(%sp),%d1      // d1 = col

    move.b %d1,-(%sp)
    move.w (%sp)+,%d0           // d0 = d1 << 8
    move.b %d1,%d0              // d0 = col word extended
    move.w %d0,%d1              // d1 = col word extended
    swap %d1
    move.w %d0,%d1              // d1 = odd line col extended to 32 bits

    move.l %d1,%d0
    rol.l  #4,%d0               // d0 = even line col exchanged to 32 bits
    btst   #0,%d2               // odd line ?
    jeq    .dp_odd_line

    exg    %d0,%d1              // change to odd color scheme

.dp_odd_line:
    add.w %d2,%d2               // d2 = minY * 2
    lea 0(%sp,%d2.w),%a2        // a2 = edgeL = &leftEdge[minY]
    lea 320(%a2),%a3            // a3 = edgeR = &rightEdge[minY]

    move.l bmp_buffer_write,%a0
    lsl.w  #6,%d2
    add.w  %d2,%a0              // a0 = buf = &bmp_buffer_write[minY * BMP_PITCH]

                                // while (len--)
.dp_293:                        // {
    move.w (%a2)+,%d2           //   xl = *edgeL
    jge .dp_291

    moveq #0,%d2

.dp_291:
    move.w (%a3)+,%d3           //   xr = *edgeR
//    cmp.w #255,%d3
//    jle .dp_292

//    move.w #255,%d3

.dp_292:
    cmp.w %d2,%d3               //   if (xr < xl) continue;
    jlt .dp_175

.dp_290:
    asr.w  #1,%d2               //   a1 = dst = &buf[xl >> 1]
    lea    (%a0,%d2.w),%a1      //   if (xl & 1)
    jcc    .dp_179              //   {

    moveq  #-16,%d4
    and.b  (%a1),%d4            //     d4 = buf[xl >> 1] & 0xF0
    moveq  #15,%d5
    and.b  %d0,%d5              //     d5 = color & 0x0F
    or.b   %d4,%d5
    move.b %d5,(%a1)+           //     buf[xl >> 1] = (buf[xl >> 1] & 0xF0) // (color & 0x0F)
    addq.w #1,%d2               //     xl++
                                //   }
.dp_179:
    asr.w  #1,%d3               //   if (!(xr & 1))
    jcs    .dp_180              //   {

    moveq  #15,%d4
    and.b  (%a0,%d3.w),%d4      //     d4 = buf[xr >> 1] & 0x0F
    moveq  #-16,%d5
    and.b  %d0,%d5              //     d5 = color & 0xF0
    or.b   %d4,%d5
    move.b %d5,(%a0,%d3.w)      //     buf[xr >> 1] = (buf[xr >> 1] & 0x0F) // (color & 0xF0)
    subq.w #1,%d3               //     xr--
                                //   }
.dp_180:
    sub.w  %d2,%d3              //   d3 = width
    jlt    .dp_175

    asr.w  #1,%d2               //   dst is byte aligned ?
    jcc    .dp_163

    move.b %d0,(%a1)+           //   align dst to word
    subq.w #1,%d3

.dp_163:
    add.w  %d3,%d3
    add.w  %d3,%d3              //   d3 = width * 4

.dp_fill_base:
    move.l (.dp_fill_table-.dp_fill_base)-2(%pc,%d3.w),%a4
    jmp (%a4)

.dp_end0:
    lea 644(%sp),%sp            // release memory for edge table and others
    moveq #0,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

    .align 4
    .long .dp_175
    .long .dp_175
    .long .dp_175

.dp_fill_table:
    .long .dp_fill_01
    .long .dp_fill_02
    .long .dp_fill_03
    .long .dp_fill_04
    .long .dp_fill_05
    .long .dp_fill_06
    .long .dp_fill_07
    .long .dp_fill_08
    .long .dp_fill_09
    .long .dp_fill_10
    .long .dp_fill_11
    .long .dp_fill_12
    .long .dp_fill_13
    .long .dp_fill_14
    .long .dp_fill_15
    .long .dp_fill_16
    .long .dp_fill_17
    .long .dp_fill_18
    .long .dp_fill_19
    .long .dp_fill_20
    .long .dp_fill_21
    .long .dp_fill_22
    .long .dp_fill_23
    .long .dp_fill_24
    .long .dp_fill_25
    .long .dp_fill_26
    .long .dp_fill_27
    .long .dp_fill_28
    .long .dp_fill_29
    .long .dp_fill_30
    .long .dp_fill_31
    .long .dp_fill_32
    .long .dp_fill_33
    .long .dp_fill_34
    .long .dp_fill_35
    .long .dp_fill_36
    .long .dp_fill_37
    .long .dp_fill_38
    .long .dp_fill_39
    .long .dp_fill_40
    .long .dp_fill_41
    .long .dp_fill_42
    .long .dp_fill_43
    .long .dp_fill_44
    .long .dp_fill_45
    .long .dp_fill_46
    .long .dp_fill_47
    .long .dp_fill_48
    .long .dp_fill_49
    .long .dp_fill_50
    .long .dp_fill_51
    .long .dp_fill_52
    .long .dp_fill_53
    .long .dp_fill_54
    .long .dp_fill_55
    .long .dp_fill_56
    .long .dp_fill_57
    .long .dp_fill_58
    .long .dp_fill_59
    .long .dp_fill_60
    .long .dp_fill_61
    .long .dp_fill_62
    .long .dp_fill_63
    .long .dp_fill_64
    .long .dp_fill_65
    .long .dp_fill_66
    .long .dp_fill_67
    .long .dp_fill_68
    .long .dp_fill_69
    .long .dp_fill_70
    .long .dp_fill_71
    .long .dp_fill_72
    .long .dp_fill_73
    .long .dp_fill_74
    .long .dp_fill_75
    .long .dp_fill_76
    .long .dp_fill_77
    .long .dp_fill_78
    .long .dp_fill_79
    .long .dp_fill_80
    .long .dp_fill_81
    .long .dp_fill_82
    .long .dp_fill_83
    .long .dp_fill_84
    .long .dp_fill_85
    .long .dp_fill_86
    .long .dp_fill_87
    .long .dp_fill_88
    .long .dp_fill_89
    .long .dp_fill_90
    .long .dp_fill_91
    .long .dp_fill_92
    .long .dp_fill_93
    .long .dp_fill_94
    .long .dp_fill_95
    .long .dp_fill_96
    .long .dp_fill_97
    .long .dp_fill_98
    .long .dp_fill_99
    .long .dp_fill_100
    .long .dp_fill_101
    .long .dp_fill_102
    .long .dp_fill_103
    .long .dp_fill_104
    .long .dp_fill_105
    .long .dp_fill_106
    .long .dp_fill_107
    .long .dp_fill_108
    .long .dp_fill_109
    .long .dp_fill_110
    .long .dp_fill_111
    .long .dp_fill_112
    .long .dp_fill_113
    .long .dp_fill_114
    .long .dp_fill_115
    .long .dp_fill_116
    .long .dp_fill_117
    .long .dp_fill_118
    .long .dp_fill_119
    .long .dp_fill_120
    .long .dp_fill_121
    .long .dp_fill_122
    .long .dp_fill_123
    .long .dp_fill_124
    .long .dp_fill_125
    .long .dp_fill_126
    .long .dp_fill_127
    .long .dp_fill_128
    .long .dp_fill_129
    .long .dp_fill_129
    .long .dp_fill_129
    .long .dp_fill_129

.dp_fill_128:
    move.l %d0,(%a1)+
.dp_fill_124:
    move.l %d0,(%a1)+
.dp_fill_120:
    move.l %d0,(%a1)+
.dp_fill_116:
    move.l %d0,(%a1)+
.dp_fill_112:
    move.l %d0,(%a1)+
.dp_fill_108:
    move.l %d0,(%a1)+
.dp_fill_104:
    move.l %d0,(%a1)+
.dp_fill_100:
    move.l %d0,(%a1)+
.dp_fill_96:
    move.l %d0,(%a1)+
.dp_fill_92:
    move.l %d0,(%a1)+
.dp_fill_88:
    move.l %d0,(%a1)+
.dp_fill_84:
    move.l %d0,(%a1)+
.dp_fill_80:
    move.l %d0,(%a1)+
.dp_fill_76:
    move.l %d0,(%a1)+
.dp_fill_72:
    move.l %d0,(%a1)+
.dp_fill_68:
    move.l %d0,(%a1)+
.dp_fill_64:
    move.l %d0,(%a1)+
.dp_fill_60:
    move.l %d0,(%a1)+
.dp_fill_56:
    move.l %d0,(%a1)+
.dp_fill_52:
    move.l %d0,(%a1)+
.dp_fill_48:
    move.l %d0,(%a1)+
.dp_fill_44:
    move.l %d0,(%a1)+
.dp_fill_40:
    move.l %d0,(%a1)+
.dp_fill_36:
    move.l %d0,(%a1)+
.dp_fill_32:
    move.l %d0,(%a1)+
.dp_fill_28:
    move.l %d0,(%a1)+
.dp_fill_24:
    move.l %d0,(%a1)+
.dp_fill_20:
    move.l %d0,(%a1)+
.dp_fill_16:
    move.l %d0,(%a1)+
.dp_fill_12:
    move.l %d0,(%a1)+
.dp_fill_08:
    move.l %d0,(%a1)+
.dp_fill_04:
    move.l %d0,(%a1)

.dp_175:
    lea 128(%a0),%a0
    exg %d0,%d1                 //   exchange color scheme
    dbra %d6,.dp_293            // }

    lea 644(%sp),%sp            // release memory for edge table and others
    moveq #1,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

.dp_fill_126:
    move.l %d0,(%a1)+
.dp_fill_122:
    move.l %d0,(%a1)+
.dp_fill_118:
    move.l %d0,(%a1)+
.dp_fill_114:
    move.l %d0,(%a1)+
.dp_fill_110:
    move.l %d0,(%a1)+
.dp_fill_106:
    move.l %d0,(%a1)+
.dp_fill_102:
    move.l %d0,(%a1)+
.dp_fill_98:
    move.l %d0,(%a1)+
.dp_fill_94:
    move.l %d0,(%a1)+
.dp_fill_90:
    move.l %d0,(%a1)+
.dp_fill_86:
    move.l %d0,(%a1)+
.dp_fill_82:
    move.l %d0,(%a1)+
.dp_fill_78:
    move.l %d0,(%a1)+
.dp_fill_74:
    move.l %d0,(%a1)+
.dp_fill_70:
    move.l %d0,(%a1)+
.dp_fill_66:
    move.l %d0,(%a1)+
.dp_fill_62:
    move.l %d0,(%a1)+
.dp_fill_58:
    move.l %d0,(%a1)+
.dp_fill_54:
    move.l %d0,(%a1)+
.dp_fill_50:
    move.l %d0,(%a1)+
.dp_fill_46:
    move.l %d0,(%a1)+
.dp_fill_42:
    move.l %d0,(%a1)+
.dp_fill_38:
    move.l %d0,(%a1)+
.dp_fill_34:
    move.l %d0,(%a1)+
.dp_fill_30:
    move.l %d0,(%a1)+
.dp_fill_26:
    move.l %d0,(%a1)+
.dp_fill_22:
    move.l %d0,(%a1)+
.dp_fill_18:
    move.l %d0,(%a1)+
.dp_fill_14:
    move.l %d0,(%a1)+
.dp_fill_10:
    move.l %d0,(%a1)+
.dp_fill_06:
    move.l %d0,(%a1)+
.dp_fill_02:
    move.w %d0,(%a1)

    lea 128(%a0),%a0
    exg %d0,%d1                 //   exchange color scheme
    dbra %d6,.dp_293            // }

    lea 644(%sp),%sp            // release memory for edge table and others
    moveq #1,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

.dp_fill_129:
    move.l %d0,(%a1)+
.dp_fill_125:
    move.l %d0,(%a1)+
.dp_fill_121:
    move.l %d0,(%a1)+
.dp_fill_117:
    move.l %d0,(%a1)+
.dp_fill_113:
    move.l %d0,(%a1)+
.dp_fill_109:
    move.l %d0,(%a1)+
.dp_fill_105:
    move.l %d0,(%a1)+
.dp_fill_101:
    move.l %d0,(%a1)+
.dp_fill_97:
    move.l %d0,(%a1)+
.dp_fill_93:
    move.l %d0,(%a1)+
.dp_fill_89:
    move.l %d0,(%a1)+
.dp_fill_85:
    move.l %d0,(%a1)+
.dp_fill_81:
    move.l %d0,(%a1)+
.dp_fill_77:
    move.l %d0,(%a1)+
.dp_fill_73:
    move.l %d0,(%a1)+
.dp_fill_69:
    move.l %d0,(%a1)+
.dp_fill_65:
    move.l %d0,(%a1)+
.dp_fill_61:
    move.l %d0,(%a1)+
.dp_fill_57:
    move.l %d0,(%a1)+
.dp_fill_53:
    move.l %d0,(%a1)+
.dp_fill_49:
    move.l %d0,(%a1)+
.dp_fill_45:
    move.l %d0,(%a1)+
.dp_fill_41:
    move.l %d0,(%a1)+
.dp_fill_37:
    move.l %d0,(%a1)+
.dp_fill_33:
    move.l %d0,(%a1)+
.dp_fill_29:
    move.l %d0,(%a1)+
.dp_fill_25:
    move.l %d0,(%a1)+
.dp_fill_21:
    move.l %d0,(%a1)+
.dp_fill_17:
    move.l %d0,(%a1)+
.dp_fill_13:
    move.l %d0,(%a1)+
.dp_fill_09:
    move.l %d0,(%a1)+
.dp_fill_05:
    move.l %d0,(%a1)+
    move.b %d0,(%a1)

    lea 128(%a0),%a0
    exg %d0,%d1                 //   exchange color scheme
    dbra %d6,.dp_293            // }

    lea 644(%sp),%sp            // release memory for edge table and others
    moveq #1,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts

.dp_fill_127:
    move.l %d0,(%a1)+
.dp_fill_123:
    move.l %d0,(%a1)+
.dp_fill_119:
    move.l %d0,(%a1)+
.dp_fill_115:
    move.l %d0,(%a1)+
.dp_fill_111:
    move.l %d0,(%a1)+
.dp_fill_107:
    move.l %d0,(%a1)+
.dp_fill_103:
    move.l %d0,(%a1)+
.dp_fill_99:
    move.l %d0,(%a1)+
.dp_fill_95:
    move.l %d0,(%a1)+
.dp_fill_91:
    move.l %d0,(%a1)+
.dp_fill_87:
    move.l %d0,(%a1)+
.dp_fill_83:
    move.l %d0,(%a1)+
.dp_fill_79:
    move.l %d0,(%a1)+
.dp_fill_75:
    move.l %d0,(%a1)+
.dp_fill_71:
    move.l %d0,(%a1)+
.dp_fill_67:
    move.l %d0,(%a1)+
.dp_fill_63:
    move.l %d0,(%a1)+
.dp_fill_59:
    move.l %d0,(%a1)+
.dp_fill_55:
    move.l %d0,(%a1)+
.dp_fill_51:
    move.l %d0,(%a1)+
.dp_fill_47:
    move.l %d0,(%a1)+
.dp_fill_43:
    move.l %d0,(%a1)+
.dp_fill_39:
    move.l %d0,(%a1)+
.dp_fill_35:
    move.l %d0,(%a1)+
.dp_fill_31:
    move.l %d0,(%a1)+
.dp_fill_27:
    move.l %d0,(%a1)+
.dp_fill_23:
    move.l %d0,(%a1)+
.dp_fill_19:
    move.l %d0,(%a1)+
.dp_fill_15:
    move.l %d0,(%a1)+
.dp_fill_11:
    move.l %d0,(%a1)+
.dp_fill_07:
    move.l %d0,(%a1)+
.dp_fill_03:
    move.w %d0,(%a1)+
.dp_fill_01:
    move.b %d0,(%a1)

    lea 128(%a0),%a0
    exg %d0,%d1                 //   exchange color scheme
    dbra %d6,.dp_293            // }

    lea 644(%sp),%sp            // release memory for edge table and others
    moveq #1,%d0
    movm.l (%sp)+,%d2-%d7/%a2-%a6
    rts
