|
|
1.1 root 1: ////////
2: /
3: / Intel 8086 floating point.
4: / Double add and subtract.
5: / SMALL model.
6: /
7: ////////
8:
9: .globl dradd
10: .globl dladd
11: .globl drsub
12: .globl dlsub
13: .globl _fpac_
14:
15: ////////
16: /
17: / dradd - double add (rvalue)
18: / dladd - double add (lvalue)
19: / drsub - double subtract (rvalue)
20: / dlsub - double subtract (lvalue)
21: /
22: / compiler calling sequences:
23: / push <right double argument>
24: / push <left double argument>
25: / call dradd/drsub
26: / add sp,16
27: /
28: / mov ax,offset <right double argument>
29: / push ax
30: / push <left double argument>
31: / call dladd/dlsub
32: / add sp,10
33: /
34: / outputs:
35: / _fpac_=result.
36: /
37: / uses:
38: / ax, bx, cx, dx
39: /
40: ////////
41:
42: l = 8 / left argument
43: r = 16 / right argument (rvalue)
44: rp = 16 / right argument (lvalue)
45:
46: signs = -2 / signs
47: ls = -2 / left sign (byte)
48: rs = -1 / right sign (byte)
49: rexp = -4 / right exponant
50: lexp = -6 / left exponant
51: rop = -14 / right op
52: lop = -22 / left op
53: claim = 22 / stack claim size
54:
55: dradd: push si / standard
56: push di / c
57: push bp / function
58: mov bp,sp / linkage
59:
60: lea bx,r(bp) / bx=pointer to right op.
61: jmp L0 / go to common code.
62:
63: dladd: push si / standard
64: push di / c
65: push bp / function
66: mov bp,sp / linkage
67:
68: mov bx,rp(bp) / bx=pointer to right op.
69:
70: L0: sub ax,ax / ax=sign flip flag.
71: jmp L2 / go to common code.
72:
73: drsub: push si / standard
74: push di / c
75: push bp / function
76: mov bp,sp / linkage.
77:
78: lea bx,r(bp) / bx=pointer to right op.
79: jmp L1 / go to common code.
80:
81: dlsub: push si / standard
82: push di / c
83: push bp / function
84: mov bp,sp / linkage.
85:
86: mov bx,rp(bp) / bx=pointer to right op.
87:
88: L1: mov ax,$0x8000 / ax=sign flip flag.
89:
90: L2: sub sp,$claim / get some autos.
91: mov signs(bp),$0 / ls=rs=0
92: cld / ascending direction.
93:
94: add ax,6(bx) / get highest word.
95: mov dx,ax / save adjusted sign.
96: shl ax,$1 / save
97: rclb rs(bp),$1 / sign in rs.
98: stc / insert the hidden bit
99: rcrb al,$1 / into the number.
100: movb rop+6(bp),al / save hi byte.
101: movb rop+7(bp),$0 / clear rest of word for add.
102: movb al,ah / al=exponant.
103: and ax,$0xFF / mask, test for zero.
104: jnz L3 / jump if non zero.
105: mov dx,l+6(bp) / if right is zero,
106: mov si,l+4(bp) / just return
107: mov di,l+2(bp) / the left
108: mov ax,l+0(bp) / operand to
109: jmp L16 / the caller.
110:
111: L3: mov rexp(bp),ax / save right exponant.
112: mov si,bx / si=source.
113: lea di,rop(bp) / di=destination.
114: movsw / copy 3 words from the argument
115: movsw / list to the
116: movsw / auto buffer.
117:
118: mov ax,l+6(bp) / ax=hi word of left operand
119: shl ax,$1 / slide
120: rclb ls(bp),$1 / sign into ls.
121: stc / insert
122: rcrb al,$1 / hidden bit.
123: movb lop+6(bp),al / save top byte of left.
124: movb lop+7(bp),$0 / clear rest of word for add.
125: movb al,ah / al=exponant.
126: and ax,$0xFF / mask, test for zero.
127: jnz L4 / jump if not zero.
128: mov si,4(bx) / just send
129: mov di,2(bx) / the right operand
130: mov ax,0(bx) / back to
131: jmp L16 / the caller.
132:
133: L4: mov lexp(bp),ax / save left exponant.
134: lea si,l(bp) / si=source.
135: lea di,lop(bp) / di=destination.
136: movsw / copy 3 words
137: movsw / to the
138: movsw / auto buffer.
139:
140: mov dx,rop+6(bp) / assume
141: mov si,rop+4(bp) / rop
142: mov di,rop+2(bp) / is
143: mov ax,rop+0(bp) / smallest.
144:
145: mov cx,lexp(bp) / compute the difference
146: sub cx,rexp(bp) / of the exponants.
147: jge L5 / the rop was the smallest.
148:
149: mov bx,rexp(bp) / reset
150: mov lexp(bp),bx / le.
151: mov bx,signs(bp) / swap
152: xchgb bh,bl / the
153: mov signs(bp),bx / signs.
154: neg cx / fix shift count.
155:
156: xchg dx,lop+6(bp) / this sequence puts
157: xchg si,lop+4(bp) / rop in lop,
158: xchg di,lop+2(bp) / and loads the lop
159: xchg ax,lop+0(bp) / into the regs.
160:
161: L5: cmp cx,$57 / too many shifts ??
162: jle L6 / nope.
163: movb dl,lop+6(bp) / load
164: mov si,lop+4(bp) / up
165: mov di,lop+2(bp) / the
166: mov ax,lop+0(bp) / result
167: mov cx,lexp(bp) / and its exponant
168: movb bl,ls(bp) / and its sign.
169: shl ax,$1 / shift left one
170: rcl di,$1 / to properly
171: rcl si,$1 / position
172: rclb dl,$1 / hidden bit,
173: jmp L15 / and go pack up.
174:
175: L6: jcxz L8 / jump if aligned.
176:
177: L7: shr dx,$1 / do
178: rcr si,$1 / the
179: rcr di,$1 / big
180: rcr ax,$1 / shift.
181: loop L7 / do all of them.
182:
183: L8: mov cx,lexp(bp) / cx=result exponant.
184: mov bx,signs(bp) / bx=signs.
185: cmpb bh,bl / are they the same ??
186: je L9 / yes.
187: call negreg / nope, negate.
188:
189: L9: add ax,lop+0(bp) / do
190: adc di,lop+2(bp) / the
191: adc si,lop+4(bp) / big
192: adc dx,lop+6(bp) / add
193: cmpb bh,bl / same signs.
194: jne L11 / nope, check for zero.
195: testb dh,$0x01 / hidden correct.
196: jz L13 / no, one left will fix it.
197: inc cx / correct, fix exponant.
198: jmp L14 / done.
199:
200: L11: or dx,dx / zero ??
201: jnz L12 / nope.
202: or si,si / zero ??
203: jnz L13 / nope.
204: or di,di / zero ??
205: jnz L13 / nope.
206: or ax,ax / zero ??
207: jz L16 / yes, return 0.0
208: jmp L13 / no
209:
210: L12: jns L13 / jump if > 0.0
211: xchgb bh,bl / swap signs.
212: call negreg / negate.
213:
214: L13: shl ax,$1 / shift
215: rcl di,$1 / one
216: rcl si,$1 / bit
217: rclb dl,$1 / left
218: jc L14 / jump if hidden shifted off.
219: dec cx / fix exponant
220: jmp L13 / loop.
221:
222: L14: add ax,$1 / round
223: adc di,$0 / up
224: adc si,$0 / the
225: adcb dl,$0 / number.
226: jnc L15 / jump if hidden bit valid.
227: shrb dl,$1 / the carry
228: rcr si,$1 / must have
229: rcr di,$1 / complemented the
230: rcr ax,$1 / hidden bit.
231: inc cx / so shift and fix exp.
232:
233: L15: movb dh,cl / put exponant in result.
234: shrb bl,$1 / sign in carry.
235: rcr dx,$1 / put
236: rcr si,$1 / number
237: rcr di,$1 / back
238: rcr ax,$1 / together.
239:
240: L16: mov _fpac_+6,dx / store
241: mov _fpac_+4,si / result
242: mov _fpac_+2,di / in
243: mov _fpac_+0,ax / _fpac_
244:
245: L17: mov sp,bp / do the
246: pop bp / standard
247: pop di / c
248: pop si / function
249: ret / return.
250:
251: ////////
252: /
253: / negreg - negate the big register.
254: /
255: / this local routine negates dx,si,di,ax
256: /
257: ////////
258:
259: negreg: not dx / complement
260: not si / all
261: not di / of the
262: not ax / bits.
263:
264: add ax,$1 / then
265: adc di,$0 / increment
266: adc si,$0 / the
267: adc dx,$0 / result
268:
269: ret / done
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.