8 |
nishi |
1 |
/* $Id: am9511.c 8 2024-08-28 16:29:15Z nishi $ */
|
|
|
2 |
|
|
|
3 |
#include "io.h"
|
|
|
4 |
|
|
|
5 |
#include "am9511.h"
|
|
|
6 |
|
|
|
7 |
#define AM_SR 0x80 /* service request on completion */
|
|
|
8 |
#define AM_SINGLE 0x60 /* 16 bit integer */
|
|
|
9 |
#define AM_DOUBLE 0x20 /* 32 bit integer */
|
|
|
10 |
#define AM_FIXED 0x20 /* fixed point */
|
|
|
11 |
#define AM_FLOAT 0x00 /* 32 bit float */
|
|
|
12 |
|
|
|
13 |
#define AM_NOP 0x00 /* no operation */
|
|
|
14 |
#define AM_SQRT 0x01 /* square root */
|
|
|
15 |
#define AM_SIN 0x02 /* sine */
|
|
|
16 |
#define AM_COS 0x03 /* cosine */
|
|
|
17 |
#define AM_TAN 0x04 /* tangent */
|
|
|
18 |
#define AM_ASIN 0x05 /* inverse sine */
|
|
|
19 |
#define AM_ACOS 0x06 /* inverse cosine */
|
|
|
20 |
#define AM_ATAN 0x07 /* inverse tangent */
|
|
|
21 |
#define AM_LOG 0x08 /* common logarithm (base 10) */
|
|
|
22 |
#define AM_LN 0x09 /* natural logairth (base e) */
|
|
|
23 |
#define AM_EXP 0x0a /* exponential (e^x) */
|
|
|
24 |
#define AM_PWR 0x0b /* power nos^tos */
|
|
|
25 |
#define AM_ADD 0x0c /* add */
|
|
|
26 |
#define AM_SUB 0x0d /* subtract nos-tos */
|
|
|
27 |
#define AM_MUL 0x0e /* multiply, lower half */
|
|
|
28 |
#define AM_DIV 0x0f /* divide nos/tos */
|
|
|
29 |
#define AM_FADD 0x10 /* floating add */
|
|
|
30 |
#define AM_FSUB 0x11 /* floating subtract */
|
|
|
31 |
#define AM_FMUL 0x12 /* floating multiply */
|
|
|
32 |
#define AM_FDIV 0x13 /* floating divide */
|
|
|
33 |
#define AM_CHS 0x14 /* change sign */
|
|
|
34 |
#define AM_CHSF 0x15 /* floating change sign */
|
|
|
35 |
#define AM_MUU 0x16 /* multiply, upper half */
|
|
|
36 |
#define AM_PTO 0x17 /* push tos to nos (copy) */
|
|
|
37 |
#define AM_POP 0x18 /* pop */
|
|
|
38 |
#define AM_XCH 0x19 /* exchange tos and nos */
|
|
|
39 |
#define AM_PUPI 0x1a /* push pi */
|
|
|
40 |
/* 0x1b */
|
|
|
41 |
#define AM_FLTD 0x1c /* 32 bit to float */
|
|
|
42 |
#define AM_FLTS 0x1d /* 16 bit to float */
|
|
|
43 |
#define AM_FIXD 0x1e /* float to 32 bit */
|
|
|
44 |
#define AM_FIXS 0x1f /* float to 16 bit */
|
|
|
45 |
|
|
|
46 |
#define AM_BUSY 0x80 /* chip is busy */
|
|
|
47 |
#define AM_SIGN 0x40 /* tos negative */
|
|
|
48 |
#define AM_ZERO 0x20 /* tos zero */
|
|
|
49 |
#define AM_ERR_MASK 0x1E /* mask for errors */
|
|
|
50 |
#define AM_CARRY 0x01 /* carry/borrow from most significant bit */
|
|
|
51 |
|
|
|
52 |
short fpu_stack;
|
|
|
53 |
short fpu_command;
|
|
|
54 |
|
|
|
55 |
long modl(long a, long b){
|
|
|
56 |
return a - mull(b, divl(a, b));
|
|
|
57 |
}
|
|
|
58 |
|
|
|
59 |
long divl(long a, long b){
|
|
|
60 |
int i;
|
|
|
61 |
for(i = 0; i < 4; i++){
|
|
|
62 |
outp(fpu_stack, a & 0xff);
|
|
|
63 |
a = a >> 8;
|
|
|
64 |
}
|
|
|
65 |
for(i = 0; i < 4; i++){
|
|
|
66 |
outp(fpu_stack, b & 0xff);
|
|
|
67 |
b = b >> 8;
|
|
|
68 |
}
|
|
|
69 |
outp(fpu_command, AM_DOUBLE | AM_DIV);
|
|
|
70 |
unsigned long r = 0;
|
|
|
71 |
for(i = 0; i < 4; i++){
|
|
|
72 |
r = r << 8;
|
|
|
73 |
r |= inp(fpu_stack);
|
|
|
74 |
}
|
|
|
75 |
return r;
|
|
|
76 |
}
|
|
|
77 |
|
|
|
78 |
long mull(long a, long b){
|
|
|
79 |
int i;
|
|
|
80 |
for(i = 0; i < 4; i++){
|
|
|
81 |
outp(fpu_stack, a & 0xff);
|
|
|
82 |
a = a >> 8;
|
|
|
83 |
}
|
|
|
84 |
for(i = 0; i < 4; i++){
|
|
|
85 |
outp(fpu_stack, b & 0xff);
|
|
|
86 |
b = b >> 8;
|
|
|
87 |
}
|
|
|
88 |
outp(fpu_command, AM_DOUBLE | AM_MUL);
|
|
|
89 |
long r = 0;
|
|
|
90 |
for(i = 0; i < 4; i++){
|
|
|
91 |
r = r << 8;
|
|
|
92 |
r |= inp(fpu_stack);
|
|
|
93 |
}
|
|
|
94 |
return r;
|
|
|
95 |
}
|
|
|
96 |
|
|
|
97 |
void fpu_card(int t, int port){
|
|
|
98 |
if(t == 0x21){
|
|
|
99 |
fpu_stack = port - 2;
|
|
|
100 |
fpu_command = port - 1;
|
|
|
101 |
}
|
|
|
102 |
}
|
|
|
103 |
|