   %const %integer max vertex = 128,
                   insert limit = 5
   %record %format edge(%integer x0, y0, x1, y1, slope, %record(edge) %name l)
   %record(edge) niledge
   %own %integer pp = 0
   %record(edge) %array edges(1:max vertex)

   %integer %function muldiv(%integer a, b, c)
      *muls d1,d0
      *divs d2,d0
      *extl d0
      *add.l #12,a7
      *rts
      %result = a*b//c
   %end

   %routine sort edges(%integer l, r)
      %record(edge) key
      %integer key y, lp, rp, i

      %return %unless l<r
      %while r-l>insert limit %cycle
         lp = l
         rp = r+1
         key = edges(l)
         key y = key_y0
         %cycle
            rp = rp-1 %until rp=lp %or key y>edges(rp)_y0 %or %c
                          (key y=edges(rp)_y0 %and key_x0>edges(rp)_x0) %or %c
                          (key y=edges(rp)_y0 %and key_x0=edges(rp)_x0 %and %c
                           key_slope>edges(rp)_slope)
            %exit %if lp=rp
            edges(lp) = edges(rp)
            lp = lp+1 %until rp=lp %or key y<edges(lp)_y0 %or %c
                          (key y=edges(lp)_y0 %and key_x0<=edges(lp)_x0) %or %c
                          (key y=edges(lp)_y0 %and key_x0=edges(lp)_x0 %and %c
                           key_slope<=edges(rp)_slope)
            %exit %if lp=rp
            edges(rp) = edges(lp)
         %repeat
         edges(lp) = key
         %if lp-l>r-rp %start
            sort edges(rp+1, r)
            r = lp-1
         %finish %else %start
            sort edges(l, lp-1)
            l = rp+1
         %finish
      %repeat
      %for rp = l+1, 1, r %cycle
         key = edges(rp)
         key y = key_y0
         lp = l
         lp = lp+1 %while lp#rp %and (key y>edges(lp)_y0 %or %c
                           (key y=edges(lp)_y0 %and key_x0>edges(lp)_x0) %or %c
                           (key y=edges(lp)_y0 %and key_x0=edges(lp)_x0 %and %c
                            key_slope>edges(lp)_slope))
         %for i = rp-1, -1, lp %cycle
            edges(i+1) = edges(i)
         %repeat
         edges(lp) = key
      %repeat
   %end

   %routine poly(%integer x, y)
      %signal 11, 1 %if pp=max vertex
      pp = pp+1
      edges(pp)_x0 = x
      edges(pp)_y0 = y
   %end

%routine print poly(%string(32) mess, %record(edge)%name p, t)
   %record(edge) %name q
   q==p
   %while %not q==t %cycle
      printstring(mess)
      write(addr(q), 10); write(q_x0, 5)
      write(q_y0, 5); write(q_x1, 5)
      write(q_y1, 5); write(q_slope, 10)
      newline
      q==q_l
   %repeat
%end

   %routine close poly
      %record %format hl(%integer x0, x1, y)
      %record(edge) %name el, ael, e0, e1, nilael, p, l, q, r, s
      %record(hl) top, btm
      %integer i, x0, x1, y0
      %record(edge) %name d

      %routine set ends(%record(edge)%name e, %integer x, y)
         %if e_y0<y %or (e_y0=y %and e_x0<=x) %start
            e_x1 = x
            e_y1 = y
         %finish %else %start
            e_x1 = e_x0
            e_y1 = e_y0
            e_x0 = x
            e_y0 = y
         %finish
         %if e_y0=e_y1 %start
            e_slope = 0
         %finish %else %start
            e_slope = ((e_x1-e_x0)<<16)//(e_y1-e_y0)
         %finish
      %end

      %routine check top(%record(edge) %name e)
         %record(edge) %name p, l
         %if e_y1>top_y %start
            e_x0 = e_x0+muldiv(e_x1-e_x0, top_y-btm_y, e_y1-btm_y)
            e_y0 = top_y
            p == el
            %while (%not p==niledge) %and (p_y0<top_y %or %c
                       (p_y0=top_y %and p_x0<e_x0) %or %c
                       (p_y0=top_y %and p_x0=e_x0 %and p_slope<e_slope)) %cycle
               l == p
               p == p_l
            %repeat
            e_l == p
            %if p==el %then el == e %else l_l == e
         %finish %else %start
            e_x0 = e_x1
         %finish
      %end

      %return %if pp=0
      %if pp=1 %start
         plot(edges(1)_x0, edges(1)_y0)
      %finish %else %start
         e1 == edges(1)
         x0 = e1_x0
         y0 = e1_y0
         %for i = 1, 1, pp %cycle
            e0 == e1
            e1 == edges(i)
            set ends(e0, e1_x0, e1_y0)
         %repeat
         set ends(e1, x0, y0)
         sort edges(1, pp)
         e1 == edges(1)
         el == e1
         e0 == e1 %and e1 == edges(i) %and e0_l == e1 %for i = 2, 1, pp
         e1_l == niledge

         %cycle
            ael == el
            btm_y =ael_y0
            x0 = ael_x0
            x1 = x0
