Search code examples
assemblyx86x86-16tasmtrigonometry

Assembly 80386 sine with TASM and DOSBox


I have to write a program that shows some kind of (possibly) complex shape that rotates and moves around. The problem is, for any kind of solution I can think of, I need the sine and cosine function.

First, I had a problem of setting to 386 mode too early (the executable should be 16 bit, compiled with TASM).

Right now the problem is that I get weird values for my loop:

.data

_180 dw 180
_25 dw 25
degrad dd ?
tempvar dw ?
alpha dw ?

.386
.code

start:

finit

fldpi
fidiv word ptr _180
fstp dword ptr degrad

    mov word ptr alpha, 0

calcsin:
mov ax, word ptr alpha
mov word ptr tempvar, ax
    fild tempvar
    fsin
    fimul word ptr _25
    fistp word ptr tempvar
mov DX,word ptr tempvar


inc word ptr alpha
cmp word ptr alpha,360
jne calcsin

    mov ax, 4c00h
    int 21h
end start

after this if I open up Turbo Debugger in DOSBox, I get weird, huge values in DX. I've also tried copying (and fixing, since they wouldn't compile) some examples from online to see if they work, they usually ended up not working...


Solution

  • You didn't initialize at least DS at the beginning of your code. Look:

    .MODEL small
    .486
    
    .STACK 1000h
    
    .DATA
        _180 dw 180
        _25 dw 25
        degrad dd ?
        tempvar dw ?
        alpha dw ?
        buf dw 8 dup (?)
    
    .CODE
    start PROC
        mov ax, @data
        mov ds, ax
        mov es, ax
    
        finit
        fldpi
        fidiv word ptr _180
        fstp dword ptr degrad
        mov word ptr alpha, 0
    
        calcsin:
        mov ax, word ptr alpha
        mov word ptr tempvar, ax
        fild tempvar
        fsin
        fimul word ptr _25
        fistp word ptr tempvar
    
        mov dx, word ptr tempvar
    
        mov ax, tempvar
        mov di, OFFSET buf
        call int2dez
        mov dx, OFFSET buf
        mov ah, 09h
        int 21h
    
        inc word ptr alpha
        cmp word ptr alpha, 360
        jne calcsin
    
        mov ax, 4C00h       ; Exit(0)
        int 21h
    start ENDP
    
    int2dez PROC
        test ax, 10000000b
        jz Convert
        mov byte ptr [di], '-'
        inc di
        neg ax
    
        Convert:
        mov bx, 10
        xor cx, cx
      Loop_1:
        xor dx, dx
        div bx
        push dx
        add cl, 1
        or  ax, ax
        jnz Loop_1
      Loop_2:
        pop ax
        or ax, 00110000b
        stosb
        loop Loop_2
    
        mov al, 10
        stosb
        mov al, '$'
        stosb
        ret
    int2dez ENDP
    
    end start
    

    The program works but I didn't check the calculation and the results. I guess a rotation without sine (http://en.wikipedia.org/wiki/Midpoint_circle_algorithm) is quicker.