;*************************************************************************** ; FastLine - Snabba linjedragningsrutiner f”r MCGA och 286 eller h”gre ; Programmerat av: Andreas Henning ; Med stort tack till: Johan Arnstr”m ,f”r optimering av koden. ; ; Historiska data: ; ; Rutinen bygger p† en algoritm utvecklad av IBM-forskaren ; Bresenham, en algoritm som bara kr„ver additioner och subtraktioner, ; vilket g”r den mycket snabb. ; Genom utnyttjande av 286 instruktioner s† har vi ocks† eliminerat ; den multiplikation som annars kr„vs f”r att placera varje ; pixel i videominnet. ; Som rutinen ser ut nu s† „r den gjord f”r att k”ras frist†ende ; som en EXE fil, f”r att testa olika v„rden p† linjen. ; ; OBS! Jag tar inget ansvar f”r funktionaliteten hos denna rutin, ; den bortsk„nkes till Public Domain 'as is'. ; Programmeraren m†ste sj„lv se till att v„rdena som skickas ; till rutinen „r till†tna, annars kan rutinen ; skriva lite ”verallt i minnet. ; ; Rutinens anropsparametrar: ; ; Fastline(xstart,ystart,xend,yend:WORD) ; ; ; Hittar du en bug i denna rutin, eller ett s„tt att kraftigt ; h”ja hastigheten hos rutinen, ring till: ; ; Hot Bits BBS Tfn 035-62332 ; Gunship BBS Tfn 031-693306 ; ; Eller skriv : Andreas Henning ; Tr„l†sv„gen 23 ; 421 68 V.Fr”lunda ; ;*************************************************************************** .286 ;Till†t 286 instruktioner stack segment para stack 'stack' db 200h dup(0) stack ends DATA SEGMENT PARA PUBLIC 'DATA' ;Alla n”dv„ndiga variabler x dw ? ;Nuvarande x koordinat y dw ? ;Nuvarande y koordinat d dw ? ;Beslutsvariabel a dw ? ;Linjef”rflyttning x b dw ? ;Linjef”rflyttning y dx_diag dw ? ;Diagonalt x steg f”r n„sta pixel dy_diag dw ? ;Diagonalt y steg f”r n„sta pixel dx_nondiag dw ? ;Icke diagonalt som ovan dy_nondiag dw ? ;Icke diagonalt som ovan diag_inc dw ? ;d:s inkrement f”r diagonala steg nondiag_inc dw ? ;d:s inkrement f”r icke-diagonala steg xstart dw ? ;xkoordinatens startv„rde ystart dw ? ;ykoordinatens startv„rde xend dw ? ;xkoordinatens slutv„rde yend dw ? ;ykoordinatens slutv„rde DATA ENDS CODE SEGMENT PARA PUBLIC 'CODE' ;------------------------------------------------------------------------- ; Bresenhams algoritm, implementerad av Andreas Henning ;------------------------------------------------------------------------- FastLine PROC FAR assume cs:code ;Ge adressen till v†rt kodsegment push ds ;Spara PSP segment adress mov ax,0 ;0 till ax push ax ;Spara returadressen (psp+0) mov ax,data ;M†ste adressera DS indirekt mov ds,ax ;via ett annat register assume ds:data ;Ge adressen till v†rt data segment ;---- ;initialiserar start och slut v„rden f”r linjen ;---- mov xstart ,0 mov ystart ,0 mov xend ,319 mov yend ,199 ;--- ;S„tt MCGA 320x200x256 mode ;--- pusha ;286 eller h”gre. mov ah,0 ;S„tt video mov al,13h ;MCGA int 10h ;Biosanrop mov ax,xstart ;x=xstart mov x,ax mov ax,ystart ;y=ystart mov y,ax mov ax,xend ;a=xend-xstart (skillnad i x) mov bx,xstart sub ax,bx mov a,ax mov ax,yend ;b=yend-ystart (skillnad i y) mov bx,ystart sub ax,bx mov b,ax Test1: cmp a,0 ;J„mf”r a med 0 jge test1_1 ;Om ej mindre „n noll, hoppa till... neg a ;Om mindre „n noll, byt tecken p† a mov dx_diag,-1 ;och s„tt dx_diag till -1 jmp test2 ;n„sta test Test1_1: mov dx_diag,1 ;om a < 0 s„tt dx_diag till 1 Test2: cmp b,0 ;J„mf”r b med 0 jge test2_1 ;Om ej mindre „n noll, hoppa till... neg b ;Om mindre „n noll, byt tecken p† b mov dy_diag,-1 ;och s„tt dx_diag till -1 jmp Test3 ;n„sta test Test2_1: mov dy_diag,1 ;om b < 0 s„tt dy_diag till 1 Test3: mov ax,b ;Av n†n anledning g†r cmp a,b inte! cmp a,ax ;J„mf”r om b „r st”rre „n a jnl test3_1 ;om b „r mindre, hoppa till xchg a,ax ;s„tt a=b, och l„gg a i ax mov b,ax ;l„gg a i b via ax mov dx_nondiag,0 ;S„tt dx_nondiag till 0 mov ax,dy_diag ;l„gg dy_diag i ax mov dy_nondiag,ax ;dy_nondiag=dy_diag jmp Stora_loopen ;Hoppa till stora loopen! Test3_1: mov ax,dx_diag ;l„gg dx_diag i ax mov dx_nondiag,ax ;dx_nondiag=dx_diag mov dy_nondiag,0 ;dy_nondiag=0 ;--------------------------------------------------------------------------- ; H„r nedanf”r ligger den stora loopen, som genomf”r de 'tyngsta' ; ber„kningarna, „ven om de kanske inte „r s† tunga... ; Det „r h„r som man skall r„kna processorcykler om det beh”vs.... ;--------------------------------------------------------------------------- Stora_Loopen: mov ax,b ;L„gg b i ax shl ax,1 ;b+b H„r tj„nar jag 1 klockcykel! mov nondiag_inc,ax ;nondiag_inc=b+b sub ax,a ;dra bort a, dvs ax=b+b-a mov d,ax ;d=b+b-a sub ax,a ;ax=b+b-a-a mov diag_inc,ax ;diag_inc=b+b-a-a mov cx,a ;a=antalet ggr att upprepa loopen add cx,1 ;F”r att f† r„tt... push es ;Spara datasegmentet mov ax,0a000h ;Adressen till videominnet mov es,ax ;I ds mov bl,32h ;En gr”n pixel!!!! DunderLoop: ;--------------------------------------------------------------------------- ; H„r nedanf”r ligger den stora loopen, som genomf”r de 'tyngsta' ; ber„kningarna, „ven om de kanske inte „r s† tunga... ; Det „r h„r som man skall r„kna processorcykler om det beh”vs.... ;--------------------------------------------------------------------------- ;-------------------------------------------------------------- ; Rutinen som s„tter pixeln m†ste „ndras beroende p† vilken ; adapter man anv„nder. Denna „r avsedd f”r MCGA 320x200x256 ;-------------------------------------------------------------- ; Putpixel rutinen skriver direkt till sk„rmminnet ; Pr”va denna p† en icke-VGA, och din dator hibernerar!!! ;-------------------------------------------------------------- mov ax,y mov dx,ax shl ax,8 shl dx,6 add ax,dx add ax,x ;L„gg till x mov di,ax ;l„gg offseten i destinationsindex mov es:[di],bl ;L„gg pixeln i videominnet cmp d,0 ;J„mf”r d med 0 jge DunderLoop_2 ;Om st”rre „n 0, hoppa till mov ax,x ;L„gg x i ax add ax,dx_nondiag ;L„gg till dx_nondiag mov x,ax ;L„gg tillbaka x. x=x+dx_nondiag mov ax,y ;L„gg y i ax add ax,dy_nondiag ;L„gg till dy_nondiag mov y,ax ;L„gg tillbaka y. y=y+dy_nondiag mov ax,d ;L„gg d i ax add ax,nondiag_inc ;L„gg till nondiag_inc mov d,ax ;L„gg tillbaka d loop DunderLoop ;Loopa DunderLoop f”r hela linjen jmp Slut ;N„r linjen „r klar, hoppa till DunderLoop_2: ;Utf”rs om d „r st”rre „n 0 mov ax,x ;L„gg x i ax add ax,dx_diag ;L„gg till dx_diag mov x,ax ;L„gg tillbaka x. x=x+dx_diag mov ax,y ;L„gg y i ax add ax,dy_diag ;L„gg till dy_diag mov y,ax ;L„gg tillbaka y mov ax,d ;L„gg d i ax add ax,diag_inc ;L„gg till diag_inc mov d,ax ;L„gg tillbaka d loop DunderLoop Slut: pop es ;poppa tebax,_just det_! popa ;286 eller h”gre ret ;Tillbax till dos... FastLine ENDP CODE ENDS END FastLine