flat assembler
Message board for the users of flat assembler.

 Index > DOS > Drawing lines on 13h mode
Author
wyvern

Joined: 08 Dec 2011
Posts: 27
wyvern 11 Mar 2013, 19:25
Hi, im trying to draw a line from (x1,x2) to (y1,y2) with the slope-point line formula: y=slope(x-x1) +y1 .

Mi goal is to use this method first doing float-point-arithmetic and later implement more advanced/eficcient ways to draw a line.

For example, considering (x1=4, y1=23) and (x2=13,y2=21), i can plot the points from x1 to x2 one by one like you can see in the attached image, those points are colored in magenta.

But, the green line is the result of mi procedure to draw the same line, dont know why every point of the line is on the y=0 coords. The code is:

Code:
```;--------------------------------
; drawLine
;
; [bp - 2] = temp var / x
; [bp - 4] = y
;
; [bp + 4]  = x1
; [bp + 6]  = y1
; [bp + 8]  = x2
; [bp + 10] = y2
;-------------------------------
drawLine:      push      bp
mov       bp, sp
sub        sp, 4

mov       si, word [bp + 6]
fld         dword [si]
mov       si, word [bp + 10]
fsubr     dword [si]                 ;y1-y2

mov       si, word [bp + 4]
fld         dword [si]

fist        word [bp - 2]
mov       cx, word [bp - 2]

mov       si, word [bp + 8]
fld         dword [si]
fist         word [bp - 2]
mov       bx, word [bp - 2]
fsubrp    st(1), st(0)                 ;x1-x2

fdivp      st(1), st(0)                     ;slope=(y1-y2)/(x1-x2)

drawPoint:
cmp       cx, bx                        ;while x1 <= x2
jnle        finish

mov       word [bp - 2], cx         ;[bp-2]=cx=x
fild        dword [bp - 2]                ;st0=x
mov       si, word [bp + 8]         ;
fsubr     dword [si]                    ;x-x1
fmul      st(0), st(1)                  ;slope*(x-x1)

mov       si, word [bp + 6]
fadd      dword [si]                    ;y=slope*(x-x1) + y1

fistp       word [bp - 4]               ;store "y" in [bp-4]

push      word [colour]               ; colour
push      word [bp - 4]              ;  y
push      word [bp - 2]              ;   x
call        drawPixel                  ;plot in (X, Y)

inc         cx                             ;x+1
jmp       drawPoint

finish:
mov       sp, bp
pop       bp
ret        10

;data
x1     dd     4.0
y1      dd    23.0
x2      dd    13.0
y2      dd     21.0
colour  dw   0002h
```

When debugged, on the main drawLine loop, all the computed Y values for every X are just fine and are passed to drawPixel, the computed values are:

X Y
4 21
5 21
6 21
7 22
8 22
9 22
10 23
11 23
12 23

This are the same coordinates for the magenta manually ploted points, however just the green line appears.

By the way, im using Turbo Debugger and the "Numeric processor" view is not working (at least on DOSBOX), the STx regs appears as empty or unused all the time, it would be really cool to make it work.

 Description: Filesize: 14.4 KB Viewed: 8104 Time(s)

_________________
Thanks
11 Mar 2013, 19:25
revolution
When all else fails, read the source

Joined: 24 Aug 2004
Posts: 20138
revolution 11 Mar 2013, 20:19
Perhaps Bresenham's line algorithm would be better for the task?
11 Mar 2013, 20:19
wyvern

Joined: 08 Dec 2011
Posts: 27
wyvern 11 Mar 2013, 20:31
Hi revolution:

Is not exactly a "task", i want to learn from the basis, sure later i will try the Bresenham's algorithm. But this is mi first attempt to draw a line and i want to make it work.
11 Mar 2013, 20:31
f0dder

Joined: 19 Feb 2004
Posts: 3175
Location: Denmark
f0dder 11 Mar 2013, 21:15
revolution wrote:
Perhaps Bresenham's line algorithm would be better for the task?

Some years ago I bumped into an article claiming that DDA is actually faster than Bresenham on modern CPUs - don't have a link handy, but it might be worth looking into.

_________________
- carpe noctem
11 Mar 2013, 21:15
freecrac

Joined: 19 Oct 2011
Posts: 117
Location: Germany Hamburg
freecrac 11 Mar 2013, 21:46
I loose the focus mixing integer addresses with floating point values on the stack of the program.

; [bp + 4] = offset of x1
; [bp + 6] = offset of y1
; [bp + 8] = offset of x2
; [bp + 10] = offset of y2

Maybe we can simplify the situation if the delivery of the parameter uses named locations instead of involving the stack of the program?

(I think a floating-point-arithmetic for to calculate integer addresses is not the simplest way.)

Dirk
11 Mar 2013, 21:46
baldr

Joined: 19 Mar 2008
Posts: 1651
baldr 11 Mar 2013, 22:54
freecrac wrote:
I think a floating-point-arithmetic for to calculate integer addresses is not the simplest way.
Coordinates are still integer, thus rational (∆y/∆x) calculations can be scaled somewhat.

And yes, that's amazing why someone do prefer to use direct [bp+xx] references instead of equs or some macros (LocoDelAssembly or Benjamin).
11 Mar 2013, 22:54
bitshifter

Joined: 04 Dec 2007
Posts: 790
Location: Massachusetts, USA
bitshifter 15 Mar 2013, 03:04
http://board.flatassembler.net/topic.php?p=118603#118603
15 Mar 2013, 03:04
SeproMan

Joined: 11 Oct 2009
Posts: 69
Location: Belgium
SeproMan 18 Mar 2013, 16:42
wyvern,

Seems nobody actually looked at your code!
What happens in 'drawPixel' is unknown but I suppose you know if it is OK...
Here are some hints for the code you've submitted:

Code:
`fild        dword [bp - 2]                ;st0=x    `

It's not a dword at this location!

Code:
```mov       si, word [bp + 8]         ;
fsubr     dword [si]                    ;x-x1    ```

Code:
`ret        10    `

Should be 'ret 8'

_________________