forked from microsoft/GW-BASIC
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MATH1.ASM
3828 lines (3651 loc) · 115 KB
/
MATH1.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; [ This translation created 10-Feb-83 by Version 4.3 ]
.RADIX 8 ; To be safe
CSEG SEGMENT PUBLIC 'CODESG'
ASSUME CS:CSEG
INCLUDE OEM.H
TITLE MATH86 8086 MATH PACK
.SALL
.RADIX 8
SIXDIG=0 ;Floating pnt output 6 bit S.P. numbers
PUBLIC ABSFN,ATN,COS,DADD
PUBLIC DDIV,DMULT,EXP,FINDBL,FIN,FOUT,FRCDBL
PUBLIC FRCINT,FRCSNG,INEG,INEG2,_INT,LOG,LOPFND,_NEG
PUBLIC PUFOUT,RND,SIGN,SIN,SQR,TAN
PUBLIC VALINT,VINT,VNEG,ZERO,$CDS,$CSD,$CSI
PUBLIC $DCMPA,$DIV0S,$DZERO,$EXPCN,$FADDS,$FCOMP,$FDIVS
PUBLIC $FI,$FLT,$FMULS,$FOUTH,$FOUTO,$FOUT2,$FPWR
PUBLIC $FSUBD,$FSUBS,$FS,$GETYP,$LOGP,$MOVFA,$MOVFM
PUBLIC $MOVFR,$MOVMF,$MOVRF,$NEG,$NORMD,$NORMS,$POPA
PUBLIC $SIGNS,$VINT,$VPSHF
PUBLIC SIGNS,DCXBRT,_FADD,VSIGN,MOVFR,ISIGN,INEG2
PUBLIC IMOD,GETBCD,ISUB,FPWRQ,INRART,MOVRF,DCOMP
PUBLIC VDFACS,MOVFM,FDIVT,ICOMP,VMOVAF,UMULT,FOUTH,_FSUB
PUBLIC ICMPA,VMOVFA,_IDIV,VMOVFM,IMULT,RNDMN2,BLTU,FMULT
PUBLIC FRCSTR,POPHRT,MOVE,MOVMF,CONIA,VMOVE,RNDMON,CHKSTR
PUBLIC LOPFD1,INPRT,MAKINT,_FDIV,SGN,SIGNC,_FCOMP,INXHRT
PUBLIC IADD,FOUTO,DSUB,VALSNG,BLTUC,FIXER,MOVRM
PUBLIC FADDS,LINPRT,MOVE1,CONSIH,_PUSHF,VMOVMF
PUBLIC STROUT
EXTRN CRFIN:NEAR,OUTDO:NEAR
EXTRN ARYEXT:NEAR,BSERR:NEAR,CHRGTR:NEAR,DV0ERR:NEAR,FRQINT:NEAR
EXTRN INTXT:NEAR,NOTFDD:NEAR,NOTFNS:NEAR,OVERR:NEAR
EXTRN REASON:NEAR,STROUI:NEAR,TMERR:NEAR
EXTRN $CATTY:NEAR,$CLROV:NEAR,$DIV0M:NEAR,$FLGOC:NEAR
EXTRN $OHCNS:NEAR,$OVERR:NEAR,$OVMSG:NEAR,$FCERR:NEAR
EXTRN $SNERR:NEAR,$STPRN:NEAR,$TMERR:NEAR
DSEG SEGMENT PUBLIC 'DATASG'
ASSUME DS:DSEG
EXTRN ARYTA2:WORD,NAMBUF:WORD,NAMCNT:WORD,ONELIN:WORD
EXTRN STREND:WORD,TEMP3:WORD,VALTYP:WORD
EXTRN $ARG:WORD,$ARGLO:WORD,$DBUFF:WORD,$DFACL:WORD
EXTRN $DPADR:WORD,$FAC:WORD,$FACLO:WORD,$FACM1:WORD,$FBUFF:WORD
EXTRN $FLGOV:WORD,$FMTAL:WORD,$FMTAX:WORD,$FMTCX:WORD,$RNDX:WORD
EXTRN $VALTP:WORD,$ZLO:WORD,$Z1LO:WORD,$Z1:WORD
DSEG ENDS
SUBTTL $FOTCI CONVERT INTEGER IN (FACLO) TO ASCII DIGITS
;*************************************************************
;
; $FOTCI CONVERT THE INTEGER IN (FACLO)-TWO BYTES TO
; ASCII DIGITS.
; CALLING SEQUENCE: CALL $FOTCI
; WITH DECIMAL POINT AND COMMA COUNTS IN (CX)
; $FOUTO CONVERT INTEGER IN $FACLO:FACLO+1 TO OCTAL
; $FOUTH CONVERT INTEGER IN $FACLO:FACLO+1 TO HEXIDECIMAL
; CALLING SEQUENCE: CALL $FOUTO/$FOUTH
; WITH $FACLO:FACLO+1 CONTAINING INTEGER TO BE
; PRINTED. RETURNS WITH (BX) POINTING TO $FBUFF
;
;**************************************************************
PUBLIC $FOTCI
$FOTCI: MOV AH,LOW 5 ;MAX DIGITS TO CONVERT
MOV BP,OFFSET $FOITB
$FCI4: ;ENTRY FOR FOTCV SO WE WILL ONLY CONVERT 4 DIGITS
FCI10: CALL $FOTED ;CHECK FOR NEEDED D.P. OR ","
;TABLE IN CODE SEGMENT
MOV DX,WORD PTR CS:0[BP] ;FETCH POWER OF TEN TO DX
INC BP ;POINT (BP) TO NEXT PWR 10
INC BP
MOV SI,WORD PTR $FACLO ;FETCH INTEGER TO BE CONVERTED
MOV AL,LOW OFFSET "0"-1 ;WILL BUILD DIGIT IN (AL)
FCI20: INC AL
SUB SI,DX ;SUBTRACT OUT POWER OF TEN
JNB FCI20 ;CONTINUE UNTIL DIGIT FORMED
ADD SI,DX ;SUBTRACTED OUT ONE TOO MANY
MOV BYTE PTR 0[BX],AL ;MOVE DIGIT TO BUFFER
INC BX ;POINT (BX) TO NEXT BUFF POS.
MOV WORD PTR $FACLO,SI ;SAVE UPDATED INTEGER
DEC AH ;LOOP TILL DIGITS FORMED
JNZ FCI10
CALL $FOTED ;SEE IF DECIMAL POINT NEEDED
MOV BYTE PTR 0[BX],LOW 0 ;AND PUT BINARY
RET ;ZERO AFTER.
$FOUTO: ;OCTAL OUTPUT OF INTEGER IN $FACLO:FACLO+1
MOV CX,OFFSET 3*400+1 ;WILL PROCESS 3 BITS AT A TIME
MOV SI,6 ;OCTAL DIGITS
JMP SHORT FTH10
$FOUTH: ;HEXIDECIMAL OUTPUT OF INTEGER IN FACLO:FACLO+1
MOV CX,OFFSET 4*400+4 ;WILL PROCESS 4 BITS AT A TIME
MOV SI,4 ;HEX DIGITS
FTH10: MOV DI,OFFSET $FBUFF ;POINT DI TO OUTPUT LOCATION
CLD ;SO SUBSEQUENT STOC WILL INC
MOV BX,OFFSET $NUMB
MOV DX,WORD PTR $FACLO ;FETCH INTEGER
PUSH SI ;SAVE FOR ZERO SUPPRESS CODE
FTH20: MOV AL,DH ;GET INTEGER
XOR AH,AH ;CLEAR UPPER AX
SHL AX,CL ;SHIFT HIGH ORDER BITS INTO AH
XCHG AH,AL ;NOW IN AL
;LOOK FROM CODE SEGMENT
?CSLAB: ; Code segment dummy label
XLAT BYTE PTR ?CSLAB ;LOOK-UP ASCII
STOSB
SHL DX,CL ;SHIFT NUMBER
MOV CL,CH ;GET NO. BITS TO SHIFT
DEC SI ;DECREMENT NO. OF DIGITS
JNZ FTH20
MOV BYTE PTR 0[DI],LOW 0 ;DENOTE END OF NO.
MOV BX,OFFSET $FBUFF
POP CX ;RECALL FOR ZERO SUPPRESS
DEC CL ;CAN'T DELETE ALL THE ZEROS
FTH40: CMP BYTE PTR 0[BX],LOW "0" ;DO ZERO SUPPRESS
JNZ FTH50 ;NO MORE SUPPRESS
INC BX
LOOP FTH40
FTH50: RET
SUBTTL $PUFXE PRINT USING FIX-UP CODE
;****************************************************************
;
; $PUFXE THIS CODE IS CALLED ONCE PRINT-USING ROUTINES
; HAVE BUILT THE NUMBER IN THE OUTPUT BUFFER (FBUFF)
; ITS JOB IS TO ASSURE THE NUMBER MEETS OUTPUT
; SPECIFICATIONS. IF THE NUMBER TRULY OVERFLOWS THE
; OUTPUT BUFFER A "%" SIGN WILL BE INSERTED AS THE
; LEADING CHARACTER.
; CALLING SEQUENCE: CALL $PUFXE
; WITH $FBUFF CONTAINING THE FORMATTED NUMBER
;
;*****************************************************************
CURNCY="$" ;Default floating currency is dollars.
$PUFXE: PUSH BX ;SAVE END OF BUFFER POINTER
CALL $FOTZS ;DO ZERO SUPPRESSION
;$FOTZS WILL LEAVE ZF=0 IF THERE IS
;TO BE A TRAILING SIGN AND THE SIGN
;WILL BE LEFT IN (CH)
POP BX ;RECALL END-OF-BUFFER POINTER
JZ PFX10 ;IF NO TRAILING SIGN PROCEED
MOV BYTE PTR 0[BX],CH ;PUT IN TRAILING SIGN
INC BX ;MUST NOW PUT IN BINARY ZERO
PFX10: MOV BYTE PTR 0[BX],LOW 0 ;TO SIGNIFY END OF PRINT
MOV BX,OFFSET $FBUFF ;FETCH START OF BUFFER ADDRESS
PFX20: INC BX ;INCREMENT (BX) TO NEXT BUFFER POSITION
PFX30: MOV DI,WORD PTR $DPADR ;GET DECIMAL POINT ADDRESS
MOV DX,WORD PTR $FMTCX ;FETCH DECIMAL POINT INFO.
MOV AL,BYTE PTR $FMTCX+1 ;FETCH NO. DIGITS TO LEFT OF D.P.
XOR AH,AH ;(AX) = DIGITS LEFT OF DECIMAL POINT
SUB DI,BX ;WILL FORM THE SUBTRACTION:
SUB DI,AX ;D.P. ADDR.-BUFF PTR-DIGITS LEFT OF D.P
JZ PFX90 ;RETURN IF ALL IS OK.
;********************************************************************
;FIELD IS CURRENTLY TOO LARGE. WE CAN SHORTEN THE FIELD BY ELIMINATING
;LEADING " " AND "*" CHARACTERS AND A LEADING "0" IF THE CHARACTER
;FOLLOWING THE DECIMAL POINT IS A NUMERIC DIGIT. DOING THIS ANALYSIS
;WILL BE WHAT THE FOLLOWING SONG & DANCE IS ALL ABOUT
;THE INCREMENT OF (BX) AT PFX20 IN EFFECT SHORTENS THE FIELD BECAUSE
;(BX) WILL POINT TO THE STARTING LOCATION FOR PRINTOUT UPON RETURN
;FROM THIS ROUTINE.
;******************************************************************
MOV AL,BYTE PTR 0[BX] ;FETCH NEXT CHARACTER IN BUFFER
CMP AL,LOW " " ;SPACE?
JZ PFX20 ;IF SO ELIMINATE AND SEE IF NOW OK
CMP AL,LOW "*" ;IF ASTERISK FILL THEN ASTERISK?
JZ PFX20
MOV AH,LOW 1 ;TO SIGNAL END OF CHARACTERS IN
;THE FOLLOWING CODE
DEC BX ;BECAUSE $CHRGT WILL DO INC BX FIRST
PUSH BX ;SAVE THIS LOCATION FOR POSSIBLE "%"
PFX40: PUSH AX
CALL $CHRGT ;GET NEXT CHARACTER( NOTE THAT THIS
;RE-FETCHES THE PREVIOUS FAILING
;CHARACTER THE FIRST TIME THROUGH)
XOR AH,AH ;CLEAR (AH)
CMP AL,LOW "-" ;IF EQUAL NEED TO SAVE THIS GUY
JZ PFX40 ;GO SAVE AND GET NEXT CHAR.
CMP AL,LOW "+"
JZ PFX40 ;GO SAVE THIS GUY IF EQUAL
CMP AL,LOW OFFSET CURNCY
JZ PFX40 ;GO SAVE IF EQUAL
CMP AL,LOW "0" ;IF EQUAL POSSIBLE TO ELIMINATE
JNZ PFX70 ;MUST GIVE UP AND PUT LEADING "%"
;**************************************************************
;AT THIS POINT WE HAVE A LEADING ZERO. IT CAN BE ELIMINATED
;ONLY IF THERE ARE DIGITS BEYOND THE DECIMAL POINT. IF THIS
;IS THE CASE WE HAVE POSITIONED TO THE CORRECT PLACE AND
;HAVE CHARACTERS TO MOVE DOWN IN THE STACK AND CAN ELIMINATE
;THE ZERO BY NOT PUSHING IT ON THE STACK SINCE ALL
;CHARACTERS TO BE RE-INSERTED WILL COME FROM THE STACK.
;***************************************************************
INC BX ;THIS WILL CAUSE ELIMINATION OF "0"
CALL $CHRGT ;GET CHARACTER AFTER DECIMAL POINT
JNB PFX70 ;NO HOPE GIVE UP AND PUT IN "%"
DEC BX ;(BX) NOW POINTS TO DECIMAL POINT
JMP SHORT PFX60
PFX50: DEC BX ;NEXT CHARACTER POSITION TO MOVE INTO
MOV BYTE PTR 0[BX],AL ;MOVE IT IN
PFX60: POP AX ;FETCH CHARACTER OFF THE STACK
OR AH,AH ;ONCE (AH)=1 IS REACHED CHARS.
;HAVE BEEN RE-ENSTATED
JZ PFX50 ;KEEP GOING IF (AH)=0
ADD SP,2 ;GET OLD START OF BUFFER ADDRESS OFF
;THE STACK
JMP SHORT PFX30 ;AND SEE IF WE NOW FIT INTO THE
;REQUIRED SPACE
PFX70:
;******************************************************************
;WE COULD NOT FIT THE NUMBER INTO THE BUFFER DESPITE OUR VALIENT
;EFFORTS WE MUST POP ALL THE CHARACTERS BACK OFF THE STACK AND
;POP OFF THE BEGINNING BUFFER PRINT LOCATION AND INPUT A "%" SIGN
;THERE
;******************************************************************
POP AX ;GET CHARACTER OFF THE STACK
OR AH,AH ;IF ZF=1 AFTER THIS-MORE CHARS.
JZ PFX70
POP BX ;GET BEGINNING BUFFER POINTER
MOV BYTE PTR 0[BX],LOW "%" ;INSERT OVERFLOW FLAG
PFX90: RET
SUBTTL $FOTZS ZERO SUPRESSION UPON OUTPUT ROUTINE
;*************************************************************
;
; $FOTZS THIS ROUTINE WILL LOOK AT THE OUTPUT GENERATED
; BY THE REST OF THE PUFOT ROUTINES AND SUPRESS
; LEADING ZEROES.
; CALLING SEQUENCE: CALL $FOTZS
; ONLY PREREQUISITE IS THAT OTHER PUFOT ROUTINES
; HAVE EXECUTED TO PROVIDE FOTZS WITH $FBUFF
; CONTAINING OUTPUT TEXT.
;
; $FOTZ THIS ROUTINE PUTS IN (AL) LEADING ZEROS
; CALLING SEQUENCE: CALL $FOTZ
; WITH (AL) SET TO NO. OF LEADING ZEROS DESIRED
; $FOTZC THIS ROUTINE PUTS IN (AL) LEADING ZEROS AND
; PAYS ATTENTION TO DECIMAL POINT AND COMMA COUNTS
; AND FURTHER PUTS IN COMMAS AND A D.P. AS NECESSARY
; CALLING SEQUENCE: CALL $FOTZC
; WITH (CX) SET TO NO. PLACES TO LEFT/RIGHT OF D.P.
; AND (AL) TO NO. LEADING ZEROS
;*************************************************************
CURNCY="$" ;Default floating currency is dollars.
$FOTZS: MOV BX,OFFSET $FBUFF+1 ;ADDRESS OF SIGN(IF LEADING)
MOV CH,BYTE PTR 0[BX] ;FETCH LEADING CHARACTER
MOV CL,LOW " " ;SPACE TO CL
MOV AH,BYTE PTR $FMTAL ;FETCH FORMAT SPECIFICATIONS
;BIT 76543210 OF AH
; ABCDEFGH WHERE
;A=FREE FORMAT FLAG
;B=GROUP INTEGER DIGITS IN 3'S AND
; SEPARATE WITH COMMAS
;C=FILL LEADING SPACES WITH "*"
;D=OUTPUT WITH FLOATING "$"
;E=PRINT SIGN WITH "+" INSTEAD OF" "
;F=PRINT SIGN AS TRAILING
;G=UNUSED
;H=USE SCIENTIFIC NOTATION
TEST AH,LOW 40 ;WILL TEST FOR LEADING "*" FIRST
JZ FZ10 ;LEADING ASTERISKS NOT DESIRED IF JMP
CMP CH,CL ;SPACE?
MOV CL,LOW "*" ;SINCE IT'S ASTERISK FILL DESIRED
JNZ FZ10 ;JUMP IF NOT SPACE
TEST AH,LOW 4 ;WILL NOW CHECK FOR TRAILING SIGN
JNZ FZ10
MOV CH,CL
FZ10: MOV BYTE PTR 0[BX],CL ;REPLACE SIGN AS NECESSARY
CALL $CHRGT ;GET NEXT CHARACTER AND SET CONDITION
JZ FZ50 ;CODES. JUMP IF END OF NUMBER
MOV BP,OFFSET $FINCH+11
FZ20:
CMP AL,BYTE PTR CS:0[BP] ;SEE IF SPECIAL CHARACTER
JZ FZ30 ;
CMP BP,OFFSET $FINCH ;SEE IF SEARCHED ALL TABLE
JZ FZ60 ;IF SO GO CHECK FOR FLOATING "$"
DEC BP ;POINT TO NEXT SPECIAL CHARACTER
JMP SHORT FZ20 ;AND CONTINUE SEARCH
FZ30: SUB BP,OFFSET $FINCH ;CALCULATE TABLE OFFSET
SHL BP,1 ;TO ACCOUNT FOR 2 BYTE TABLE ENTRY
;ADD BASE ADDRESS (BP) NOW HAS ADDR.
FZ40:
;CODE SEGMENT OVERRIDE
JMP WORD PTR CS:FZ45[BP]
FZ45 LABEL WORD
DW OFFSET FZ50 ;"."
DW OFFSET FZ50 ;"E"
DW OFFSET FZ60 ;"E"+40
DW OFFSET FZ60 ;"%"
DW OFFSET FZ60 ;"#"
DW OFFSET FZ60 ;"!"
DW OFFSET FZ50 ;"D"
DW OFFSET FZ60 ;"D"+40
DW OFFSET FZ10 ;","
DW OFFSET FZ10 ;"0"
FZ50: DEC BX ;NEED TO PUT IN LEADING "0"
MOV BYTE PTR 0[BX],LOW "0"
FZ60: MOV AH,BYTE PTR $FMTAL ;GET FORMAT SPECS AGAIN
TEST AH,LOW 20 ;TEST FOR FLOATING "$"
;FLOATING "$" DESIRED?
JZ FZ70 ;IF NOT PROCEED
DEC BX ;
MOV BYTE PTR 0[BX],LOW OFFSET CURNCY ;PUT IN FLOATING "$"
FZ70: TEST AH,LOW 4 ;RECALL FORMAT SPECS
;SEE IF TRAILING SIGN
JNZ FZ90 ;IF SO RETURN
DEC BX
MOV BYTE PTR 0[BX],CH ;PUT IN SIGN
XOR CH,CH ;MUST RETURN ZF=1 IF NOT TRAILING
;SIGN.
FZ90: RET
$FOTZ: ;PUT (AL) LEADING ZEROS IN BUFFER POINTED TO BY (BX)
OR AL,AL ;SEE IF FURTHER WORK TO DO
JMP SHORT FTZ15
FTZ10: MOV BYTE PTR 0[BX],LOW "0" ;PUT IN LEADING ZERO
INC BX ;NEXT BUFFER POSITION
DEC AL
FTZ15: JNZ FTZ10
RET
FTZC10: CALL $FOTED ;PUT IN COMMA AND DECIMAL POINT AS
;NECESSARY
$FOTZC: MOV BYTE PTR 0[BX],LOW "0" ;PUT IN LEADING ZERO
INC BX ;NEXT BUFFER POSITION
DEC AL ;
JNZ FTZC10
RET
SUBTTL $PUFE PRINT USING FLOATING IN "E" TYPE FORMAT
;************************************************************
;
; $PUFE THIS ROUTINE IS CALLED TO FORMAT A SINGLE
; OR DOUBLE PRECISION NUMBER WITH A DESIRED
; "E" TYPE OUTPUT FORMAT. FURTHER SPECIFICATIONS
; CAN BE THE NUMBER DESIRED PRINT POSITIONS
; TO THE LEFT AND RIGHT OF THE DECIMAL POINT.
; CALLING SEQUENCE: CALL $PUFE
; WITH (BX) POINTING TO THE CURRENT OUTPUT POSITION
; AND ZF=1 IF THE OUTPUT NUMBER IS SINGLE
; PRECISION, ZF=0 IF DOUBLE PRECISION.
;
;*************************************************************
$PUFE: CALL $GETYP ;SET CONDITION CODES ACCORDING TO TYPE
MOV AH,LOW 7 ;7 print positions if single precision
JB PFE10 ;AND JUMP IF SINGLE PRECISION
MOV AH,LOW 20 ;IT'S DOUBLE
PFE10: CALL $SIGNS ;SET COND CODES ACCORDING TO NO.
POP BX ;GET BUFFER PTR IN CASE NO. IS ZERO
STC ;CF WILL BE OUR FLAG TO REMEMBER
JZ PFE20 ;IF THE NO. WAS ZERO SINCE $FOTNV
;WILL RETURN WITH CF=0
PUSH BX ;SAVE BUFFER PTR
PUSH AX ;SAVE NO. DIGITS IN NUMBER
CALL $FOTNV ;BRACKET NO. SO DIGITS TO PRINT ARE
;IN THE INTEGER PART
POP DX ;$FOTNV ALSO RETURNS WITH EXPONENT
;IN (AL)
POP BX ;CF=0
MOV AH,DH ;(AH)=NO DIGITS RETURNED FROM $FOTNV
PFE20: PUSHF ;SAVE CF FLAG IN CASE NO. IS ZERO
PUSH AX ;SAVE EXP. AND NO. SIG. DIGITS
MOV DX,WORD PTR $FMTCX ;DIG LEFT/RT.OF D.P.
OR DH,DH ;WILL NEED TO KNOW IF SIGN DESIRED
PUSHF
OR DL,DL ;SEE IF DECIMAL POINT DESIRED.
JZ PFE30 ;IF NOT PROCEED
DEC DL ;
PFE30: ADD DH,DL ;NO. DIGITS DESIRED
POPF ;SEE IF SIGN DESIRED
JZ PFE40 ;JUMP IF NOT DESIRED
TEST BYTE PTR $FMTAX,LOW 4 ;SEE IF TRAILING SIGN DESIRED
JNZ PFE40 ;IF SO PROCEED
DEC DH ;MUST USE ONE PRINT POSITION FOR SIGN
PFE40: SUB DH,AH ;MUST SEE IF HAVE EXCESS DIGITS AVAIL.
MOV AH,DH ;IF TO MANY WE MUST DIVIDE NO BY
;10 UNTIL CORRECT DIGITS .
PUSH AX ;SAVE COMPAREISON OF DESIRED-AVAILABLE
;DIGITS. AH IS GREATER THAN 0 IF
;TRAILING ZEROS.
JS PFE45
JMP PFE65 ;IF NO INTERNAL ROUNDING PROCEED
;*********************************************************************
;WHAT IS HAPPENING HERE IS THAT IF WE HAVE MORE DIGITS THAN REQUIRED
;WE MUST DIVIDE OUT THE EXCESS DIGITS SO THAT WE CAN ROUND AT THE
;CORRECT PRINT POSITION. ONCE WE HAVE PERFORMED THIS DIVISION WE
;WILL NEED TO CALCULATE THE CORRECT DECIMAL POINT POSITION BY ADDING
;THE DESIRED PRINT POSITIONS TO THE LEFT TO THE NUMBER OF POSITIONS
;WE SHIFTED OUT. THE REASON FOR THIS IS THAT REGARDLESS OF THE SIZE
;OF THE NUMBER WE GO TO $FOTCV WITH , A FIXED NUMBER OF DIGITS
;WILL BE PLACED IN THE OUTPUT BUFFER. FOR EXAMPLE, SAY WE REQUESTED
;A PRINT LIKE ##.###^^^^ FOR A SINGLE PRECISION NUMBER. $FOTNV WILL
;PRODUCE AN INTEGER OF 7 DIGITS SAY AXXXXXX WHERE A IS NON-ZERO
;USING THE LEADING POSITION FOR THE SIGN WE NEED ONLY FOUR DIGITS
;PRINTED SO WE NEED IT ROUNDED AT THE FOURTH POSITION. TO DO THIS WE
;DIVIDE THE AXXXXXX BY 10 THREE TIMES TO GET AXXX.XXX , WHEN
;WE GO TO $FOTCV , HE WILL ROUND THIS NUMBER AND PRODUCE AN OUTPUT
; OF 000AXXX IN THE OUTPUT BUFFER. THE CORRECT PRINT POSITION
;FOR THE DECIMAL POINT IS BETWEEN "A" AND "X". THIS IS CALCULATED
;AS PRINT POSITION= POSITIONS TO LEFT+SIGN+NO. POSITIONS DIVIDED
;OFF.
;*****************************************************************
PFE45: PUSH BX ;SAVE BUFFER PTR.
PUSH AX ;SAVE NO TIMES TO DIVIDE
PFE50: PUSH AX ;SAVE DIVIDE COUNT
CALL $DIV10 ;SHIFT NO TO GET CORRECT ROUNDING
POP AX ;RECALL DIVIDE COUNT
INC AH ;INCREMENT TO REFLECT DIVIDE
JNZ PFE50 ;CONTINUE UNTIL GET CORRECT NO.
CALL $VADDH ;ROUND UP AT THE CORRECT POSITION
CALL $VINT ;AND MAKE INTEGER
POP AX ;RECALL NO. DIVIDES
PUSH AX ;SAVE # DIVIDES
MOV CX,3 ;WILL SHIFT AH 3 BITS LEFT
SHL AH,CL ;BECAUSE DP TABLE IS 8 BYTES/ENTRY
CALL $GETYP ;DETERMINE TYPE
JB PFE55 ;JUMP IF SINGLE PRECISION
MOV AL,AH ;WILL CONVERT AH TO WORD IN AX
CBW
MOV BX,OFFSET $DP16 ;ADDRESS OF 10^16
ADD BX,AX ;FAC SHOULD BE LESS THAN NO. POINTED
CALL $MOVBF ;MOVE CODE SEG NO. TO DBUFF
CALL $DCMPM ;TO BY BX
JMP SHORT PFE57
PFE55:
MOV BX,OFFSET $DP07+4 ;address of 10^7
MOV AL,AH ;WILL CONVERT AH TO WORD IN AX
CBW
ADD BX,AX ;FAC SHOULD BE LESS THAN THIS NO
CALL $MOVBS ;MOVE CODE SEG NO. TO DBUFF
CALL $COMPM ;UNLESS ROUND UP HAS OCCURRED
PFE57: POP AX ;RECALL NO. DIVIDES. WE MAY NEED
POP BX ;GET BUFFER PTR BACK
JS PFE66 ;ROUND-UP DID NOT OCCUR
POP AX ;MUST GET TO ORIGINAL COPY
POP CX ;EXPONENT NOW IN CL
INC CL ;MUST INCREMENT EXPONENT
PUSH CX ;SAVE EXP ON STACK
PUSH AX ;SAVE FOR POSSIBLE TRAILING ZEROS
PUSH BX ;SAVE BUFFER PTR
PUSH AX ;SAVE DIVIDED OUT DIGITS & EXPONENT
CALL $DIV10 ;SO CORRECT DIGITS TO RIGHT OF
POP AX
POP BX ;DECIMAL POINT ARE PRINTED
JMP SHORT PFE66
PFE65: XOR AH,AH ;NO DIVIDES
PFE66: NEG AH ;IF PREVIOUSLY NEGATIVE MAKE POSITIVE
MOV AL,BYTE PTR $FMTCX+1 ;GET DESIRED PLACES TO LEFT OF DEC. PT.
ADD AH,AL ;NEW TOTAL
INC AH ;BECAUSE FOTED DECREMENTS AT FIRST
OR AL,AL ;SEE IF PLACES LEFT DESIRED
JZ PFE70
TEST BYTE PTR $FMTAX,LOW 4 ;SEE IF TRAILING SIGN
JNZ PFE70 ;IF TRAILING SIGN PROCEED
DEC AH ;ALLOW PRINT POSITION FOR SIGN
PFE70: MOV CH,AH ;SET DECIMAL POINT POSITION
XOR CL,CL ;NO COMMAS FOR EXPONENTIAL PRINTOUT
POP AX ;RECALL SIG. DIGIT COMPARISON
PUSH WORD PTR $FMTCX ;SAVE FORMAT SPECS
PUSH AX ;SAVE SIG. DIGIT COMPARISON
MOV BYTE PTR $FMTCX+1,CH ;UPDATE DIGITS TO LEFT
CALL $FOTCV ;CONVERT TO ASCII DIGITS
POP AX ;RECALL SIG. DIGIT COMPARISON
OR AH,AH ;WILL SET SF=0 IF TRAILING ZEROS
JLE PFE80 ;IF TRAILING ZEROS NOT REQ. JUMP
MOV AL,AH ;NO. TRAILING ZEROS TO AL
CALL $FOTZC ;put in trailing zeros
CALL $FOTED ;put in decimal point (if necessary)
PFE80: POP AX ;FETCH DIGITS TO LEFT/RT. OF D.P.
MOV WORD PTR $FMTCX,AX ;KEEP COPY FORMAT SPECS
OR AL,AL ;SEE IF DECIMAL POINT DESIRED
JNZ PFE100 ;IF SO PROCEED
DEC BX ;NOT DESIRED SEE IF CAN ELIMINATE
MOV AL,BYTE PTR 0[BX] ;FETCH LAST PRINT POSITION
CMP AL,LOW "." ;DECIMAL POINT?
JZ PFE90 ;IF SO THIS JUMP WILL ELIMINATE
INC BX ;MUST RETAIN AS IS
PFE90: MOV WORD PTR $DPADR,BX ;SAVE ADDRESS OF DECIMAL POINT
PFE100: POP AX ;RECALL EXPONENT
POPF ;RECALL CF (=1 IF NO. IS ZERO)
JB PFE110 ;JUMP IF NO. IS ZERO
ADD AL,AH ;ADD EXP. AND NO SIG. DIGITS
MOV AH,BYTE PTR $FMTCX+1 ;SUBTRACT OUT DIGITS TO LEFT OF D.P.
SUB AL,AH ;SUBTRACT DIGITS TO LEFT
OR AH,AH ;IF NONE THEN NO SIGN
JZ PFE110
TEST BYTE PTR $FMTAX,LOW 4 ;IF SO WILL NEED TO INCREMENT AL
JNZ PFE110
INC AL ;MUST ACCOUNT FOR SIGN POSITION
PFE110: OR AL,AL
CALL $PUEXP ;PUT EXPONENT IN BUFFER
;$PUEXP IS LOCATED IN THE FILE WITH
;$FOFMT. WHEN HE FINISHES BUILDING
;THE EXPONENT IN $FBUFF HE LEAVES
;THE END-OF-BUFFER POINTER IN CX
;AND START OF BUFFER IN BX.
MOV BX,CX ;MUST GO TO PUFXE WITH END OF
;BUFFER PTR. IN BX
JMP $PUFXE ;DO FIX-UP
SUBTTL CON86 8086 BASIC CONSTANTS
;*****************************************************************
;
; THIS FILE CONTAINS 8086 CONSTANT TABLES
;
;*****************************************************************
.RADIX 10
$FOTB DB 38,38,38,38,38,38,38,38
DB 38,38,38,38,38,38,38,38
DB 38,38,38,38,38,38,38,38
DB 38,37,37,37,36,36,36,35
DB 35,35,34,34,34,34,33,33
DB 33,32,32,32,31,31,31,31
DB 30,30,30,29,29,29,29,28
DB 28,28,27,27,27,26,26,26
DB 25,25,25,25,24,24,24,23
DB 23,23,23,22,22,22,22,21
DB 21,21,20,20,20,19,19,19
DB 19,18,18,18,17,17,17,16
DB 16,16,16,15,15,15,14,14
DB 14,13,13,13,13,12,12,12
DB 11,11,11,10,10,10,10,09
DB 09,09,08,08,08,07,07,07
DB 06,06,06,06,05,05,05,04
DB 04,04,03,03,03,03,02,02
DB 02,01,01,01,00,00,00,00
DB -01,-01,-01,-02,-02,-02,-03,-03
DB -03,-03,-04,-04,-04,-05,-05,-05
DB -06,-06,-06,-06,-07,-07,-07,-08
DB -08,-08,-09,-09,-09,-09,-10,-10
DB -10,-11,-11,-11,-12,-12,-12,-12
DB -13,-13,-13,-14,-14,-14,-15,-15
DB -15,-15,-16,-16,-16,-17,-17,-17
DB -18,-18,-18,-18,-19,-19,-19,-20
DB -20,-20,-21,-21,-21,-21,-22,-22
DB -22,-23,-23,-23,-24,-24,-24,-25
DB -25,-25,-25,-26,-26,-26,-27,-27
DB -27,-28,-28,-28,-28,-29,-29,-29
DB -30,-30,-30,-31,-31,-31,-31,-32
;****************************************************************
;
;TABLE DXX CONTAINS DOUBLE PRECISION POWERS OF TEN
;FROM -38 TO +38
;
; 20-May-82 / MLC - Most of the negative powers of ten have been
; removed. Routines which used to multiply by these negative powers of
; ten have been changed to divide by the corresponding positive power
; of ten. ($FINE and $FOTNV)
;
;*************************************************************
.RADIX 8
$DPM01 DB 315,314,314,314,314,314,114,175 ;10^-01
$DP00 DB 000,000,000,000,000,000,000,201 ;10^00
$DP01 DB 000,000,000,000,000,000,040,204 ;10^01
DB 000,000,000,000,000,000,110,207 ;10^02
DB 000,000,000,000,000,000,172,212 ;10^03
DB 000,000,000,000,000,100,034,216 ;10^04
DB 000,000,000,000,000,120,103,221 ;10^05
$DP06 DB 000,000,000,000,000,044,164,224 ;10^06
$DP07 DB 000,000,000,000,200,226,030,230 ;10^07
DB 000,000,000,000,040,274,076,233 ;10^08
$DP09 DB 000,000,000,000,050,153,156,236 ;10^09
DB 000,000,000,000,371,002,025,242 ;10^10
DB 000,000,000,100,267,103,072,245 ;10^11
DB 000,000,000,020,245,324,150,250 ;10^12
DB 000,000,000,052,347,204,021,254 ;10^13
DB 000,000,200,364,040,346,065,257 ;10^14
DB 000,000,240,061,251,137,143,262 ;10^15
$DP16 DB 000,000,004,277,311,033,016,266 ;10^16
DB 000,000,305,056,274,242,061,271 ;10^17
DB 000,100,166,072,153,013,136,274 ;10^18
DB 000,350,211,004,043,307,012,300 ;10^19
DB 000,142,254,305,353,170,055,303 ;10^20
DB 200,172,027,267,046,327,130,306 ;10^21
DB 220,254,156,062,170,206,007,312 ;10^22
DB 264,127,012,077,026,150,051,315 ;10^23
DB 241,355,314,316,033,302,123,320 ;10^24
DB 205,024,100,141,121,131,004,324 ;10^25
DB 246,031,220,271,245,157,045,327 ;10^26
DB 017,040,364,047,217,313,116,332 ;10^27
DB 012,224,370,170,071,077,001,336 ;10^28
DB 014,271,066,327,007,217,041,341 ;10^29
DB 117,147,004,315,311,362,111,344 ;10^30
DB 043,201,105,100,174,157,174,347 ;10^31
DB 266,160,053,250,255,305,035,353 ;10^32
DB 343,114,066,022,031,067,105,356 ;10^33
DB 034,340,303,126,337,204,166,361 ;10^34
DB 021,154,072,226,013,023,032,365 ;10^35
DB 026,007,311,173,316,227,100,370 ;10^36
DB 333,110,273,032,302,275,160,373 ;10^37
DB 211,015,265,120,231,166,026,377 ;10^38
;DOUBLE PRECISION .5D00
$DHALF DB 000 ;.5D00
DB 000
DB 000
DB 000
;SINGLE PRECISION .5E00
$SHALF DB 000 ;.5E00
DB 000
DB 000
DB 200
$SQRH DB 361 ;SQR(.5)
DB 004
DB 065
DB 200
;**********************************************************
;FOR LOG CALCULATIONS HART ALGORITHM 2524 WILL BE USED
;IN THIS ALGORITHM WE WILL CALCULATE BASE 2 LOG AS FOLLOWS
;LOG(X)=P(X)/Q(X)
;***************************************************************
$LOGP DB 4
DB 232 ;4.8114746
DB 367
DB 031
DB 203
DB 044 ;6.105852
DB 143
DB 103
DB 203
DB 165 ;-8.86266
DB 315
DB 215
DB 204
DB 251 ;-2.054667
DB 177
DB 203
DB 202
$LOGQ DB 4
DB 000 ;1.
DB 000
DB 000
DB 201
DB 342 ;6.427842
DB 260
DB 115
DB 203
DB 012 ;4.545171
DB 162
DB 021
DB 203
DB 364 ;.3535534
DB 004
DB 065
DB 177
;LOG BASE E OF 2.0
$LN2 DB 030
DB 162
DB 061
DB 200
;SPECIAL CHARACTERS FOR INPUT/OUTPUT
$FINCH DB "."
DB OFFSET "E"+40 ;LOWER CASE "E"
DB "E"
DB "%"
DB "#"
DB "!"
DB "D"
DB OFFSET "D"+40 ;LOWER CASE "D"
DB 54 ;COMMA
DB "0"
$FODTB DB 000 ; 1D15
DB 200
DB 306
DB 244
DB 176
DB 215
DB 003
DB 000 ; 1D14
DB 100
DB 172
DB 020
DB 363
DB 132
DB 000
DB 000 ; 1D13
DB 240
DB 162
DB 116
DB 030
DB 011
DB 000
DB 000 ; 1D12
DB 020
DB 245
DB 324
DB 350
DB 000
DB 000
DB 000 ; 1D11
DB 350
DB 166
DB 110
DB 027
DB 000
DB 000
DB 000 ; 1D10
DB 344
DB 013
DB 124
DB 002
DB 000
DB 000
DB 000 ; 1D9
DB 312
DB 232
DB 073
DB 000
DB 000
DB 000
DB 000 ; 1D8
DB 341
DB 365
DB 005
DB 000
DB 000
DB 000
DB 200 ; 1D7
DB 226
DB 230
DB 000
DB 000
DB 000
DB 000
DB 100 ; 1D6
DB 102
DB 017
DB 000
DB 000
DB 000
DB 000
;SINGLE PRECISION POWER OF TEN TABLE
$FOSTB DB 100 ;1,000,000
DB 102
DB 017
DB 240 ; 1E5
DB 206
DB 001
DB 020 ; 1E4
DB 047
DB 000
;INTEGER POWER OF TEN TABLE
$FOITB DB 020 ; 10000
DB 047
DB 350 ; 1000
DB 003
DB 144 ; 100
DB 000
DB 012 ; 10
DB 000
DB 001 ; 1
DB 000
$S32KM DB 000 ;SINGLE PRECISION -32768
DB 000
DB 200
DB 220
$INFPD DB 377 ;DOUBLE PRECISION +INFINITY
DB 377
DB 377
DB 377
DB 377 ;SINGLE PREC. +INFINITY
DB 377
DB 177
DB 377
$INFMD DB 377 ;DOUBLE PRECISION -INFINITY
DB 377
DB 377
DB 377
DB 377 ;SINGLE PREC. -INFINITY
DB 377
DB 377
DB 377
$LG2E DB 073 ;LOG BASE 2 OF E
DB 252
DB 070
DB 201
;*********************************************************
;$EXPCN CONTAINS THE COEFFICIENTS FOR POLYNOMIAL EVALUATION
;OF LOG BASE 2 OF X WHERE .5.LE.X.LE.1
;THE COEFFICIENTS ARE FROM HART #1302
;***********************************************************
$EXPCN DB 7 ;DEGREE + 1
DB 174 ;.00020745577403-
DB 210
DB 131
DB 164
DB 340 ;.00127100574569-
DB 227
DB 046
DB 167
DB 304 ;.00965065093202+
DB 035
DB 036
DB 172
DB 136 ;.05549656508324+
DB 120
DB 143
DB 174
DB 032 ;.24022713817633-
DB 376
DB 165
DB 176
DB 030 ;.69314717213716+
DB 162
DB 061
DB 200
DB 000 ;1.0
DB 000
DB 000
DB 201
; COEFFICIENTS FOR SINE FUNCTION
; SEE HART'S #3341
; RELATIVE ERROR 8.27
$SINCN DB 5 ;NUMBER OF CONSTANTS
DB 373 ;39.71091766+
DB 327
DB 036
DB 206
DB 145 ;-76.57498378-
DB 046
DB 231
DB 207
DB 130 ;81.60223119+
DB 064
DB 043
DB 207
DB 341 ;-41.34167747+
DB 135
DB 245
DB 206
DB 333 ;6.283185272+
DB 017
DB 111
DB 203
;CONSTANTS FOR ARCTANGENT RANGE REDUCTION
$ATNC1 DB 2
DB 327 ;SQR(3)
DB 263
DB 135
DB 201
DB 000 ;-1.0
DB 000
DB 200
DB 201
;HART ALGORITHM 4940 COEFFICIENTS
$ATNC2 DB 4
DB 142 ;-.1281333
DB 065
DB 203
DB 176
DB 120 ;.1993573
DB 044
DB 114
DB 176
DB 171 ;-.3333324
DB 251
DB 252
DB 177
DB 000 ;1.0
DB 000
DB 000
DB 201
;************************************************************
;THE FOLLOWING CONSTANT LABELED $IN2PI IS USED FOR RANGE
;REDUCTION IN SIN,COS, & TAN. THE LOW ORDER BYTES ARE PURPOSELY
;ZERO TO PROVIDE A MORE ACCURATE REDUCTION OF SINGLE PRECISION
;NUMBERS. THIS CONSTANT SHOULD NOT BE USED WITH ORDINARY DOUBLE
;PRECISION NUMBERS.
;************************************************************
$IN2PI DB 013 ;1/(2*PI)
DB 104
DB 116
DB 156
DB 203
DB 371
DB 042
DB 176
;***********************************************************
;CONSTANTS FOR THE RANDOM NUMBER GENERATOR FOLLOW
;DO NOT CHANGE THESE WITHOUT CONSULTING KNUTH VOL 2
;CHAPTER 3 FIRST
;************************************************************
$RNDA DB 375 ;214013
DB 103
DB 003
$RNDC DB 303 ;2531011
DB 236
DB 046
$RND0 DB 001
DB 000 ;1
DB 000
$NUMB DB "0" ;TABLE FOR OCTAL/HEX OUTPUT
DB "1"
DB "2"
DB "3"
DB "4"
DB "5"
DB "6"
DB "7"
DB "8"
DB "9"
DB "A"
DB "B"
DB "C"
DB "D"
DB "E"
DB "F"
SUBTTL $SIN SINGLE PRECISION SINE/COSINE/TANGENT/ARCTANGENT
;****************************************************************
;
; $SIN,$COS,$TAN CALCULATE THE SINE/COSINE/TAN OF NO.
; IN THE $FAC.USES HART POLYNOMIAL EVALUATION
; WITH COEFFICIENTS FROM #3341
; CALLING SEQUENCE: CALL $SIN
; OR CALL $COS
; OR CALL $TAN
; WITH ARGUMENT IN THE $FAC
;
; $ATAN CALCULATE THE ARCTANGENT OF THE VALUE IN THE
; FAC. USES COEFFICIENTS FROM HART 4940
; CALLING SEQUENCE: CALL $ATAN
; WITH THE ARGUMENT IN THE FAC
;
; Changed COS to double precision range reduction 24-JUN-82/NGT
;
;******************************************************************
COS:
$COS:
AND BYTE PTR $FACM1,LOW 177O ;clear sign bit ( cos(-x) = cos(x) )
CALL RR ; Do range reduction, FAC=REM(FAC/2pi)
CALL ONEARG ; Zero the accumulator
MOV BYTE PTR $ARG,LOW 177O ; ARG = DP 1/4
CALL $FADDD ; FAC = reduced angle + PI/2
CALL RR1 ; Make sure we are still in 0 - 2*PI
JMP SHORT SIN30
SIN:
$SIN: ;Will now take advantage of identity SIN(-X)=-SIN(X)
MOV AX,WORD PTR $FAC-1 ;FETCH SIGN BYTE
CMP AH,LOW 167O ;IF EXP SMALLER THEN RETURN X
JNB SIN10
RET
SIN10:
OR AL,AL
JNS SIN20
;(FAC) is negative will make positive and push neg on stack
AND AL,LOW 177O ;CLEAR SIGN BYTE
MOV BYTE PTR $FAC-1,AL
MOV AX,OFFSET $NEG ;FETCH ADDRESS OF NEG
PUSH AX ;AND PUSH ON STACK
SIN20:
CALL RR ; Do DP range reduction
;
; At this point the FAC has the remainder of the angle / 2*PI
;
SIN30:
MOV AL,LOW OFFSET $FAC
OR AL,AL
JZ SIN31
ADD BYTE PTR $FAC,LOW 2 ; FAC = FAC*4 = Reduce angle / PI/2
SIN31:
CALL RR3 ;ARG= INT(FAC)
;
; Now we have the reduced angle mod PI/2, so that we can find what quadrant
; it's in. The FAC should have a value in the range 0-3 corresponding to
; the quadrant. If the value is 2 or 3, corresponding to the interval
; PI - 2*PI, we must return a negative value for the Sine. If the value is
; in quadrants 1 or 3, we must subtract the reduced angle from 1 (PI/2).
; Algorithm:
; FAC = (angle / (2*PI))*4 ; Yields number in 0.LE.FAC.LT.4
; Save FAC
; ARG = INT( FAC ) ; ARG = quadrant 0-3
; Restore FAC
; FAC = (FAC - ARG)/4 ; FAC = angle in range 0 - PI/2
; IF quadrant = 1 or 3 THEN
; FAC = 1 - FAC ; FAC = PI/2 - angle
; Calculate polynomial