COREMATH.A 165 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * COREMATH.A - trig functions and error handling *
  5. * *
  6. * COPYRIGHT (C) 1989..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. include "corelib.inc"
  11. StdFloat = (_WINDOWS) | ~(_jpicall)
  12. module CoreMath
  13. (*%T RegParam *)
  14. PopParam = 1
  15. (*%E RegParam *)
  16. (*************************************************************************)
  17. segment _BSS(BSS,28H)
  18. public _matherr : org CodePtrSize
  19. public __SH_sword : org 2
  20. public __exc_addr : org 4
  21. segment _BSS(BSS,28H)
  22. public __fac : org 10 (* return address & first error argument *)
  23. segment _DATA(DATA,28H)
  24. public _HUGE : db 098H,060H,0B9H,0D7H,0FFH,0FFH,0EFH,07FH
  25. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  26. public @coremath_HUGE : db 098H,060H,0B9H,0D7H,0FFH,0FFH,0EFH,07FH
  27. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  28. public @coremath_MIN : db 00H,00H,00H,00H,00H,00H,10H,00H
  29. segment _DATA(DATA,28H)
  30. public _LHUGE : db 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FEH,07FH
  31. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  32. public @coremath_LHUGE : db 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FEH,07FH
  33. segment PROC_TEXT(CODE,28H)
  34. public @Save8087 : dw 0 (* 1 if floating point context save required *)
  35. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  36. public @coremath_int_one : dw 1
  37. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  38. public @coremath_int_two : dw 2
  39. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  40. public @coremath_int_four : dw 4
  41. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  42. public @coremath_int_ten : dw 10
  43. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  44. public @coremath_tbyte_Pi_By_2 : dw 0C235H, 02168H, 0DAA2H, 0C90FH, 03FFFH
  45. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  46. public @coremath_tbyte_Pi_By_4: dw 0C235H, 02168H, 0DAA2H, 0C90FH, 03FFEH
  47. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  48. public @coremath_floor: dw 173FH (* affine,errors masked *)
  49. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  50. public @coremath_ceil: dw 1B3FH (* affine errors masked *)
  51. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  52. public @coremath_nearest: dw 133FH (* affine,errors masked *)
  53. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  54. public @coremath_default: dw 1F22H (* affine,chop,64 bit precision,*)
  55. (* denorm & precision masked *)
  56. (*************************************************************************)
  57. section
  58. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  59. public __fpreset :
  60. db Ret0@
  61. (************************************************************************)
  62. (*%F StdFloat *)
  63. section
  64. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,48H)
  65. extrn _matherr
  66. extrn __seterrno
  67. extrn @coremath_HUGE
  68. extrn @coremath_MIN
  69. (* __report_math_error is used for error reporting from math error functions.
  70. It is called from __lib_error where the table mechanism for error recovery
  71. is used, or may be called directly from a function detecting an error
  72. condition.
  73. On entry, st(0) == intended return value
  74. st(5) == arg1
  75. st(6) == arg2
  76. cs:bx points to function name, null terminated
  77. ax == exception type.
  78. If a user-defined matherr has been installed, it is called, otherwise
  79. errno is set and we return to the caller.
  80. struct exception { int type;
  81. char *name;
  82. double arg1;
  83. double arg2;
  84. double retval; }
  85. *)
  86. public __report_math_error:
  87. push bp
  88. mov bp,sp
  89. push di
  90. push si
  91. push cx
  92. (*%F SameDS *)
  93. push ds
  94. (*%E *)
  95. mov cx,ax (* cx == exception type *)
  96. (*%T _fcall *)
  97. (*%F SameDS *)
  98. mov ax, seg _matherr
  99. mov ds, ax
  100. (*%E *)
  101. les ax, [_matherr]
  102. mov si, es
  103. or si, ax
  104. (*%E *)
  105. (*%F _fcall *)
  106. cmp word [_matherr], 0
  107. (*%E *)
  108. je doerrno
  109. (* A user-defined error handler has been installed. Call it *)
  110. (* First, copy the name into the stack segment *)
  111. push cs
  112. pop es
  113. mov di,bx
  114. sub al,al
  115. push cx
  116. mov cx,-1
  117. repne; scasb
  118. not cx
  119. inc cx
  120. and cx,-2
  121. mov si,cx
  122. pop cx
  123. sub sp,si
  124. mov si,sp (* si = ^name *)
  125. mov di,si
  126. lp: mov al,es:[bx]
  127. mov ss:[di],al
  128. inc bx
  129. inc di
  130. or al,al
  131. jnz lp
  132. (* Now create the structure on the stack *)
  133. sub sp,34 (* space for 3 doubles, one tbyte *)
  134. mov bx,sp
  135. fld st(0),st(0)
  136. fstp tbyte ss:[bx][24], st(0)
  137. call forcedouble
  138. fst qword ss:[bx][16], st(0)
  139. fld st(0),st(6)
  140. call forcedouble
  141. fstp qword ss:[bx][8], st(0)
  142. fld st(0),st(5)
  143. call forcedouble
  144. fstp qword ss:[bx][0], st(0)
  145. (*%T FarPtr *)
  146. push ss
  147. (*%E *)
  148. push si (* ^name *)
  149. push cx (* type *)
  150. mov ax,sp (* pointer to exception structure *)
  151. (*%T FarPtr *)
  152. mov bx,ss (* segment part of the above *)
  153. (*%E *)
  154. (*%T _fcall *)
  155. call dword [_matherr]
  156. (*%E *)
  157. (*%F _fcall *)
  158. call word [_matherr]
  159. (*%E *)
  160. test ax,ax
  161. mov bx,sp
  162. jnz newretval (* matherr supplied a new retval *)
  163. (* Reload the saved return value *)
  164. (*%T FarPtr *)
  165. fld tbyte st(0),ss:[bx][30]
  166. (*%E *)
  167. (*%F FarPtr *)
  168. fld tbyte st(0),ss:[bx][28]
  169. (*%E *)
  170. fstp st(1),st(0) (* retval in st(0) *)
  171. jmp doerrno
  172. newretval:
  173. (*%T FarPtr *)
  174. fld qword st(0),ss:[bx][22]
  175. (*%E *)
  176. (*%F FarPtr *)
  177. fld qword st(0),ss:[bx][20]
  178. (*%E *)
  179. fstp st(1),st(0) (* user's new retval in st(0) *)
  180. jmp done
  181. doerrno:
  182. mov ax, EDOM
  183. cmp cx,_DOMAIN (* type == _DOMAIN *)
  184. je wasdomain
  185. mov ax, ERANGE
  186. wasdomain:
  187. (*%T _fcall *)
  188. call far __seterrno
  189. (*%E *)
  190. (*%F _fcall *)
  191. call __seterrno
  192. (*%E *)
  193. done:
  194. (*%F SameDS *)
  195. lea sp,[bp][-8]
  196. pop ds
  197. (*%E *)
  198. (*%T SameDS *)
  199. lea sp,[bp][-6]
  200. (*%E *)
  201. pop cx
  202. pop si
  203. pop di
  204. mov sp,bp
  205. pop bp
  206. ret 0
  207. forcedouble:
  208. (* force st(0) into the range that fits in a double *)
  209. push ax
  210. push bx
  211. mov bx,sp
  212. fcom qword st(0),cs:[@coremath_HUGE]
  213. push ax
  214. fstsw ss:[bx][-2]
  215. fwait
  216. pop ax
  217. sahf
  218. jb NotPosH
  219. fstp st(0),st(0)
  220. fld qword st(0),cs:[@coremath_HUGE]
  221. jmp fddone
  222. NotPosH:
  223. fcom qword st(0),cs:[@coremath_MIN]
  224. push ax
  225. fstsw ss:[bx][-2]
  226. fwait
  227. pop ax
  228. sahf
  229. ja fddone
  230. (* now st(0) must be < coremath_min *)
  231. fchs st(0)
  232. fcom qword st(0),cs:[@coremath_HUGE]
  233. push ax
  234. fstsw ss:[bx][-2]
  235. fwait
  236. pop ax
  237. sahf
  238. jb NotNegH
  239. fstp st(0),st(0)
  240. fld qword st(0),cs:[@coremath_HUGE]
  241. fchs st(0)
  242. jmp fddone
  243. NotNegH:
  244. fcom qword st(0),cs:[@coremath_MIN]
  245. push ax
  246. fstsw ss:[bx][-2]
  247. fchs st(0)
  248. pop ax
  249. sahf
  250. ja fddone
  251. fstp st(0),st(0)
  252. fldz st(0)
  253. fddone:
  254. pop bx
  255. pop ax
  256. ret 0
  257. (*%E NOT StdFloat *)
  258. (*************************************************************************)
  259. (*%F StdFloat *)
  260. section
  261. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  262. extrn __report_math_error
  263. (* __lib_error is used by the math library functions to report range, domain
  264. and underflow errors etcetera. It may be called via two routes:
  265. 1. An exception occurring inside a math library function will cause
  266. __math_excep to call this function. __math_excep reads the address
  267. of a table from ss:InMathLib. This table contains a (short) resume
  268. address and then a table in the format below. The address of the
  269. table (excluding the resume address) is passed to __lib_error in si.
  270. 2. math library functions pre-emptively detecting an error case without
  271. causing an exception may call __lib_error directly. In this case,
  272. si must point to a table as described below.
  273. The table processed by __lib_error is in the following format:
  274. [si][0] short address of procedure to yield return value when
  275. arg1 is negative
  276. [si][2] ditto when arg1 is positive
  277. [si][4] flags byte.
  278. If [si][4] & f_st5 != 0, arg1 is in the st(5) register
  279. at the point of the exception or call to __lib_error.
  280. Otherwise, it is in st(0).
  281. If [si][4] & f_two != 0, there is a second argument in
  282. st(6).
  283. [si][6] null terminated string containing name of function with error.
  284. The procedures pointed to by [si][0] and [si][2] push the required return
  285. value into st(0), and return the error type in ax.
  286. *)
  287. public __lib_error:
  288. push bp
  289. mov bp, sp
  290. sub sp,2
  291. push ax
  292. push bx
  293. push cx
  294. push dx
  295. test byte cs:[si][4], f_st5 (* is arg1 in st5? *)
  296. jz not_st5
  297. fld st(0), st(5)
  298. fstp st(1), st(0) (* st(0) == st(5) == arg1 *)
  299. jmp st5_done
  300. not_st5:
  301. fst st(5), st(0) (* st(0) == st(5) == arg1 *)
  302. st5_done:
  303. ftst st(0)
  304. fstsw [bp][-2]
  305. fwait
  306. test byte [bp][-1], 1 (* Check if arg1 was +ve *)
  307. mov ax, cs:[si][2] (* negative entry from table *)
  308. jz me_positive
  309. mov ax, cs:[si][0] (* positive entry from table *)
  310. me_positive:
  311. call ax (* Call function to yield retval, pushed into st(0) *)
  312. fstp st(1), st(0) (* retval into st(0), arg1 in st(5) *)
  313. or ax, ax (* is it an error? *)
  314. jz me_ok
  315. test byte cs:[si][4], f_two (* Clear st(6) if there is only one argument *)
  316. jnz has_two
  317. fldz st(0)
  318. fstp st(7), st(0)
  319. has_two:
  320. lea bx, [si][5] (* st(0)==retval, st(5)==arg1, st(6)==arg2, bx=name *)
  321. call __report_math_error
  322. me_ok:
  323. pop dx
  324. pop cx
  325. pop bx
  326. pop ax
  327. mov sp, bp
  328. pop bp
  329. ret 0
  330. (*%E NOT StdFloat *)
  331. (*************************************************************************)
  332. (*%F StdFloat *)
  333. section
  334. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  335. extrn @coremath_int_one
  336. extrn $err_domain
  337. public $check_abs_one:
  338. fld st(0), st(0)
  339. fabs st(0)
  340. ficomp word st(0), cs:[@coremath_int_one]
  341. fstsw [bp][-2]
  342. fwait
  343. test byte [bp][-1], 40H
  344. jz ab1_err
  345. ret 0
  346. ab1_err:
  347. add sp,2
  348. jmp near $err_domain
  349. (*%E NOT StdFloat *)
  350. (*************************************************************************)
  351. (*%F StdFloat *)
  352. section
  353. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  354. extrn $err_underflow
  355. extrn $err_plus_infinity
  356. extrn $err_minus_infinity
  357. public _ldexp:
  358. push bp
  359. mov bp,sp
  360. sub sp,10
  361. mov word ss:[InMathLib], ldexptable
  362. mov word ss:[InMathLib][2], bp
  363. push ax
  364. fst st(5), st(0)
  365. fild word st(0), [bp][-12]
  366. fst st(7), st(0)
  367. fxch st(0),st(1)
  368. fscale st(0), st(1)
  369. fst qword [bp][-10],st(0) (* to provoke error if too big for double *)
  370. fstp st(1), st(0)
  371. ldexp_exit:
  372. mov sp,bp
  373. pop bp
  374. mov word ss:[InMathLib], 0
  375. db Ret0@
  376. ldexptable:
  377. dw ldexp_exit, ldexp_err_neg, ldexp_err_pos; db f_st5+f_two, "ldexp", 0
  378. ldexp_err_pos:
  379. fld st(0),st(6)
  380. ftst st(0)
  381. fstsw [bp][-2]
  382. fstp st(0), st(0)
  383. test byte [bp][-1], 1
  384. jnz $err_underflow
  385. jmp $err_plus_infinity
  386. ldexp_err_neg:
  387. fld st(0),st(6)
  388. ftst st(0)
  389. fstsw [bp][-2]
  390. fstp st(0), st(0)
  391. test byte [bp][-1], 1
  392. jnz $err_underflow
  393. jmp $err_minus_infinity
  394. (*%E NOT StdFloat *)
  395. (*************************************************************************)
  396. (*%F StdFloat *)
  397. section
  398. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  399. extrn $err_underflow
  400. extrn $err_huge_plus_infinity
  401. extrn $err_huge_minus_infinity
  402. public _ldexpl :
  403. push bp
  404. mov bp,sp
  405. mov word ss:[InMathLib], ldexpltable
  406. mov word ss:[InMathLib][2], bp
  407. push ax
  408. fst st(5), st(0)
  409. fild word st(0), [bp][-2]
  410. fst st(7), st(0)
  411. fxch st(0),st(1)
  412. fscale st(0), st(1)
  413. fstp st(1), st(0)
  414. ldexpl_exit:
  415. mov sp,bp
  416. pop bp
  417. mov word ss:[InMathLib], 0
  418. db Ret0@
  419. ldexpltable:
  420. dw ldexpl_exit, ldexpl_err_neg, ldexpl_err_pos; db f_st5+f_two, "ldexpl", 0
  421. ldexpl_err_pos:
  422. fld st(0),st(6)
  423. ftst st(0)
  424. fstsw [bp][-2]
  425. fstp st(0), st(0)
  426. test byte [bp][-1], 1
  427. jnz $err_underflow
  428. jmp $err_huge_plus_infinity
  429. ldexpl_err_neg:
  430. fld st(0),st(6)
  431. ftst st(0)
  432. fstsw [bp][-2]
  433. fstp st(0), st(0)
  434. test byte [bp][-1], 1
  435. jnz $err_underflow
  436. jmp $err_huge_minus_infinity
  437. (*%E NOT StdFloat *)
  438. (*************************************************************************)
  439. (*%F StdFloat *)
  440. section
  441. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  442. public _hypot:
  443. public _hypotl:
  444. (*%T _DLLOVL *)
  445. push bp
  446. mov bp, sp
  447. (*%E *)
  448. hypotCommon:
  449. fmul st(0), st(0)
  450. fld st(0), st(6)
  451. fmul st(0), st(0)
  452. faddp st(1), st(0)
  453. fsqrt st(0)
  454. (*%T _DLLOVL *)
  455. pop bp
  456. (*%E *)
  457. db Ret0@
  458. (*%E NOT StdFloat *)
  459. (*************************************************************************)
  460. (*%F StdFloat *)
  461. section
  462. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  463. public __round:
  464. (*%T _DLLOVL *)
  465. push bp
  466. mov bp, sp
  467. (*%E *)
  468. frndint st(0)
  469. (*%T _DLLOVL *)
  470. pop bp
  471. (*%E *)
  472. (*%F NearCall *)
  473. ret far 0
  474. (*%E *)
  475. (*%T NearCall *)
  476. ret 0
  477. (*%E *)
  478. (*%E NOT StdFloat *)
  479. (*************************************************************************)
  480. (*%F StdFloat *)
  481. section
  482. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  483. extrn @coremath_tbyte_Pi_By_4
  484. public _sin :
  485. public _sinl :
  486. push bp
  487. mov bp, sp
  488. sub sp, 2
  489. push cx
  490. xor cl, cl
  491. jmp trig
  492. public _cos :
  493. public _cosl :
  494. push bp
  495. mov bp, sp
  496. sub sp, 2
  497. push cx
  498. mov cl, 2
  499. jmp trig
  500. public _tan :
  501. public _tanl :
  502. push bp
  503. mov bp, sp
  504. sub sp, 2
  505. push cx
  506. mov cl, 4
  507. trig:
  508. push ax
  509. trigCommon:
  510. fxam st(0) (* '87 works while we enter routine*)
  511. fstsw [bp][-2]
  512. fwait
  513. mov ah, [bp][-1]
  514. fabs st(0)
  515. fldpi st(0)
  516. fadd st(0),st(0) (* st(0) = 2*pi *)
  517. fxch st(0),st(1)
  518. Lp: fprem st(0) (* reduce abs(arg1) by 2*pi *)
  519. fwait
  520. fstsw [bp][-2]
  521. test byte [bp][-1],4
  522. jnz Lp
  523. fstp st(1),st(0)
  524. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_4]
  525. fxch st(0),st(1)
  526. fprem st(0)
  527. mov ch, ah
  528. and ch, 2
  529. shr ch, 1 (* ch := sign *)
  530. fstsw [bp][-2]
  531. fwait
  532. mov ax, [bp][-2]
  533. mov al, ah
  534. and al, 3 (* select the C3, C1, and C0 status bits*)
  535. shl ah, 1
  536. shl ah, 1
  537. rcl al, 1 (* arrange them in the ls 3 bits of BX*)
  538. add al, 0FCH
  539. rcl al, 1 (* al now contains the octant number*)
  540. cmp cl, 2 (* are we doing Cosine ?*)
  541. jne trig_notCosine
  542. add al, cl (* Cos (x) = Sin (x + 2 octants)*)
  543. mov ch, 0 (* Cosine has even symmetry around 0*)
  544. trig_notCosine:
  545. and al, 7
  546. test al, 1
  547. jz trig_evens
  548. fsubp st(1), st(0) (* overwrites pi/4 in st(1), pops.*)
  549. jmp trig_ptan
  550. trig_evens:
  551. fstp st(1), st(0)
  552. trig_ptan:
  553. fptan st(0)
  554. cmp cl, 4
  555. je trig_tangent
  556. test al, 3
  557. jpe trig_sineOctant
  558. trig_cosOctant:
  559. fxch st(0), st(1)
  560. trig_sineOctant:
  561. fmul st(0), st(0)
  562. fstp st(7), st(0)
  563. fld st(0), st(0)
  564. fmul st(0), st(0)
  565. fadd st(0), st(7)
  566. fsqrt st(0)
  567. shr al, 1
  568. shr al, 1
  569. xor al, ch
  570. jz trig_sineDiv
  571. fchs st(0)
  572. trig_sineDiv:
  573. fdivp st(1), st(0)
  574. jmp trig_end
  575. trig_tangent:
  576. mov ah, al
  577. shr ah, 1
  578. and ah, 1
  579. xor ah, ch
  580. jz trig_tanSigned
  581. fchs st(0)
  582. trig_tanSigned:
  583. test al, 3
  584. jpe trig_ratio
  585. fdivrp st(1),st(0)
  586. jmp trig_end
  587. trig_ratio:
  588. fdivp st(1), st(0)
  589. trig_end:
  590. pop ax
  591. pop cx
  592. mov sp, bp
  593. pop bp
  594. db Ret0@
  595. (*%E NOT StdFloat *)
  596. (*************************************************************************)
  597. (*%F StdFloat *)
  598. section
  599. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  600. extrn $err_domain
  601. extrn __lib_error
  602. extrn @coremath_tbyte_Pi_By_2
  603. public _atan2:
  604. public _atan2l:
  605. push bp
  606. mov bp, sp
  607. sub sp, 4
  608. atan2Common:
  609. call atan20
  610. mov sp, bp
  611. pop bp
  612. db Ret0@
  613. atan20:
  614. ftst st(0)
  615. fstsw [bp][-2]
  616. fwait
  617. test byte [bp][-1],1
  618. je atan21
  619. fchs st(0)
  620. call atan21
  621. fchs st(0)
  622. ret 0
  623. atan21:
  624. fld st(0), st(6)
  625. ftst st(0)
  626. fstsw [bp][-4]
  627. fwait
  628. test byte [bp][-3],1
  629. je atan22
  630. fchs st(0)
  631. call atan22
  632. fldpi st(0)
  633. fsubrp st(1),st(0)
  634. ret 0
  635. atan22:
  636. test byte [bp][-3],40H
  637. jnz maybe_zero_zero
  638. not_zero_zero:
  639. fcom st(0), st(1)
  640. fstsw [bp][-2]
  641. fwait
  642. test byte [bp][-1],1
  643. jz atan23
  644. fxch st(0), st(1)
  645. fpatan st(1), st(0)
  646. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_2]
  647. fsubrp st(1),st(0)
  648. ret 0
  649. atan23:
  650. fpatan st(1),st(0)
  651. ret 0
  652. maybe_zero_zero:
  653. test byte [bp][-1],40H
  654. jz not_zero_zero
  655. fstp st(0), st(0)
  656. push si
  657. mov si, atan2_err_data
  658. call __lib_error
  659. pop si
  660. ret 0
  661. atan2_err_data: dw $err_domain, $err_domain; db f_two, "atan2", 0
  662. (*%E NOT StdFloat *)
  663. (*************************************************************************)
  664. (*%F StdFloat *)
  665. section
  666. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  667. extrn $atan0
  668. public _atan:
  669. public _atanl:
  670. push bp
  671. mov bp, sp
  672. sub sp, 2
  673. atanCommon:
  674. call $atan0
  675. mov sp, bp
  676. pop bp
  677. db Ret0@
  678. (*%E StdFloat *)
  679. (*************************************************************************)
  680. (*%F StdFloat *)
  681. section
  682. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  683. extrn @coremath_tbyte_Pi_By_2
  684. public $atan0:
  685. ftst st(0)
  686. fstsw [bp][-2]
  687. fwait
  688. test byte [bp][-1],1
  689. je atan1
  690. fchs st(0)
  691. call atan1
  692. fchs st(0)
  693. ret 0
  694. atan1:
  695. fld1 st(0)
  696. fcom st(0), st(1)
  697. fstsw [bp][-2]
  698. fwait
  699. test byte [bp][-1],1
  700. jnz atan2
  701. fpatan st(1), st(0)
  702. ret 0
  703. atan2:
  704. fxch st(0), st(1)
  705. fpatan st(1),st(0)
  706. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2]
  707. fsubrp st(1),st(0)
  708. ret 0
  709. (*%E NOT StdFloat *)
  710. (*************************************************************************)
  711. (*%F StdFloat *)
  712. section
  713. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  714. extrn $err_domain
  715. extrn $err_minus_infinity
  716. extrn __lib_error
  717. public _log :
  718. push bp
  719. mov bp, sp
  720. sub sp, 2
  721. logCommon:
  722. ftst st(0)
  723. fstsw [bp][-2]
  724. test byte [bp][-1], 41H
  725. jnz log_error
  726. fldln2 st(0)
  727. fxch st(0), st(1)
  728. fyl2x st(1), st(0)
  729. log_exit:
  730. mov sp, bp
  731. pop bp
  732. db Ret0@
  733. log_error:
  734. push si
  735. mov si, log_err_data
  736. call __lib_error
  737. pop si
  738. jmp log_exit
  739. log_err_data: dw $err_domain, $err_minus_infinity; db 0, "log", 0
  740. (*%E NOT StdFloat *)
  741. (*************************************************************************)
  742. (*%F StdFloat *)
  743. section
  744. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  745. extrn $err_domain
  746. extrn $err_huge_minus_infinity
  747. extrn __lib_error
  748. public _logl :
  749. push bp
  750. mov bp, sp
  751. sub sp, 2
  752. logCommon:
  753. ftst st(0)
  754. fstsw [bp][-2]
  755. test byte [bp][-1], 41H
  756. jnz log_error
  757. fldln2 st(0)
  758. fxch st(0), st(1)
  759. fyl2x st(1), st(0)
  760. log_exit:
  761. mov sp, bp
  762. pop bp
  763. db Ret0@
  764. log_error:
  765. push si
  766. mov si, log_err_data
  767. call __lib_error
  768. pop si
  769. jmp log_exit
  770. log_err_data: dw $err_domain, $err_huge_minus_infinity; db f_long, "logl", 0
  771. (*%E NOT StdFloat *)
  772. (*************************************************************************)
  773. (*%F StdFloat *)
  774. section
  775. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  776. extrn $err_domain
  777. extrn $err_minus_infinity
  778. extrn __lib_error
  779. public _log10 :
  780. push bp
  781. mov bp, sp
  782. sub sp, 2
  783. log10Common:
  784. ftst st(0)
  785. fstsw [bp][-2]
  786. fwait
  787. test byte [bp][-1], 41H
  788. jnz log10_error
  789. fldlg2 st(0)
  790. fxch st(0), st(1)
  791. fyl2x st(1), st(0)
  792. log10_exit:
  793. mov sp, bp
  794. pop bp
  795. db Ret0@
  796. log10_error:
  797. push si
  798. mov si, log10_err_data
  799. call __lib_error
  800. pop si
  801. jmp log10_exit
  802. log10_err_data: dw $err_domain, $err_minus_infinity; db 0, "log10", 0
  803. (*%E NOT StdFloat *)
  804. (*************************************************************************)
  805. (*%F StdFloat *)
  806. section
  807. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  808. extrn $err_domain
  809. extrn $err_huge_minus_infinity
  810. extrn __lib_error
  811. public _log10l :
  812. push bp
  813. mov bp, sp
  814. sub sp, 2
  815. log10Common:
  816. ftst st(0)
  817. fstsw [bp][-2]
  818. fwait
  819. test byte [bp][-1], 41H
  820. jnz log10_error
  821. fldlg2 st(0)
  822. fxch st(0), st(1)
  823. fyl2x st(1), st(0)
  824. log10_exit:
  825. mov sp, bp
  826. pop bp
  827. db Ret0@
  828. log10_error:
  829. push si
  830. mov si, log10_err_data
  831. call __lib_error
  832. pop si
  833. jmp log10_exit
  834. log10_err_data: dw $err_domain, $err_huge_minus_infinity; db f_long, "log10l", 0
  835. (*%E NOT StdFloat *)
  836. (*************************************************************************)
  837. (*%F StdFloat *)
  838. section
  839. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  840. extrn $err_domain
  841. public _sqrt :
  842. public _sqrtl :
  843. push bp
  844. mov bp, sp
  845. mov word ss:[InMathLib], sqrttable
  846. mov word ss:[InMathLib][2], bp
  847. sqrtCommon:
  848. (* Return the square root of x, which must be greater than zero. *)
  849. fsqrt st(0) (*invalid op possible*)
  850. fwait
  851. sqrt_exit:
  852. mov word ss:[InMathLib], 0
  853. mov sp,bp
  854. pop bp
  855. db Ret0@
  856. sqrttable:
  857. dw sqrt_exit, $err_domain, $err_domain; db 0, "sqrt", 0
  858. (*%E NOT StdFloat *)
  859. (*************************************************************************)
  860. (*%F StdFloat *)
  861. section
  862. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  863. (* compute 2^st(0) , result is represented as st(0) * 2^st(4) *)
  864. extrn @coremath_int_four
  865. public $pow2 :
  866. fld1 st(0)
  867. fxch st(0), st(1)
  868. fst st(5), st(0)
  869. frndint st(0)
  870. fsub st(0), st(1)
  871. fxch st(0), st(5)
  872. fsub st(0), st(5) (* we now know that st(0) is in range [0..2) *)
  873. fidiv word st(0), cs:[@coremath_int_four] (* now in range [0..0.5] *)
  874. f2xm1 st(0)
  875. faddp st(1), st(0)
  876. fmul st(0), st(0)
  877. fmul st(0), st(0)
  878. ret 0
  879. (*%E NOT StdFloat *)
  880. (*************************************************************************)
  881. (*%F StdFloat *)
  882. section
  883. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  884. extrn $err_underflow
  885. extrn $err_plus_infinity
  886. extrn $pow2
  887. public _exp :
  888. push bp
  889. mov bp, sp
  890. mov word ss:[InMathLib], exptable
  891. mov word ss:[InMathLib][2], bp
  892. sub sp, 10
  893. expCommon:
  894. fst st(5), st(0) (* save parameter for error processing *)
  895. fldl2e st(0)
  896. fmulp st(1), st(0)
  897. fist word [bp][-2], st(0) (* to check that it is not too large *)
  898. fwait
  899. call $pow2
  900. fld st(0), st(4) (* retrieve integral part *)
  901. fxch st(1), st(0)
  902. fscale st(0), st(1)
  903. fst qword [bp][-10],st(0) (* to provoke error if too big for double *)
  904. fstp st(1),st(0)
  905. exp_exit:
  906. mov sp, bp
  907. pop bp
  908. mov word ss:[InMathLib], 0
  909. db Ret0@
  910. exptable:
  911. dw exp_exit, $err_underflow, $err_plus_infinity; db f_st5, "exp", 0
  912. (*%E NOT StdFloat *)
  913. (*************************************************************************)
  914. (*%F StdFloat *)
  915. section
  916. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  917. extrn $err_underflow
  918. extrn $err_huge_plus_infinity
  919. extrn $pow2
  920. public _expl :
  921. push bp
  922. mov bp, sp
  923. mov word ss:[InMathLib], expltable
  924. mov word ss:[InMathLib][2], bp
  925. sub sp, 2
  926. expCommon:
  927. fst st(5), st(0) (* save parameter for error processing *)
  928. fldl2e st(0)
  929. fmulp st(1), st(0)
  930. fist word [bp][-2], st(0) (* to check that it is not too large *)
  931. fwait
  932. call $pow2
  933. fld st(0), st(4) (* retrieve integral part *)
  934. fxch st(1), st(0)
  935. fscale st(0), st(1)
  936. fstp st(1),st(0)
  937. exp_exit:
  938. mov sp, bp
  939. pop bp
  940. mov word ss:[InMathLib], 0
  941. db Ret0@
  942. expltable:
  943. dw exp_exit, $err_underflow, $err_huge_plus_infinity; db f_st5+f_long, "expl", 0
  944. (*%E NOT StdFloat *)
  945. (*************************************************************************)
  946. (*%F StdFloat *)
  947. section
  948. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  949. extrn $pow2
  950. public _tanh :
  951. public _tanhl :
  952. push bp
  953. mov bp, sp
  954. mov word ss:[InMathLib], tanhtable
  955. mov word ss:[InMathLib][2], bp
  956. sub sp, 2
  957. tanhCommon:
  958. fst st(5), st(0) (* save for error processing *)
  959. fldl2e st(0)
  960. fmulp st(1), st(0)
  961. fist word [bp][-2], st(0) (* to check that it is not too large *)
  962. fwait
  963. call $pow2
  964. fld st(0), st(4) (* retrieve integral part *)
  965. fxch st(1), st(0)
  966. fscale st(0), st(1)
  967. fstp st(1), st(0) (* st(0) = e**arg1 *)
  968. fld1 st(0)
  969. fdiv st(0), st(1) (* Exp (-x) *) (* st(0) = e**arg1,st(1) = e**-arg1 *)
  970. fst st(7), st(0) (* st(7) = e**arg1 *)
  971. fadd st(0), st(1) (* st(0) = (e**arg1)+(e**-arg1) *)
  972. fxch st(0), st(1) (* st(0) = e**-arg1 *)
  973. fsub st(0), st(7) (* st(0) = (e**-arg1)-(e**arg1) *)
  974. fdivrp st(1), st(0)
  975. (* st(0) = (e**-arg1)-(e**arg1)/(e**arg1)+(e**-arg1) *)
  976. tanh_exit:
  977. mov sp, bp
  978. pop bp
  979. mov word ss:[InMathLib], 0
  980. db Ret0@
  981. tanhtable:
  982. dw tanh_exit, tanh_minus_one,tanh_one; db f_st5, "tanh", 0
  983. tanh_one:
  984. sub ax, ax
  985. fld1 st(0)
  986. ret 0
  987. tanh_minus_one:
  988. call tanh_one
  989. fchs st(0)
  990. ret 0
  991. (*%E NOT StdFloat *)
  992. (*************************************************************************)
  993. (*%F StdFloat *)
  994. section
  995. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  996. extrn $pow2
  997. extrn $err_minus_infinity
  998. extrn $err_plus_infinity
  999. extrn @coremath_int_two
  1000. public _sinh :
  1001. push bp
  1002. mov bp, sp
  1003. mov word ss:[InMathLib], sinhtable
  1004. mov word ss:[InMathLib][2], bp
  1005. sub sp, 10
  1006. sinhCommon:
  1007. fst st(5), st(0) (* save for error processing *)
  1008. fldl2e st(0)
  1009. fmulp st(1), st(0)
  1010. fist word [bp][-2], st(0) (* to check that it is not too large *)
  1011. fwait
  1012. call $pow2
  1013. fld st(0), st(4) (* retrieve integral part *)
  1014. fxch st(1), st(0)
  1015. fscale st(0), st(1)
  1016. fstp st(1), st(0)
  1017. fld1 st(0)
  1018. fchs st(0)
  1019. fdiv st(0), st(1) (* - Exp (-x) *)
  1020. faddp st(1), st(0)
  1021. fidiv word st(0), cs:[@coremath_int_two ]
  1022. fst qword [bp][-10], st(0) (* To check not overflowed double *)
  1023. fwait
  1024. sinh_exit:
  1025. mov sp, bp
  1026. pop bp
  1027. mov word ss:[InMathLib], 0
  1028. db Ret0@
  1029. sinhtable:
  1030. dw sinh_exit, $err_minus_infinity, $err_plus_infinity; db f_st5, "sinh", 0
  1031. (*%E NOT StdFloat *)
  1032. (*************************************************************************)
  1033. (*%F StdFloat *)
  1034. section
  1035. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1036. extrn $pow2
  1037. extrn $err_huge_minus_infinity
  1038. extrn $err_huge_plus_infinity
  1039. extrn @coremath_int_two
  1040. public _sinhl :
  1041. push bp
  1042. mov bp, sp
  1043. mov word ss:[InMathLib], sinhltable
  1044. mov word ss:[InMathLib][2], bp
  1045. sub sp, 2
  1046. sinhCommon:
  1047. fst st(5), st(0) (* save for error processing *)
  1048. fldl2e st(0)
  1049. fmulp st(1), st(0)
  1050. fist word [bp][-2], st(0) (* to check that it is not too large *)
  1051. fwait
  1052. call $pow2
  1053. fld st(0), st(4) (* retrieve integral part *)
  1054. fxch st(1), st(0)
  1055. fscale st(0), st(1)
  1056. fstp st(1), st(0)
  1057. fld1 st(0)
  1058. fchs st(0)
  1059. fdiv st(0), st(1) (* - Exp (-x) *)
  1060. faddp st(1), st(0)
  1061. fidiv word st(0), cs:[@coremath_int_two ]
  1062. sinh_exit:
  1063. mov sp, bp
  1064. pop bp
  1065. mov word ss:[InMathLib], 0
  1066. db Ret0@
  1067. sinhltable:
  1068. dw sinh_exit, $err_huge_minus_infinity, $err_huge_plus_infinity; db f_st5, "sinhl", 0
  1069. (*%E NOT StdFloat *)
  1070. (*************************************************************************)
  1071. (*%F StdFloat *)
  1072. section
  1073. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1074. extrn $err_plus_infinity
  1075. extrn $pow2
  1076. extrn @coremath_int_two
  1077. public _cosh :
  1078. push bp
  1079. mov bp, sp
  1080. mov word ss:[InMathLib], coshtable
  1081. mov word ss:[InMathLib][2], bp
  1082. sub sp, 10
  1083. coshCommon:
  1084. fst st(5), st(0) (* save for error processing *)
  1085. fabs st(0)
  1086. fldl2e st(0)
  1087. fmulp st(1), st(0)
  1088. fist word [bp][-2], st(0) (* to check that it is not too large *)
  1089. fwait
  1090. call $pow2
  1091. fld st(0), st(4) (* retrieve integral part *)
  1092. fxch st(1), st(0)
  1093. fscale st(0), st(1)
  1094. fstp st(1), st(0)
  1095. fld1 st(0)
  1096. fdiv st(0), st(1) (* Exp (-x) *)
  1097. faddp st(1), st(0)
  1098. fidiv word st(0), cs:[@coremath_int_two ]
  1099. fst qword [bp][-10], st(0) (* to check result is in double range *)
  1100. fwait
  1101. cosh_exit:
  1102. mov sp, bp
  1103. pop bp
  1104. mov word ss:[InMathLib], 0
  1105. db Ret0@
  1106. coshtable:
  1107. dw cosh_exit, $err_plus_infinity, $err_plus_infinity; db f_st5, "cosh", 0
  1108. (*%E NOT StdFloat *)
  1109. (*************************************************************************)
  1110. (*%F StdFloat *)
  1111. section
  1112. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1113. extrn $err_huge_plus_infinity
  1114. extrn $pow2
  1115. extrn @coremath_int_two
  1116. public _coshl :
  1117. push bp
  1118. mov bp, sp
  1119. mov word ss:[InMathLib], coshltable
  1120. mov word ss:[InMathLib][2], bp
  1121. sub sp, 2
  1122. coshCommon:
  1123. fst st(5), st(0) (* save for error processing *)
  1124. fabs st(0)
  1125. fldl2e st(0)
  1126. fmulp st(1), st(0)
  1127. fist word [bp][-2], st(0) (* to check that it is not too large *)
  1128. fwait
  1129. call $pow2
  1130. fld st(0), st(4) (* retrieve integral part *)
  1131. fxch st(1), st(0)
  1132. fscale st(0), st(1)
  1133. fstp st(1), st(0)
  1134. fld1 st(0)
  1135. fdiv st(0), st(1) (* Exp (-x) *)
  1136. faddp st(1), st(0)
  1137. fidiv word st(0), cs:[@coremath_int_two ]
  1138. cosh_exit:
  1139. mov sp, bp
  1140. pop bp
  1141. mov word ss:[InMathLib], 0
  1142. db Ret0@
  1143. coshltable:
  1144. dw cosh_exit, $err_huge_plus_infinity, $err_huge_plus_infinity; db f_st5, "coshl", 0
  1145. (*%E NOT StdFloat *)
  1146. (*************************************************************************)
  1147. (*%F StdFloat *)
  1148. section
  1149. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1150. extrn $atan0
  1151. extrn $check_abs_one
  1152. extrn @coremath_tbyte_Pi_By_2
  1153. public _asin:
  1154. public _asinl :
  1155. push bp
  1156. mov bp, sp
  1157. mov word ss:[InMathLib], asintable
  1158. mov word ss:[InMathLib][2], bp
  1159. sub sp, 2
  1160. asinCommon:
  1161. fst st(5), st(0)
  1162. fmul st(0), st(0) (* arg1**2 *)
  1163. fld1 st(0)
  1164. fsubrp st(1),st(0) (* arg1**2-1 *)
  1165. ftst st(0)
  1166. fstsw [bp][-2]
  1167. fsqrt st(0) (* sqrt (arg1**2-1) *)
  1168. test byte [bp][-1],40H (* is result 0 *)
  1169. jz Not0 (* no *)
  1170. fcom st(0),st(5) (* was arg1 neg ? *)
  1171. fstsw [bp][-2]
  1172. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2] (* $1 *)
  1173. fstp st(1),st(0) (* $0 *)
  1174. pop ax (* flags of cmp 0,arg1 *)
  1175. sahf
  1176. jb asin_exit (* arg1 was positive. return pi/2 *)
  1177. fchs st(0)
  1178. jmp asin_exit (* arg1 was negative. return -pi/2 *)
  1179. Not0:
  1180. fdivr st(0),st(5) (* arg1/(sqrt(arg1**2-1)) *)
  1181. fwait
  1182. call $atan0
  1183. asin_exit:
  1184. mov sp,bp
  1185. pop bp
  1186. mov word ss:[InMathLib], 0
  1187. db Ret0@
  1188. asintable:
  1189. dw asin_exit, err_asin_neg, err_asin_pos; db f_st5, "asin", 0
  1190. err_asin_pos:
  1191. call $check_abs_one
  1192. fld1 st(0)
  1193. fstp st(1),st(0)
  1194. fchs st(0)
  1195. fldpi st(0)
  1196. fscale st(0),st(1)
  1197. sub ax, ax
  1198. ret 0
  1199. err_asin_neg:
  1200. call err_asin_pos
  1201. fchs st(0)
  1202. ret 0
  1203. (*%E NOT StdFloat *)
  1204. (*************************************************************************)
  1205. (*%F StdFloat *)
  1206. section
  1207. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1208. extrn $atan0
  1209. extrn $check_abs_one
  1210. extrn @coremath_tbyte_Pi_By_2
  1211. public _acos :
  1212. public _acosl :
  1213. push bp
  1214. mov bp, sp
  1215. mov word ss:[InMathLib], acostable
  1216. mov word ss:[InMathLib][2], bp
  1217. sub sp, 2
  1218. acosCommon:
  1219. ftst st(0) (* is arg1 0 or -0 ? *)
  1220. fstsw [bp][-2] (* store SW *)
  1221. fst st(5), st(0)
  1222. test byte [bp][-1],40H (* test for zero flag *)
  1223. jnz PiBy2 (* arg1 is 0,so return pi/2 *)
  1224. fmul st(0), st(0)
  1225. fld1 st(0)
  1226. fsubrp st(1),st(0)
  1227. fsqrt st(0)
  1228. fdivr st(0),st(5)
  1229. fwait
  1230. call $atan0
  1231. PiBy2:
  1232. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_2]
  1233. fsubrp st(1), st(0)
  1234. acos_exit:
  1235. mov sp, bp
  1236. pop bp
  1237. mov word ss:[InMathLib], 0
  1238. db Ret0@
  1239. acostable:
  1240. dw acos_exit, err_acos_neg, err_acos_pos; db f_st5, "acos", 0
  1241. err_acos_pos:
  1242. call $check_abs_one
  1243. fldz st(0)
  1244. sub ax, ax
  1245. ret 0
  1246. err_acos_neg:
  1247. call $check_abs_one
  1248. fldpi st(0)
  1249. sub ax, ax
  1250. ret 0
  1251. (*%E NOT StdFloat *)
  1252. (*************************************************************************)
  1253. (*%F StdFloat *)
  1254. section
  1255. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1256. public __bcd_to_int : (* si = bcd, di = int mantissa *)
  1257. ret 0
  1258. (*%E NOT StdFloat *)
  1259. (*************************************************************************)
  1260. (*%F StdFloat *)
  1261. section
  1262. segment _DATA(DATA,28H)
  1263. segment SIG_TEXT(CODE,28H)
  1264. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1265. extrn __SH_sword
  1266. extrn __exc_addr
  1267. extrn __lib_error
  1268. public __math_excep:
  1269. (* called from floating point exception handler *)
  1270. (*
  1271. 8087 status word on stack, behind FAR return address to
  1272. signal handler.
  1273. This function must reside in the same segment as the math
  1274. library functions which use InMathLib
  1275. [bp][0] == saved bp
  1276. [bp][2] == return ip to signal handler
  1277. [bp][4] == return cs to signal handler
  1278. [bp][6] == 8087 status word
  1279. [bp][8] == return ip to point of exception
  1280. [bp][10] == return cs to point of exception
  1281. [bp][12] == flags for iret
  1282. *)
  1283. push bp
  1284. mov bp,sp
  1285. sub sp,2
  1286. cmp word ss:[InMathLib], 0
  1287. je user_error
  1288. (* An exception has occurred in a math library function *)
  1289. jmp pop_8087
  1290. pop_8087_loop:
  1291. fstp st(0), st(0)
  1292. pop_8087:
  1293. fstsw [bp][-2]
  1294. fwait
  1295. and word [bp][-2], 3800H
  1296. cmp word [bp][-2], 0800H
  1297. jnz pop_8087_loop
  1298. (* The address of the handler table is in ss:[InMathLib] *)
  1299. push si
  1300. push ax
  1301. push bx
  1302. mov si,ss:[InMathLib]
  1303. mov word ss:[InMathLib], 0
  1304. mov ax, cs:[si] (* resume address *)
  1305. inc si
  1306. inc si
  1307. mov [bp][2],ax (* adjust local return address *)
  1308. mov bx,ss:[InMathLib][2] (* get the BP at the point of error *)
  1309. mov [bp],bx (* and make sure we restore to it *)
  1310. call __lib_error
  1311. pop bx
  1312. pop ax
  1313. pop si
  1314. mov sp,bp
  1315. pop bp
  1316. ret 10 (* return NEAR to resume point (we know it's in same code segment)
  1317. discard signal hadler cs, 8087 status word, and 6 byte iret info *)
  1318. user_error:
  1319. push ax
  1320. push ds
  1321. (*%T _WINDOWS *)
  1322. mov ax, ss
  1323. (*%E *)
  1324. (*%F _WINDOWS *)
  1325. mov ax, _DATA
  1326. (*%E *)
  1327. mov ds, ax
  1328. mov ax, [bp][6] (* status word *)
  1329. mov [__SH_sword], ax
  1330. mov ax, [bp][8] (* error offset *)
  1331. mov [__exc_addr], ax
  1332. mov ax, [bp][10] (* error segment *)
  1333. mov [__exc_addr][2], ax
  1334. pop ds
  1335. pop ax
  1336. mov sp, bp
  1337. pop bp
  1338. ret far 2 (* return FAR to signal handler, discarding status word *)
  1339. (*%E NOT StdFloat *)
  1340. (*************************************************************************)
  1341. (*%T StdFloat *)
  1342. section
  1343. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,48H)
  1344. extrn _matherr
  1345. extrn __seterrno
  1346. extrn @coremath_HUGE
  1347. extrn @coremath_MIN
  1348. (* __report_math_error is used for error reporting from math error functions.
  1349. It is called from __lib_error where the table mechanism for error recovery
  1350. is used, or may be called directly from a function detecting an error
  1351. condition.
  1352. On entry, st(0) == intended return value
  1353. st(1) == arg1
  1354. st(2) == arg2
  1355. cs:bx points to function name, terminated by linefeed character
  1356. ax == exception type.
  1357. On exit, st(0) == return value
  1358. If a user-defined matherr has been installed, it is called, otherwise
  1359. errno is set and we return to the caller.
  1360. struct exception { int type;
  1361. char *name;
  1362. double arg1;
  1363. double arg2;
  1364. double retval; }
  1365. *)
  1366. public __report_math_error:
  1367. push bp
  1368. mov bp,sp
  1369. push di
  1370. push si
  1371. push cx
  1372. (*%T SameDS *)
  1373. push ds
  1374. (*%E *)
  1375. mov cx,ax (* cx == exception type *)
  1376. (*%T _fcall *)
  1377. (*%F SameDS *)
  1378. mov ax, seg _matherr
  1379. mov ds, ax
  1380. (*%E *)
  1381. les ax, [_matherr]
  1382. mov si, es
  1383. or si, ax
  1384. (*%E *)
  1385. (*%F _fcall *)
  1386. cmp word [_matherr], 0
  1387. (*%E *)
  1388. je nomatherr
  1389. (* A user-defined error handler has been installed. Call it *)
  1390. (* First, copy the name into the stack segment *)
  1391. push cs
  1392. pop es
  1393. mov di,bx
  1394. sub al,al
  1395. push cx
  1396. mov cx,-1
  1397. repne; scasb
  1398. not cx
  1399. inc cx
  1400. and cx,-2
  1401. mov si,cx
  1402. pop cx
  1403. sub sp,si
  1404. mov si,sp (* si = ^name *)
  1405. mov di,si
  1406. lp: mov al,es:[bx]
  1407. mov ss:[di],al
  1408. inc bx
  1409. inc di
  1410. or al,al
  1411. jnz lp
  1412. (* Now create the structure on the stack *)
  1413. sub sp,34 (* space for 3 doubles, one tbyte *)
  1414. mov bx,sp
  1415. fld st(0),st(0)
  1416. fstp tbyte ss:[bx][24], st(0)
  1417. call forcedouble
  1418. fstp qword ss:[bx][16], st(0)
  1419. call forcedouble
  1420. fstp qword ss:[bx][0], st(0)
  1421. call forcedouble
  1422. fstp qword ss:[bx][8], st(0)
  1423. (*%T FarPtr *)
  1424. push ss
  1425. (*%E *)
  1426. push si (* ^name *)
  1427. push cx (* type *)
  1428. mov ax,sp (* pointer to exception structure *)
  1429. (*%F RegParam *) (*%T FarPtr *)
  1430. mov bx,ss (* segment part of the above *)
  1431. (*%E *) (*%E *)
  1432. push cx (* save exception type *)
  1433. (*%F RegParam *)
  1434. (*%T FarPtr *)
  1435. push ss
  1436. (*%E *)
  1437. push ax
  1438. (*%E *)
  1439. (*%T _fcall *)
  1440. call dword [_matherr]
  1441. (*%E *)
  1442. (*%F _fcall *)
  1443. call word [_matherr]
  1444. (*%E *)
  1445. (*%F RegParam *)
  1446. (*%T FarPtr *)
  1447. add sp,4
  1448. (*%E *)
  1449. (*%F FarPtr *)
  1450. add sp,2
  1451. (*%E*)
  1452. (*%E *)
  1453. pop cx (* recover the exception type *)
  1454. test ax,ax
  1455. mov bx,sp
  1456. jnz newretval (* matherr supplied a new retval *)
  1457. (* Reload the saved return value *)
  1458. (*%T FarPtr *)
  1459. fld tbyte st(0),ss:[bx][30]
  1460. (*%E *)
  1461. (*%F FarPtr *)
  1462. fld tbyte st(0),ss:[bx][28]
  1463. (*%E *)
  1464. jmp doerrno
  1465. newretval:
  1466. (*%T FarPtr *)
  1467. fld qword st(0),ss:[bx][22]
  1468. (*%E *)
  1469. (*%F FarPtr *)
  1470. fld qword st(0),ss:[bx][20]
  1471. (*%E *)
  1472. jmp done
  1473. nomatherr:
  1474. fstp st(1), st(0)
  1475. fstp st(1), st(0) (* discard arguments, keeping result *)
  1476. doerrno:
  1477. mov ax, EDOM
  1478. cmp cx,_DOMAIN (* type == _DOMAIN *)
  1479. je wasdomain
  1480. mov ax, ERANGE
  1481. wasdomain:
  1482. (*%T _fcall *)
  1483. call far __seterrno
  1484. (*%E *)
  1485. (*%F _fcall *)
  1486. call __seterrno
  1487. (*%E *)
  1488. done:
  1489. (*%F SameDS *)
  1490. lea sp,[bp][-8]
  1491. pop ds
  1492. (*%E *)
  1493. (*%T SameDS *)
  1494. lea sp,[bp][-6]
  1495. (*%E *)
  1496. pop cx
  1497. pop si
  1498. pop di
  1499. mov sp,bp
  1500. pop bp
  1501. ret 0
  1502. forcedouble:
  1503. (* force st(0) into the range that fits in a double *)
  1504. push ax
  1505. push bx
  1506. mov bx,sp
  1507. fcom qword st(0),cs:[@coremath_HUGE]
  1508. push ax
  1509. fstsw ss:[bx][-2]
  1510. fwait
  1511. pop ax
  1512. sahf
  1513. jb NotPosH
  1514. fstp st(0),st(0)
  1515. fld qword st(0),cs:[@coremath_HUGE]
  1516. jmp fddone
  1517. NotPosH:
  1518. fcom qword st(0),cs:[@coremath_MIN]
  1519. push ax
  1520. fstsw ss:[bx][-2]
  1521. fwait
  1522. pop ax
  1523. sahf
  1524. ja fddone
  1525. (* now st(0) must be < coremath_min *)
  1526. fchs st(0)
  1527. fcom qword st(0),cs:[@coremath_HUGE]
  1528. push ax
  1529. fstsw ss:[bx][-2]
  1530. fwait
  1531. pop ax
  1532. sahf
  1533. jb NotNegH
  1534. fstp st(0),st(0)
  1535. fld qword st(0),cs:[@coremath_HUGE]
  1536. fchs st(0)
  1537. jmp fddone
  1538. NotNegH:
  1539. fcom qword st(0),cs:[@coremath_MIN]
  1540. push ax
  1541. fstsw ss:[bx][-2]
  1542. fchs st(0)
  1543. pop ax
  1544. sahf
  1545. ja fddone
  1546. fstp st(0),st(0)
  1547. fldz st(0)
  1548. fddone:
  1549. pop bx
  1550. pop ax
  1551. ret 0
  1552. (*%E StdFloat *)
  1553. (*************************************************************************)
  1554. (*%T StdFloat *)
  1555. section
  1556. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1557. extrn __report_math_error
  1558. (* __lib_error is used by the math library functions to report range, domain
  1559. and underflow errors etcetera. It may be called via two routes:
  1560. 1. An exception occurring inside a math library function will cause
  1561. __math_excep to call this function. __math_excep reads the address
  1562. of a table from ss:InMathLib. This table contains a (short) resume
  1563. address and then a table in the format below. The address of the
  1564. table (excluding the resume address) is passed to __lib_error in si.
  1565. 2. math library functions pre-emptively detecting an error case without
  1566. causing an exception may call __lib_error directly. In this case,
  1567. si must point to a table as described below, and bx must contain
  1568. a pointer to the stack frame (i.e., a copy of bp).
  1569. The table processed by __lib_error is in the following format:
  1570. [si][0] short address of procedure to yield return value when
  1571. arg1 is negative
  1572. [si][2] ditto when arg1 is positive
  1573. [si][4] flags byte.
  1574. If [si][4] & f_two != 0, there is a second argument
  1575. If [si][4] & f_long != 0, the arguments are long double
  1576. [si][6] null terminated string containing name of function with error.
  1577. The procedures pointed to by [si][0] and [si][2] push the required return
  1578. value into st(0), and return the error type in ax.
  1579. *)
  1580. public __lib_error:
  1581. push bp
  1582. mov bp, sp
  1583. sub sp,2
  1584. push ax
  1585. push cx
  1586. push dx
  1587. test byte cs:[si][4], f_two (* find out arg count *)
  1588. jnz has_two
  1589. (* function has a single argument *)
  1590. fldz st(0) (* arg2 == 0 *)
  1591. test byte cs:[si][4], f_long (* long double args? *)
  1592. jnz long_arg1
  1593. fld qword st(0), ss:[bx][2][CodePtrSize]
  1594. jmp gotargs
  1595. long_arg1:
  1596. fld tbyte st(0), ss:[bx][2][CodePtrSize]
  1597. jmp gotargs
  1598. has_two:
  1599. test byte cs:[si][4], f_long (* long double args? *)
  1600. jnz long_arg2
  1601. (*%T RegParam *)
  1602. fld qword st(0), ss:[bx][2][CodePtrSize]
  1603. fld qword st(0), ss:[bx][2][CodePtrSize][8]
  1604. (*%E *)
  1605. (*%F RegParam *)
  1606. fld qword st(0), ss:[bx][2][CodePtrSize][8]
  1607. fld qword st(0), ss:[bx][2][CodePtrSize]
  1608. (*%E *)
  1609. jmp gotargs
  1610. long_arg2:
  1611. (*%T RegParam *)
  1612. fld tbyte st(0), ss:[bx][2][CodePtrSize]
  1613. fld tbyte st(0), ss:[bx][2][CodePtrSize][10]
  1614. (*%E *)
  1615. (*%F RegParam *)
  1616. fld tbyte st(0), ss:[bx][2][CodePtrSize][10]
  1617. fld tbyte st(0), ss:[bx][2][CodePtrSize]
  1618. (*%E *)
  1619. (* Now st(0)== arg1, st(1)==arg2 *)
  1620. gotargs:
  1621. ftst st(0)
  1622. fstsw [bp][-2]
  1623. fwait
  1624. test byte [bp][-1], 1 (* Check if arg1 was +ve *)
  1625. mov ax, cs:[si][2] (* negative entry from table *)
  1626. jz me_positive
  1627. mov ax, cs:[si][0] (* positive entry from table *)
  1628. me_positive:
  1629. call ax (* Call function to yield retval, pushed into st(0) *)
  1630. or ax, ax (* is it an error? *)
  1631. jz me_ok
  1632. lea bx, [si][5] (* st(0)==retval, st(1)==arg1, st(2)==arg2, bx=name *)
  1633. call __report_math_error
  1634. jmp exit
  1635. me_ok:
  1636. (* Not an error - discard st(1) and st(2) *)
  1637. fstp st(1), st(0)
  1638. fstp st(1), st(0)
  1639. exit:
  1640. pop dx
  1641. pop cx
  1642. pop ax
  1643. mov sp, bp
  1644. pop bp
  1645. ret 0
  1646. (*%E StdFloat *)
  1647. (*************************************************************************)
  1648. (*%T StdFloat *)
  1649. section
  1650. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1651. extrn @coremath_int_one
  1652. extrn $err_domain
  1653. public $check_abs_one:
  1654. fld st(0),st(0)
  1655. fabs st(0)
  1656. ficomp word st(0), cs:[@coremath_int_one]
  1657. fstsw [bp][-2]
  1658. fwait
  1659. test byte [bp][-1], 40H
  1660. jz ab1_err
  1661. ret 0
  1662. ab1_err:
  1663. add sp, 2
  1664. jmp near $err_domain
  1665. (*%E StdFloat *)
  1666. (*************************************************************************)
  1667. (*%T StdFloat *)
  1668. section
  1669. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1670. extrn __fac
  1671. extrn @coremath_HUGE
  1672. extrn @coremath_nearest
  1673. extrn __report_math_error
  1674. public _ldexp:
  1675. push bp
  1676. mov bp,sp
  1677. sub sp,10
  1678. fld qword st(0), [bp][frame]
  1679. (*%F RegParam *)
  1680. mov ax, [bp][frame][8]
  1681. fild word st(0), [bp][frame][8]
  1682. (*%E *)
  1683. (*%T RegParam *)
  1684. or ax,ax
  1685. jz ldexp_exit (* scale by 0 doesn't work in windows emulator *)
  1686. mov [bp][-2],ax
  1687. fild word st(0), [bp][-2]
  1688. (*%E *)
  1689. fstcw [bp][-2] (* save CW *)
  1690. fldcw cs:[@coremath_nearest] (* mask exceptions *)
  1691. fclex
  1692. fxch st(0), st(1)
  1693. fscale st(0), st(1)
  1694. fst qword [bp][-10], st(0) (* ensure result fits in double variable *)
  1695. fstsw [bp][-4]
  1696. fclex
  1697. fldcw [bp][-2]
  1698. test byte [bp][-4], 1FH
  1699. jnz ldexp_error
  1700. fstp st(1),st(0)
  1701. ldexp_exit:
  1702. (*%F NearPtr *)
  1703. mov dx, seg __fac
  1704. mov es, dx
  1705. fstp qword es:[__fac], st(0)
  1706. (*%E *)
  1707. (*%T NearPtr *)
  1708. fstp qword [__fac], st(0)
  1709. (*%E *)
  1710. mov ax, __fac
  1711. fwait
  1712. mov sp,bp
  1713. pop bp
  1714. (*%T RegParam *)
  1715. (*%T NearCall*)
  1716. ret near PopParam*8
  1717. (*%E*)
  1718. (*%F NearCall*)
  1719. ret far PopParam*8
  1720. (*%E*)
  1721. (*%E *)
  1722. (*%F RegParam *)
  1723. db Ret0@
  1724. (*%E*)
  1725. ldexp_error:
  1726. (* the scale has generated an exception of some sort *)
  1727. (* ax == st(0) == arg2, arg1 on stack *)
  1728. fld qword st(0), [bp][frame]
  1729. fstp st(1),st(0)
  1730. test ax,ax
  1731. js underflow
  1732. mov ax, _OVERFLOW
  1733. ftst st(0) (* check sign of arg1 *)
  1734. fstsw [bp][-2]
  1735. fld qword st(0), cs:[@coremath_HUGE]
  1736. test byte [bp][-1],1
  1737. jz report
  1738. fchs st(0)
  1739. jmp report
  1740. underflow:
  1741. fldz st(0)
  1742. mov ax, _UNDERFLOW
  1743. report:
  1744. (* st(0) == retval, st(1) == arg1, st(2) == arg2, ax == error type *)
  1745. mov bx, ldexp_name
  1746. call __report_math_error
  1747. jmp ldexp_exit
  1748. ldexp_name:
  1749. db "ldexp", 0
  1750. (*%E StdFloat *)
  1751. (*************************************************************************)
  1752. (*%T StdFloat *)
  1753. section
  1754. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1755. extrn __fac
  1756. extrn @coremath_LHUGE
  1757. extrn @coremath_nearest
  1758. extrn __report_math_error
  1759. public _ldexpl:
  1760. push bp
  1761. mov bp,sp
  1762. sub sp,4
  1763. fld tbyte st(0), [bp][frame]
  1764. (*%F RegParam *)
  1765. mov ax, [bp][frame][10]
  1766. fild word st(0), [bp][frame][10]
  1767. (*%E *)
  1768. (*%T RegParam *)
  1769. or ax,ax
  1770. jz ldexpl_exit (* scale by 0 doesn't work in windows emulator *)
  1771. mov [bp][-2],ax
  1772. fild word st(0), [bp][-2]
  1773. (*%E *)
  1774. fstcw [bp][-2] (* save CW in #1 *)
  1775. fldcw cs:[@coremath_nearest] (* mask exceptions *)
  1776. fclex
  1777. fxch st(0), st(1)
  1778. fscale st(0), st(1)
  1779. fstsw [bp][-4]
  1780. fclex
  1781. fldcw [bp][-2]
  1782. test byte [bp][-4], 1FH
  1783. jnz ldexpl_error
  1784. (*%T _WINDOWS *)
  1785. fxam st(0) (* Windows emulator doesn't signal oflow properly *)
  1786. fstsw [bp][-4]
  1787. fwait
  1788. test byte [bp][-3], 1
  1789. jnz ldexpl_error
  1790. (*%E *)
  1791. fstp st(1), st(0)
  1792. ldexpl_exit:
  1793. (*%F NearPtr *)
  1794. mov dx, seg __fac
  1795. mov es, dx
  1796. fstp tbyte es:[__fac], st(0)
  1797. (*%E *)
  1798. (*%T NearPtr *)
  1799. fstp tbyte [__fac], st(0)
  1800. (*%E *)
  1801. mov ax, __fac
  1802. fwait
  1803. mov sp,bp
  1804. pop bp
  1805. (*%T RegParam *)
  1806. (*%T NearCall*)
  1807. ret near PopParam*10
  1808. (*%E*)
  1809. (*%F NearCall*)
  1810. ret far PopParam*10
  1811. (*%E*)
  1812. (*%E *)
  1813. (*%F RegParam *)
  1814. db Ret0@
  1815. (*%E*)
  1816. ldexpl_error:
  1817. (* the scale has generated an exception of some sort *)
  1818. (* ax == st(0) == result of scale, st(1) == arg2, arg1 on stack *)
  1819. fld tbyte st(0), [bp][frame]
  1820. fstp st(1), st(0)
  1821. test ax,ax
  1822. js underflow
  1823. mov ax, _OVERFLOW
  1824. ftst st(0) (* check sign of arg1 *)
  1825. fstsw [bp][-2]
  1826. fld tbyte st(0), cs:[@coremath_LHUGE]
  1827. test byte [bp][-1],1
  1828. jz report
  1829. fchs st(0)
  1830. jmp report
  1831. underflow:
  1832. fldz st(0)
  1833. mov ax, _UNDERFLOW
  1834. report:
  1835. (* st(0) == retval, st(1) == arg1, st(2) == arg2, ax == error type *)
  1836. mov bx, ldexpl_name
  1837. call __report_math_error
  1838. jmp ldexpl_exit
  1839. ldexpl_name:
  1840. db "ldexpl", 0
  1841. (*%E StdFloat *)
  1842. (*************************************************************************)
  1843. (*%T StdFloat *)
  1844. section
  1845. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1846. extrn __fac
  1847. public _hypot:
  1848. push bp
  1849. mov bp, sp
  1850. (*%T StkParam *)
  1851. fld qword st(0), [bp][frame]
  1852. fmul st(0), st(0)
  1853. fld qword st(0), [bp][frame][8]
  1854. (*%E StkParam *)
  1855. (*%T RegParam *)
  1856. fld qword st(0), [bp][frame][8]
  1857. fmul st(0), st(0)
  1858. fld qword st(0), [bp][frame]
  1859. (*%E RegParam *)
  1860. fmul st(0), st(0)
  1861. faddp st(1), st(0)
  1862. fsqrt st(0)
  1863. (*%F NearPtr *)
  1864. mov dx, seg __fac
  1865. mov es, dx
  1866. fstp qword es:[__fac], st(0)
  1867. (*%E *)
  1868. (*%T NearPtr *)
  1869. fstp qword [__fac], st(0)
  1870. (*%E *)
  1871. mov ax, __fac
  1872. fwait
  1873. pop bp
  1874. (*%T NearCall*)
  1875. ret near PopParam*16
  1876. (*%E*)
  1877. (*%F NearCall*)
  1878. ret far PopParam*16
  1879. (*%E*)
  1880. (*%E StdFloat *)
  1881. (*************************************************************************)
  1882. (*%T StdFloat *)
  1883. section
  1884. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1885. extrn __fac
  1886. public _hypotl:
  1887. push bp
  1888. mov bp, sp
  1889. (*%T StkParam *)
  1890. fld tbyte st(0), [bp][frame]
  1891. fmul st(0), st(0)
  1892. fld tbyte st(0), [bp][frame][10]
  1893. (*%E StkParam *)
  1894. (*%T RegParam *)
  1895. fld tbyte st(0), [bp][frame][10]
  1896. fmul st(0), st(0)
  1897. fld tbyte st(0), [bp][frame]
  1898. (*%E RegParam *)
  1899. fmul st(0), st(0)
  1900. faddp st(1), st(0)
  1901. fsqrt st(0)
  1902. (*%F NearPtr *)
  1903. mov dx, seg __fac
  1904. mov es, dx
  1905. fstp tbyte es:[__fac], st(0)
  1906. (*%E *)
  1907. (*%T NearPtr *)
  1908. fstp tbyte [__fac], st(0)
  1909. (*%E *)
  1910. mov ax, __fac
  1911. fwait
  1912. pop bp
  1913. (*%T NearCall*)
  1914. ret near PopParam*20
  1915. (*%E*)
  1916. (*%F NearCall*)
  1917. ret far PopParam*20
  1918. (*%E*)
  1919. (*%E StdFloat *)
  1920. (*************************************************************************)
  1921. (*%T StdFloat *)
  1922. section
  1923. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1924. extrn __fac
  1925. public __round:
  1926. push bp
  1927. mov bp, sp
  1928. fld tbyte st(0), [bp][frame]
  1929. frndint st(0)
  1930. (*%F NearPtr *)
  1931. mov dx, seg __fac
  1932. mov es, dx
  1933. fstp tbyte es:[__fac], st(0)
  1934. (*%E *)
  1935. (*%T NearPtr *)
  1936. fstp tbyte [__fac], st(0)
  1937. (*%E *)
  1938. mov ax, __fac
  1939. fwait
  1940. pop bp
  1941. (*%F NearCall *)
  1942. ret far 0
  1943. (*%E *)
  1944. (*%T NearCall *)
  1945. ret 0
  1946. (*%E *)
  1947. (*%E StdFloat *)
  1948. (*************************************************************************)
  1949. (*%T StdFloat *)
  1950. section
  1951. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1952. (* compute 2^st(0) , result is represented as st(0) * 2^st(4) *)
  1953. extrn @coremath_int_four
  1954. public $pow2 :
  1955. fld1 st(0)
  1956. fxch st(0), st(1)
  1957. fst qword [bp][-12], st(0)
  1958. frndint st(0)
  1959. fsub st(0), st(1)
  1960. fld qword st(0), [bp][-12]
  1961. fxch st(0), st(1)
  1962. fstp qword [bp][-12], st(0)
  1963. fsub qword st(0), [bp][-12] (* we now know that st(0) is in range [0..2) *)
  1964. fidiv word st(0), cs:[@coremath_int_four] (* now in range [0..0.5] *)
  1965. f2xm1 st(0)
  1966. faddp st(1), st(0)
  1967. fmul st(0), st(0)
  1968. fmul st(0), st(0)
  1969. ret 0
  1970. (*%E StdFloat *)
  1971. (*************************************************************************)
  1972. (*%T StdFloat *)
  1973. section
  1974. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  1975. extrn @coremath_tbyte_Pi_By_4
  1976. public __do_sct :
  1977. fxam st(0) (* '87 works while we enter routine*)
  1978. fstsw [bp][-2]
  1979. fwait
  1980. mov ah, [bp][-1]
  1981. fabs st(0)
  1982. fldpi st(0)
  1983. fadd st(0),st(0) (* st(0) = 2*pi *)
  1984. mov ch, ah
  1985. and ch, 2
  1986. shr ch, 1 (* ch := sign *)
  1987. fxch st(0),st(1)
  1988. Lp: fprem st(0) (* reduce abs(arg1) by 2*pi *)
  1989. fstsw [bp][-2]
  1990. fwait
  1991. test byte [bp][-1],4
  1992. jnz Lp
  1993. (*%T _WINDOWS *)
  1994. fst st(1),st(0) (* st(0)=st(1)=abs(arg1) reduced by 2*pi *)
  1995. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_4]
  1996. fxch st(0),st(1) (* st(0)=st(2) = arg1. st(1) = pi/4 *)
  1997. fprem st(0) (* st(0)=abs(arg1) reduced by pi/4 *)
  1998. fsub st(2),st(0) (* st(2)= octant*pi/4 *)
  1999. fxch st(0),st(2) (* st(2)=abs(arg1) reduced by pi/4.st(0)=octant*pi/4 *)
  2000. fdiv st(0),st(1) (* st(0)=octant *)
  2001. fldlg2 st(0) (* st(0) = 0.3 --gives round to nearest *)
  2002. faddp st(1),st(0) (* st(0) = octant+a smidgeon *)
  2003. fistp word [bp][-2],st(0) (* store octant in [bp][-2] *)
  2004. fxch st(0),st(1) (* st(0)=abs(arg1) reduced by pi/4.st(1)=pi/4 *)
  2005. mov al,[bp][-2] (* al = octant *)
  2006. (*%E _WINDOWS *)
  2007. (*%F _WINDOWS *)
  2008. fstp st(1),st(0)
  2009. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_4]
  2010. fxch st(0),st(1)
  2011. fprem st(0)
  2012. fstsw [bp][-2]
  2013. fwait
  2014. mov ax, [bp][-2]
  2015. mov al, ah
  2016. and al, 3 (* select the C3, C1, and C0 status bits*)
  2017. shl ah, 1
  2018. shl ah, 1
  2019. rcl al, 1 (* arrange them in the ls 3 bits of AL as c1,c0,c3*)
  2020. add al, 0FCH
  2021. rcl al, 1 (* al now contains the octant number*)
  2022. (*%E NOT _WINDOWS *)
  2023. cmp cl, 2 (* are we doing Cosine ?*)
  2024. jne trig_notCosine
  2025. add al, cl (* Cos (x) = Sin (x + 2 octants)*)
  2026. mov ch, 0 (* Cosine has even symmetry around 0*)
  2027. trig_notCosine:
  2028. and al, 7
  2029. test al, 1
  2030. jz trig_evens
  2031. fsubp st(1), st(0) (* overwrites pi/4 in st(1), pops.*)
  2032. jmp trig_ptan
  2033. trig_evens:
  2034. fstp st(1), st(0)
  2035. trig_ptan:
  2036. fptan st(0) (* st(1) / st(0) == tan(x) *)
  2037. cmp cl, 4
  2038. je trig_tangent
  2039. test al, 3
  2040. jpe trig_sineOctant
  2041. trig_cosOctant:
  2042. fxch st(0), st(1)
  2043. trig_sineOctant:
  2044. fmul st(0), st(0)
  2045. fstp tbyte [bp][-12], st(0)
  2046. fld st(0), st(0)
  2047. fmul st(0), st(0)
  2048. fld tbyte st(0), [bp][-12]
  2049. faddp st(1), st(0)
  2050. fsqrt st(0)
  2051. shr al, 1
  2052. shr al, 1
  2053. xor al, ch
  2054. jz trig_sineDiv
  2055. fchs st(0)
  2056. trig_sineDiv:
  2057. fdivp st(1), st(0)
  2058. jmp trig_end
  2059. trig_tangent:
  2060. mov ah, al
  2061. shr ah, 1
  2062. and ah, 1
  2063. xor ah, ch
  2064. jz trig_tanSigned
  2065. fchs st(0)
  2066. trig_tanSigned:
  2067. test al, 3
  2068. jpe trig_ratio
  2069. fdivrp st(1),st(0)
  2070. jmp trig_end
  2071. trig_ratio:
  2072. fdivp st(1), st(0)
  2073. trig_end:
  2074. ret 0
  2075. (*%E StdFloat *)
  2076. (*************************************************************************)
  2077. (*%T StdFloat *)
  2078. section
  2079. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2080. extrn __fac
  2081. extrn __do_sct
  2082. public _sinl :
  2083. push bp
  2084. mov bp, sp
  2085. (*%T RegParam *) push cx (*%E RegParam *)
  2086. xor cl, cl
  2087. jmp trigl
  2088. public _cosl:
  2089. push bp
  2090. mov bp, sp
  2091. (*%T RegParam *) push cx (*%E RegParam *)
  2092. mov cl, 2
  2093. jmp trigl
  2094. public _tanl :
  2095. push bp
  2096. mov bp, sp
  2097. (*%T RegParam *) push cx (*%E RegParam *)
  2098. mov cl, 4
  2099. trigl:
  2100. (*%T RegParam *)(*%T NearPtr *) push dx (*%E NearPtr *)(*%E RegParam *)
  2101. sub sp, 12
  2102. mov dx, cx
  2103. fld tbyte st(0), [bp][frame]
  2104. call __do_sct
  2105. (*%F NearPtr *)
  2106. mov dx, seg __fac
  2107. mov es, dx
  2108. fstp tbyte es:[__fac], st(0)
  2109. (*%E *)
  2110. (*%T NearPtr *)
  2111. fstp tbyte [__fac], st(0)
  2112. (*%E *)
  2113. mov ax, __fac
  2114. add sp,12
  2115. (*%T RegParam *)(*%T NearPtr *) pop dx (*%E NearPtr *)(*%E RegParam *)
  2116. (*%T RegParam *) pop cx (*%E RegParam *)
  2117. fwait
  2118. pop bp
  2119. (*%T NearCall*)
  2120. ret near PopParam*10
  2121. (*%E*)
  2122. (*%F NearCall*)
  2123. ret far PopParam*10
  2124. (*%E*)
  2125. (*%E StdFloat *)
  2126. (*************************************************************************)
  2127. (*%T StdFloat *)
  2128. section
  2129. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2130. extrn __fac
  2131. extrn __do_sct
  2132. public _sin :
  2133. push bp
  2134. mov bp, sp
  2135. (*%T RegParam *) push cx (*%E RegParam *)
  2136. xor cl, cl
  2137. jmp trig
  2138. public _cos:
  2139. push bp
  2140. mov bp, sp
  2141. (*%T RegParam *) push cx (*%E RegParam *)
  2142. mov cl, 2
  2143. jmp trig
  2144. public _tan :
  2145. push bp
  2146. mov bp, sp
  2147. (*%T RegParam *) push cx (*%E RegParam *)
  2148. mov cl, 4
  2149. trig:
  2150. (*%T RegParam *)(*%T NearPtr *) push dx (*%E NearPtr *)(*%E RegParam *)
  2151. sub sp, 12
  2152. fld qword st(0), [bp][frame]
  2153. call __do_sct
  2154. (*%F NearPtr *)
  2155. mov dx, seg __fac
  2156. mov es, dx
  2157. fstp qword es:[__fac], st(0)
  2158. (*%E *)
  2159. (*%T NearPtr *)
  2160. fstp qword [__fac], st(0)
  2161. (*%E *)
  2162. mov ax, __fac
  2163. add sp,12
  2164. (*%T RegParam *)(*%T NearPtr *) pop dx (*%E NearPtr *)(*%E RegParam *)
  2165. (*%T RegParam *) pop cx (*%E RegParam *)
  2166. fwait
  2167. pop bp
  2168. (*%T NearCall*)
  2169. ret near PopParam*8
  2170. (*%E*)
  2171. (*%F NearCall*)
  2172. ret far PopParam*8
  2173. (*%E*)
  2174. (*%E StdFloat *)
  2175. (*************************************************************************)
  2176. (*%T StdFloat *)
  2177. section
  2178. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2179. extrn @coremath_tbyte_Pi_By_2
  2180. extrn __fac
  2181. extrn __lib_error
  2182. extrn $err_domain
  2183. public _atan2l:
  2184. push bp
  2185. mov bp, sp
  2186. sub sp, 4
  2187. (*%T StkParam *)
  2188. fld tbyte st(0), [bp][frame][10]
  2189. fld tbyte st(0), [bp][frame]
  2190. (*%E StkParam *)
  2191. (*%T RegParam *)
  2192. fld tbyte st(0), [bp][frame]
  2193. fld tbyte st(0), [bp][frame][10]
  2194. (*%E RegParam *)
  2195. ftst st(0)
  2196. fstsw [bp][-2]
  2197. fwait
  2198. test byte [bp][-1],1
  2199. je atan20
  2200. fchs st(0)
  2201. call atan21
  2202. fchs st(0)
  2203. jmp over
  2204. atan20:
  2205. call atan21
  2206. over:
  2207. (*%F NearPtr *)
  2208. mov dx, seg __fac
  2209. mov es, dx
  2210. fstp tbyte es:[__fac], st(0)
  2211. (*%E *)
  2212. (*%T NearPtr *)
  2213. fstp tbyte [__fac], st(0)
  2214. (*%E *)
  2215. mov ax, __fac
  2216. fwait
  2217. mov sp, bp
  2218. pop bp
  2219. (*%T NearCall*)
  2220. ret near PopParam*20
  2221. (*%E*)
  2222. (*%F NearCall*)
  2223. ret far PopParam*20
  2224. (*%E*)
  2225. atan21:
  2226. fxch st(0), st(1)
  2227. ftst st(0)
  2228. fstsw [bp][-4]
  2229. fwait
  2230. test byte [bp][-3],1
  2231. je atan22
  2232. fchs st(0)
  2233. call atan22
  2234. fldpi st(0)
  2235. fsubrp st(1),st(0)
  2236. ret 0
  2237. atan22:
  2238. test byte [bp][-3],40H
  2239. jnz maybe_zero_zero
  2240. not_zero_zero:
  2241. fcom st(0), st(1)
  2242. fstsw [bp][-2]
  2243. fwait
  2244. test byte [bp][-1],1
  2245. jz atan23
  2246. fxch st(0), st(1)
  2247. fpatan st(1), st(0)
  2248. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2]
  2249. fsubrp st(1),st(0)
  2250. ret 0
  2251. atan23:
  2252. fpatan st(1),st(0)
  2253. ret 0
  2254. maybe_zero_zero:
  2255. test byte [bp][-1],40H
  2256. jz not_zero_zero
  2257. fstp st(0), st(0)
  2258. push si
  2259. mov si, atan2_err_data
  2260. mov bx, bp
  2261. call __lib_error
  2262. pop si
  2263. ret 0
  2264. atan2_err_data: dw $err_domain, $err_domain; db f_two+f_long, "atan2l", 0
  2265. (*%E StdFloat *)
  2266. (*************************************************************************)
  2267. (*%T StdFloat *)
  2268. section
  2269. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2270. extrn @coremath_tbyte_Pi_By_2
  2271. extrn __fac
  2272. extrn __lib_error
  2273. extrn $err_domain
  2274. public _atan2:
  2275. push bp
  2276. mov bp, sp
  2277. sub sp, 4
  2278. (*%T StkParam *)
  2279. fld qword st(0), [bp][frame][8];
  2280. fld qword st(0), [bp][frame];
  2281. (*%E StkParam *)
  2282. (*%T RegParam *)
  2283. fld qword st(0), [bp][frame]
  2284. fld qword st(0), [bp][frame][8]
  2285. (*%E RegParam *)
  2286. ftst st(0)
  2287. fstsw [bp][-2]
  2288. fwait
  2289. test byte [bp][-1],1
  2290. je atan20
  2291. fchs st(0)
  2292. call atan21
  2293. fchs st(0)
  2294. jmp over
  2295. atan20:
  2296. call atan21
  2297. over:
  2298. (*%F NearPtr *)
  2299. mov dx, seg __fac
  2300. mov es, dx
  2301. fstp qword es:[__fac], st(0)
  2302. (*%E *)
  2303. (*%T NearPtr *)
  2304. fstp qword [__fac], st(0)
  2305. (*%E *)
  2306. mov ax, __fac
  2307. fwait
  2308. mov sp, bp
  2309. pop bp
  2310. (*%T NearCall*)
  2311. ret near PopParam*16
  2312. (*%E*)
  2313. (*%F NearCall*)
  2314. ret far PopParam*16
  2315. (*%E*)
  2316. atan21:
  2317. fxch st(0), st(1)
  2318. ftst st(0)
  2319. fstsw [bp][-4]
  2320. fwait
  2321. test byte [bp][-3],1
  2322. je atan22
  2323. fchs st(0)
  2324. call atan22
  2325. fldpi st(0)
  2326. fsubrp st(1),st(0)
  2327. ret 0
  2328. atan22:
  2329. test byte [bp][-3],40H
  2330. jnz maybe_zero_zero
  2331. not_zero_zero:
  2332. fcom st(0), st(1)
  2333. fstsw [bp][-2]
  2334. fwait
  2335. test byte [bp][-1],1
  2336. jz atan23
  2337. fxch st(0), st(1)
  2338. fpatan st(1), st(0)
  2339. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2]
  2340. fsubrp st(1),st(0)
  2341. ret 0
  2342. atan23:
  2343. fpatan st(1),st(0)
  2344. ret 0
  2345. maybe_zero_zero:
  2346. test byte [bp][-1],40H
  2347. jz not_zero_zero
  2348. fstp st(0), st(0)
  2349. push si
  2350. mov si, atan2_err_data
  2351. mov bx, bp
  2352. call __lib_error
  2353. pop si
  2354. ret 0
  2355. atan2_err_data: dw $err_domain, $err_domain; db f_two, "atan2", 0
  2356. (*%E StdFloat *)
  2357. (*************************************************************************)
  2358. (*%T StdFloat *)
  2359. section
  2360. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2361. extrn __fac
  2362. extrn $atan0
  2363. public _atanl:
  2364. push bp
  2365. mov bp, sp
  2366. sub sp, 2
  2367. fld tbyte st(0), [bp][frame];
  2368. call $atan0
  2369. (*%F NearPtr *)
  2370. mov dx, seg __fac
  2371. mov es, dx
  2372. fstp tbyte es:[__fac], st(0)
  2373. (*%E *)
  2374. (*%T NearPtr *)
  2375. fstp tbyte [__fac], st(0)
  2376. (*%E *)
  2377. mov ax, __fac
  2378. fwait
  2379. mov sp, bp
  2380. pop bp
  2381. (*%T NearCall*)
  2382. ret near PopParam*10
  2383. (*%E*)
  2384. (*%F NearCall*)
  2385. ret far PopParam*10
  2386. (*%E*)
  2387. (*%E StdFloat *)
  2388. (*************************************************************************)
  2389. (*%T StdFloat *)
  2390. section
  2391. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2392. extrn __fac
  2393. extrn $atan0
  2394. public _atan:
  2395. push bp
  2396. mov bp, sp
  2397. sub sp, 2
  2398. fld qword st(0), [bp][frame];
  2399. call $atan0
  2400. (*%F NearPtr *)
  2401. mov dx, seg __fac
  2402. mov es, dx
  2403. fstp qword es:[__fac], st(0)
  2404. (*%E *)
  2405. (*%T NearPtr *)
  2406. fstp qword [__fac], st(0)
  2407. (*%E *)
  2408. mov ax, __fac
  2409. fwait
  2410. mov sp, bp
  2411. pop bp
  2412. (*%T NearCall*)
  2413. ret near PopParam*8
  2414. (*%E*)
  2415. (*%F NearCall*)
  2416. ret far PopParam*8
  2417. (*%E*)
  2418. (*%E StdFloat *)
  2419. (*************************************************************************)
  2420. (*%T StdFloat *)
  2421. section
  2422. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2423. extrn @coremath_tbyte_Pi_By_2
  2424. public $atan0:
  2425. (* Note - this procedure must not have a stack frame *)
  2426. ftst st(0)
  2427. fstsw [bp][-2]
  2428. fwait
  2429. test byte [bp][-1],1
  2430. je atan1
  2431. fchs st(0)
  2432. call atan1
  2433. fchs st(0)
  2434. ret 0
  2435. atan1:
  2436. fld1 st(0)
  2437. fcom st(0), st(1)
  2438. fstsw [bp][-2]
  2439. fwait
  2440. test byte [bp][-1],1
  2441. jnz atan2
  2442. fpatan st(1), st(0)
  2443. ret 0
  2444. atan2:
  2445. fxch st(0), st(1)
  2446. fpatan st(1),st(0)
  2447. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2]
  2448. fsubrp st(1),st(0)
  2449. ret 0
  2450. (*%E StdFloat *)
  2451. (*************************************************************************)
  2452. (*%T StdFloat *)
  2453. section
  2454. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2455. extrn __lib_error
  2456. extrn $err_domain
  2457. extrn $err_huge_minus_infinity
  2458. extrn __fac
  2459. public _logl :
  2460. push bp
  2461. mov bp, sp
  2462. sub sp, 2
  2463. fld tbyte st(0), [bp][frame]
  2464. ftst st(0)
  2465. fstsw [bp][-2]
  2466. fwait
  2467. test byte [bp][-1], 41H
  2468. jnz logl_error
  2469. fldln2 st(0)
  2470. fxch st(0),st(1)
  2471. fyl2x st(1),st(0)
  2472. logl_exit:
  2473. (*%F NearPtr *)
  2474. mov dx, seg __fac
  2475. mov es, dx
  2476. fstp tbyte es:[__fac], st(0)
  2477. (*%E *)
  2478. (*%T NearPtr *)
  2479. fstp tbyte [__fac], st(0)
  2480. (*%E *)
  2481. mov ax, __fac
  2482. fwait
  2483. mov sp, bp
  2484. pop bp
  2485. (*%T NearCall*)
  2486. ret near PopParam*10
  2487. (*%E*)
  2488. (*%F NearCall*)
  2489. ret far PopParam*10
  2490. (*%E*)
  2491. logl_error:
  2492. fstp st(0), st(0) (* return fp stack to empty state *)
  2493. push si
  2494. mov si, logl_err_data
  2495. mov bx, bp
  2496. call __lib_error
  2497. pop si
  2498. jmp logl_exit
  2499. logl_err_data: dw $err_domain, $err_huge_minus_infinity; db f_long, "logl", 0
  2500. (*%E StdFloat *)
  2501. (*************************************************************************)
  2502. (*%T StdFloat *)
  2503. section
  2504. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2505. extrn __fac
  2506. extrn __lib_error
  2507. extrn $err_domain
  2508. extrn $err_minus_infinity
  2509. public _log :
  2510. push bp
  2511. mov bp, sp
  2512. sub sp, 2
  2513. fld qword st(0), [bp][frame]
  2514. ftst st(0)
  2515. fstsw [bp][-2]
  2516. fwait
  2517. test byte [bp][-1], 41H
  2518. jnz log_error
  2519. fldln2 st(0)
  2520. fxch st(0),st(1)
  2521. fyl2x st(1),st(0)
  2522. log_exit:
  2523. (*%F NearPtr *)
  2524. mov dx, seg __fac
  2525. mov es, dx
  2526. fstp qword es:[__fac], st(0)
  2527. (*%E *)
  2528. (*%T NearPtr *)
  2529. fstp qword [__fac], st(0)
  2530. (*%E *)
  2531. mov ax, __fac
  2532. fwait
  2533. mov sp, bp
  2534. pop bp
  2535. (*%T NearCall*)
  2536. ret near PopParam*8
  2537. (*%E*)
  2538. (*%F NearCall*)
  2539. ret far PopParam*8
  2540. (*%E*)
  2541. log_error:
  2542. fstp st(0), st(0) (* return fp stack to empty state *)
  2543. push si
  2544. mov si, log_err_data
  2545. mov bx, bp
  2546. call __lib_error
  2547. pop si
  2548. jmp log_exit
  2549. log_err_data: dw $err_domain, $err_minus_infinity; db 0, "log", 0
  2550. (*%E StdFloat *)
  2551. (*************************************************************************)
  2552. (*%T StdFloat *)
  2553. section
  2554. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2555. extrn __lib_error
  2556. extrn $err_domain
  2557. extrn $err_huge_minus_infinity
  2558. extrn __fac
  2559. public _log10l :
  2560. push bp
  2561. mov bp, sp
  2562. sub sp, 2
  2563. fld tbyte st(0), [bp][frame]
  2564. ftst st(0)
  2565. fstsw [bp][-2]
  2566. fwait
  2567. test byte [bp][-1], 41H
  2568. jnz log10l_error
  2569. fldlg2 st(0)
  2570. fxch st(0), st(1)
  2571. fyl2x st(1), st(0)
  2572. log10l_exit:
  2573. (*%F NearPtr *)
  2574. mov dx, seg __fac
  2575. mov es, dx
  2576. fstp tbyte es:[__fac], st(0)
  2577. (*%E *)
  2578. (*%T NearPtr *)
  2579. fstp tbyte [__fac], st(0)
  2580. (*%E *)
  2581. mov ax, __fac
  2582. fwait
  2583. mov sp, bp
  2584. pop bp
  2585. (*%T NearCall*)
  2586. ret near PopParam*10
  2587. (*%E*)
  2588. (*%F NearCall*)
  2589. ret far PopParam*10
  2590. (*%E*)
  2591. log10l_error:
  2592. fstp st(0), st(0) (* return fp stack to empty state *)
  2593. push si
  2594. mov si, log10l_err_data
  2595. mov bx, bp
  2596. call __lib_error
  2597. pop si
  2598. jmp log10l_exit
  2599. log10l_err_data: dw $err_domain, $err_huge_minus_infinity; db f_long, "log10l", 0
  2600. (*%E StdFloat *)
  2601. (*************************************************************************)
  2602. (*%T StdFloat *)
  2603. section
  2604. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2605. extrn __fac
  2606. extrn __lib_error
  2607. extrn $err_domain
  2608. extrn $err_minus_infinity
  2609. public _log10 :
  2610. push bp
  2611. mov bp, sp
  2612. sub sp, 2
  2613. fld qword st(0), [bp][frame]
  2614. ftst st(0)
  2615. fstsw [bp][-2]
  2616. fwait
  2617. test byte [bp][-1], 41H
  2618. jnz log10_error
  2619. fldlg2 st(0)
  2620. fxch st(0), st(1)
  2621. fyl2x st(1), st(0)
  2622. log10_exit:
  2623. (*%F NearPtr *)
  2624. mov dx, seg __fac
  2625. mov es, dx
  2626. fstp qword es:[__fac], st(0)
  2627. (*%E *)
  2628. (*%T NearPtr *)
  2629. fstp qword [__fac], st(0)
  2630. (*%E *)
  2631. mov ax, __fac
  2632. fwait
  2633. mov sp, bp
  2634. pop bp
  2635. (*%T NearCall*)
  2636. ret near PopParam*8
  2637. (*%E*)
  2638. (*%F NearCall*)
  2639. ret far PopParam*8
  2640. (*%E*)
  2641. log10_error:
  2642. fstp st(0), st(0) (* return fp stack to empty state *)
  2643. push si
  2644. mov si, log10_err_data
  2645. mov bx, bp
  2646. call __lib_error
  2647. pop si
  2648. jmp log10_exit
  2649. log10_err_data: dw $err_domain, $err_minus_infinity; db 0, "log10", 0
  2650. (*%E StdFloat *)
  2651. (*************************************************************************)
  2652. (*%T StdFloat *)
  2653. section
  2654. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2655. extrn __fac
  2656. extrn $err_domain
  2657. public _sqrtl :
  2658. push bp
  2659. mov bp, sp
  2660. mov word ss:[InMathLib], sqrtltable
  2661. mov word ss:[InMathLib][2], bp
  2662. fld tbyte st(0), [bp][frame]
  2663. (* Return the square root of x, which must be greater than zero. *)
  2664. fsqrt st(0) (*invalid op possible*)
  2665. fwait
  2666. sqrtl_exit:
  2667. mov word ss:[InMathLib], 0
  2668. (*%F NearPtr *)
  2669. mov dx, seg __fac
  2670. mov es, dx
  2671. fstp tbyte es:[__fac], st(0)
  2672. (*%E *)
  2673. (*%T NearPtr *)
  2674. fstp tbyte [__fac], st(0)
  2675. (*%E *)
  2676. mov ax, __fac
  2677. fwait
  2678. mov sp,bp
  2679. pop bp
  2680. (*%T NearCall*)
  2681. ret near PopParam*10
  2682. (*%E*)
  2683. (*%F NearCall*)
  2684. ret far PopParam*10
  2685. (*%E*)
  2686. sqrtltable:
  2687. dw sqrtl_exit, $err_domain, $err_domain; db f_long, "sqrtl", 0
  2688. (*%E StdFloat *)
  2689. (*************************************************************************)
  2690. (*%T StdFloat *)
  2691. section
  2692. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2693. extrn __fac
  2694. extrn $err_domain
  2695. public _sqrt :
  2696. push bp
  2697. mov bp, sp
  2698. mov word ss:[InMathLib], sqrttable
  2699. mov word ss:[InMathLib][2], bp
  2700. fld qword st(0), [bp][frame]
  2701. (* Return the square root of x, which must be greater than zero. *)
  2702. fsqrt st(0) (*invalid op possible*)
  2703. fwait
  2704. sqrt_exit:
  2705. mov word ss:[InMathLib], 0
  2706. (*%F NearPtr *)
  2707. mov dx, seg __fac
  2708. mov es, dx
  2709. fstp qword es:[__fac], st(0)
  2710. (*%E *)
  2711. (*%T NearPtr *)
  2712. fstp qword [__fac], st(0)
  2713. (*%E *)
  2714. mov ax, __fac
  2715. fwait
  2716. mov sp,bp
  2717. pop bp
  2718. (*%T NearCall*)
  2719. ret near PopParam*8
  2720. (*%E*)
  2721. (*%F NearCall*)
  2722. ret far PopParam*8
  2723. (*%E*)
  2724. sqrttable:
  2725. dw sqrt_exit, $err_domain, $err_domain; db 0, "sqrt", 0
  2726. (*%E StdFloat *)
  2727. (*************************************************************************)
  2728. (*%T StdFloat *)
  2729. section
  2730. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2731. extrn $pow2
  2732. extrn __fac
  2733. extrn $err_underflow
  2734. extrn $err_huge_plus_infinity
  2735. public _expl :
  2736. push bp
  2737. mov bp, sp
  2738. mov word ss:[InMathLib], expltable
  2739. mov word ss:[InMathLib][2], bp
  2740. sub sp, 12
  2741. fld tbyte st(0), [bp][frame]
  2742. (*%F SameDS *) (* for error processing *)
  2743. mov ax, seg __fac
  2744. mov es, ax
  2745. fst qword es:[__fac], st(0)
  2746. (*%E *)
  2747. (*%T SameDS *)
  2748. fst qword [__fac], st(0)
  2749. (*%E *)
  2750. fwait
  2751. fldl2e st(0)
  2752. fmulp st(1), st(0)
  2753. fist word [bp][-2], st(0) (* to check that it is not too large *)
  2754. fwait
  2755. call $pow2
  2756. fld qword st(0), [bp][-12] (* retrieve integral part *)
  2757. (*%T _WINDOWS *)
  2758. ftst st(0) (* work around windows emulator bug *)
  2759. fstsw [bp][-2]
  2760. (*%E *)
  2761. fxch st(1), st(0)
  2762. (*%T _WINDOWS *)
  2763. test byte [bp][-1], 40H
  2764. jnz skipscale
  2765. (*%E *)
  2766. fscale st(0), st(1)
  2767. skipscale:
  2768. fstp st(1),st(0)
  2769. expl_exit:
  2770. (*%F NearPtr *)
  2771. mov dx, seg __fac
  2772. mov es, dx
  2773. fstp tbyte es:[__fac], st(0)
  2774. (*%E *)
  2775. (*%T NearPtr *)
  2776. fstp tbyte [__fac], st(0)
  2777. (*%E *)
  2778. mov ax, __fac
  2779. fwait
  2780. mov sp, bp
  2781. pop bp
  2782. mov word ss:[InMathLib], 0
  2783. (*%T NearCall*)
  2784. ret near PopParam*10
  2785. (*%E*)
  2786. (*%F NearCall*)
  2787. ret far PopParam*10
  2788. (*%E*)
  2789. expltable:
  2790. dw expl_exit, $err_underflow, $err_huge_plus_infinity; db f_st5+f_long, "expl", 0
  2791. (*%E StdFloat *)
  2792. (*************************************************************************)
  2793. (*%T StdFloat *)
  2794. section
  2795. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2796. extrn __fac
  2797. extrn $pow2
  2798. extrn $err_underflow
  2799. extrn $err_plus_infinity
  2800. public _exp :
  2801. push bp
  2802. mov bp, sp
  2803. mov word ss:[InMathLib], exptable
  2804. mov word ss:[InMathLib][2], bp
  2805. sub sp, 12
  2806. fld qword st(0), [bp][frame]
  2807. (*%F SameDS *) (* for error processing *)
  2808. mov ax, seg __fac
  2809. mov es, ax
  2810. fst qword es:[__fac], st(0)
  2811. (*%E *)
  2812. (*%T SameDS *)
  2813. fst qword [__fac], st(0)
  2814. (*%E *)
  2815. fwait
  2816. fldl2e st(0)
  2817. fmulp st(1), st(0)
  2818. fist word [bp][-2], st(0) (* to check that it is not too large *)
  2819. fwait
  2820. call $pow2
  2821. fld qword st(0), [bp][-12] (* retrieve integral part *)
  2822. (*%T _WINDOWS *)
  2823. ftst st(0) (* work around windows emulator bug *)
  2824. fstsw [bp][-2]
  2825. (*%E *)
  2826. fxch st(1), st(0)
  2827. (*%T _WINDOWS *)
  2828. test byte [bp][-1], 40H
  2829. jnz skipscale
  2830. (*%E *)
  2831. fscale st(0), st(1)
  2832. skipscale:
  2833. fstp st(1),st(0)
  2834. exp_exit:
  2835. (*%F NearPtr *)
  2836. mov dx, seg __fac
  2837. mov es, dx
  2838. fstp qword es:[__fac], st(0)
  2839. (*%E *)
  2840. (*%T NearPtr *)
  2841. fstp qword [__fac], st(0)
  2842. (*%E *)
  2843. mov ax, __fac
  2844. fwait
  2845. mov sp, bp
  2846. pop bp
  2847. mov word ss:[InMathLib], 0
  2848. (*%T NearCall*)
  2849. ret near PopParam*8
  2850. (*%E*)
  2851. (*%F NearCall*)
  2852. ret far PopParam*8
  2853. (*%E*)
  2854. exptable:
  2855. dw exp_exit, $err_underflow, $err_plus_infinity; db f_st5, "exp", 0
  2856. (*%E StdFloat *)
  2857. (****************************************************************************)
  2858. (*%T StdFloat *)
  2859. section
  2860. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2861. extrn $pow2
  2862. extrn __fac
  2863. public _tanhl :
  2864. push bp
  2865. mov bp, sp
  2866. mov word ss:[InMathLib], tanhltable
  2867. mov word ss:[InMathLib][2], bp
  2868. sub sp, 12
  2869. fld tbyte st(0), [bp][frame]
  2870. (*%F SameDS *) (* for error processing *)
  2871. mov ax, seg __fac
  2872. mov es, ax
  2873. fst qword es:[__fac], st(0)
  2874. (*%E *)
  2875. (*%T SameDS *)
  2876. fst qword [__fac], st(0)
  2877. (*%E *)
  2878. fwait
  2879. fldl2e st(0)
  2880. fmulp st(1), st(0)
  2881. fist word [bp][-2], st(0) (* to check that it is not too large *)
  2882. fwait
  2883. call $pow2
  2884. fld qword st(0), [bp][-12] (* retrieve integral part *)
  2885. (*%T _WINDOWS *)
  2886. ftst st(0) (* work around windows emulator bug *)
  2887. fstsw [bp][-2]
  2888. (*%E *)
  2889. fxch st(1), st(0)
  2890. (*%T _WINDOWS *)
  2891. test byte [bp][-1], 40H
  2892. jnz skipscale
  2893. (*%E *)
  2894. fscale st(0), st(1)
  2895. skipscale:
  2896. fstp st(1), st(0)
  2897. fld1 st(0)
  2898. fdiv st(0), st(1) (* Exp (-x) *)
  2899. fst qword [bp][-12], st(0)
  2900. fadd st(0), st(1)
  2901. fxch st(0), st(1)
  2902. fsub qword st(0), [bp][-12]
  2903. fdivrp st(1), st(0)
  2904. tanhl_exit:
  2905. (*%F NearPtr *) (* for error processing *)
  2906. mov dx, seg __fac
  2907. mov es, dx
  2908. fstp tbyte es:[__fac], st(0)
  2909. (*%E *)
  2910. (*%T NearPtr *)
  2911. fstp tbyte [__fac], st(0)
  2912. (*%E *)
  2913. mov ax, __fac
  2914. fwait
  2915. mov sp, bp
  2916. pop bp
  2917. mov word ss:[InMathLib], 0
  2918. (*%T NearCall*)
  2919. ret near PopParam*10
  2920. (*%E*)
  2921. (*%F NearCall*)
  2922. ret far PopParam*10
  2923. (*%E*)
  2924. tanhltable:
  2925. dw tanhl_exit,tanhl_minus_one,tanhl_one ; db f_st5+f_long, "tanhl", 0
  2926. tanhl_one:
  2927. sub ax, ax
  2928. fld1 st(0)
  2929. ret 0
  2930. tanhl_minus_one:
  2931. call tanhl_one
  2932. fchs st(0)
  2933. ret 0
  2934. (*%E StdFloat *)
  2935. (*************************************************************************)
  2936. (*%T StdFloat *)
  2937. section
  2938. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  2939. extrn $pow2
  2940. extrn __fac
  2941. public _tanh :
  2942. push bp
  2943. mov bp, sp
  2944. mov word ss:[InMathLib], tanhtable
  2945. mov word ss:[InMathLib][2], bp
  2946. sub sp, 12
  2947. fld qword st(0), [bp][frame]
  2948. (*%F SameDS *) (* for error processing *)
  2949. mov ax, seg __fac
  2950. mov es, ax
  2951. fst qword es:[__fac], st(0)
  2952. (*%E *)
  2953. (*%T SameDS *)
  2954. fst qword [__fac], st(0)
  2955. (*%E *)
  2956. fwait
  2957. fldl2e st(0)
  2958. fmulp st(1), st(0)
  2959. fist word [bp][-2], st(0) (* to check that it is not too large *)
  2960. fwait
  2961. call $pow2
  2962. fld qword st(0), [bp][-12] (* retrieve integral part *)
  2963. (*%T _WINDOWS *)
  2964. ftst st(0) (* work around windows emulator bug *)
  2965. fstsw [bp][-2]
  2966. (*%E *)
  2967. fxch st(1), st(0)
  2968. (*%T _WINDOWS *)
  2969. test byte [bp][-1], 40H
  2970. jnz skipscale
  2971. (*%E *)
  2972. fscale st(0), st(1)
  2973. skipscale:
  2974. fstp st(1), st(0)
  2975. fld1 st(0)
  2976. fdiv st(0), st(1) (* Exp (-x) *)
  2977. fst qword [bp][-12], st(0)
  2978. fadd st(0), st(1)
  2979. fxch st(0), st(1)
  2980. fsub qword st(0), [bp][-12]
  2981. fdivrp st(1), st(0)
  2982. tanh_exit:
  2983. (*%F NearPtr *) (* for error processing *)
  2984. mov dx, seg __fac
  2985. mov es, dx
  2986. fstp qword es:[__fac], st(0)
  2987. (*%E *)
  2988. (*%T NearPtr *)
  2989. fstp qword [__fac], st(0)
  2990. (*%E *)
  2991. mov ax, __fac
  2992. fwait
  2993. mov sp, bp
  2994. pop bp
  2995. mov word ss:[InMathLib], 0
  2996. (*%T NearCall*)
  2997. ret near PopParam*8
  2998. (*%E*)
  2999. (*%F NearCall*)
  3000. ret far PopParam*8
  3001. (*%E*)
  3002. tanhtable:
  3003. dw tanh_exit,tanh_minus_one,tanh_one; db f_st5, "tanh", 0
  3004. tanh_one:
  3005. sub ax, ax
  3006. fld1 st(0)
  3007. ret 0
  3008. tanh_minus_one:
  3009. call tanh_one
  3010. fchs st(0)
  3011. ret 0
  3012. (*%E StdFloat *)
  3013. (*************************************************************************)
  3014. (*%T StdFloat *)
  3015. section
  3016. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3017. extrn $pow2
  3018. extrn $err_huge_plus_infinity
  3019. extrn $err_huge_minus_infinity
  3020. extrn __fac
  3021. extrn @coremath_int_two
  3022. public _sinhl :
  3023. push bp
  3024. mov bp, sp
  3025. mov word ss:[InMathLib], sinhltable
  3026. mov word ss:[InMathLib][2], bp
  3027. sub sp, 12
  3028. fld tbyte st(0), [bp][frame]
  3029. (*%F SameDS *) (* for error processing *)
  3030. mov ax, seg __fac
  3031. mov es, ax
  3032. fst qword es:[__fac], st(0)
  3033. (*%E *)
  3034. (*%T SameDS *)
  3035. fst qword [__fac], st(0)
  3036. (*%E *)
  3037. fwait
  3038. fldl2e st(0)
  3039. fmulp st(1), st(0)
  3040. fist word [bp][-2], st(0) (* to check that it is not too large *)
  3041. fwait
  3042. call $pow2
  3043. fld qword st(0), [bp][-12] (* retrieve integral part *)
  3044. (*%T _WINDOWS *)
  3045. ftst st(0) (* work around windows emulator bug *)
  3046. fstsw [bp][-2]
  3047. (*%E *)
  3048. fxch st(1), st(0)
  3049. (*%T _WINDOWS *)
  3050. test byte [bp][-1], 40H
  3051. jnz skipscale
  3052. (*%E *)
  3053. fscale st(0), st(1)
  3054. skipscale:
  3055. fstp st(1), st(0)
  3056. fld1 st(0)
  3057. fchs st(0)
  3058. fdiv st(0), st(1) (* - Exp (-x) *)
  3059. faddp st(1), st(0)
  3060. fidiv word st(0), cs:[@coremath_int_two ]
  3061. sinhl_exit:
  3062. (*%F NearPtr *)
  3063. mov dx, seg __fac
  3064. mov es, dx
  3065. fstp tbyte es:[__fac], st(0)
  3066. (*%E *)
  3067. (*%T NearPtr *)
  3068. fstp tbyte [__fac], st(0)
  3069. (*%E *)
  3070. mov ax, __fac
  3071. fwait
  3072. mov sp, bp
  3073. pop bp
  3074. mov word ss:[InMathLib], 0
  3075. (*%T NearCall*)
  3076. ret near PopParam*10
  3077. (*%E*)
  3078. (*%F NearCall*)
  3079. ret far PopParam*10
  3080. (*%E*)
  3081. sinhltable:
  3082. dw sinhl_exit, $err_huge_minus_infinity, $err_huge_plus_infinity; db f_st5+f_long, "sinhl", 0
  3083. (*%E StdFloat *)
  3084. (*************************************************************************)
  3085. (*%T StdFloat *)
  3086. section
  3087. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3088. extrn $pow2
  3089. extrn $err_plus_infinity
  3090. extrn $err_minus_infinity
  3091. extrn __fac
  3092. extrn @coremath_int_two
  3093. public _sinh :
  3094. push bp
  3095. mov bp, sp
  3096. mov word ss:[InMathLib], sinhtable
  3097. mov word ss:[InMathLib][2], bp
  3098. sub sp, 12
  3099. fld qword st(0), [bp][frame]
  3100. (*%F SameDS *) (* for error processing *)
  3101. mov ax, seg __fac
  3102. mov es, ax
  3103. fst qword es:[__fac], st(0)
  3104. (*%E *)
  3105. (*%T SameDS *)
  3106. fst qword [__fac], st(0)
  3107. (*%E *)
  3108. fwait
  3109. fldl2e st(0)
  3110. fmulp st(1), st(0)
  3111. fist word [bp][-2], st(0) (* to check that it is not too large *)
  3112. fwait
  3113. call $pow2
  3114. fld qword st(0), [bp][-12] (* retrieve integral part *)
  3115. (*%T _WINDOWS *)
  3116. ftst st(0) (* work around windows emulator bug *)
  3117. fstsw [bp][-2]
  3118. (*%E *)
  3119. fxch st(1), st(0)
  3120. (*%T _WINDOWS *)
  3121. test byte [bp][-1], 40H
  3122. jnz skipscale
  3123. (*%E *)
  3124. fscale st(0), st(1)
  3125. skipscale:
  3126. fstp st(1), st(0)
  3127. fld1 st(0)
  3128. fchs st(0)
  3129. fdiv st(0), st(1) (* - Exp (-x) *)
  3130. faddp st(1), st(0)
  3131. fidiv word st(0), cs:[@coremath_int_two ]
  3132. sinh_exit:
  3133. (*%F NearPtr *)
  3134. mov dx, seg __fac
  3135. mov es, dx
  3136. fstp qword es:[__fac], st(0)
  3137. (*%E *)
  3138. (*%T NearPtr *)
  3139. fstp qword [__fac], st(0)
  3140. (*%E *)
  3141. mov ax, __fac
  3142. fwait
  3143. mov sp, bp
  3144. pop bp
  3145. mov word ss:[InMathLib], 0
  3146. (*%T NearCall*)
  3147. ret near PopParam*8
  3148. (*%E*)
  3149. (*%F NearCall*)
  3150. ret far PopParam*8
  3151. (*%E*)
  3152. sinhtable:
  3153. dw sinh_exit, $err_minus_infinity, $err_plus_infinity; db f_st5, "sinh", 0
  3154. (*%E StdFloat *)
  3155. (*************************************************************************)
  3156. (*%T StdFloat *)
  3157. section
  3158. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3159. extrn $err_huge_plus_infinity
  3160. extrn __fac
  3161. extrn @coremath_int_two
  3162. extrn $pow2
  3163. public _coshl :
  3164. push bp
  3165. mov bp, sp
  3166. mov word ss:[InMathLib], coshltable
  3167. mov word ss:[InMathLib][2], bp
  3168. sub sp, 12
  3169. fld tbyte st(0), [bp][frame];
  3170. (*%F SameDS *) (* for error processing *)
  3171. mov ax, seg __fac
  3172. mov es, ax
  3173. fst qword es:[__fac], st(0)
  3174. (*%E *)
  3175. (*%T SameDS *)
  3176. fst qword [__fac], st(0)
  3177. (*%E *)
  3178. fwait
  3179. fabs st(0)
  3180. fldl2e st(0)
  3181. fmulp st(1), st(0)
  3182. fist word [bp][-2], st(0) (* to check that it is not too large *)
  3183. fwait
  3184. call $pow2
  3185. fld qword st(0), [bp][-12] (* retrieve integral part *)
  3186. (*%T _WINDOWS *)
  3187. ftst st(0) (* work around windows emulator bug *)
  3188. fstsw [bp][-2]
  3189. (*%E *)
  3190. fxch st(1), st(0)
  3191. (*%T _WINDOWS *)
  3192. test byte [bp][-1], 40H
  3193. jnz skipscale
  3194. (*%E *)
  3195. fscale st(0), st(1)
  3196. skipscale:
  3197. fstp st(1), st(0)
  3198. fld1 st(0)
  3199. fdiv st(0), st(1) (* Exp (-x) *)
  3200. faddp st(1), st(0)
  3201. fidiv word st(0), cs:[@coremath_int_two ]
  3202. coshl_exit:
  3203. (*%F NearPtr *)
  3204. mov dx, seg __fac
  3205. mov es, dx
  3206. fstp tbyte es:[__fac], st(0)
  3207. (*%E *)
  3208. (*%T NearPtr *)
  3209. fstp tbyte [__fac], st(0)
  3210. (*%E *)
  3211. mov ax, __fac
  3212. fwait
  3213. mov sp, bp
  3214. pop bp
  3215. mov word ss:[InMathLib], 0
  3216. (*%T NearCall*)
  3217. ret near PopParam*10
  3218. (*%E*)
  3219. (*%F NearCall*)
  3220. ret far PopParam*10
  3221. (*%E*)
  3222. coshltable:
  3223. dw coshl_exit, $err_huge_plus_infinity, $err_huge_plus_infinity; db f_st5+f_long, "coshl", 0
  3224. (*%E StdFloat *)
  3225. (*************************************************************************)
  3226. (*%T StdFloat *)
  3227. section
  3228. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3229. extrn $err_plus_infinity
  3230. extrn __fac
  3231. extrn @coremath_int_two
  3232. extrn $pow2
  3233. public _cosh :
  3234. push bp
  3235. mov bp, sp
  3236. mov word ss:[InMathLib], coshtable
  3237. mov word ss:[InMathLib][2], bp
  3238. sub sp, 12
  3239. fld qword st(0), [bp][frame];
  3240. (*%F SameDS *) (* for error processing *)
  3241. mov ax, seg __fac
  3242. mov es, ax
  3243. fst qword es:[__fac], st(0)
  3244. (*%E *)
  3245. (*%T SameDS *)
  3246. fst qword [__fac], st(0)
  3247. (*%E *)
  3248. fwait
  3249. fabs st(0)
  3250. fldl2e st(0)
  3251. fmulp st(1), st(0)
  3252. fist word [bp][-2], st(0) (* to check that it is not too large *)
  3253. fwait
  3254. call $pow2
  3255. fld qword st(0), [bp][-12] (* retrieve integral part *)
  3256. (*%T _WINDOWS *)
  3257. ftst st(0) (* work around windows emulator bug *)
  3258. fstsw [bp][-2]
  3259. (*%E *)
  3260. fxch st(1), st(0)
  3261. (*%T _WINDOWS *)
  3262. test byte [bp][-1], 40H
  3263. jnz skipscale
  3264. (*%E *)
  3265. fscale st(0), st(1)
  3266. skipscale:
  3267. fstp st(1), st(0)
  3268. fld1 st(0)
  3269. fdiv st(0), st(1) (* Exp (-x) *)
  3270. faddp st(1), st(0)
  3271. fidiv word st(0), cs:[@coremath_int_two ]
  3272. cosh_exit:
  3273. (*%F NearPtr *)
  3274. mov dx, seg __fac
  3275. mov es, dx
  3276. fstp qword es:[__fac], st(0)
  3277. (*%E *)
  3278. (*%T NearPtr *)
  3279. fstp qword [__fac], st(0)
  3280. (*%E *)
  3281. mov ax, __fac
  3282. fwait
  3283. mov sp, bp
  3284. pop bp
  3285. mov word ss:[InMathLib], 0
  3286. (*%T NearCall*)
  3287. ret near PopParam*8
  3288. (*%E*)
  3289. (*%F NearCall*)
  3290. ret far PopParam*8
  3291. (*%E*)
  3292. coshtable:
  3293. dw cosh_exit, $err_plus_infinity, $err_plus_infinity; db f_st5, "cosh", 0
  3294. (*%E StdFloat *)
  3295. (*************************************************************************)
  3296. (*%T StdFloat *)
  3297. section
  3298. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3299. extrn $check_abs_one
  3300. extrn __fac
  3301. extrn $atan0
  3302. extrn @coremath_tbyte_Pi_By_2
  3303. public _asinl:
  3304. push bp
  3305. mov bp, sp
  3306. mov word ss:[InMathLib], asinltable
  3307. mov word ss:[InMathLib][2], bp
  3308. sub sp, 12
  3309. fld tbyte st(0), [bp][frame]
  3310. (*%F SameDS *)
  3311. mov dx, seg __fac
  3312. mov es, dx
  3313. fst qword es:[__fac], st(0)
  3314. (*%E *)
  3315. (*%T SameDS *)
  3316. fst qword [__fac], st(0)
  3317. (*%E *)
  3318. fst qword [bp][-12], st(0)
  3319. fmul st(0), st(0) (* arg1**2 *)
  3320. fld1 st(0)
  3321. fsubrp st(1),st(0) (* arg1**2-1 *)
  3322. ftst st(0)
  3323. fstsw [bp][-2]
  3324. fsqrt st(0) (* sqrt (arg1**2-1) *)
  3325. test byte [bp][-1],40H (* is result 0 *)
  3326. jz Not0 (* no *)
  3327. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2] (* $2 *)
  3328. fstp st(1),st(0) (* $1 *)
  3329. test byte [bp][frame][9],80H (* was arg1 neg ? *)
  3330. jz asinl_exit (* arg1 was positive. return pi/2 *)
  3331. fchs st(0)
  3332. jmp asinl_exit (* arg1 was negative. return -pi/2 *)
  3333. Not0:
  3334. fdivr qword st(0), [bp][-12]
  3335. fwait
  3336. call $atan0
  3337. asinl_exit:
  3338. (*%F NearPtr *)
  3339. mov dx, seg __fac
  3340. mov es, dx
  3341. fstp tbyte es:[__fac], st(0)
  3342. (*%E *)
  3343. (*%T NearPtr *)
  3344. fstp tbyte [__fac], st(0)
  3345. (*%E *)
  3346. mov ax, __fac
  3347. fwait
  3348. mov sp, bp
  3349. pop bp
  3350. mov word ss:[InMathLib], 0
  3351. (*%T NearCall*)
  3352. ret near PopParam*10
  3353. (*%E*)
  3354. (*%F NearCall*)
  3355. ret far PopParam*10
  3356. (*%E*)
  3357. asinltable:
  3358. dw asinl_exit, err_asinl_neg, err_asinl_pos; db f_st5+f_long, "asinl", 0
  3359. err_asinl_pos:
  3360. call $check_abs_one
  3361. fld1 st(0)
  3362. fstp st(1), st(0)
  3363. fchs st(0)
  3364. fldpi st(0)
  3365. fscale st(0),st(1)
  3366. sub ax, ax
  3367. ret 0
  3368. err_asinl_neg:
  3369. call err_asinl_pos
  3370. fchs st(0)
  3371. ret 0
  3372. (*%E StdFloat *)
  3373. (*************************************************************************)
  3374. (*%T StdFloat *)
  3375. section
  3376. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3377. extrn $check_abs_one
  3378. extrn __fac
  3379. extrn $atan0
  3380. extrn @coremath_tbyte_Pi_By_2
  3381. public _asin:
  3382. push bp
  3383. mov bp, sp
  3384. mov word ss:[InMathLib], asintable
  3385. mov word ss:[InMathLib][2], bp
  3386. sub sp, 12
  3387. fld qword st(0),[bp][frame]
  3388. (*%F SameDS *)
  3389. mov dx, seg __fac
  3390. mov es, dx
  3391. fst qword es:[__fac], st(0)
  3392. (*%E *)
  3393. (*%T SameDS *)
  3394. fst qword [__fac], st(0)
  3395. (*%E *)
  3396. fst qword [bp][-12], st(0)
  3397. fmul st(0), st(0) (* arg1**2 *)
  3398. fld1 st(0)
  3399. fsubrp st(1),st(0) (* arg1**2-1 *)
  3400. ftst st(0)
  3401. fstsw [bp][-2]
  3402. fsqrt st(0) (* sqrt (arg1**2-1) *)
  3403. test byte [bp][-1],40H (* is result 0 *)
  3404. jz Not0 (* no *)
  3405. fld tbyte st(0),cs:[@coremath_tbyte_Pi_By_2] (* $2 *)
  3406. fstp st(1),st(0) (* $1 *)
  3407. test byte [bp][frame][7],80H (* was arg1 neg ? *)
  3408. jz asin_exit (* arg1 was positive. return pi/2 *)
  3409. fchs st(0)
  3410. jmp asin_exit (* arg1 was negative. return -pi/2 *)
  3411. Not0:
  3412. fdivr qword st(0), [bp][-12]
  3413. fwait
  3414. call $atan0
  3415. asin_exit:
  3416. (*%F NearPtr *)
  3417. mov dx, seg __fac
  3418. mov es, dx
  3419. fstp qword es:[__fac], st(0)
  3420. (*%E *)
  3421. (*%T NearPtr *)
  3422. fstp qword [__fac], st(0)
  3423. (*%E *)
  3424. mov ax, __fac
  3425. fwait
  3426. mov sp, bp
  3427. pop bp
  3428. mov word ss:[InMathLib], 0
  3429. (*%T NearCall*)
  3430. ret near PopParam*8
  3431. (*%E*)
  3432. (*%F NearCall*)
  3433. ret far PopParam*8
  3434. (*%E*)
  3435. asintable:
  3436. dw asin_exit, err_asin_neg, err_asin_pos; db f_st5, "asin", 0
  3437. err_asin_pos:
  3438. call $check_abs_one
  3439. fld1 st(0)
  3440. fstp st(1), st(0)
  3441. fchs st(0)
  3442. fldpi st(0)
  3443. fscale st(0),st(1)
  3444. sub ax, ax
  3445. ret 0
  3446. err_asin_neg:
  3447. call err_asin_pos
  3448. fchs st(0)
  3449. ret 0
  3450. (*%E StdFloat *)
  3451. (*************************************************************************)
  3452. (*%T StdFloat *)
  3453. section
  3454. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3455. extrn __fac
  3456. extrn @coremath_tbyte_Pi_By_2
  3457. extrn $check_abs_one
  3458. extrn $atan0
  3459. public _acosl :
  3460. push bp
  3461. mov bp, sp
  3462. mov word ss:[InMathLib], acosltable
  3463. mov word ss:[InMathLib][2], bp
  3464. sub sp, 12
  3465. fld tbyte st(0), [bp][frame]
  3466. (*%F SameDS *) (* for error processing *)
  3467. mov ax, seg __fac
  3468. mov es, ax
  3469. fst qword es:[__fac], st(0)
  3470. (*%E *)
  3471. (*%T SameDS *)
  3472. fst qword [__fac], st(0)
  3473. (*%E *)
  3474. ftst st(0) (* is st(0) 0 or -0 ? *)
  3475. fstsw [bp][-2]
  3476. fst qword [bp][-12], st(0)
  3477. test byte [bp][-1],40H (* test for zero flag *)
  3478. jnz DoPiBy2 (* if arg1 was 0,return pi/2 *)
  3479. fmul st(0), st(0)
  3480. fld1 st(0)
  3481. fsubrp st(1),st(0)
  3482. fsqrt st(0)
  3483. fdivr qword st(0), [bp][-12]
  3484. fwait
  3485. call $atan0
  3486. DoPiBy2:
  3487. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_2]
  3488. fsubrp st(1), st(0)
  3489. acosl_exit:
  3490. (*%F NearPtr *)
  3491. mov dx, seg __fac
  3492. mov es, dx
  3493. fstp tbyte es:[__fac], st(0)
  3494. (*%E *)
  3495. (*%T NearPtr *)
  3496. fstp tbyte [__fac], st(0)
  3497. (*%E *)
  3498. mov ax, __fac
  3499. mov sp, bp
  3500. pop bp
  3501. mov word ss:[InMathLib], 0
  3502. (*%T NearCall*)
  3503. ret near PopParam*10
  3504. (*%E*)
  3505. (*%F NearCall*)
  3506. ret far PopParam*10
  3507. (*%E*)
  3508. acosltable:
  3509. dw acosl_exit, err_acosl_neg, err_acosl_pos; db f_long+f_st5, "acosl", 0
  3510. err_acosl_pos:
  3511. call $check_abs_one
  3512. fldz st(0)
  3513. sub ax, ax
  3514. ret 0
  3515. err_acosl_neg:
  3516. call $check_abs_one
  3517. fldpi st(0)
  3518. sub ax, ax
  3519. ret 0
  3520. (*%E StdFloat *)
  3521. (*************************************************************************)
  3522. (*%T StdFloat *)
  3523. section
  3524. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3525. extrn __fac
  3526. extrn @coremath_tbyte_Pi_By_2
  3527. extrn $atan0
  3528. extrn $check_abs_one
  3529. public _acos :
  3530. push bp
  3531. mov bp, sp
  3532. mov word ss:[InMathLib], acostable
  3533. mov word ss:[InMathLib][2], bp
  3534. sub sp, 12
  3535. fld qword st(0), [bp][frame]
  3536. (*%F SameDS *) (* for error processing *)
  3537. mov ax, seg __fac
  3538. mov es, ax
  3539. fst qword es:[__fac], st(0)
  3540. (*%E *)
  3541. (*%T SameDS *)
  3542. fst qword [__fac], st(0)
  3543. (*%E *)
  3544. ftst st(0) (* is st(0) 0 or -0 ? *)
  3545. fstsw [bp][-2]
  3546. fst qword [bp][-12], st(0)
  3547. test byte [bp][-1],40H (* test for zero flag *)
  3548. jnz DoPiBy2 (* if arg1 was 0,return pi/2 *)
  3549. fmul st(0), st(0)
  3550. fld1 st(0)
  3551. fsubrp st(1),st(0)
  3552. fsqrt st(0)
  3553. fdivr qword st(0), [bp][-12]
  3554. fwait
  3555. call $atan0
  3556. DoPiBy2:
  3557. fld tbyte st(0), cs:[@coremath_tbyte_Pi_By_2]
  3558. fsubrp st(1), st(0)
  3559. acos_exit:
  3560. (*%F NearPtr *)
  3561. mov dx, seg __fac
  3562. mov es, dx
  3563. fstp qword es:[__fac], st(0)
  3564. (*%E *)
  3565. (*%T NearPtr *)
  3566. fstp qword [__fac], st(0)
  3567. (*%E *)
  3568. mov ax, __fac
  3569. mov sp, bp
  3570. pop bp
  3571. mov word ss:[InMathLib], 0
  3572. (*%T NearCall*)
  3573. ret near PopParam*8
  3574. (*%E*)
  3575. (*%F NearCall*)
  3576. ret far PopParam*8
  3577. (*%E*)
  3578. acostable:
  3579. dw acos_exit, err_acos_neg, err_acos_pos; db f_st5, "acos", 0
  3580. err_acos_pos:
  3581. call $check_abs_one
  3582. fldz st(0)
  3583. sub ax, ax
  3584. ret 0
  3585. err_acos_neg:
  3586. call $check_abs_one
  3587. fldpi st(0)
  3588. sub ax, ax
  3589. ret 0
  3590. (*%E StdFloat *)
  3591. (*************************************************************************)
  3592. (*%T StdFloat *)
  3593. (*%F _WINDOWS *)
  3594. section
  3595. segment _DATA(DATA,28H)
  3596. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3597. extrn __lib_error
  3598. extrn __SH_sword
  3599. extrn __exc_addr
  3600. public __math_excep:
  3601. (* called from floating point exception handler *)
  3602. (*
  3603. 8087 status word on stack, behind FAR return address to
  3604. signal handler.
  3605. This function must reside in the same segment as the math
  3606. library functions which use InMathLib
  3607. [bp][0] == saved bp
  3608. [bp][2] == return ip to signal handler
  3609. [bp][4] == return cs to signal handler
  3610. [bp][6] == 8087 status word
  3611. [bp][8] == return ip to point of exception
  3612. [bp][10] == return cs to point of exception
  3613. [bp][12] == flags for iret
  3614. *)
  3615. push bp
  3616. mov bp,sp
  3617. sub sp,2
  3618. cmp word ss:[InMathLib], 0
  3619. je user_error
  3620. (* An error has occurred in a library function. Put the stack into a
  3621. canonical state *)
  3622. jmp pop_8087
  3623. pop_8087_loop:
  3624. fstp st(0), st(0)
  3625. pop_8087:
  3626. fstsw [bp][-2]
  3627. fwait
  3628. test word [bp][-2], 3800H
  3629. jnz pop_8087_loop
  3630. (* The address of the handler table is in ss:[InMathLib] *)
  3631. push si
  3632. push ax
  3633. push bx
  3634. mov si,ss:[InMathLib]
  3635. mov word ss:[InMathLib], 0
  3636. mov ax, cs:[si] (* resume address *)
  3637. inc si
  3638. inc si
  3639. mov [bp][2],ax (* adjust local return address *)
  3640. mov bx,ss:[InMathLib][2] (* get the BP at the point of error *)
  3641. mov [bp],bx (* and make sure we restore to it *)
  3642. call __lib_error
  3643. pop bx
  3644. pop ax
  3645. pop si
  3646. mov sp,bp
  3647. pop bp
  3648. ret 10 (* return NEAR to resume point (we know it's in same code segment)
  3649. discard signal handler cs, 8087 status word, and 6 byte iret info *)
  3650. user_error:
  3651. push ax
  3652. push ds
  3653. mov ax, _DATA
  3654. mov ds, ax
  3655. mov ax, [bp][6]
  3656. mov [__SH_sword], ax
  3657. mov ax, [bp][8]
  3658. mov [__exc_addr], ax
  3659. mov ax, [bp][10]
  3660. mov [__exc_addr][2], ax
  3661. pop ds
  3662. pop ax
  3663. mov sp, bp
  3664. pop bp
  3665. ret far 2 (* return FAR to signal handler, discarding status word *)
  3666. (*%E _WINDOWS *)
  3667. (*%E StdFloat *)
  3668. (**************************************************************************)
  3669. (*%T StdFloat *)
  3670. (*%T _WINDOWS *)
  3671. section
  3672. segment _DATA(DATA,28H)
  3673. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3674. extrn __lib_error
  3675. extrn __SH_sword
  3676. extrn __exc_addr
  3677. public __math_excep:
  3678. (* called from floating point exception handler *)
  3679. (*
  3680. 8087 status word on stack, behind FAR return address to
  3681. signal handler.
  3682. This function must reside in the same segment as the math
  3683. library functions which use InMathLib
  3684. [bp][0] == saved bp
  3685. [bp][2] == return ip to signal handler
  3686. [bp][4] == return cs to signal handler
  3687. [bp][6] == 8087 status word
  3688. [bp][8] == return ip to windows emulator
  3689. [bp][10] == return cs to windows emulator
  3690. *)
  3691. (*
  3692. Windows version - emulator may or may not have placed junk on the stack,
  3693. so use the saved info to work out where we are.
  3694. *)
  3695. push bp
  3696. mov bp,sp
  3697. sub sp,2
  3698. cmp word ss:[InMathLib], 0
  3699. je user_error
  3700. (* An error has occurred in a library function. Put the stack into a
  3701. canonical state *)
  3702. jmp pop_8087
  3703. pop_8087_loop:
  3704. fstp st(0), st(0)
  3705. pop_8087:
  3706. fxam st(0)
  3707. fstsw [bp][-2]
  3708. fwait
  3709. and byte [bp][-1], 41H
  3710. cmp byte [bp][-1], 41H
  3711. jnz pop_8087_loop
  3712. (* The address of the handler table is in ss:[InMathLib] *)
  3713. push si
  3714. push ax
  3715. push bx
  3716. mov si,ss:[InMathLib]
  3717. mov word ss:[InMathLib], 0
  3718. mov ax, cs:[si] (* resume address *)
  3719. inc si
  3720. inc si
  3721. mov [bp][2],ax (* adjust local return address *)
  3722. mov bx,ss:[InMathLib][2] (* get the BP at the point of error *)
  3723. mov [bp],bx (* and make sure we restore to it *)
  3724. call __lib_error
  3725. pop bx
  3726. pop ax
  3727. pop si
  3728. mov sp,bp
  3729. pop bp (* == BP at point of error *)
  3730. ret 8 (* return NEAR to resume point (we know it's in same code segment)
  3731. discard signal handler cs, 8087 status word, and return address
  3732. to Windows. Anything else left on stack by Windows emulator
  3733. is removed at the resume address by the mov sp,bp
  3734. it will perform *)
  3735. user_error:
  3736. push ax
  3737. push ds
  3738. mov ax, ss
  3739. mov ds, ax
  3740. mov ax, [bp][6]
  3741. mov [__SH_sword], ax
  3742. sub ax, ax (* No hope of locating error source under windows *)
  3743. mov [__exc_addr], ax
  3744. mov [__exc_addr][2], ax
  3745. pop ds
  3746. pop ax
  3747. mov sp, bp
  3748. pop bp
  3749. ret far 2 (* return FAR to signal handler, discarding status word *)
  3750. (*%E _WINDOWS *)
  3751. (*%E StdFloat *)
  3752. section
  3753. (*****************************************************************************)
  3754. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3755. public $err_domain:
  3756. fldz st(0)
  3757. mov ax, _DOMAIN
  3758. ret 0
  3759. (************************************************************************)
  3760. section
  3761. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3762. public $err_underflow:
  3763. fldz st(0)
  3764. mov ax, _UNDERFLOW
  3765. ret 0
  3766. (************************************************************************)
  3767. section
  3768. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3769. public $err_plus_infinity:
  3770. (*%T SameDS *)
  3771. extrn _HUGE
  3772. fld qword st(0), [_HUGE]
  3773. mov ax, _OVERFLOW
  3774. ret 0
  3775. (*%E SameDS *)
  3776. (*%F SameDS *)
  3777. extrn @coremath_HUGE
  3778. fld qword st(0), cs:[@coremath_HUGE]
  3779. mov ax, _OVERFLOW
  3780. ret 0
  3781. (*%E NOT SameDS *)
  3782. (***********************************************************************)
  3783. section
  3784. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3785. extrn $err_plus_infinity
  3786. public $err_minus_infinity:
  3787. call $err_plus_infinity
  3788. fchs st(0)
  3789. ret 0
  3790. (************************************************************************)
  3791. section
  3792. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3793. public $err_huge_plus_infinity:
  3794. (*%T SameDS *)
  3795. extrn _LHUGE
  3796. fld tbyte st(0), [_LHUGE]
  3797. mov ax, _OVERFLOW
  3798. ret 0
  3799. (*%E SameDS *)
  3800. (*%F SameDS *)
  3801. extrn @coremath_LHUGE
  3802. fld tbyte st(0),cs:[@coremath_LHUGE]
  3803. mov ax, _OVERFLOW
  3804. ret 0
  3805. (*%E NOT SameDS *)
  3806. (***********************************************************************)
  3807. section
  3808. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3809. extrn $err_huge_plus_infinity
  3810. public $err_huge_minus_infinity:
  3811. call $err_huge_plus_infinity
  3812. fchs st(0)
  3813. ret 0
  3814. (***** Common Procedures *************************************************)
  3815. (******************** __bcd ******************************************
  3816. void __bcd(LONGDOUBLE num,tbyte *return_area)
  3817. COVENTIONS: all
  3818. ROUNDING: to nearest
  3819. OVERFLOW: returns signed Maximum
  3820. UNDERFLOW: returns +0
  3821. converts the long double num to a standard packed tbyte bcd at
  3822. address ss:return_area.
  3823. ***********************************************************************)
  3824. section
  3825. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  3826. num = CodePtrSize+2
  3827. (*%F _WINDOWS *)
  3828. extrn @coremath_nearest
  3829. (*%E NOT _WINDOWS *)
  3830. public __bcd:
  3831. (*%T StkParam *)(*%F _WINDOWS *)
  3832. push bp
  3833. mov bp,sp
  3834. push ax (* to store cw *)
  3835. fstcw [bp][-2] (* store cw *)
  3836. fld tbyte st(0),[bp][num] (* load num *)
  3837. fldcw cs:[@coremath_nearest] (* set cw to "round to nearest" *)
  3838. mov bx,[bp][12][CodePtrSize] (* ss:[bx] = return_area *)
  3839. frndint st(0) (* 80287 does not use rounding controls on fbstp *)
  3840. fbstp tbyte ss:[bx],st(0) (* store num as packed bcd in return_area *)
  3841. fldcw [bp][-2] (* restore cw *)
  3842. fwait
  3843. mov sp,bp (* destroy stack frame *)
  3844. pop bp
  3845. db Ret0@
  3846. (*%E StkParam *)(*%E NOT _WINDOWS *)
  3847. (*%F StdFloat *)
  3848. push bp
  3849. mov bp,sp
  3850. push ax (* to store cw *)
  3851. fstcw [bp][-2] (* store cw *)
  3852. fldcw cs:[@coremath_nearest] (* set cw to "round to nearest" *)
  3853. fld tbyte st(0),st(0) (* load num *)
  3854. xchg bx,ax (* ss:[bx] = return_area *)
  3855. frndint st(0) (* 80287 does not use rounding controls on fbstp *)
  3856. fbstp tbyte ss:[bx],st(0) (* store num as packed bcd in return_area *)
  3857. fldcw [bp][-2] (* restore cw *)
  3858. xchg bx,ax (* restore bx *)
  3859. fwait
  3860. mov sp,bp (* destroy stack frame *)
  3861. pop bp
  3862. db Ret0@
  3863. (*%E StdFloat *)
  3864. (*%T _WINDOWS *)
  3865. extrn __FloatLoadCW
  3866. extrn __FloatStoreCW
  3867. (*%T RegParam *)
  3868. push bp (* #1 save registers *)
  3869. mov bp,sp
  3870. push si (* #2 *)
  3871. push di (* #3 *)
  3872. push bx (* #4 *)
  3873. push cx (* #5 *)
  3874. push dx (* #6 *)
  3875. mov di,ax (* ss:[di] = return area *)
  3876. (*%E RegParam *)
  3877. (*%T StkParam *)
  3878. push bp (* #1 save registers *)
  3879. mov bp,sp
  3880. push si (* #2 *)
  3881. push di (* #3 *)
  3882. mov di,[bp][12][CodePtrSize](* ss:[di] = return area *)
  3883. (*%E StkParam *)
  3884. push ss
  3885. pop es
  3886. call far __FloatStoreCW (* store cur control word in ax *)
  3887. push ax (* push cur control word *)
  3888. and ax,~0C00H (* round to nearest or even *)
  3889. call far __FloatLoadCW (* rounding control now set *)
  3890. mov ax,[bp][8][num] (* load exponent & sign *)
  3891. mov dl,80H (* sign mask *)
  3892. and dl,ah (* sign in dl *)
  3893. xor ah,dl (* remove from ax *)
  3894. mov [bp][9][num],ah(* make long double positive *)
  3895. mov es:[di][9],dl (* store sign in bcd *)
  3896. cmp ax,3FFFH+60 (* overflow ? coarse test *)
  3897. jae OverFlow (* dbl>2**60.definite overflow *)
  3898. fld tbyte st(0),[bp][num](* load long double *)
  3899. fistp qword [bp][num],st(0)(* return quad intiger *)
  3900. fwait
  3901. mov si,[bp][num] (* si =least sig word *)
  3902. cmp ax,3FFFH (* if long double<1.... *)
  3903. cmc
  3904. sbb ax,ax (* clear ax *)
  3905. or ax,si (* long double<1 & least sig=0 ? *)
  3906. jz Zilch (* YES so return 0 *)
  3907. (* ##1 divide quad int by 10000 *)
  3908. mov dx,[bp][6][num] (* most sig word *)
  3909. mov ax,[bp][4][num] (* 2'nd most sig word *)
  3910. mov cx,10000 (* divisor *)
  3911. div cx (* ##1.1 *)
  3912. mov bx,ax (* bx = R1.1 *)
  3913. mov ax,[bp][2][num] (* 3'rd most sig word *)
  3914. div cx (* ##1.2 *)
  3915. xchg ax,si (* si = R1.2 .ax = 4th sig *)
  3916. div cx (* ##1.3 *)
  3917. push dx (* push Rem.1 *)
  3918. xchg ax,bx (* ax = R1.1 bx= R1.3 *)
  3919. (* ##2 2'nd divide by 10000 *)
  3920. cwd (* zero extend R1.1 *)
  3921. div cx (* ##2.1 *)
  3922. xchg ax,si (* ax = R1.2.si = R2.1 *)
  3923. div cx (* ##2.2 *)
  3924. xchg ax,bx (* ax = R1.3.bx = R2.2 *)
  3925. div cx (* ##2.3 *)
  3926. push dx (* push Rem.2 *)
  3927. xchg ax,bx (* bx = R2.3. ax = R2.2 *)
  3928. (* ## 3'rd divide by 10000 *)
  3929. mov dx,si (* dx = R2.1,ax = R2.2 *)
  3930. div cx (* ##3.1 *)
  3931. xchg ax,bx (* ax = R2.3,bx = R3.1 *)
  3932. div cx (* ##3.2 *)
  3933. push dx (* push Rem.3 *)
  3934. (* ## 4'th divide by 10000 *)
  3935. mov dx,bx (* dx = R3.1,ax = R3.2 *)
  3936. div cx (* ##4.1 *)
  3937. mov cx,25604 (* ch =100,cl=4 *)
  3938. cmp al,ch (* fine overflow test *)
  3939. jb NotOver (* test passed *)
  3940. add sp,6 (* destroy 3 pushes *)
  3941. OverFlow: mov ax,9999H (* return signed max *)
  3942. stosb (* 9 packed bytes set *)
  3943. jmp Over2 (* don't set sign byte *)
  3944. Zilch: stosw (* zilch clears all byte's including sign *)
  3945. Over2: stosw
  3946. stosw
  3947. stosw
  3948. stosw
  3949. jmp Done
  3950. NotOver: push dx (* push Rem.4 *)
  3951. aam (* ah top digit,al = 2'nd *)
  3952. shl ah,cl (* pack *)
  3953. add al,ah
  3954. add di,8 (* di -> top packed byte *)
  3955. std (* packed words stored in reverse order *)
  3956. stosb (* store top packed byte *)
  3957. dec di (* di -> 4'th packed word *)
  3958. mov si,4 (* 4 iterations of store loop *)
  3959. StoreLp: pop ax (* pop next 4 digits *)
  3960. div ch (* al = X34, ah =X12 *)
  3961. mov dl,ah (* dl = X12 *)
  3962. aam (* ah = X4,al = X3 *)
  3963. xchg ax,dx (* al = X12,dh =X4,dl = X3 *)
  3964. aam (* al = X1,ah = X2 *)
  3965. xchg ah,dl (* al=X1,ah =X3,dl=X2,dh=X4 *)
  3966. shl dx,cl (* dx<<4 *)
  3967. add ax,dx (* ax = 4 packed bcd digits *)
  3968. stosw (* store digits *)
  3969. dec si
  3970. jnz StoreLp (* next 4 digits *)
  3971. cld (* reset direction flag *)
  3972. Done: pop ax (* ax = original CW *)
  3973. call far __FloatLoadCW (* restore CW *)
  3974. (*%T StkParam *)
  3975. pop di (* #3 restore registers *)
  3976. pop si (* #2 *)
  3977. pop bp (* #1 *)
  3978. db Ret0@
  3979. (*%E StkParam *)
  3980. (*%T RegParam *)
  3981. pop dx (* #6 restore registers *)
  3982. pop cx (* #5 *)
  3983. pop bx (* #4 *)
  3984. pop di (* #3 *)
  3985. pop si (* #2 *)
  3986. pop bp (* #1 *)
  3987. db RetX@;dw 10
  3988. (*%E RegParam *)
  3989. (*%E _WINDOWS *)
  3990. (************************* _acvt() ************************************
  3991. LONGDOUBLE _acvt(int flag, char *mbuf, int exp, int len);
  3992. converts the ascii string *mbuf of len digits to a long double,
  3993. and multiplys it by 10**exp.
  3994. the following asumptions are not checked:
  3995. len is asumed to be 18 or less.
  3996. all digits are asumed to be valid askii decimal with no '.'
  3997. *************************************************************************)
  3998. section
  3999. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4000. extrn @coremath_int_ten
  4001. extrn @coremath_int_one
  4002. extrn __seterrno
  4003. (*%T StdFloat *)
  4004. extrn __fac
  4005. (*%E StdFloat *)
  4006. (*%T SameDS *)
  4007. extrn _HUGE
  4008. extrn _LHUGE
  4009. (*%E SameDS *)
  4010. (*%F SameDS *)
  4011. extrn @coremath_HUGE
  4012. extrn @coremath_LHUGE
  4013. (*%E NOT SameDS *)
  4014. (*%T _WINDOWS *)
  4015. extrn __FloatLoadCW
  4016. extrn __FloatStoreCW
  4017. (*%E _WINDOWS *)
  4018. (*%F _WINDOWS *)
  4019. extrn @coremath_nearest
  4020. (*%E NOT _WINDOWS *)
  4021. _MNEG = 1 (* True -> result should be negative *)
  4022. _STD = 8 (* True -> set errno if overflow *)
  4023. _ACVTL = 16 (* False -> max return is HUGE, not LHUGE *)
  4024. public __acvt:
  4025. (*%F _WINDOWS *)
  4026. push bp (* #0 *)
  4027. mov bp,sp
  4028. push ax (* #1 for CW *)
  4029. fstcw [bp][-2] (* save old CW *)
  4030. (*%T RegParam *)(*%T FarPtr *)
  4031. mov es,cx (* es:[bx] = mbuff *)
  4032. mov cx,[bp][2][CodePtrSize] (* cx = len. dx = exp *)
  4033. (*%E RegParam *)(*%E FarPtr *)
  4034. (*%T RegParam *)(*%T NearPtr *)
  4035. xchg cx,dx (* cx = len. dx = exp *)
  4036. (*%E RegParam *)(*%E NearPtr *)
  4037. (*%T StkParam *)(*%T FarPtr *)
  4038. mov ax,[bp][2][CodePtrSize] (* flags *)
  4039. les bx,[bp][4][CodePtrSize] (* mbuff *)
  4040. mov dx,[bp][8][CodePtrSize] (* exp *)
  4041. mov cx,[bp][10][CodePtrSize] (* len *)
  4042. (*%E StkParam *)(*%E FarPtr *)
  4043. (*%T StkParam *)(*%T NearPtr *)
  4044. mov ax,[bp][2][CodePtrSize] (* flags *)
  4045. mov bx,[bp][4][CodePtrSize] (* mbuff *)
  4046. mov dx,[bp][6][CodePtrSize] (* exp *)
  4047. mov cx,[bp][8][CodePtrSize] (* len *)
  4048. (*%E StkParam *)(*%E NearPtr *)
  4049. xor bp,bp
  4050. push bp (* #2 create cleared tbyte for packed bcd *)
  4051. push bp (* #3 *)
  4052. push bp (* #4 *)
  4053. push bp (* #5 *)
  4054. push bp (* #6 *)
  4055. fldcw cs:[@coremath_nearest] (* round to nearest, mask exceptions *)
  4056. mov bp,sp (* ss:[bp]->bcd_store *)
  4057. push ax (* #7 save flags *)
  4058. add bx,cx (* bx-> end of mbuf *)
  4059. jmp PkEnt
  4060. Pack: dec bx (* next 2 digits *)
  4061. dec bx
  4062. (*%T FarPtr *) db es@ (*%E es seg for mbuff *)
  4063. mov ax,[bx] (* load digits from mbuff *)
  4064. and ah,0FH (* convert lower digit to decimal from askii *)
  4065. add al,al (* upper_digit<<4 . also converts to decimal *)
  4066. add al,al
  4067. add al,al
  4068. add al,al
  4069. add al,ah (* pack digits into al *)
  4070. mov [bp],al (* store packed byte in bcd_store *)
  4071. inc bp (* next byte of bcd_store *)
  4072. PkEnt: sub cx,2 (* sub 2 from count *)
  4073. jae Pack (* 2 or more characters remain *)
  4074. jnp NoOdd (* cx= -2 so no odd character *)
  4075. (*%T FarPtr *) db es@ (*%E es: for mbuff *)
  4076. mov al,[bx][-1] (* pack last digit *)
  4077. and al,0FH
  4078. mov [bp],al
  4079. NoOdd: mov bp,sp (* bp = stack frame *)
  4080. add bp,14 (* compensate for 7 pushes *)
  4081. fbld tbyte st(0),[bp][-12](* $1 load packed digits *)
  4082. pop bx (* #7 flags *)
  4083. or dx,dx (* test exponent *)
  4084. (*%T RegParam *) fstp st(1),st(0) (*%E $0 *)
  4085. jz Sign (* no power- return digits *)
  4086. fild word st(0),cs:[@coremath_int_ten] (*$1or2 load 10 *)
  4087. jns Ploop
  4088. neg dx
  4089. fidivr word st(0),cs:[@coremath_int_one] (* st(0) = 1/10 *)
  4090. jmp Ploop
  4091. Htest: fstsw [bp][-12] (* store SW *)
  4092. fwait
  4093. pop ax (* #6 ax = SW *)
  4094. test al,8 (* has an overflow been recorded ? *)
  4095. jz Sign (* No Error result<LHUGE *)
  4096. (*%T SameDS *) fld tbyte st(0),[_LHUGE] (*%E $1or2 return LHUGE *)
  4097. (*%F SameDS *) fld tbyte st(0),cs:[@coremath_LHUGE] (*%E *)
  4098. jmp Error
  4099. (* accumulate powers of 10 or 1/10 in st(1) *)
  4100. Ploop2: fmul st(1),st(0) (* mul st(1) by 10**2**N *)
  4101. Ploop1: fmul st(0),st(0) (* N++ *)
  4102. Ploop: shr dx,1
  4103. ja Ploop1
  4104. jnz Ploop2
  4105. fmulp st(1),st(0) (* $0or1 last power *)
  4106. test bl,_ACVTL (* is max HUGE or LHUGE ? *)
  4107. jnz Htest
  4108. (*%T SameDS *) fcom qword st(0),[_HUGE] (*%E cmp result,HUGE *)
  4109. (*%F SameDS *) fcom qword st(0),cs:[@coremath_HUGE] (*%E *)
  4110. fstsw [bp][-12] (* store result of test *)
  4111. fwait
  4112. pop ax (* #6 ax = cmp result,HUGE *)
  4113. sahf (* flags = cmp result,HUGE *)
  4114. jb Sign (* No Error result<HUGE *)
  4115. (*%T SameDS *) fld qword st(0),[_HUGE] (*%E $1or2 return HUGE *)
  4116. (*%F SameDS *) fld qword st(0),cs:[@coremath_HUGE] (*%E *)
  4117. Error: fstp st(1),st(0) (* $0or1 destroy old return *)
  4118. test bl,_STD (* set errno ? *)
  4119. jz Sign (* atof does not set errno *)
  4120. mov ax,_OVERFLOW (* set errno to _OVERFLOW *)
  4121. (*%T NearCall *) call __seterrno (*%E NearCall *)
  4122. (*%T FarCall *) call far __seterrno (*%E FarCall *)
  4123. Sign: test bl,_MNEG (* test for sign flag *)
  4124. jz Done (* result is positive *)
  4125. fchs st(0) (* result is negative *)
  4126. Done: fclex (* clear any exception *)
  4127. fldcw [bp][-2] (* restore original CW *)
  4128. (*%T NearPtr *)(*%T RegParam *)
  4129. fwait (* wait for fldcw to finish *)
  4130. mov sp,bp (* #1 destroy pushed CW,& remaining bcd *)
  4131. pop bp (* #0 *)
  4132. db Ret0@
  4133. (*%E NearPtr *)(*%E RegParam *)
  4134. (*%T FarPtr *)(*%T RegParam *)
  4135. fwait (* wait for fldcw to finish *)
  4136. mov sp,bp (* #1 destroy pushed CW,& remaining bcd *)
  4137. pop bp (* #0 *)
  4138. db RetX@ ;dw 2
  4139. (*%E FarPtr *)(*%E RegParam *)
  4140. (*%T NearPtr *)(*%T StdFloat *)
  4141. mov ax,__fac (* return tbyte in __fac *)
  4142. fstp tbyte [__fac],st(0)
  4143. mov sp,bp (* #1 destroy pushed CW,& remaining bcd *)
  4144. fwait (* wait for tbyte store to end *)
  4145. pop bp (* #0 *)
  4146. db Ret0@
  4147. (*%E NearPtr *)(*%E StdFloat *)
  4148. (*%T FarPtr *)(*%T SameDS *)(*%T StdFloat *)
  4149. mov ax,__fac (* return tbyte in __fac *)
  4150. mov dx,ds
  4151. fstp tbyte [__fac],st(0)
  4152. mov sp,bp (* #1 destroy pushed CW,& remaining bcd *)
  4153. fwait (* wait for tbyte store to end *)
  4154. pop bp (* #0 *)
  4155. db RetX@ ;dw 2
  4156. (*%E FarPtr *)(*%E SameDS *)(*%E StdFloat *)
  4157. (*%T FarPtr *)(*%F SameDS *)(*%T StdFloat *)
  4158. mov ax,__fac (* return tbyte in __fac *)
  4159. mov dx,seg __fac
  4160. mov es,dx
  4161. fstp tbyte es:[__fac],st(0)
  4162. mov sp,bp (* #1 destroy pushed CW,& remaining bcd *)
  4163. fwait (* wait for tbyte store to end *)
  4164. pop bp (* #0 *)
  4165. db RetX@ ;dw 2
  4166. (*%E FarPtr *)(*%E NOT SameDS *)(*%E StdFloat *)
  4167. (*%E NOT _WINDOWS *)
  4168. (******************* _WINDOWS _acvt **********************************)
  4169. (*%T _WINDOWS *)
  4170. (*%T RegParam *)
  4171. push bp (* #0 *)
  4172. push si (* #1 *)
  4173. push di (* #2 *)
  4174. mov di,ax (* save flags *)
  4175. call far __FloatStoreCW
  4176. push ax (* #3 save old cw *)
  4177. mov ax,133FH (* round to nearest,affine,excepts masked *)
  4178. call far __FloatLoadCW
  4179. (*%T FarPtr *)
  4180. push dx (* #4 push exp *)
  4181. mov si,bx (* es:[si] = mbuf *)
  4182. mov es,cx
  4183. mov bp,sp
  4184. mov cx,[bp][10][CodePtrSize] (* cx = len *)
  4185. (*%E FarPtr *)
  4186. (*%T NearPtr *)
  4187. mov si,bx (* ds:[si] = mbuf *)
  4188. push cx (* #4 push exp *)
  4189. mov cx,dx (* cx = len *)
  4190. (*%E NearPtr *)
  4191. push di (* #5 flags *)
  4192. (*%E RegParam *)
  4193. (*%T StkParam *)
  4194. push bp (* #0 *)
  4195. mov bp,sp
  4196. push si (* #1 *)
  4197. push di (* #2 *)
  4198. call far __FloatStoreCW
  4199. push ax (* #3 save old cw *)
  4200. mov ax,133FH (* round to nearest,affine,excepts masked *)
  4201. call far __FloatLoadCW
  4202. push [bp][4][CodePtrSize][DataPtrSize] (* #4 push exp *)
  4203. push [bp][2][CodePtrSize] (* #5 flags *)
  4204. mov cx,[bp][6][CodePtrSize][DataPtrSize] (* cx = len *)
  4205. (*%T FarPtr *)
  4206. les si,[bp][4][CodePtrSize] (* es:[si] = mbuf *)
  4207. (*%E FarPtr *)
  4208. (*%T NearPtr *)
  4209. mov si,[bp][4][CodePtrSize] (* ds:[si] = mbuf *)
  4210. (*%E NearPtr *)
  4211. (*%E StkParam *)
  4212. xor dx,dx (* clear Qint *)
  4213. xor bx,bx
  4214. xor di,di
  4215. xor bp,bp
  4216. jcxz NoNum
  4217. jmp Qent
  4218. (* convert string to qword intiger in bp,di,bx,dx *)
  4219. QLoop: push bp (* store Qint*1 *)
  4220. push di
  4221. mov ax,dx
  4222. push bx
  4223. add dx,dx (* Qint = Qint*2 *)
  4224. adc bx,bx
  4225. adc di,di
  4226. adc bp,bp
  4227. add dx,dx (* Qint = Qint*4 *)
  4228. adc bx,bx
  4229. adc di,di
  4230. adc bp,bp
  4231. add dx,ax (* Qint = Qint*4 + Qint*1 *)
  4232. pop ax
  4233. adc bx,ax
  4234. pop ax
  4235. adc di,ax
  4236. pop ax
  4237. adc bp,ax
  4238. add dx,dx (* Qint = Qint*5*2 *)
  4239. adc bx,bx
  4240. adc di,di
  4241. adc bp,bp
  4242. (*%T NearPtr *)
  4243. Qent: lodsb (* load next character *)
  4244. (*%E NearPtr *)
  4245. (*%F NearPtr *)
  4246. Qent: db es@;lodsb (* load next character, with es: override *)
  4247. (*%E NearPtr *)
  4248. and ax,0FH (* convert askii char to int *)
  4249. add dx,ax (* add Qint,next digit *)
  4250. mov al,ah (* clear ax *)
  4251. adc bx,ax
  4252. adc di,ax
  4253. adc bp,ax
  4254. loop QLoop
  4255. (* Qint = bp,di,bx,dx *)
  4256. NoNum: pop cx (* #5 pop flags *)
  4257. pop si (* #4 pop exp *)
  4258. push bp (* #4 push Qint *)
  4259. push di (* #5 *)
  4260. push bx (* #6 *)
  4261. push dx (* #7 *)
  4262. mov bp,sp (* set bp to Qint *)
  4263. fild qword st(0),[bp] (* $1 load Qint *)
  4264. or si,si (* test exponent *)
  4265. jz Sign (* no power - return digits *)
  4266. fild word st(0),cs:[@coremath_int_ten] (* $2 load 10 *)
  4267. jns Ploop
  4268. neg si
  4269. fidivr word st(0),cs:[@coremath_int_one] (* st(0) = 1/10 *)
  4270. jmp Ploop
  4271. Htest: fstsw [bp] (* store condition of chip *)
  4272. fwait (* wait for result *)
  4273. test byte [bp],8 (* has an overflow been recorded ? *)
  4274. jz Sign (* No Error result<HUGE *)
  4275. fld tbyte st(0),[_LHUGE]
  4276. jmp Error
  4277. (* accumulate powers of 10 or 1/10 in st(1) *)
  4278. Ploop2: fmul st(1),st(0) (* mul st(1) by 10**2**N *)
  4279. Ploop1: fmul st(0),st(0) (* N++ *)
  4280. Ploop: shr si,1
  4281. ja Ploop1
  4282. jnz Ploop2
  4283. fmulp st(1),st(0) (* $1 last power *)
  4284. test cl,_ACVTL (* is max HUGE or LHUGE ? *)
  4285. jnz Htest
  4286. fcom qword st(0),[_HUGE]
  4287. fstsw [bp] (* store result of test *)
  4288. fwait (* wait for result *)
  4289. test byte [bp][1],1 (* flags = cmp result,HUGE *)
  4290. jnz Sign (* No Error result<HUGE *)
  4291. fld qword st(0),[_HUGE](* $2 Return Huge *)
  4292. Error: fstp st(1),st(0) (* $1 *)
  4293. test cl,_STD (* set errno ? *)
  4294. fclex (* clear any exception *)
  4295. jz Sign (* atof does not set errno *)
  4296. mov ax,_OVERFLOW (* set errno to _OVERFLOW *)
  4297. (*%T NearCall *) call __seterrno (*%E NearCall *)
  4298. (*%T FarCall *) call far __seterrno (*%E FarCall *)
  4299. Sign: test cl,_MNEG (* test for sign flag *)
  4300. jz Done (* result is positive *)
  4301. fchs st(0) (* result is negative *)
  4302. Done: add sp,8 (* #7-4 destroy pushed qword intiger *)
  4303. pop ax (* #3 original CW *)
  4304. call far __FloatLoadCW (* restore original CW *)
  4305. mov ax,__fac (* return tbyte in __fac *)
  4306. fstp tbyte [__fac],st(0) (* $0 *)
  4307. pop di (* #2 restore registers *)
  4308. pop si (* #1 *)
  4309. pop bp (* #0 *)
  4310. fwait
  4311. (*%T NearPtr *)
  4312. db Ret0@
  4313. (*%E NearPtr *)
  4314. (*%T FarPtr *)(*%T RegParam *)
  4315. mov dx,ds (* return tbyte seg in __fac *)
  4316. db RetX@ ;dw 2
  4317. (*%E FarPtr *)(*%E RegParam *)
  4318. (*%T FarPtr *)(*%T StkParam *)
  4319. mov dx,ds (* return tbyte seg in __fac *)
  4320. db Ret0@
  4321. (*%E FarPtr *)(*%E StkParam *)
  4322. (*%E _WINDOWS *)
  4323. (************************ pow() ******************************************
  4324. double pow(double X,double Y)
  4325. LONGDOUBLE powl(LONGDOUBLE X,LONGDOUBLE Y)
  4326. return: X to the power Y
  4327. Error: handled by matherr()
  4328. Limits: if (X==0 && Y>0) or (X<0 && Y isn't an integer) pow calls matherr,
  4329. with error = DOMAIN,& result = 0.
  4330. ***************************************************************************)
  4331. section
  4332. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4333. PowName: db "pow",0 (* name for exception handler *)
  4334. extrn $err_plus_infinity
  4335. extrn $err_huge_plus_infinity
  4336. extrn $err_minus_infinity
  4337. extrn $err_huge_minus_infinity
  4338. extrn $err_domain
  4339. extrn $err_underflow
  4340. extrn __report_math_error
  4341. extrn @coremath_int_one
  4342. extrn @coremath_int_two
  4343. (*%T StdFloat *)
  4344. extrn __fac
  4345. (*%E StdFloat *)
  4346. (*%F _WINDOWS *)
  4347. extrn @coremath_nearest
  4348. (*%E NOT _WINDOWS *)
  4349. (*%T _WINDOWS *)
  4350. extrn __FloatStoreCW
  4351. extrn __FloatStoreSW
  4352. extrn __FloatLoadCW
  4353. (*%E _WINDOWS *)
  4354. (*%T RegParam *)
  4355. (*%T NearPtr *) x=-6 (*%E NearPtr *)
  4356. (*%T FarPtr *) x=-4 (*%E FarPtr *)
  4357. Arg1Dbl = 2+CodePtrSize+8
  4358. Arg1Tbt = 2+CodePtrSize+10
  4359. Arg2Dbl = 2+CodePtrSize
  4360. Arg2Tbt = 2+CodePtrSize
  4361. (*%E RegParam *)
  4362. (*%T StkParam *)
  4363. x=0
  4364. Arg1Dbl = 2+CodePtrSize
  4365. Arg1Tbt = 2+CodePtrSize
  4366. Arg2Dbl = 2+CodePtrSize+8
  4367. Arg2Tbt = 2+CodePtrSize+10
  4368. (*%E StkParam *)
  4369. (*%F StdFloat ********************************************)
  4370. public _powl:
  4371. push bp (* #0 save bp *)
  4372. mov bp,sp
  4373. push cx (* #1 save cx *)
  4374. xor cx,cx (* powl flag: set cx = 0 *)
  4375. jmp Ent
  4376. public _pow:
  4377. push bp (* #0 save bp *)
  4378. mov bp,sp
  4379. push cx (* #1 save cx *)
  4380. mov ch,-1 (* pow flag: set cx =! 0 *)
  4381. Ent: push ax (* #2 save ax *)
  4382. ftst st(0) (* test X *)
  4383. push ax (* #3 to store CW *)
  4384. push ax (* #4 for test X *)
  4385. fstsw word [bp][-8] (* store result of test *)
  4386. fstcw [bp][-6] (* store control word *)
  4387. fst st(5),st(0) (* save X in st(5) for error handler *)
  4388. pop ax (* #4 ax = cmp X,0 *)
  4389. sahf (* flags =cmp X,0 *)
  4390. fld st(0),st(6) (* $1 Y = st(0) *)
  4391. push bx (* #4 save bx *)
  4392. mov ah,-1 (* set ZF flag in ax *)
  4393. fldcw cs:[@coremath_nearest](* round to nearest,affine,excepts masked *)
  4394. push ax (* #5 assume result is positive *)
  4395. jz X0 (* X is Zero *)
  4396. ja Xpos (* X is positive non-Zero *)
  4397. Xneg: frndint st(0) (* X is neg. Y rounded to int *)
  4398. fcom st(0),st(7) (* cmp Y,rounded Y *)
  4399. fstsw [bp][-10] (* store result of test *)
  4400. fidiv word st(0),cs:[@coremath_int_two]
  4401. pop ax (* #5 ax = cmp Y,chopped Y *)
  4402. sahf (* flags = cmp Y,chopped Y *)
  4403. jne Domain (* Y isn't an integer *)
  4404. frndint st(0) (* round 1/2Y - altered if Y was odd *)
  4405. fadd st(0),st(0)
  4406. fcomp st(0),st(7) (* $0 Y = st(0) if Y is even *)
  4407. push ax (* #5 to store result sign *)
  4408. fstsw [bp][-10] (* ZF = 1 if pos result *)
  4409. fabs st(0) (* st(0) = abs(X) *)
  4410. fld st(0),st(6) (* $1 st(0) = Y, st(1) = X *)
  4411. Xpos: fxch st(0),st(1) (* st(0) = X,st(1) = Y *)
  4412. fyl2x st(1),st(0) (* $0 st(0) = log2 result *)
  4413. sub sp,10 (*#6-10 for tempory tbyte *)
  4414. fld st(0),st(0) (* $1 *)
  4415. fstp tbyte [bp][-20],st(0) (* $0 log2 result *)
  4416. fld st(0),st(0) (* $1 st(1) = log2 result *)
  4417. add sp,6 (* destroy 3 least sig words of tbyte *)
  4418. frndint st(0) (* st(0) = integer part of log2 result *)
  4419. pop bx (* #7 most sig mantisa word of log2 result*)
  4420. fxch st(0),st(1) (* st(1) = integer part of log2 result *)
  4421. pop ax (* #6 ax = biased exponent of log2 result *)
  4422. fsub st(0),st(1) (* st(0) = fractional part of log2 result *)
  4423. push ax (* #6 to test fractional exponent *)
  4424. ftst st(0) (* is fractional part neg ? *)
  4425. fstsw [bp][-12] (* store result of test *)
  4426. fabs st(0) (* st(0) = abs(fraction) *)
  4427. f2xm1 st(0) (* st(0) = (2 to power abs(fraction))-1 *)
  4428. jcxz Lexp (* test for over/under tbyte result *)
  4429. cmp ax,4009H (* 04009,8000 = max posible valid exponent *)
  4430. jge Over (* tbyte>400H.overflow *)
  4431. jb NoErr (* positive - no error *)
  4432. cmp ax,0C008H (* 0C008,FFC0 = min posible valid exponent *)
  4433. ja Under (* tbyte<-3FFH.underfow *)
  4434. jb NoErr (* tbyte>-3FFH.in range *)
  4435. cmp bx,0FFC0H (* 2'nd underflow test *)
  4436. jb NoErr
  4437. Under: pop ax (* #6 ax= sign of fractional exponent *)
  4438. pop ax (* #5 destroy result's sign *)
  4439. mov ax,$err_underflow
  4440. jmp Error
  4441. X0: fcomp st(0),st(1) (* $0 cmp Y,0. st(0)=0 *)
  4442. fstsw [bp][-10] (* store result of test *)
  4443. fwait
  4444. pop ax (* #5 ax = cmp Y,0 *)
  4445. sahf (* flags = cmp Y,0 *)
  4446. ja Done (* Y>0.return 0 *)
  4447. fld st(0),st(0) (* $1 *)
  4448. Domain:mov ax,$err_domain (* else domain error *)
  4449. Error: mov bx,PowName
  4450. fstp st(1),st(0) (* $0 *)
  4451. call ax (* st(0) = default return,ax =error num *)
  4452. fstp st(1),st(0) (* $0 *)
  4453. call __report_math_error (* call error handler *)
  4454. jmp Done
  4455. Over: pop ax (* #6 fractional exponent sign *)
  4456. pop ax (* #5 result sign ? *)
  4457. sahf (* sign *)
  4458. jnz NegOv (* return -HUGE *)
  4459. mov ax,$err_plus_infinity
  4460. jmp Error
  4461. NegOv: mov ax,$err_minus_infinity
  4462. jmp Error
  4463. LOver: pop ax (* #6 fractional exponent sign *)
  4464. pop ax (* #5 result sign ? *)
  4465. sahf
  4466. jnz LNegOv (* return -LHUGE *)
  4467. mov ax,$err_huge_plus_infinity
  4468. jmp Error
  4469. LNegOv:mov ax,$err_huge_minus_infinity
  4470. jmp Error
  4471. Lexp: cmp ax,400DH (* 0400D,8000 = max posible valid exponent *)
  4472. jge LOver (* tbyte>4000H.overflow *)
  4473. ja NoErr (* positive exp *)
  4474. cmp ax,0C00CH (* 0C00C,FFFC = min posible valid exponent *)
  4475. jb NoErr (* tbyte>-3FFFH.in range *)
  4476. ja Under (* tbyte<-3FFFH.underfow *)
  4477. cmp bx,0FFFCH (* 2'nd underflow test *)
  4478. jae Under (* tbyte<-3FFFH.underfow *)
  4479. NoErr: pop ax (* #6 ax= sign of fractional exponent *)
  4480. fiadd word st(0),cs:[@coremath_int_one]
  4481. sahf (* flags = sign of fractional exponent *)
  4482. jae Pos (* st(0) = 2 to power fraction *)
  4483. fidivr word st(0),cs:[@coremath_int_one] (* st(0) = 2 to power fraction *)
  4484. Pos: fscale st(0),st(1) (* scale st(0) by integer power *)
  4485. fstp st(1),st(0) (* $0 *)
  4486. pop ax (* #5 sign of result ? *)
  4487. sahf
  4488. jz Done (* result is positive *)
  4489. fchs st(0) (* negative result *)
  4490. Done: fclex (* clear exceptions *)
  4491. fldcw [bp][-6] (* load original cw *)
  4492. pop bx (* #4 restore bx *)
  4493. fwait (* when loaded.. *)
  4494. pop ax (* #3 destroy original CW *)
  4495. pop ax (* #2 restore registers *)
  4496. pop cx (* #1 *)
  4497. pop bp (* #0 *)
  4498. db Ret0@
  4499. (*%E NOT StdFloat *********************************************)
  4500. (*%T StdFloat *************************************************)
  4501. public _powl:
  4502. push bp
  4503. mov bp,sp
  4504. (*%T RegParam *)
  4505. push bx
  4506. push cx
  4507. (*%T NearPtr *) push dx (*%E NearPtr *)
  4508. (*%E RegParam *)
  4509. xor cx,cx (* powl flag: set cx = 0 *)
  4510. fld tbyte st(0),[bp][Arg1Tbt] (* $1 load X *)
  4511. push ax (* #1 for test X *)
  4512. ftst st(0) (* test X *)
  4513. fstsw [bp][-2][x]
  4514. fld tbyte st(0),[bp][Arg2Tbt] (* $2 load Y *)
  4515. jmp Ent
  4516. public _pow:
  4517. push bp
  4518. mov bp,sp
  4519. (*%T RegParam *)
  4520. push bx
  4521. push cx
  4522. (*%T NearPtr *) push dx (*%E NearPtr *)
  4523. (*%E RegParam *)
  4524. mov ch,-1 (* pow flag: cx != 0 *)
  4525. fld qword st(0),[bp][Arg1Dbl] (* $1 load X *)
  4526. push ax (* for test X *)
  4527. ftst st(0) (* test X *)
  4528. fstsw [bp][-2][x]
  4529. fld qword st(0),[bp][Arg2Dbl] (* $2 load Y *)
  4530. Ent: pop ax (* #1 ax = Test X *)
  4531. (*%F _WINDOWS *)
  4532. push ax (* #1 to save cw *)
  4533. fstcw [bp][-2][x] (* save cw *)
  4534. fldcw cs:[@coremath_nearest](* round to nearest,affine,excepts masked *)
  4535. (*%E NOT _WINDOWS *)
  4536. (*%T _WINDOWS *)
  4537. mov bx,ax (* save test X *)
  4538. call far __FloatStoreCW (* store control word *)
  4539. push ax (* #1 original CW *)
  4540. mov ax,133FH (* round to nearest,affine,excepts masked *)
  4541. call far __FloatLoadCW
  4542. mov ax,bx (* ax = Test X *)
  4543. (*%E _WINDOWS *)
  4544. sahf (* flags =cmp X,0 *)
  4545. ja Xpos (* X is positive non-Zero *)
  4546. push ax (* #2 to store cmp Y,rounded Y *)
  4547. jz X0 (* X is Zero *)
  4548. Xneg: fld st(0),st(0) (* $3 save Y in st(1) *)
  4549. frndint st(0) (* X is neg. Y rounded to int *)
  4550. fcom st(0),st(1) (* cmp Y,rounded Y *)
  4551. fstsw [bp][-4][x] (* store result of test *)
  4552. fidiv word st(0),cs:[@coremath_int_two]
  4553. pop ax
  4554. frndint st(0)
  4555. fadd st(0),st(0)
  4556. fcomp st(0),st(1) (* $2 Y = st(0) flags->ZF=0 if Y is even *)
  4557. sahf (* flags = cmp Y,choped Y *)
  4558. jnz Domain (* Y is not an integer *)
  4559. push ax (* #2 to store result's sign *)
  4560. fstsw [bp][-4][x] (* store result of test *)
  4561. fxch st(0),st(1) (* st(1) = Y *)
  4562. fabs st(0) (* st(0) = abs(X) *)
  4563. not byte [bp][-3][x] (* #2 zf=1 if odd *)
  4564. jmp Xneg2
  4565. Xpos: push ax (* #2 ZF in ax = 1 if neg result *)
  4566. fxch st(0),st(1) (* st(0) = X,st(1) = Y *)
  4567. Xneg2: fyl2x st(1),st(0) (* $1 st(0) = log2 result *)
  4568. fld st(0),st(0) (* $2 st(1) = log2 result *)
  4569. sub sp,10 (*#3-7 for tempory tbyte *)
  4570. fld st(0),st(0) (* $3 *)
  4571. fstp tbyte [bp][-14][x],st(0) (* $2 log2 result *)
  4572. frndint st(0) (* st(0) = integer part of log2 result *)
  4573. add sp,6 (* destoy 3 least sig words of tbyte *)
  4574. fxch st(0),st(1) (* st(1) = integer part of log2 result *)
  4575. pop bx (* #4 most sig word of mantisa *)
  4576. fsub st(0),st(1) (* st(0) = factional part of log2 result *)
  4577. pop dx (* #3 dx = biased exponent of log2 result *)
  4578. ftst st(0) (* is fractional part neg ? *)
  4579. push ax (* #3 to test sign of fraction *)
  4580. fstsw [bp][-6][x] (* store result of test *)
  4581. fabs st(0) (* st(0) = abs(fraction) *)
  4582. pop ax (* #3 ax = result of test *)
  4583. f2xm1 st(0) (* st(0) = (2 to power abs(fraction))-1 *)
  4584. jcxz Lexp (* test for over/under tbyte result *)
  4585. cmp dx,4009H (* 04009,8000 = max posible valid exponent *)
  4586. jge Over (* tbyte>400H.overflow *)
  4587. jb NoErr (* positive exponent *)
  4588. cmp dx,0C008H (* 0C008,FFC0 = min posible valid exponent *)
  4589. jb NoErr (* tbyte>-3FFH.in range *)
  4590. ja Under (* tbyte<-3FFH.underfow *)
  4591. cmp bx,0FFC0H (* 2'nd underflow test *)
  4592. jb NoErr
  4593. Under: pop ax (* #2 destroy result's sign *)
  4594. mov ax,$err_underflow
  4595. jmp Error
  4596. X0: fcomp st(0),st(1) (* $1 cmp Y,0. st(0)=0 *)
  4597. fstsw [bp][-4][x] (* store result of test *)
  4598. fwait
  4599. pop ax
  4600. sahf
  4601. ja Done1 (* Y>0.return 0 NOTE $1 *)
  4602. fld st(0),st(0) (* $2 *)
  4603. Domain:mov ax,$err_domain (* else domain error *)
  4604. Error: mov bx,PowName (* ss:[bx]->"pow" *)
  4605. fstp st(0),st(0) (* $1 *)
  4606. fstp st(0),st(0) (* $0 *)
  4607. jcxz Terr
  4608. fld qword st(0),[bp][Arg2Dbl]
  4609. fld qword st(0),[bp][Arg1Dbl]
  4610. jmp Qerr
  4611. Terr: fld tbyte st(0),[bp][Arg2Tbt]
  4612. fld tbyte st(0),[bp][Arg1Tbt]
  4613. Qerr: call ax (* st(0) =ret val,ax = exception type *)
  4614. call __report_math_error
  4615. Done1: jmp Done
  4616. Over: pop ax (* #2 result sign ? *)
  4617. sahf (* sign *)
  4618. jz NegOv (* return -HUGE *)
  4619. mov ax,$err_plus_infinity
  4620. jmp Error
  4621. NegOv: mov ax,$err_minus_infinity
  4622. jmp Error
  4623. LOver: pop ax (* #2 result sign ? *)
  4624. sahf
  4625. jz LNegOv (* return -LHUGE *)
  4626. mov ax,$err_huge_plus_infinity
  4627. jmp Error
  4628. LNegOv:mov ax,$err_huge_minus_infinity
  4629. jmp Error
  4630. Lexp: cmp dx,400DH (* 0400D,8000 = max posible valid exponent *)
  4631. jge LOver (* tbyte>4000H.overflow *)
  4632. ja NoErr (* positive - no error *)
  4633. cmp dx,0C00CH (* 0C00C,FFC0 = min posible valid exponent *)
  4634. jb NoErr (* tbyte>-3FFFH.in range *)
  4635. ja Under (* tbyte<-3FFFH.underfow *)
  4636. cmp bx,0FFFCH (* 2'nd underflow test *)
  4637. jae Under (* tbyte<-3FFFH.underfow *)
  4638. NoErr: fiadd word st(0),cs:[@coremath_int_one]
  4639. sahf (* flags = cmp st(0),0 *)
  4640. jae Pos (* st(0) = 2 to power fraction *)
  4641. fidivr word st(0),cs:[@coremath_int_one] (* st(0) = 2 to power fraction *)
  4642. Pos:
  4643. (*%T _WINDOWS *)
  4644. fxch st(1), st(0)
  4645. ftst st(0) (* work around windows emulator bug *)
  4646. call far __FloatStoreSW
  4647. fxch st(1), st(0)
  4648. sahf
  4649. jz skipscale
  4650. (*%E *)
  4651. fscale st(0),st(1) (* scale st(0) by integer power *)
  4652. skipscale:
  4653. fstp st(1),st(0) (* $1 *)
  4654. pop ax (* #2 sign of result ? *)
  4655. sahf
  4656. jnz Done (* result is positive *)
  4657. fchs st(0) (* negative result *)
  4658. Done: fclex (* clear exceptions *)
  4659. (*%T _WINDOWS *)
  4660. pop ax (* #1 original CW *)
  4661. call far __FloatLoadCW (* restore CW *)
  4662. (*%E _WINDOWS *)
  4663. (*%F _WINDOWS *)
  4664. fldcw [bp][-2][x] (* restore original CW *)
  4665. pop ax (* #1 original CW *)
  4666. (*%E NOT _WINDOWS *)
  4667. (*** TAIL for StdFloat pow **********************************)
  4668. (*%T StkParam *)(*%T NearPtr *)
  4669. jcxz Huge
  4670. fstp qword [__fac], st(0)
  4671. jmp Done2
  4672. Huge: fstp tbyte [__fac], st(0)
  4673. Done2: pop bp (* restore bp *)
  4674. mov ax, __fac
  4675. fwait
  4676. db Ret0@
  4677. (*%E StkParam *)(*%E NearPtr *)
  4678. (*%T StkParam *)(*%T FarPtr *)(*%F _fdata *)
  4679. jcxz Huge
  4680. fstp qword [__fac], st(0)
  4681. jmp Done2
  4682. Huge: fstp tbyte [__fac], st(0)
  4683. Done2: pop bp (* restore bp *)
  4684. mov ax, __fac
  4685. mov dx,ds
  4686. fwait
  4687. db Ret0@
  4688. (*%E StkParam *)(*%E FarPtr *)(*%E NOT _fdata *)
  4689. (*%T StkParam *)(*%T FarPtr *)(*%T _fdata *)
  4690. mov dx,seg __fac
  4691. mov es,dx
  4692. jcxz Huge
  4693. fstp qword es:[__fac], st(0)
  4694. jmp Done2
  4695. Huge: fstp tbyte es:[__fac], st(0)
  4696. Done2: pop bp (* restore bp *)
  4697. mov ax, __fac
  4698. fwait
  4699. db Ret0@
  4700. (*%E StkParam *)(*%E FarPtr *)(*%E _fdata *)
  4701. (*%T RegParam *)(*%T NearPtr *)
  4702. mov ax, __fac
  4703. jcxz Huge
  4704. fstp qword [__fac],st(0)
  4705. pop dx
  4706. pop cx
  4707. pop bx
  4708. fwait
  4709. pop bp
  4710. db RetX@;dw 16
  4711. Huge: fstp tbyte [__fac],st(0)
  4712. pop dx
  4713. pop cx
  4714. pop bx
  4715. fwait
  4716. pop bp
  4717. db RetX@;dw 20
  4718. (*%E RegParam *)(*%E NearPtr *)
  4719. (*%T RegParam *)(*%T FarPtr *)
  4720. mov ax, __fac
  4721. mov dx,ds
  4722. jcxz Huge
  4723. fstp qword [__fac], st(0)
  4724. pop cx
  4725. pop bx
  4726. fwait
  4727. pop bp
  4728. db RetX@;dw 16
  4729. Huge: fstp tbyte [__fac], st(0)
  4730. pop cx
  4731. pop bx
  4732. fwait
  4733. pop bp
  4734. db RetX@;dw 20
  4735. (*%E RegParam *)(*%E FarPtr *)
  4736. (*%E StdFloat End of StdFloat pow *********************)
  4737. (* __pow_int ************************************************************
  4738. internal function.
  4739. LONGDOUBLE __pow_int(LONGDOUBLE X,int Y)
  4740. conventions: all
  4741. returns X to the power Y
  4742. Error Handling: NONE
  4743. *************************************************************************)
  4744. section
  4745. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4746. extrn @coremath_int_one
  4747. (*%T StdFloat *)
  4748. extrn __fac
  4749. (*%E StdFloat *)
  4750. public __pow_int:
  4751. push bp
  4752. mov bp,sp
  4753. (*%T StdFloat *)
  4754. fld tbyte st(0),[bp][2][CodePtrSize] (*$1 num *)
  4755. (*%E StdFloat *)
  4756. (*%T StkParam *)
  4757. mov ax,[bp][12][CodePtrSize] (* integral power *)
  4758. (*%E StkParam *)
  4759. or ax,ax (* power ? *)
  4760. jg PosExp (* positive non-zero *)
  4761. jz Pow0 (* power is 0,return 1 *)
  4762. neg ax (* power was negative *)
  4763. fidivr word st(0),cs:[@coremath_int_one]
  4764. PosExp: dec ax
  4765. jz Done
  4766. fld st(0),st(0)
  4767. jmp Ploop
  4768. Pow0: fld1 st(0) (* store 1 in st(0) *)
  4769. fstp st(1),st(0)
  4770. jmp Done
  4771. Ploop2: fmul st(1),st(0) (* mul st(1) by 10**2**N *)
  4772. Ploop1: fmul st(0),st(0) (* N++ *)
  4773. Ploop: shr ax,1
  4774. ja Ploop1
  4775. jnz Ploop2
  4776. fmulp st(1),st(0) (* last power,result in st(0) *)
  4777. (*%T StdFloat *)(*%T _fdata *)
  4778. Done: mov ax, __fac
  4779. mov dx, seg __fac
  4780. mov es, dx
  4781. fstp tbyte es:[__fac], st(0)
  4782. fwait
  4783. (*%E StdFloat *)(*%E _fdata *)
  4784. (*%T StdFloat *)(*%T FarPtr *)(*%T SameDS *)
  4785. Done: mov ax, __fac
  4786. mov dx,ds
  4787. fstp tbyte [__fac], st(0)
  4788. fwait
  4789. (*%E StdFloat *)(*%E FarPtr *)(*%E SameDS *)
  4790. (*%T StdFloat *)(*%T NearPtr *)
  4791. Done: mov ax, __fac
  4792. fstp tbyte [__fac], st(0)
  4793. fwait
  4794. (*%E StdFloat *)(*%E NearPtr *)
  4795. (*%T StkParam *)
  4796. pop bp
  4797. db Ret0@
  4798. (*%E StkParam *)
  4799. (*%T RegParam *)(*%T _WINDOWS *)
  4800. pop bp
  4801. db RetX@;dw 10
  4802. (*%E RegParam *)(*%E _WINDOWS *)
  4803. (*%T RegParam *)(*%F _WINDOWS *)
  4804. Done: pop bp
  4805. db Ret0@
  4806. (*%E RegParam *)(*%E NOT _WINDOWS *)
  4807. (*************************************************************************)
  4808. section
  4809. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4810. public __clear87 :
  4811. push bp
  4812. mov bp, sp
  4813. push ax
  4814. fstsw [bp][-2]
  4815. fclex
  4816. pop ax
  4817. pop bp
  4818. db Ret0@
  4819. (*************************************************************************)
  4820. section
  4821. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4822. (* returns status word in ax *)
  4823. public __status87 :
  4824. push bp
  4825. mov bp, sp
  4826. push ax
  4827. fstsw [bp][-2]
  4828. fwait
  4829. pop ax
  4830. pop bp
  4831. db Ret0@
  4832. (*************************************************************************)
  4833. section
  4834. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4835. (*%T _WINDOWS *)
  4836. extrn __FloatStoreCW
  4837. extrn __FloatLoadCW
  4838. (*%E _WINDOWS *)
  4839. public __control87 :
  4840. (*%F _WINDOWS *)
  4841. (*%T RegParam *)
  4842. push bp (* save bp *)
  4843. mov bp,sp
  4844. (*%E RegParam *)
  4845. (*%T StkParam *)
  4846. push bp
  4847. mov bp,sp
  4848. mov ax,[bp][2][CodePtrSize] (* ax = new *)
  4849. mov bx,[bp][4][CodePtrSize] (* bx = mask *)
  4850. (*%E StkParam *)
  4851. push ax (* for storeing CW *)
  4852. fstcw [bp][-2]
  4853. and ax,bx (* ax = new & mask *)
  4854. not bx (* bx = ~mask *)
  4855. fwait (* wait for old CW to be stored *)
  4856. xchg ax,[bp][-2] (* ax = old CW, [bp][-2] = new & mask *)
  4857. and bx,ax (* bx = old CW & ~mask *)
  4858. or [bp][-2],bx (* [bp][-2] =(old CW & ~mask) | (new & mask) *)
  4859. fldcw [bp][-2] (* load new CW *)
  4860. fwait (* wait for CW to load *)
  4861. pop bx (* destoy CW on stack *)
  4862. pop bp (* restore bp *)
  4863. db Ret0@ (* return old CW *)
  4864. (*%E _WINDOWS *)
  4865. (*%T _WINDOWS *)
  4866. (*%T RegParam *)
  4867. push cx
  4868. mov cx,ax (* cx = new *)
  4869. (*%E RegParam *)
  4870. (*%T StkParam *)
  4871. push bp
  4872. mov bp,sp
  4873. mov cx,[bp][2][CodePtrSize] (* cx = new *)
  4874. mov bx,[bp][4][CodePtrSize] (* bx = mask *)
  4875. (*%E StkParam *)
  4876. and cx,bx (* cx = new & mask *)
  4877. not bx (* bx = ~mask *)
  4878. call far __FloatStoreCW (* ax = old CW *)
  4879. and bx,ax (* bx = old CW & ~mask *)
  4880. or bx,cx (* bx = (old CW & ~mask) | (new & mask) *)
  4881. xchg ax,bx (* ax = new CW, bx = old CW *)
  4882. call far __FloatLoadCW
  4883. mov ax,bx (* return old CW *)
  4884. (*%T RegParam *)
  4885. pop cx (* restore cx *)
  4886. db Ret0@ (* return old CW *)
  4887. (*%E RegParam *)
  4888. (*%T StkParam *)
  4889. pop bp (* restore bp *)
  4890. db Ret0@ (* return old CW *)
  4891. (*%E StkParam *)
  4892. (*%E _WINDOWS *)
  4893. (***********************************************************************
  4894. double floor(double num)
  4895. LONGEDOUBLE floorl(LONGDOUBLE num)
  4896. returns num rounded down to the nearest intiger
  4897. Error handling: NONE
  4898. ************************************************************************)
  4899. section
  4900. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4901. (*%F _WINDOWS *)
  4902. extrn @coremath_floor
  4903. (*%E NOT _WINDOWS *)
  4904. (*%T StdFloat *)
  4905. extrn __fac
  4906. (*%E StdFloat *)
  4907. (*%T _WINDOWS *)
  4908. extrn __FloatStoreCW
  4909. extrn __FloatLoadCW
  4910. (*%E _WINDOWS *)
  4911. (*%F StdFloat *)
  4912. public _floor:
  4913. public _floorl:
  4914. push bp
  4915. mov bp,sp
  4916. push ax (* space for old CW *)
  4917. fstcw [bp][-2] (* save old CW *)
  4918. fldcw cs:[@coremath_floor] (* round down,affine,exceptions masked *)
  4919. frndint st(0) (* round down to intiger *)
  4920. fldcw [bp][-2] (* restore old CW *)
  4921. fwait
  4922. mov sp,bp (* destroy old CW on stack *)
  4923. pop bp
  4924. db Ret0@
  4925. (*%E NOT StdFloat *)
  4926. (*%T StdFloat *)
  4927. public _floor:
  4928. push bp
  4929. mov bp,sp
  4930. fld qword st(0),[bp][2][CodePtrSize] (* load double *)
  4931. (*%F _WINDOWS *)
  4932. push ax (* space for old CW *)
  4933. fstcw [bp][-2] (* save old CW *)
  4934. fldcw cs:[@coremath_floor] (* round down,affine,exceptions masked *)
  4935. frndint st(0) (* round down to intiger *)
  4936. fldcw [bp][-2] (* restore old CW *)
  4937. (*%E NOT _WINDOWS *)
  4938. (*%T _WINDOWS *)
  4939. call far __FloatStoreCW
  4940. push ax (* save old cw *)
  4941. mov ax,173FH (* round down,affine,exceptions masked *)
  4942. call far __FloatLoadCW (* load ax into cw *)
  4943. frndint st(0) (* round down to intiger *)
  4944. pop ax (* old cw *)
  4945. call far __FloatLoadCW (* restore old cw *)
  4946. (*%E _WINDOWS *)
  4947. mov ax,__fac (* return result in __fac *)
  4948. (*%T FarPtr *)(*%T SameDS *)
  4949. mov dx,ds
  4950. fstp qword [__fac],st(0)
  4951. (*%E FarPtr *)(*%E SameDS *)
  4952. (*%T NearPtr *)
  4953. fstp qword [__fac],st(0)
  4954. (*%E NearPtr *)
  4955. (*%F SameDS *)
  4956. mov dx,seg __fac
  4957. mov es,dx
  4958. fstp qword es:[__fac],st(0)
  4959. (*%E NOT SameDS *)
  4960. (*%F _WINDOWS *)
  4961. mov sp,bp (* desroy CW on stack *)
  4962. (*%E NOT _WINDOWS *)
  4963. fwait (* wait for return to be stored *)
  4964. pop bp
  4965. (*%T RegParam *)
  4966. db RetX@;dw 8
  4967. (*%E RegParam *)
  4968. (*%T StkParam *)
  4969. db Ret0@
  4970. (*%E StkParam *)
  4971. (*%E StdFloat *)
  4972. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  4973. (****** LONGDOUBLE version. StdFloat only *)
  4974. (*%T StdFloat *)
  4975. public _floorl:
  4976. push bp
  4977. mov bp,sp
  4978. fld tbyte st(0),[bp][2][CodePtrSize] (* load double *)
  4979. (*%F _WINDOWS *)
  4980. push ax (* space for old CW *)
  4981. fstcw [bp][-2] (* save old CW *)
  4982. fldcw cs:[@coremath_floor] (* round down,affine,exceptions masked *)
  4983. frndint st(0) (* round down to intiger *)
  4984. fldcw [bp][-2] (* restore old CW *)
  4985. (*%E _WINDOWS *)
  4986. (*%T _WINDOWS *)
  4987. call far __FloatStoreCW
  4988. push ax (* save old cw *)
  4989. mov ax,173FH (* round down,affine,exceptions masked *)
  4990. call far __FloatLoadCW (* load ax into cw *)
  4991. frndint st(0) (* round down to intiger *)
  4992. pop ax (* old cw *)
  4993. call far __FloatLoadCW (* restore old cw *)
  4994. (*%E _WINDOWS *)
  4995. mov ax,__fac (* return result in __fac *)
  4996. (*%T FarPtr *)(*%T SameDS *)
  4997. mov dx,ds
  4998. fstp tbyte [__fac],st(0)
  4999. (*%E FarPtr *)(*%E SameDS *)
  5000. (*%T NearPtr *)
  5001. fstp tbyte [__fac],st(0)
  5002. (*%E NearPtr *)
  5003. (*%F SameDS *)
  5004. mov dx,seg __fac
  5005. mov es,dx
  5006. fstp tbyte es:[__fac],st(0)
  5007. (*%E NOT SameDS *)
  5008. (*%F _WINDOWS *)
  5009. mov sp,bp (* destroy CW on stack *)
  5010. (*%E NOT _WINDOWS *)
  5011. fwait (* wait for return to be stored *)
  5012. pop bp
  5013. (*%T RegParam *)
  5014. db RetX@;dw 10
  5015. (*%E RegParam *)
  5016. (*%T StkParam *)
  5017. db Ret0@
  5018. (*%E StkParam *)
  5019. (*%E StdFloat *)
  5020. (***********************************************************************
  5021. double ceil( double num )
  5022. LONGEDOUBLE ceill( LONGDOUBLE num)
  5023. returns num rounded up to the nearest intiger
  5024. Error handling: NONE
  5025. ************************************************************************)
  5026. section
  5027. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5028. (*%T StdFloat *)
  5029. extrn __fac
  5030. (*%E StdFloat *)
  5031. (*%F _WINDOWS *)
  5032. extrn @coremath_ceil
  5033. (*%E NOT _WINDOWS *)
  5034. (*%T _WINDOWS *)
  5035. extrn __FloatStoreCW
  5036. extrn __FloatLoadCW
  5037. (*%E _WINDOWS *)
  5038. (*%F StdFloat *)
  5039. public _ceil:
  5040. public _ceill:
  5041. push bp
  5042. mov bp,sp
  5043. push ax (* space for old CW *)
  5044. fstcw [bp][-2] (* save old CW *)
  5045. fldcw cs:[@coremath_ceil] (* round up,affine,exceptions masked *)
  5046. frndint st(0) (* round up to intiger *)
  5047. fldcw [bp][-2] (* restore old CW *)
  5048. fwait
  5049. mov sp,bp (* destroy old CW on stack *)
  5050. pop bp
  5051. db Ret0@
  5052. (*%E NOT StdFloat *)
  5053. (*%T StdFloat *)
  5054. public _ceil:
  5055. push bp
  5056. mov bp,sp
  5057. fld qword st(0),[bp][2][CodePtrSize] (* $1 load double *)
  5058. (*%F _WINDOWS *)
  5059. push ax (* space for old CW *)
  5060. fstcw [bp][-2] (* save old CW *)
  5061. fldcw cs:[@coremath_ceil] (* round up,affine,exceptions masked *)
  5062. frndint st(0) (* round up to intiger *)
  5063. fldcw [bp][-2] (* restore old CW *)
  5064. (*%E _WINDOWS *)
  5065. (*%T _WINDOWS *)
  5066. call far __FloatStoreCW
  5067. push ax (* save old cw *)
  5068. mov ax,1B3FH (* round up,affine,exceptions masked *)
  5069. call far __FloatLoadCW (* load ax into cw *)
  5070. frndint st(0) (* round up to intiger *)
  5071. pop ax (* old cw *)
  5072. call far __FloatLoadCW (* restore old cw *)
  5073. (*%E _WINDOWS *)
  5074. mov ax,__fac (* return result in __fac *)
  5075. (*%T FarPtr *)(*%T SameDS *)
  5076. mov dx,ds
  5077. fstp qword [__fac],st(0)
  5078. (*%E FarPtr *)(*%E SameDS *)
  5079. (*%T NearPtr *)
  5080. fstp qword [__fac],st(0)
  5081. (*%E NearPtr *)
  5082. (*%F SameDS *)
  5083. mov dx,seg __fac
  5084. mov es,dx
  5085. fstp qword es:[__fac],st(0)
  5086. (*%E NOT SameDS *)
  5087. (*%F _WINDOWS *)
  5088. mov sp,bp (* desroy CW on stack *)
  5089. (*%E NOT _WINDOWS *)
  5090. fwait (* wait for return to be stored *)
  5091. pop bp
  5092. (*%T RegParam *)
  5093. db RetX@;dw 8
  5094. (*%E RegParam *)
  5095. (*%T StkParam *)
  5096. db Ret0@
  5097. (*%E StkParam *)
  5098. (*%E StdFloat *)
  5099. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5100. (****** LONGDOUBLE version. StdFloat only *)
  5101. (*%T StdFloat *)
  5102. public _ceill:
  5103. push bp
  5104. mov bp,sp
  5105. fld tbyte st(0),[bp][2][CodePtrSize] (* load double *)
  5106. (*%F _WINDOWS *)
  5107. push ax (* space for old CW *)
  5108. fstcw [bp][-2] (* save old CW *)
  5109. fldcw cs:[@coremath_ceil] (* round up,affine,exceptions masked *)
  5110. frndint st(0) (* round up to intiger *)
  5111. fldcw [bp][-2] (* restore old CW *)
  5112. (*%E NOT _WINDOWS *)
  5113. (*%T _WINDOWS *)
  5114. call far __FloatStoreCW
  5115. push ax (* save old cw *)
  5116. mov ax,1B3FH (* round up,affine,exceptions masked *)
  5117. call far __FloatLoadCW (* load ax into cw *)
  5118. frndint st(0) (* round up to intiger *)
  5119. pop ax (* old cw *)
  5120. call far __FloatLoadCW (* restore old cw *)
  5121. (*%E _WINDOWS *)
  5122. mov ax,__fac (* return result in __fac *)
  5123. (*%T FarPtr *)(*%T SameDS *)
  5124. mov dx,ds
  5125. fstp tbyte [__fac],st(0)
  5126. (*%E FarPtr *)(*%E SameDS *)
  5127. (*%T NearPtr *)
  5128. fstp tbyte [__fac],st(0)
  5129. (*%E NearPtr *)
  5130. (*%F SameDS *)
  5131. mov dx,seg __fac
  5132. mov es,dx
  5133. fstp tbyte es:[__fac],st(0)
  5134. (*%E NOT SameDS *)
  5135. (*%F _WINDOWS *)
  5136. mov sp,bp (* destroy CW on stack *)
  5137. (*%E NOT _WINDOWS *)
  5138. fwait (* wait for return to be stored *)
  5139. pop bp
  5140. (*%T RegParam *)
  5141. db RetX@;dw 10
  5142. (*%E RegParam *)
  5143. (*%T StkParam *)
  5144. db Ret0@
  5145. (*%E StkParam *)
  5146. (*%E StdFloat *)
  5147. (*************************************************************************
  5148. double fabs(double num)
  5149. LONGDOUBLE fabsl(LONGDOUBLE num)
  5150. Return: the absolute value of num
  5151. Error Handling: no error is possible
  5152. **************************************************************************)
  5153. section
  5154. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5155. (*%T StdFloat *)
  5156. extrn __fac
  5157. (*%E StdFloat *)
  5158. (*%F StdFloat *)(*%T _DLLOVL *)
  5159. public _fabsl:
  5160. public _fabs:
  5161. push bp
  5162. mov bp,sp
  5163. fabs st(0)
  5164. pop bp
  5165. db Ret0@
  5166. (*%E NOT StdFloat *)(*%E _DLLOVL *)
  5167. (*%F StdFloat *)(*%F _DLLOVL *)
  5168. public _fabsl:
  5169. public _fabs:
  5170. fabs st(0)
  5171. db Ret0@
  5172. (*%E NOT StdFloat *)(*%E NOT _DLLOVL *)
  5173. (*%T StdFloat *)
  5174. public _fabsl:
  5175. push bp
  5176. mov bp,sp
  5177. (*%T SameDS *)
  5178. (*%T FarPtr *)
  5179. mov dx,ds (* return seg __fac *)
  5180. (*%E FarPtr *)
  5181. mov ax,[bp][CodePtrSize][2] (* transfer tbyte to __fac *)
  5182. mov [__fac],ax
  5183. mov ax,[bp][CodePtrSize][4]
  5184. mov [__fac][2],ax
  5185. mov ax,[bp][CodePtrSize][6]
  5186. mov [__fac][4],ax
  5187. mov ax,[bp][CodePtrSize][8]
  5188. mov [__fac][6],ax
  5189. mov ax,[bp][CodePtrSize][10]
  5190. and ax,7FFFH (* remove sign from exponent *)
  5191. mov [__fac][8],ax
  5192. (*%E SameDS *)
  5193. (*%F SameDS *)
  5194. mov dx,seg __fac (* return seg __fac *)
  5195. mov es,dx
  5196. mov ax,[bp][CodePtrSize][2] (* transfer tbyte to __fac *)
  5197. mov es:[__fac],ax
  5198. mov ax,[bp][CodePtrSize][4]
  5199. mov es:[__fac][2],ax
  5200. mov ax,[bp][CodePtrSize][6]
  5201. mov es:[__fac][4],ax
  5202. mov ax,[bp][CodePtrSize][8]
  5203. mov es:[__fac][6],ax
  5204. mov ax,[bp][CodePtrSize][10]
  5205. and ax,7FFFH (* remove sign from exponent *)
  5206. mov es:[__fac][8],ax
  5207. (*%E SameDS *)
  5208. mov ax,__fac (* return __fac *)
  5209. pop bp (* restore bp *)
  5210. (*%T RegParam *)
  5211. db RetX@;dw 10
  5212. (*%E RegParam *)
  5213. (*%T StkParam *)
  5214. db Ret0@
  5215. (*%E StkParam *)
  5216. (*%E StdFloat *)
  5217. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5218. (*%T StdFloat *)
  5219. public _fabs:
  5220. push bp
  5221. mov bp,sp
  5222. (*%T SameDS *)
  5223. (*%T FarPtr *)
  5224. mov dx,ds (* return seg __fac *)
  5225. (*%E FarPtr *)
  5226. mov ax,[bp][CodePtrSize][2] (* transfer qword to __fac *)
  5227. mov [__fac],ax
  5228. mov ax,[bp][CodePtrSize][4]
  5229. mov [__fac][2],ax
  5230. mov ax,[bp][CodePtrSize][6]
  5231. mov [__fac][4],ax
  5232. mov ax,[bp][CodePtrSize][8]
  5233. and ax,7FFFH (* remove sign from exponent *)
  5234. mov [__fac][6],ax
  5235. (*%E SameDS *)
  5236. (*%F SameDS *)
  5237. mov dx,seg __fac (* return seg __fac *)
  5238. mov es,dx
  5239. mov ax,[bp][CodePtrSize][2] (* transfer qword to __fac *)
  5240. mov es:[__fac],ax
  5241. mov ax,[bp][CodePtrSize][4]
  5242. mov es:[__fac][2],ax
  5243. mov ax,[bp][CodePtrSize][6]
  5244. mov es:[__fac][4],ax
  5245. mov ax,[bp][CodePtrSize][8]
  5246. and ax,7FFFH (* remove sign from exponent *)
  5247. mov es:[__fac][6],ax
  5248. (*%E SameDS *)
  5249. mov ax,__fac (* return __fac *)
  5250. pop bp (* restore bp *)
  5251. (*%T RegParam *)
  5252. db RetX@;dw 8
  5253. (*%E RegParam *)
  5254. (*%T StkParam *)
  5255. db Ret0@
  5256. (*%E StkParam *)
  5257. (*%E StdFloat *)
  5258. (*************************************************************************
  5259. double _fmod(double X,double Y)
  5260. LONGDOUBLE _fmodl(LONGDOUBLE X,LONGDOUBLE Y)
  5261. Return: X % Y or 0 if Y is 0
  5262. Error: no error handling
  5263. **************************************************************************)
  5264. section
  5265. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5266. (*%T RegParam *)
  5267. X = 2+CodePtrSize+8
  5268. Y = 2+CodePtrSize
  5269. LX = 2+CodePtrSize+10
  5270. LY = 2+CodePtrSize
  5271. (*%E RegParam *)
  5272. (*%T StkParam *)
  5273. X = 2+CodePtrSize
  5274. Y = 2+CodePtrSize+8
  5275. LX = 2+CodePtrSize
  5276. LY = 2+CodePtrSize+10
  5277. (*%E StkParam *)
  5278. (*%T StdFloat *)
  5279. extrn __fac
  5280. (*%E StdFloat *)
  5281. (*%F StdFloat *)
  5282. public _fmod:
  5283. public _fmodl:
  5284. push bp
  5285. mov bp, sp
  5286. fld st(0), st(6) (* $1 st(0) = Y,st(1) = X *)
  5287. push ax (* space for SW *)
  5288. ftst st(0) (* Y=0 ? *)
  5289. fstsw [bp][-2]
  5290. fwait
  5291. test byte [bp][-1], 40H
  5292. jnz Done (* Y=0, so return 0 *)
  5293. fxch st(0), st(1) (* st(1) = Y,st(0) = X *)
  5294. More: fprem st(0) (* get partial remainder *)
  5295. fstsw [bp][-2]
  5296. fwait
  5297. test byte [bp][-1], 4 (* C2 = 0 if reduction is complete *)
  5298. jnz More (* reduction is incomplete *)
  5299. Done: fstp st(1), st(0) (* $0 *)
  5300. mov sp, bp (* destroy space for SW *)
  5301. pop bp
  5302. db Ret0@
  5303. (*%E NOT StdFloat *)
  5304. (*%T StdFloat *)
  5305. public _fmod:
  5306. push bp
  5307. mov bp,sp
  5308. fld qword st(0),[bp][Y] (* $1 st(0) = Y *)
  5309. push ax (* space for SW *)
  5310. ftst st(0)
  5311. fstsw [bp][-2]
  5312. fwait
  5313. test byte [bp][-1], 40H
  5314. jnz Done (* Y=0, so return 0 *)
  5315. fld qword st(0),[bp][X] (* st(0) = X,st(1) = Y *)
  5316. More: fprem st(0) (* get partial remainder *)
  5317. fstsw [bp][-2]
  5318. fwait
  5319. test byte [bp][-1], 4 (* C2 = 0 if reduction is complete *)
  5320. jnz More (* reduction is incomplete *)
  5321. fstp st(1),st(0) (* $1 *)
  5322. Done: pop ax (* destroy space for CW *)
  5323. (*%T NearPtr *)
  5324. mov ax,__fac (* return in __fac *)
  5325. fstp qword [__fac],st(0)
  5326. (*%E NearPtr *)
  5327. (*%T FarPtr *)(*%T SameDS *)
  5328. mov ax,__fac (* return in __fac *)
  5329. mov dx,ds
  5330. fstp qword [__fac],st(0)
  5331. (*%E FarPtr *)(*%E SameDS *)
  5332. (*%T FarPtr *)(*%F SameDS *)
  5333. mov ax,__fac (* return in __fac *)
  5334. mov dx,seg __fac
  5335. mov es,dx
  5336. fstp qword es:[__fac],st(0)
  5337. (*%E FarPtr *)(*%E NOT SameDS *)
  5338. (*%T RegParam *)
  5339. fwait (* wait for return to store *)
  5340. pop bp (* restore bp *)
  5341. db RetX@;dw 16 (* return,with cleanup *)
  5342. (*%E RegParam *)
  5343. (*%T StkParam *)
  5344. fwait (* wait for return to store *)
  5345. pop bp (* restore bp *)
  5346. db Ret0@ (* return,without cleanup *)
  5347. (*%E StkParam *)
  5348. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5349. public _fmodl:
  5350. push bp
  5351. mov bp,sp
  5352. fld tbyte st(0),[bp][LY] (* $1 st(0) = Y *)
  5353. push ax (* space for SW *)
  5354. ftst st(0)
  5355. fstsw [bp][-2]
  5356. fwait
  5357. test byte [bp][-1], 40H
  5358. jnz LDone (* Y=0, so return 0 *)
  5359. fld tbyte st(0),[bp][LX] (* st(0) = X,st(1) = Y *)
  5360. LMore: fprem st(0) (* get partial remainder *)
  5361. fstsw [bp][-2]
  5362. fwait
  5363. test byte [bp][-1], 4 (* C2 = 0 if reduction is complete *)
  5364. jnz LMore (* reduction is incomplete *)
  5365. fstp st(1),st(0) (* $1 *)
  5366. LDone: pop ax (* destroy space for CW *)
  5367. (*%T NearPtr *)
  5368. mov ax,__fac (* return in __fac *)
  5369. fstp tbyte [__fac],st(0)
  5370. (*%E NearPtr *)
  5371. (*%T FarPtr *)(*%T SameDS *)
  5372. mov ax,__fac (* return in __fac *)
  5373. mov dx,ds
  5374. fstp tbyte [__fac],st(0)
  5375. (*%E FarPtr *)(*%E SameDS *)
  5376. (*%T FarPtr *)(*%F SameDS *)
  5377. mov ax,__fac (* return in __fac *)
  5378. mov dx,seg __fac
  5379. mov es,dx
  5380. fstp tbyte es:[__fac],st(0)
  5381. (*%E FarPtr *)(*%E NOT SameDS *)
  5382. (*%T RegParam *)
  5383. fwait (* wait for return to store *)
  5384. pop bp (* restore bp *)
  5385. db RetX@;dw 20 (* return,with cleanup *)
  5386. (*%E RegParam *)
  5387. (*%T StkParam *)
  5388. fwait (* wait for return to store *)
  5389. pop bp (* restore bp *)
  5390. db Ret0@ (* return,without cleanup *)
  5391. (*%E StkParam *)
  5392. (*%E StdFloat *)
  5393. (************************************************************************
  5394. *************************************************************************)
  5395. section
  5396. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5397. (*%T StdFloat *)
  5398. extrn __fac
  5399. (*%E StdFloat *)
  5400. (*%F StdFloat *)
  5401. extrn @coremath_int_two
  5402. public _frexp :
  5403. (*%E NOT StdFloat *)
  5404. public _frexpl :
  5405. push bp
  5406. mov bp, sp
  5407. (*%T StdFloat *)
  5408. fld tbyte st(0),[bp][2][CodePtrSize] (* $1 val *)
  5409. (*%E StdFloat *)
  5410. (*%T FarPtr *)(*%T RegParam *)
  5411. mov es, bx (* es:[bx] = *exp *)
  5412. mov bx, ax
  5413. (*%E FarPtr *)(*%E RegParam *)
  5414. (*%T NearPtr *)(*%T RegParam *)
  5415. xchg bx, ax (* ds:[bx] = *exp *)
  5416. (*%E NearPtr*)(*%E RegParam *)
  5417. (*%T FarPtr *)(*%T StkParam *)
  5418. les bx,[bp][2][CodePtrSize][10] (* es:[bx] = *exp *)
  5419. (*%E FarPtr *)(*%E StkParam *)
  5420. (*%T FarPtr *)(*%T StkParam *)
  5421. mov bx,[bp][2][CodePtrSize][10] (* ds:[bx] = *exp *)
  5422. (*%E FarPtr *)(*%E StkParam *)
  5423. ftst st(0) (* cmp val,0 *)
  5424. push ax (* make room for CW *)
  5425. fstsw [bp][-2] (* store CW *)
  5426. (*%T FarPtr *) mov word es:[bx],0 (*%E assume 0 *)
  5427. (*%T NearPtr *) mov word [bx],0 (*%E assume 0 *)
  5428. fwait
  5429. pop ax
  5430. sahf (* is val 0 ? *)
  5431. jz Done (* yes *)
  5432. fxtract st(0) (* st(1) = val's exponent,st(0) = mantissa *)
  5433. (*%T FarPtr *)(*%F StdFloat *)
  5434. fxch st(0), st(1)
  5435. fistp word es:[bx], st(0) (* store val's exponent *)
  5436. fidiv word st(0), cs:[@coremath_int_two ] (* divide mantisa by 2 *)
  5437. inc word es:[bx] (* exponent plus 1 *)
  5438. Done: pop bp (* restore bp *)
  5439. db Ret0@
  5440. (*%E FarPtr *)(*%E NOT StdFloat *)
  5441. (*%T NearPtr *)(*%F StdFloat *)
  5442. fxch st(0), st(1)
  5443. fistp word [bx], st(0) (* store val's exponent *)
  5444. fidiv word st(0), cs:[@coremath_int_two ] (* divide mantisa by 2 *)
  5445. inc word [bx] (* exponent plus 1 *)
  5446. Done: xchg bx,ax (* restore bx *)
  5447. pop bp (* restore bp *)
  5448. db Ret0@
  5449. (*%E NearPtr *)(*%E NOT StdFloat *)
  5450. (*%T NearPtr *)(*%T StdFloat *)
  5451. Done: fstp tbyte [__fac],st(0) (* store mantisa in __fac *)
  5452. jz Done2 (* result was 0 *)
  5453. dec word [__fac][8] (* dec exponent of mantissa *)
  5454. fistp word es:[bx], st(0) (* store val's exponent *)
  5455. fwait
  5456. inc word es:[bx] (* exponent plus 1 *)
  5457. Done2: pop bp (* restore bp *)
  5458. (*%T RegParam *) xchg bx,ax (*%E restore bx *)
  5459. mov ax,__fac (* return offset __fac *)
  5460. (*%T RegParam *) db RetX@; dw 10 (*%E clean up stack & return *)
  5461. (*%T StkParam *) db Ret0@ (*%E Return *)
  5462. (*%E NearPtr *)(*%E StdFloat *)
  5463. (*%T FarPtr *)(*%T SameDS *)(*%T StdFloat *)
  5464. Done: mov ax,__fac (* return offset __fac *)
  5465. mov dx,ds (* return seg __fac *)
  5466. fstp tbyte [__fac],st(0) (* store mantisa in __fac *)
  5467. jz Done2 (* result was 0 *)
  5468. dec word [__fac][8] (* dec exponent of mantissa *)
  5469. fistp word es:[bx], st(0) (* store val's exponent *)
  5470. fwait
  5471. inc word es:[bx] (* exponent plus 1 *)
  5472. Done2: pop bp (* restore bp *)
  5473. (*%T RegParam *) db RetX@; dw 10 (*%E clean up stack & return *)
  5474. (*%T StkParam *) db Ret0@ (*%E Return *)
  5475. (*%E FarPtr *)(*%E SameDS *)(*%E StdFloat *)
  5476. (*%T FarPtr *)(*%F SameDS *)(*%T StdFloat *)
  5477. Done: push ds (* save ds *)
  5478. mov ax,__fac (* return offset __fac *)
  5479. mov dx,seg __fac (* return seg __fac *)
  5480. mov ds,dx
  5481. fstp tbyte [__fac],st(0) (* store mantisa in __fac *)
  5482. jz Done2 (* result was 0 *)
  5483. dec word [__fac][8] (* dec exponent of mantissa *)
  5484. fistp word es:[bx], st(0) (* store val's exponent *)
  5485. fwait
  5486. inc word es:[bx] (* exponent plus 1 *)
  5487. Done2: pop ds (* restore ds *)
  5488. pop bp (* restore bp *)
  5489. (*%T RegParam *) db RetX@; dw 10 (*%E clean up stack & return *)
  5490. (*%T StkParam *) db Ret0@ (*%E Return *)
  5491. (*%E FarPtr *)(*%E NOT SameDS *)(*%E StdFloat *)
  5492. segment (*%F SameDS*)MATH_TEXT(*%E*)(*%T SameDS*)_TEXT(*%E*)(CODE,28H)
  5493. (*%T StdFloat *)
  5494. public _frexp :
  5495. push bp
  5496. mov bp, sp
  5497. fld qword st(0),[bp][2][CodePtrSize] (* $1 val *)
  5498. (*%T FarPtr *)(*%T RegParam *)
  5499. mov es, bx (* es:[bx] = *exp *)
  5500. mov bx, ax
  5501. (*%E FarPtr *)(*%E RegParam *)
  5502. (*%T NearPtr *)(*%T RegParam *)
  5503. xchg bx, ax (* ds:[bx] = *exp *)
  5504. (*%E NearPtr*)(*%E RegParam *)
  5505. (*%T FarPtr *)(*%T StkParam *)
  5506. les bx,[bp][2][CodePtrSize][8] (* es:[bx] = *exp *)
  5507. (*%E FarPtr *)(*%E StkParam *)
  5508. (*%T NearPtr *)(*%T StkParam *)
  5509. mov bx,[bp][2][CodePtrSize][8] (* ds:[bx] = *exp *)
  5510. (*%E NearPtr *)(*%E StkParam *)
  5511. ftst st(0) (* cmp val,0 *)
  5512. push ax (* make room for CW *)
  5513. fstsw [bp][-2] (* store CW *)
  5514. (*%T FarPtr *) mov word es:[bx],0 (*%E assume 0 *)
  5515. (*%T NearPtr *) mov word [bx],0 (*%E assume 0 *)
  5516. fwait
  5517. pop ax
  5518. sahf (* is val 0 ? *)
  5519. jz DoneL (* yes *)
  5520. fxtract st(0) (* st(1) = val's exponent,st(0) = mantissa *)
  5521. (*%T NearPtr *)
  5522. DoneL: fstp qword [__fac],st(0) (* store mantisa in __fac *)
  5523. jz Done2L (* result was 0 *)
  5524. sub word [__fac][6],10H (* dec exponent of mantissa *)
  5525. fistp word es:[bx], st(0) (* store val's exponent *)
  5526. fwait
  5527. inc word es:[bx] (* exponent plus 1 *)
  5528. Done2L: pop bp (* restore bp *)
  5529. (*%T RegParam *) xchg bx,ax (*%E restore bx *)
  5530. mov ax,__fac (* return offset __fac *)
  5531. (*%T RegParam *) db RetX@;dw 8 (*%E clean up stack & return *)
  5532. (*%T StkParam *) db Ret0@ (*%E Return *)
  5533. (*%E NearPtr *)
  5534. (*%T FarPtr *)(*%T SameDS *)
  5535. DoneL: mov ax,__fac (* return offset __fac *)
  5536. mov dx,ds (* return seg __fac *)
  5537. fstp qword [__fac],st(0) (* store mantisa in __fac *)
  5538. jz Done2L (* result was 0 *)
  5539. sub word [__fac][6],10H (* dec exponent of mantissa *)
  5540. fistp word es:[bx], st(0) (* store val's exponent *)
  5541. fwait
  5542. inc word es:[bx] (* exponent plus 1 *)
  5543. Done2L: pop bp (* restore bp *)
  5544. (*%T RegParam *) db RetX@; dw 8 (*%E clean up stack & return *)
  5545. (*%T StkParam *) db Ret0@ (*%E Return *)
  5546. (*%E FarPtr *)(*%E SameDS *)
  5547. (*%T FarPtr *)(*%F SameDS *)
  5548. DoneL: push ds (* save ds *)
  5549. mov ax,__fac (* return offset __fac *)
  5550. mov dx,seg __fac (* return seg __fac *)
  5551. mov ds,dx
  5552. fstp qword [__fac],st(0) (* store mantisa in __fac *)
  5553. jz Done2L (* result was 0 *)
  5554. sub word [__fac][6],10H (* dec exponent of mantissa *)
  5555. fistp word es:[bx], st(0) (* store val's exponent *)
  5556. fwait
  5557. inc word es:[bx] (* exponent plus 1 *)
  5558. Done2L: pop ds (* restore ds *)
  5559. pop bp (* restore bp *)
  5560. (*%T RegParam *) db RetX@; dw 8 (*%E clean up stack & return *)
  5561. (*%T StkParam *) db Ret0@ (*%E Return *)
  5562. (*%E FarPtr *)(*%E NOT SameDS *)
  5563. (*%E StdFloat *)
  5564. end