!print poly("start", el, niledge)
            el == el_l %until el==niledge %or el_y0#btm_y
            nilael == el
!print poly("split1", ael, nilael)
!print poly("split2",  el, niledge)
            %cycle
               %while (%not ael==nilael) %and %c
                                  ael_y1=btm_y %and ael_x0<=x1 %cycle
                  x1 = ael_x1 %if x1<ael_x1
                  ael == ael_l
               %repeat
               %exit %if ael==nilael
               e0 == ael
               ael == ael_l
               %if e0_y1=btm_y %start
                  %exit %if ael==nilael
                  line(x0, btm_y, x1, btm_y) %unless x0=x1
                  x0 = ael_x0
                  x1 = x0
                  %continue
               %finish

               %while (%not ael==nilael) %and ael_y1=btm_y %cycle
                  x1 = ael_x1 %if x1<ael_x1
                  ael == ael_l
               %repeat
               e1 == ael
               ael == ael_l
               line(x0, btm_y, e0_x0, btm_y) %if x0<e0_x0 %and x0<x1
               %if x1>e1_x0 %start
                  x0 = e1_x0
               %finish %else %if %not ael==nilael %start
                  x0 = ael_x0
                  x1 = x0
               %finish %else %start
                  x0 = x1
               %finish
               %if e0_y1<e1_y1 %start
                  top_y = e0_y1
               %finish %else %start
                  top_y = e1_y1
               %finish
               top_y = nilael_y0 %unless nilael==niledge %or top_y<nilael_y0
               btm_x0 = e0_x0
               check top(e0)
               top_x0 = e0_x0
               btm_x1 = e1_x0
               check top(e1)
               top_x1 = e1_x0
               trapeze(btm, top)
               p == el
               %while (%not p==niledge) %and p_y0<=top_y %cycle
                  %if p_y0=top_y %and p_y1=top_y %start
                     %if top_x0<=p_x0 %and p_x1<=top_x1 %start
                        %if p==el %start
                           el == p_l
                        %finish %else %start
                           l_l == p_l
                        %finish
                     %finish %else %if top_x0<p_x1<=top_x1 %start
                        p_x1 = top_x0
                     %finish %else %if top_x0<=p_x0<top_x1 %start
                        p_x0 = top_x1
                     %finish %else %if p_x0<top_x0 %and top_x1<p_x1 %start
                        pp = pp+1
                        q == edges(pp)
                        q_x0 = top_x1
                        q_y0 = top_y
                        q_x1 = p_x1
                        q_y1 = top_y
                        p_x1 = top_x0
                        r == p_l
                        %while (%not r==niledge) %and r_y0=top_y %and %c
                                                          r_x0<top_x1 %cycle
                           s == r
                           r == r_l
                        %repeat
                        q_l == r
                        %if r==p_l %then p_l == q %else s_l == q
                     %finish
                  %finish
                  l == p
                  p == p_l
               %repeat
            %repeat %until ael==nilael
            line(x0, btm_y, x1, btm_y) %unless x0=x1
         %repeat %until el==niledge
      %finish
      pp = 0
   %end
%end %of %file
