Subversion Repositories Shiroi

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
18 nishi 1
/* $Id: math.c 18 2024-08-29 06:56:23Z nishi $ */
2
 
3
#include "math.h"
4
 
5
#include "../io.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
	while(!(inp(fpu_command) & 1));
71
	unsigned long r = 0;
72
	for(i = 0; i < 4; i++){
73
		r = r << 8;
74
		r |= inp(fpu_stack);
75
	}
76
	return r;
77
}
78
 
79
long mull(long a, long b){
80
	int i;
81
	for(i = 0; i < 4; i++){
82
		outp(fpu_stack, a & 0xff);
83
		a = a >> 8;
84
	}
85
	for(i = 0; i < 4; i++){
86
		outp(fpu_stack, b & 0xff);
87
		b = b >> 8;
88
	}
89
	outp(fpu_command, AM_DOUBLE | AM_MUL);
90
	while(!(inp(fpu_command) & 1));
91
	long r = 0;
92
	for(i = 0; i < 4; i++){
93
		r = r << 8;
94
		r |= inp(fpu_stack);
95
	}
96
	return r;
97
}
98
 
99
void math_card(int t, int port){
100
	if(t == 0x21){
101
		fpu_stack = port - 2;
102
		fpu_command = port - 1;
103
	}
104
}
105
 
106
int muli(int a, int b){
107
	int n = 0;
108
	int i;
109
	if(b > 0){
110
		for(i = 0; i < b; i++) n += a;
111
	}else if(b < 0){
112
		for(i = 0; i > b; i--) n -= a;
113
	}
114
	return n;
115
}