TomCat hat geschrieben:Hallo,
habe mit dem Co-Prozessor noch nicht viel gemacht.
Nur mal die Quadrat-Wurzel berechnet. also mit:
fild das Quadword geladen. dann
fsqrt aufgerufen
und das Ergebnis mit:
fistp in ein Double-Word geladen
es geht mir darum jetzt den Sinus, bzw. die trigonometrischen Funktionen mittels Co-Prozessor zu erhalten.
Weiß jemand wie das geht?
Danke schon mal im Voraus,
TomCat
Weil die FPU nicht so schnell arbeitet empfielt es sich nach Möglickeit stattdessen Integer-Befehlen der CPU zu verwenden. Die Vorarbeit dazu kann aber die FPU für uns erledigen.
(Ich bin aber nicht so gut darin mathematische Aufgaben zu lösen und tue mich damit selber schwer.)
Mit der folgenden Routine wird eine Sinus/Cosinus-Tabelle mit Integerwerten erstellt und gespeichert.
Diese Tabelle kann dann später von einem anderen Programm geladen und verwendet werden.
Code: Alles auswählen
.MODEL SMALL
.386P
.387
Scale = 4
Grad = 360 * Scale
Endtab = 450 * Scale
Foktor = 10000h
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
;---------------------------------------------------------------------------
org 100h
START: mov ax, DATEN
mov ds, ax
finit
call TABLE
mov dx, OFFSET TABNAM
call MAKDAT
xor dx, dx
mov cx, Endtab*4
call WRITE
call CLOSE
;---------------------------------------------------------------------------
xor al, al ; kein Fehler
DOS: mov ah, 4Ch ; Dos-Rücksprung, Programm-Ende
int 21h
;────────────────────────────────────────────────────────────────────────────
; U N T E R - R O U T I N E N
;────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;─────────────────────────────────────────────────────────────────────────────
; S i n u s - T a b e l l e
;─────────────────────────────────────────────────────────────────────────────
TABLE: xor di, di ; Sinus-Tabelle anlegen
;-------------------------------------
TAB: fldpi ; PI laden
fimul DWORD PTR[I] ; Zaehler mal PI
fidiv DWORD PTR[TEIL] ; durch 180(INT) teilen
fsin ; davon den Sinus
fimul DWORD PTR[FAKT]
fistp DWORD PTR[di] ; in die Sinus-Tabelle schreiben
;-------------------------------------
inc WORD PTR[I] ; Grad-Zähler erhöhen
add di, 4 ; Tabellen-Index erhöhen
cmp WORD PTR[I], Endtab ; Tabellen-Ende erreicht ?
jnz TAB
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
MAKDAT: mov ah, 3Ch ; Datei erstellen (ah=3C/5B)
xor cx, cx
int 21h
mov bx, ax
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
WRITE: mov ah, 40h ; Datei beschreiben
int 21h
ret
;─────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16
;----------------------------------------------------------------------------
CLOSE: mov ah, 3Eh ; Datei schließen
int 21h
ret
;---------------------------------------------------------------------------
CODE ends
;────────────────────────────────────────────────────────────────────────────
; D A T E N - B E R E I C H
;────────────────────────────────────────────────────────────────────────────
DATEN SEGMENT use32 'DATA'
org 0
;---------------------------------------------------------------------------
SINTAB DB Endtab DUP (?,?,?,?)
;-------------------------------------
TEIL DW Grad/2, ?
I DW 0, 0
;-------------------------------------
FAKT DD Foktor
;-------------------------------------
TABNAM DB "Sin2Int.tab", 0
DATEN ends
;────────────────────────────────────────────────────────────────────────────
STAPEL SEGMENT use16 STACK 'STACK'
DB 10h dup (?)
STAPEL ends
;────────────────────────────────────────────────────────────────────────────
end
Im nachfolgendem Listing wird ein Fraktalbild mit der FPU berechnet.
Code: Alles auswählen
.MODEL SMALL
.386
.387
;────────────────────────────────────────────────────────────────────────────
Col = 0C0h
Iter = 456
Xstart = 0
Ystart = 1699
;────────────────────────────────────────────────────────────────────────────
Tast_Port = 60h ; Port-Adresse des Tastatur-Controllers
RGB_Write = 3C8h ; Port-Adresse der Farb-Anteile (write)
;────────────────────────────────────────────────────────────────────────────
CODE SEGMENT use16 'CODE'
assume cs:CODE,ds:DATEN,ss:STAPEL
org 100h
;────────────────────────────────────────────────────────────────────────────
START: mov ax, 13h ; 320 x 200 x 256
int 10h
;-------------------------------------
mov ax, DATEN
mov ds, ax
mov ax, 0A000h
mov es, ax
;-------------------------------------
xor al, al
mov dx, RGB_Write
mov si, OFFSET DAC ; Quelle
mov cx, 0FFh*3
out dx, al ; Farb-Nr. zur VGA-Karte
inc dx ; VGA-PORT der Farb-Anteile (data)
rep outsb ; Farb-Anteile zur Grafik-Karte
;-------------------------------------
finit ; FPU initialisieren
mov DWORD PTR[Z], 100000
mov DWORD PTR[A], 76541
fild A
fidiv Z
fchs
fst A ; -.76548
mov DWORD PTR[B], 76529
fild B
fidiv Z
fchs
fst B ; -.76528
mov DWORD PTR[C], 9986
fild C
fidiv Z
fst C ; .0997
mov DWORD PTR[D], 9990
fild D
fidiv Z
fst D ; .1003
;-------------------------------------
fild NEUN
fidiv ZEHN
fstp PNEUN ; 0.9
;-------------------------------------
fld D
fsub C
fidiv YMAX
fstp G ; G = (D-C)/YMAX
fld B
fsub A
fidiv XMAX
fstp F ; F = (B-A)/XMAX
mov WORD PTR[X1], Xstart
mov WORD PTR[Y1], Ystart
;---------------------------------------------------------------------------
DB 0EAh ; Prefetch-Puffer löschen:
DW (OFFSET BEGINN) ; Die folgenden Zeilen erzeugen
DW SEG CODE ; das Kommando JMP FAR CS:BEGINN
;---------------------------------------------------------------------------
org START + ((($-START)/16)*16)+16 ; Code-Ausrichtung
;---------------------------------------------------------------------------
BEGINN: mov WORD PTR[X], 0
WW1: call FRAK
inc WORD PTR[X]
inc WORD PTR[X1]
cmp WORD PTR[X], 140h
jnz WW1
sbb WORD PTR[X1], 140h
inc WORD PTR[Y1]
;-------------------------------------
lds si, DWORD PTR[COSEG] ; 320 * 200 = 64000 letzte Zeile
xor di, di ; vorletzte Zeile
mov cx, 15920 ; Anzahl Zeilen die gescrollt werden
rep movsd
mov ax, DATEN
mov ds, ax
;-------------------------------------
in al, Tast_Port ; Tasten-Code holen
dec al ; Escape-Taste gedrückt ?
jnz BEGINN
;-------------------------------------
mov ax, 3 ; Text-Mode
int 10h
;-------------------------------------
mov ah, 1 ; Tastatur-Puffer löschen
int 16h
;-------------------------------------
xor al, al ; kein Fehler
DOS: mov ah, 4Ch ; Dos-Rücksprung, Programm-Ende
int 21h
;────────────────────────────────────────────────────────────────────────────
; U N T E R - R O U T I N E N
;────────────────────────────────────────────────────────────────────────────
org START + ((($-START)/16)*16)+16 ; Code-Ausrichtung
;---------------------------------------------------------------------------
FRAK: fld G
mov dx, 1
fimul Y1
fadd C
fst st(1) ; K = G * Y + C
fstp st(2) ; J = K
fld F
fimul X1
fadd A
fst st(3) ; I = F * X + A
fstp st(4) ; H = I
fld st(2-1)
fmul st, st(2)
fstp st(5) ; L = J * J
fld st(4-1)
fmul st, st(4)
fstp st(6) ; M = H * H
FRAK1: cmp dx, Iter ; Iteration
ja short FRAK2
fild ZWEI
fmul st, st(4)
fmul st, st(2)
fadd st, st(1)
fstp st(2) ; J = 2 * H * J + K
fld st(6-1)
fsub st, st(5)
fadd st, st(3)
fstp st(4) ; H = M - L + I
fld st(2-1)
fmul st, st(2)
fstp st(5) ; L = J * J
fld st(4-1)
fmul st, st(4)
fst st(6) ; M = H * H
fadd st, st(5) ; M + L
fadd PNEUN
fistp WW
inc dx
cmp WORD PTR[WW], 5
jb FRAK1
FRAK2: add dx, Col
mov bx, 199
mov di, bx ; 320 Pixel a Zeile
shl bx, 8
shl di, 6
add bx, di
add bx, X ; Y + X
mov BYTE PTR es:[bx], dl ; Farb-Byte schreiben 0-255
ret
;---------------------------------------------------------------------------
CODE ends
;────────────────────────────────────────────────────────────────────────────
; D A T E N - B E R E I C H
;────────────────────────────────────────────────────────────────────────────
DATEN SEGMENT use32 'DATA'
org 0
;---------------------------------------------------------------------------
A DD ?
B DD ?
C DD ?
D DD ?
F DD ?
G DD ?
Z DD ?
X DW ?, ?
Y DW ?, ?
X1 DW ?, ?
Y1 DW ?, ?
XMAX DW 320, ?
YMAX DW 200, ?
ZWEI DD 2
NEUN DD 9
ZEHN DD 10
PNEUN DD ? ; 0.9
WW DW ?, ?
COSEG DW 140h, 0A000h
; rot grün blau
DAC DB 000h,000h,000h ; 0 rot
DB 001h,000h,000h ; 1
DB 002h,000h,000h ; 2
..... gekürzt... im Original werden alle Farbanteile aufgeführt...
DB 0FDh,07Dh,000h ; 3
DB 0FEh,07Eh,000h ; 4
DB 0FFh,07Fh,000h ; 5
;---------------------------------------------------------------------------
DATEN ends
;────────────────────────────────────────────────────────────────────────────
STAPEL SEGMENT use16 STACK 'STACK'
;---------------------------------------------------------------------------
DB 10h dup (?)
;---------------------------------------------------------------------------
STAPEL ends
;────────────────────────────────────────────────────────────────────────────
end
Dirk