;by Sean Palmer--Public Domain. Please credit me if you use it. ideal model tpascal p386n extrn segA000:word codeseg public line proc line near x:word,y:word,x2:word,y2:word,c:byte mov edi,[dword y] mov ebx,[dword y2] cmp di,bx jle @@TOPDOWN ;always draw top-down to normalize lines mov [dword y],ebx ;swap coord pairs to keep from drawing bottom-up mov [dword y2],edi ;stack is top down, left-to-right. Do pair as one dword xchg di,bx @@TOPDOWN: sub bx,di ;bx=positive vertical distance mov cx,320 ;screen width, used to step to next line down shl di,6 ;*64*(4+1)=*320 lea di,[edi*4+edi] add di,[x] shl edi,16 ;dest adr out of harm's way for now mov dx,1 ;from one pixel to the next on the right mov ax,[x2] sub ax,[x] jnc @@XS neg ax neg dx @@XS: cmp ax,bx jae @@XMAJ xchg bx,ax xchg cx,dx @@XMAJ: mov si,ax neg si test cx,cx jns @@SGNOK dec si ;adjust for consistent carry into edihi @@SGNOK: ;this is safe because di will not overflow (line offscreen) shl esi,16 ;esihi=decision var adjuster for minor step mov si,cx ;si=minor step for di mov cx,ax ;set line length to major axis distance-1 mov di,ax ;set decision var halfway in edihi neg di sar di,1 rol edi,16 test dx,dx jns @@SGNOK2 dec bx ;adjust for consistent carry into edihi @@SGNOK2: ;this is safe because di will not overflow (line offscreen) shl ebx,16 ;ebxhi=major adjust for decision var mov bx,dx ;bx=major adjust for dest adr mov ah,[c] ;color push ds mov ds,[segA000] ; this inner loop's about as optimized as it's gonna get, and ; still have edx,ecxhi,al,and eaxhi left over. Could even use ebp... ; would work really well in a 32-bit operand segment. ; as it is, the benefits over the old version is mainly the unrolling ; of the loop, and the fact that it no longer uses memory variables. shr cx,1 jc @@L ;unrolled 2x below, so take care of odd count case mov [di],ah dec cx js @@X add edi,ebx jns @@MIN2 @@L: mov [di],ah ;plot pixel add edi,ebx ;do major step jns @@MIN ;did decision var wrap? (do NOT test carry!) mov [di],ah ;kinda unrolled again here. Doesn't help on a Pentium. dec cx ;check counter every two major steps js @@X add edi,ebx ;do major step js @@L @@MIN2: add edi,esi ;adjust decision var/adr for minor step jmp @@L @@X: ;clean up and exit pop ds ret @@MIN: ;Minor step for first unrolled part add edi,esi ;adjust decision var/adr for minor step mov [di],ah ;kinda unrolled again here. Doesn't help on a Pentium. dec cx js @@X add edi,ebx ;did decision var wrap? and do major step js @@L add edi,esi jmp @@L endp ends end