COREMEM.A 136 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881
  1. (* Release 3.10 *)
  2. (*-------------------------------------------------------------------------*
  3. * *
  4. * COREMEM.A - common memory management (real mode) *
  5. * *
  6. * COPYRIGHT (C) 1989..1992 Clarion Software Corporation. *
  7. * All Rights Reserved *
  8. * *
  9. *--------------------------------------------------------------------------*)
  10. include "corelib.inc"
  11. include "standard.inc"
  12. module CoreMem
  13. (************************************************************************)
  14. segment _BSS(BSS, 28H)
  15. public __memtype : org 2 (* OS2 memory allocation type *)
  16. public __fheaptop : org 2 (* top of far heap *)
  17. segment _DATA(DATA, 28H)
  18. public __firstfree : dw -1 (* first free block *)
  19. segment _BSS(BSS, 28H)
  20. public __fheapsem : org 4 (* process control semaphore *)
  21. segment _BSS(BSS, 28H)
  22. public __nheapstart : org 2 (* beginning of near heap *)
  23. public __nheaptop : org 2 (* end of near heap *)
  24. section
  25. (***************************************************************************)
  26. (*%F _DLL *)
  27. (* ------------------------------------------------------------------------
  28. PROCEDURE - calloc, _ncalloc.
  29. PRECONDITIONS - near heap initialised.
  30. POSTCONDITIONS - If successful, block of size*num bytes allocated and
  31. cleared to zero.
  32. If size = 0 or heap full, errno set to ENOMEM.
  33. IN PARAMETERS - Number of blocks requested(size_t),
  34. Size of block requested(size_t)
  35. OUT PARAMETERS - If successful Near pointer to allocated block.
  36. On error NULL pointer.
  37. CALLING CONVENTION - Standard.
  38. NOTES - Jumps to shared code in malloc.
  39. VERSION - _OS2 and MSDOS.
  40. ------------------------------------------------------------------------ *)
  41. segment _TEXT(CODE,28H)
  42. segment _DATA(DATA,28H)
  43. nearFreeSize = 0
  44. nearnextBlock = 2
  45. extrn __nmallocError
  46. extrn __ncallocEntry
  47. extrn __nheaptop
  48. extrn __nfirstfree
  49. extrn __farstack
  50. extrn _errno
  51. select _TEXT
  52. public __ncalloc :
  53. (*%T NearPtr *)
  54. public _calloc :
  55. (*%E *)
  56. num = frame
  57. size = 2+frame
  58. currentblock = -2
  59. newsize = -4
  60. prevblock = -6
  61. flag = -8
  62. request = -10
  63. dgroup = -12
  64. locals = 12
  65. push bp
  66. mov bp, sp
  67. sub sp, locals
  68. push bx
  69. push cx
  70. push dx
  71. push di
  72. push si
  73. (*%F SameDS *)
  74. push ds
  75. mov cx, _DATA
  76. mov ds, cx
  77. (*%E *)
  78. (*%F RegParam *)
  79. mov ax, [bp][size]
  80. (*%E *)
  81. or ax, ax (* Error if size = 0 *)
  82. je near __nmallocError
  83. (*%F RegParam *)
  84. mov dx, [bp][num]
  85. (*%E *)
  86. (*%T RegParam *)
  87. mov dx, bx
  88. (*%E *)
  89. or dx, dx
  90. je near __nmallocError
  91. mul dx
  92. or dx, dx
  93. jne near __nmallocError (* over flow *)
  94. mov byte [bp][flag], 1
  95. jmp __ncallocEntry
  96. (*%E *)
  97. section
  98. (*********************************************************************)
  99. (*%F _DLL *)
  100. (* ------------------------------------------------------------------------
  101. PROCEDURE - malloc, _nmalloc.
  102. PRECONDITIONS - near heap initialised.
  103. POSTCONDITIONS - If successful, block of size bytes allocated and
  104. cleared to zero.
  105. If size = 0 or heap full, errno set to ENOMEM.
  106. IN PARAMETERS - Size of block requested(size_t)
  107. OUT PARAMETERS - If successful Near pointer to allocated block.
  108. On error NULL pointer.
  109. CALLING CONVENTION - Standard.
  110. NOTES - .
  111. VERSION - _OS2 and MSDOS.
  112. ------------------------------------------------------------------------ *)
  113. segment _TEXT(CODE,28H)
  114. segment _DATA(DATA,28H)
  115. nearFreeSize = 0
  116. nearnextBlock = 2
  117. extrn __nheaptop
  118. extrn __nfirstfree
  119. extrn __farstack
  120. extrn _errno
  121. select _TEXT
  122. num = frame
  123. size = 2+frame
  124. currentblock = -2
  125. newsize = -4
  126. prevblock = -6
  127. flag = -8
  128. request = -10
  129. dgroup = -12
  130. locals = 12
  131. public __nmalloc :
  132. (*%T NearPtr *)
  133. public _malloc :
  134. (*%E *)
  135. size = frame
  136. push bp
  137. mov bp, sp
  138. sub sp, locals
  139. push bx
  140. push cx
  141. push dx
  142. push di
  143. push si
  144. (*%F SameDS *)
  145. push ds
  146. mov cx, _DATA
  147. mov ds, cx
  148. (*%E *)
  149. (*%F RegParam *)
  150. mov ax, [bp][size]
  151. (*%E *)
  152. or ax, ax
  153. je near __nmallocError (* return NULL if size = 0 *)
  154. mov byte [bp][flag], 0
  155. public __ncallocEntry :
  156. test ax, 1
  157. jz sizeEven
  158. inc ax
  159. or ax, ax
  160. jz near __nmallocError
  161. sizeEven:
  162. add ax, 2 (* block + header *)
  163. jc near __nmallocError
  164. mov [bp][request], ax
  165. mov di, [__nfirstfree]
  166. or di, di
  167. jz mallocFull
  168. cmp di, -1
  169. je near __nmallocError
  170. heapSearch:
  171. mov word [bp][prevblock], 0
  172. heapLoop: (* search for big enough block *)
  173. cmp ax, [di][nearFreeSize]
  174. jbe blockFound (* found a free block big enough *)
  175. mov bx, [di][nearnextBlock]
  176. or bx, bx
  177. je atHeapTop (* last free block *)
  178. mov [bp][prevblock], di
  179. mov di, bx
  180. jmp heapLoop (* try next block *)
  181. mallocFull: (* no free blocks *)
  182. atHeapTop: (* last block too small *)
  183. jmp __nmallocError
  184. blockFound: (* di is current block header *)
  185. mov bx, di
  186. mov cx, [di][nearnextBlock] (* spliced into the list *)
  187. cmp ax, [di][nearFreeSize] (* is block an exact fit ? *)
  188. je exactFit
  189. mov dx, [di][nearFreeSize]
  190. sub dx, 4
  191. cmp dx, ax
  192. jae bkEnough
  193. mov ax, [di][nearFreeSize]
  194. mov [bp][request], ax
  195. jmp exactFit
  196. bkEnough:
  197. add dx, 4
  198. mov [di][nearFreeSize], ax (* size of allocated block *)
  199. sub dx, ax (* size of new block *)
  200. add ax, bx (* offset of new free block *)
  201. mov di, ax
  202. mov [di][nearFreeSize], dx
  203. mov [di][nearnextBlock], cx
  204. hsSetPrevious:
  205. mov cx, [bp][prevblock]
  206. jcxz hsFirst
  207. mov di, cx
  208. mov [di][nearnextBlock], ax (* adjust previous block *)
  209. jmp hsDone
  210. hsFirst:
  211. mov [__nfirstfree], ax
  212. hsDone:
  213. mov ax, bx
  214. add ax, 2
  215. jmp mallocDone
  216. exactFit: (* special case - an exact fit *)
  217. mov ax, cx
  218. jmp hsSetPrevious
  219. public __nmallocError : (* arrive here to return NULL *)
  220. mov word [_errno], ENOMEM
  221. sub ax, ax
  222. jmp mallocExit
  223. mallocDone:
  224. cmp byte [bp][flag], 0
  225. jz noFill
  226. push ax
  227. mov dx, ds
  228. mov es, dx
  229. mov di, ax
  230. sub ax, ax
  231. mov cx, [bp][request]
  232. shr cx, 1
  233. dec cx
  234. rep ; stosw
  235. pop ax
  236. noFill:
  237. mallocExit:
  238. (*%F SameDS *)
  239. pop ds
  240. (*%E *)
  241. pop si
  242. pop di
  243. pop dx
  244. pop cx
  245. pop bx
  246. mov sp, bp
  247. pop bp
  248. (*%F NearCall *)
  249. ret far 0
  250. (*%E *)
  251. (*%T NearCall *)
  252. ret 0
  253. (*%E *)
  254. (* _malloc ENDP *)
  255. (*%E *)
  256. section
  257. (***************************************************************************)
  258. (*%F _DLL *)
  259. (* ------------------------------------------------------------------------
  260. PROCEDURE - coreleft, memavl, nearcoreleft.
  261. PRECONDITIONS - None.
  262. POSTCONDITIONS - None.
  263. IN PARAMETERS - None.
  264. OUT PARAMETERS - Returns number of bytes unallocated in near heap(int).
  265. CALLING CONVENTION - Standard.
  266. NOTES - Causes near heap to be initalised.
  267. VERSION - _OS2 and MSDOS (Not DLL's).
  268. ------------------------------------------------------------------------ *)
  269. segment _TEXT(CODE,28H)
  270. segment _DATA(DATA,28H)
  271. nearFreeSize = 0
  272. nearnextBlock = 2
  273. extrn __nfirstfree
  274. select _TEXT
  275. (*%T NearPtr *)
  276. public _coreleft :
  277. public __memavl :
  278. (*%E *)
  279. public _nearcoreleft :
  280. push bx
  281. push dx
  282. (*%F SameDS *)
  283. push ds
  284. mov ax, _DATA
  285. mov ds, ax
  286. (*%E *)
  287. sub ax, ax
  288. mov bx, [__nfirstfree]
  289. cmp bx, -1
  290. je leftEnd
  291. leftLoop:
  292. or bx, bx
  293. jz leftEnd
  294. add ax, [bx][nearFreeSize]
  295. mov bx, [bx][nearnextBlock]
  296. jmp leftLoop
  297. leftEnd:
  298. and ax, 0FFFEH
  299. sub ax, 2
  300. jnc leftOK
  301. sub ax, ax
  302. leftOK:
  303. (*%F SameDS *)
  304. pop ds
  305. (*%E *)
  306. pop dx
  307. pop bx
  308. (*%F NearCall *)
  309. ret far 0
  310. (*%E *)
  311. (*%T NearCall *)
  312. ret 0
  313. (*%E *)
  314. (*%E *)
  315. section
  316. (***************************************************************************)
  317. (*%F _DLL *)
  318. (* ------------------------------------------------------------------------
  319. PROCEDURE - _nfree, free.
  320. PRECONDITIONS - Near heap initialised.
  321. POSTCONDITIONS - block merged into free list.
  322. IN PARAMETERS - near pointer to block allocated from near heap.
  323. OUT PARAMETERS - None.
  324. CALLING CONVENTION - Standard.
  325. NOTES - Always merges neighbouring free blocks.
  326. VERSION - _OS2 and MSDOS.
  327. ------------------------------------------------------------------------ *)
  328. segment _TEXT(CODE,28H)
  329. segment _DATA(DATA,28H)
  330. nearFreeSize = 0
  331. nearnextBlock = 2
  332. extrn __nheapstart
  333. extrn __nheaptop
  334. extrn __nfirstfree
  335. extrn __farstack
  336. select _TEXT
  337. buffer = frame
  338. currentblock = -2
  339. locals = 2
  340. public __nfree :
  341. (*%T NearPtr *)
  342. public _free :
  343. (*%E *)
  344. push bp
  345. mov bp, sp
  346. sub sp, locals
  347. (*%F RegParam *)
  348. push ax
  349. (*%E *)
  350. push bx
  351. push cx
  352. push dx
  353. push di
  354. push si
  355. (*%F SameDS *)
  356. push ds
  357. mov cx, _DATA
  358. mov ds, cx
  359. (*%E *)
  360. (*%F RegParam *)
  361. mov dx, [bp][buffer] (* normalise and validate pointer *)
  362. (*%E *)
  363. (*%T RegParam *)
  364. mov dx, ax
  365. (*%E *)
  366. sub dx, 2
  367. cmp dx, [__nheapstart]
  368. jb freeError
  369. cmp dx, [__nheaptop]
  370. jae freeError
  371. inHeap:
  372. mov di, [__nfirstfree]
  373. or di, di
  374. jz freeFull (* heap is full *)
  375. sub ax, ax
  376. freeLoop:
  377. cmp di, dx (* are we past block ? *)
  378. jae freeFound
  379. mov ax, di (* save lower block *)
  380. mov di, [di][nearnextBlock]
  381. or di, di
  382. jnz freeLoop
  383. jmp freeFound2
  384. freeFull: (* special case *)
  385. mov [__nfirstfree], dx (* a new first free *)
  386. mov di, dx
  387. mov word [di][nearnextBlock], 0
  388. jmp freeNoMerge
  389. freeFound: (* ax is lower block *)
  390. je freeError (* block is already free *)
  391. freeFound2:
  392. or ax, ax
  393. jne notFirst
  394. mov cx, [__nfirstfree]
  395. mov [__nfirstfree], dx (* set a new first free block *)
  396. mov di, dx
  397. mov [di][nearnextBlock], cx
  398. jmp freeNoLower
  399. notFirst:
  400. mov di, ax
  401. mov cx, [di][nearnextBlock] (* splice free block into list *)
  402. mov [di][nearnextBlock], dx
  403. mov di, dx
  404. mov [di][nearnextBlock], cx (* ax still lower block *)
  405. mov di, ax
  406. add ax, [di][nearFreeSize]
  407. cmp ax, dx (* is prev free contiginous *)
  408. jne freeNoLower
  409. call __nheap_merge (* yes - merge *)
  410. jmp freeLowDone
  411. freeNoLower:
  412. mov di, dx
  413. freeLowDone:
  414. cmp word [di][nearnextBlock], 0 (* is there a lower block *)
  415. je freeNoMerge
  416. mov ax, di
  417. add ax, [di][nearFreeSize]
  418. cmp ax, [di][nearnextBlock] (* is next free contiginous *)
  419. jne freeNoMerge
  420. call __nheap_merge (* yes - merge *)
  421. freeNoMerge: (* are we in the last block ? *)
  422. freeDone:
  423. freeError:
  424. (*%F SameDS *)
  425. pop ds
  426. (*%E *)
  427. pop si
  428. pop di
  429. pop dx
  430. pop cx
  431. pop bx
  432. (*%F RegParam *)
  433. pop ax
  434. (*%E *)
  435. mov sp, bp
  436. pop bp
  437. (*%F NearCall *)
  438. ret far 0
  439. (*%E *)
  440. (*%T NearCall *)
  441. ret 0
  442. (*%E *)
  443. public __nheap_merge :
  444. mov si, [di][nearnextBlock]
  445. mov cx, [si][nearnextBlock]
  446. mov ax, [si][nearFreeSize]
  447. add [di][nearFreeSize], ax
  448. mov [di][nearnextBlock], cx
  449. ret 0
  450. (*%E *)
  451. section
  452. (***************************************************************************)
  453. (*%F _DLL *)
  454. (*%F _DLLOVL *)
  455. (* ------------------------------------------------------------------------
  456. PROCEDURE - _memmax.
  457. PRECONDITIONS - Near Heap initialised.
  458. POSTCONDITIONS - None.
  459. IN PARAMETERS - None.
  460. OUT PARAMETERS - Returns size of largest unallocated block in near heap
  461. in bytes (int).
  462. CALLING CONVENTION - Standard.
  463. NOTES - Causes near heap to be initalised.
  464. VERSION - _OS2 and MSDOS.
  465. ------------------------------------------------------------------------ *)
  466. segment _TEXT(CODE,28H)
  467. segment _DATA(DATA,28H)
  468. nearFreeSize = 0
  469. nearNextBlock = 2
  470. extrn __nfirstfree
  471. select _TEXT
  472. public __memmax :
  473. push bx
  474. (*%F SameDS *)
  475. push ds
  476. mov ax, _DATA
  477. mov ds, ax
  478. (*%E *)
  479. sub ax, ax
  480. mov bx, [__nfirstfree]
  481. cmp bx, -1
  482. je maxEnd
  483. maxLoop:
  484. or bx, bx
  485. jz maxEnd
  486. cmp ax, [bx][nearFreeSize]
  487. jae axBigger
  488. mov ax, [bx][nearFreeSize]
  489. axBigger:
  490. mov bx, [bx][nearNextBlock]
  491. jmp maxLoop
  492. maxEnd:
  493. (*%F SameDS *)
  494. pop ds
  495. (*%E *)
  496. pop bx
  497. (*%F NearCall *)
  498. ret far 0
  499. (*%E *)
  500. (*%T NearCall *)
  501. ret 0
  502. (*%E *)
  503. (*%E _DLLOVL *)
  504. (*%E _DLL*)
  505. section
  506. (***************************************************************************)
  507. (*%F _DLL *)
  508. (* ------------------------------------------------------------------------
  509. PROCEDURE - _msize, _nmsize.
  510. PRECONDITIONS - Block must be allocated from near heap.
  511. POSTCONDITIONS - None.
  512. IN PARAMETERS - Near pointer to memory block.
  513. OUT PARAMETERS - Returns size in bytes of memory block.
  514. CALLING CONVENTION - Standard.
  515. NOTES -
  516. VERSION - _OS2 and MSDOS.
  517. ------------------------------------------------------------------------ *)
  518. segment _TEXT(CODE,28H)
  519. segment _DATA(DATA,28H)
  520. select _TEXT
  521. (*%T NearPtr *)
  522. public __msize :
  523. (*%E *)
  524. public __nmsize :
  525. (*%F RegParam *)
  526. buffer = frame
  527. push bp
  528. mov bp, sp
  529. push bx
  530. mov bx, [bp][buffer]
  531. (*%E *)
  532. (*%T RegParam *)
  533. push bx
  534. mov bx, ax
  535. (*%E *)
  536. (*%F SameDS *)
  537. push ds
  538. mov ax, _DATA
  539. mov ds, ax
  540. (*%E *)
  541. mov ax, [bx][-2]
  542. sub ax, 2
  543. (*%F SameDS *)
  544. pop ds
  545. (*%E *)
  546. pop bx
  547. (*%F RegParam *)
  548. pop bp
  549. (*%E *)
  550. (*%F NearCall *)
  551. ret far 0
  552. (*%E *)
  553. (*%T NearCall *)
  554. ret 0
  555. (*%E *)
  556. (*%E *)
  557. section
  558. (***************************************************************************)
  559. (*%F _DLL*)
  560. (* ------------------------------------------------------------------------
  561. PROCEDURE - _heapchk, _nheapchk, _heapset, _nheapset.
  562. PRECONDITIONS - Near heap must be initialised.
  563. POSTCONDITIONS - _heapset fills each free block with the parameter value.
  564. IN PARAMETERS - _heapset takes fill value(int).
  565. OUT PARAMETERS - Returns state of heap.
  566. 0 _HEAPOK if OK
  567. -1 _HEAPEMPTY if heap not initialised
  568. -2 _HEAPBADBEGIN if initial header bad
  569. -3 _HEAPBADNODE if heap is damaged
  570. -4 _HEAPOVERFLOW if heap past ceiling
  571. CALLING CONVENTION - Standard.
  572. NOTES -
  573. VERSION - _OS2 and MSDOS.
  574. ------------------------------------------------------------------------ *)
  575. segment _TEXT(CODE,28H)
  576. segment _DATA(DATA,28H)
  577. mem_reg_saved = 6
  578. extrn __nheapstart
  579. extrn __nheaptop
  580. extrn __nfirstfree
  581. select _TEXT
  582. public __nheapchk :
  583. (*%T NearPtr *)
  584. public __heapchk :
  585. (*%E *)
  586. _HEAPOK = 0
  587. _HEAPEMPTY = -1
  588. _HEAPBADBEGIN = -2
  589. _HEAPBADNODE = -3
  590. _HEAPOVERFLOW = -4
  591. push bx
  592. push cx
  593. push dx
  594. sub bx, bx (* dont fill *)
  595. jmp hpShared
  596. fill = frame+mem_reg_saved
  597. public __nheapset :
  598. (*%T NearPtr *)
  599. public __heapset :
  600. (*%E *)
  601. push bx
  602. push cx
  603. push dx
  604. mov bh, 1
  605. hpShared:
  606. push bp
  607. mov bp, sp
  608. push di
  609. (*%F SameDS *)
  610. push ds
  611. mov cx, _DATA
  612. mov ds, cx
  613. (*%E *)
  614. (*%F RegParam *)
  615. mov al, [bp][fill]
  616. (*%E *)
  617. mov ah, bh
  618. mov di, [__nheapstart]
  619. or di, di
  620. je chkEmpty (* no heap *)
  621. chkNext:
  622. mov dx, [__nfirstfree]
  623. chkLoop:
  624. cmp di, dx (* is it in free list *)
  625. jne chkNotFree (* no - continue *)
  626. mov cx, [di][nearFreeSize]
  627. mov dx, [di][nearNextBlock] (* get next free *)
  628. or ah, ah
  629. je NodeOK (* fill if ah *)
  630. push ax
  631. mov ah, al
  632. push di
  633. mov bx, _DATA
  634. mov es, bx
  635. add di, 4
  636. sub cx, 4
  637. rep ; stosb
  638. pop di
  639. pop ax (* fill free block *)
  640. jmp NodeOK
  641. chkNotFree:
  642. jb NodeOK
  643. or dx, dx
  644. jne chkBadNode (* bad heap node *)
  645. NodeOK:
  646. add di, [di][nearFreeSize]
  647. cmp di, [__nheaptop]
  648. ja chkBadTop (* overflow *)
  649. jb chkLoop
  650. or dx, dx
  651. je chkOK
  652. chkBadTop:
  653. mov ax, _HEAPOVERFLOW
  654. jmp chkDone
  655. chkEmpty:
  656. mov ax, _HEAPEMPTY
  657. jmp chkDone
  658. chkBadStart:
  659. mov ax, _HEAPBADBEGIN
  660. jmp chkDone
  661. chkBadNode:
  662. mov ax, _HEAPBADNODE
  663. jmp chkDone
  664. chkOK:
  665. sub ax, ax
  666. chkDone:
  667. (*%F SameDS *)
  668. pop ds
  669. (*%E *)
  670. pop di
  671. pop bp
  672. pop dx
  673. pop cx
  674. pop bx
  675. (*%F NearCall *)
  676. ret far 0
  677. (*%E *)
  678. (*%T NearCall *)
  679. ret 0
  680. (*%E *)
  681. (*%E *)
  682. section
  683. (***************************************************************************)
  684. (*%F _DLL *)
  685. (* ------------------------------------------------------------------------
  686. PROCEDURE - _heapwalk, _nheapwalk.
  687. PRECONDITIONS - Near heap must be initialised.
  688. heapinfo structure initialised to NULL, or contains result
  689. of a preevious call to _heapwalk.
  690. POSTCONDITIONS - heapinfo structure contains details of current heap node.
  691. IN PARAMETERS - Pointer to heapinfo structure
  692. OUT PARAMETERS - Returns state of heap.
  693. _HEAPOK = 0
  694. _HEAPEMPTY = -1
  695. _HEAPBADBEGIN = -2
  696. _HEAPBADNODE = -3
  697. _HEAPOVERFLOW = -4
  698. _HEAPBADPTR = -6
  699. CALLING CONVENTION - Standard.
  700. NOTES -
  701. VERSION - _OS2 and MSDOS.
  702. ------------------------------------------------------------------------ *)
  703. segment _TEXT(CODE,28H)
  704. segment _DATA(DATA, 28H)
  705. nearFreeSize = 0
  706. nearNextBlock = 2
  707. pentry = 0
  708. size = 2
  709. useflag = 4
  710. _HEAPOK = 0
  711. _HEAPEMPTY = -1
  712. _HEAPBADBEGIN = -2
  713. _HEAPBADNODE = -3
  714. _HEAPOVERFLOW = -4
  715. _HEAPEND = -5
  716. _HEAPBADPTR = -6
  717. select _DATA
  718. extrn __nheapstart
  719. extrn __nheaptop
  720. extrn __nfirstfree
  721. lastfree : dw 0
  722. select _TEXT
  723. public __nheapwalk :
  724. (*%T NearPtr *)
  725. public __heapwalk :
  726. (*%E *)
  727. (*%F RegParam *)
  728. entry = frame
  729. push bp
  730. mov bp, sp
  731. push bx
  732. push cx
  733. push dx
  734. push si
  735. (*%F NearPtr *)
  736. les bx, [bp][entry]
  737. (*%E *)
  738. (*%T NearPtr *)
  739. mov ax, _DATA
  740. mov es, ax
  741. mov bx, [bp][entry]
  742. (*%E *)
  743. (*%E *)
  744. (*%T RegParam *)
  745. push bx
  746. push cx
  747. push dx
  748. push si
  749. (*%F NearPtr *)
  750. mov es, bx
  751. mov bx, ax
  752. (*%E *)
  753. (*%T NearPtr *)
  754. mov bx, _DATA
  755. mov es, bx
  756. mov bx, ax
  757. (*%E *)
  758. (*%E *)
  759. (*%F SameDS *)
  760. push ds
  761. mov ax, _DATA
  762. mov ds, ax
  763. (*%E *)
  764. mov si, es:[bx][pentry]
  765. or si, si
  766. jnz notFirst
  767. mov si, [__nfirstfree]
  768. cmp si, -1
  769. je heapNotInit
  770. mov [lastfree], si
  771. mov si, [__nheapstart]
  772. mov ax, [si][nearFreeSize]
  773. jmp storeNode
  774. notFirst:
  775. cmp si, [__nheapstart]
  776. jb invalidPtr
  777. cmp si, [__nheaptop]
  778. jae invalidPtr
  779. mov ax, [si][nearFreeSize]
  780. add si, ax
  781. cmp si, [__nheaptop]
  782. je atHeapTop
  783. mov ax, [si][nearFreeSize]
  784. storeNode:
  785. mov es:[bx][pentry], si
  786. sub ax, 2
  787. mov es:[bx][size], ax
  788. mov ax, 1
  789. cmp si, [lastfree]
  790. jne notFree
  791. sub ax, ax
  792. mov cx, [si][nearNextBlock]
  793. mov [lastfree], cx
  794. jmp goodNode
  795. notFree:
  796. jb goodNode
  797. cmp word [lastfree], 0
  798. jne badNode
  799. goodNode:
  800. mov es:[bx][useflag], ax
  801. success:
  802. mov ax, _HEAPOK
  803. exit:
  804. (*%F SameDS *)
  805. pop ds
  806. (*%E *)
  807. pop si
  808. pop dx
  809. pop cx
  810. pop bx
  811. (*%F RegParam *)
  812. mov sp, bp
  813. pop bp
  814. (*%E *)
  815. (*%F NearCall *)
  816. ret far 0
  817. (*%E *)
  818. (*%T NearCall *)
  819. ret 0
  820. (*%E *)
  821. heapNotInit:
  822. mov ax, _HEAPEMPTY
  823. jmp exit
  824. atHeapTop:
  825. cmp word [lastfree], 0
  826. jne badNode
  827. mov ax, _HEAPEND
  828. jmp exit
  829. badNode:
  830. mov ax, _HEAPBADNODE
  831. jmp exit
  832. invalidPtr:
  833. mov ax, _HEAPBADPTR
  834. jmp exit
  835. (*%E *)
  836. section
  837. (***************************************************************************)
  838. (*%F _DLL *)
  839. (* ------------------------------------------------------------------------
  840. PROCEDURE - _expand, _nexpand, realloc, _nrealloc.
  841. PRECONDITIONS - Near heap initialised.
  842. POSTCONDITIONS - If successful, block allocation changed.
  843. On error errno set to ENOMEM.
  844. IN PARAMETERS - near pointer to memory block, block size.
  845. OUT PARAMETERS - Returns near pointer to memeory block.
  846. CALLING CONVENTION - Standard.
  847. NOTES - realloc changes size of block allocated from near heap. If the
  848. block cannot be expanded it is freed and another block allocated.
  849. The contents of the old block are copied.
  850. If size is zero the block will be freed.
  851. If the pointer is NULL a new block will be allocated.
  852. _expand will attempt to change the allocationof the block without
  853. moving it.
  854. VERSION - _OS2 and MSDOS.
  855. ------------------------------------------------------------------------ *)
  856. segment _TEXT(CODE,28H)
  857. segment _DATA(DATA,28H)
  858. nearFreeSize = 0
  859. nearNextBlock = 2
  860. extrn __nmalloc
  861. extrn __nfree
  862. extrn __nheapstart
  863. extrn __nfirstfree
  864. extrn __nheaptop
  865. extrn _errno
  866. select _TEXT
  867. public __nexpand :
  868. (*%T NearPtr *)
  869. public __expand :
  870. (*%E *)
  871. (*%F RegParam *)
  872. buffer = frame
  873. size = 2+frame
  874. locals = 12
  875. (*%E *)
  876. currentblock = -2
  877. expand = -4
  878. newsize = -6
  879. prevfree = -8
  880. nextfree = -10
  881. oldsize = -12
  882. lowfree = -14
  883. (*%T RegParam *)
  884. size = -16
  885. buffer = -18
  886. locals = 18
  887. (*%E *)
  888. push bp
  889. mov bp, sp
  890. sub sp, locals
  891. mov byte [bp][expand], 1
  892. jmp expandEntry
  893. public __nrealloc :
  894. (*%T NearPtr *)
  895. public _realloc :
  896. (*%E *)
  897. push bp
  898. mov bp, sp
  899. sub sp, locals
  900. mov byte [bp][expand], 0
  901. push bx
  902. push cx
  903. push dx
  904. expandEntry: (* expand arrives here *)
  905. push di
  906. push si
  907. (*%F SameDS *)
  908. push ds
  909. mov cx, _DATA
  910. mov ds, cx
  911. (*%E *)
  912. (*%F RegParam *)
  913. mov bx, [bp][buffer]
  914. mov ax, [bp][size]
  915. (*%E *)
  916. (*%T RegParam *)
  917. mov [bp][size], bx
  918. mov [bp][buffer], ax
  919. xchg ax, bx
  920. (*%E *)
  921. or ax, ax
  922. jne dontFree (* size = 0 - use free *)
  923. (*%T RegParam *)
  924. mov ax, bx
  925. (*%E *)
  926. (*%F RegParam *)
  927. push bx
  928. (*%E *)
  929. (*%F NearCall *)
  930. call far __nfree
  931. (*%E *)
  932. (*%T NearCall *)
  933. call __nfree
  934. (*%E *)
  935. (*%F RegParam *)
  936. add sp, 2
  937. (*%E *)
  938. sub ax, ax
  939. jmp near reallocExit
  940. dontFree:
  941. or bx, bx
  942. jne reallocWanted (* buffer = NULL, use malloc *)
  943. (*%F RegParam *)
  944. push ax
  945. (*%E *)
  946. (*%F NearCall *)
  947. call far __nmalloc
  948. (*%E *)
  949. (*%T NearCall *)
  950. call __nmalloc
  951. (*%E *)
  952. (*%F RegParam *)
  953. add sp, 2
  954. (*%E *)
  955. jmp near reallocExit
  956. reallocWanted: (* arrive here to change allocation *)
  957. cmp word [__nfirstfree], -1
  958. je near reallocError (* get out - no heap *)
  959. cmp bx, [__nheapstart]
  960. jb near reallocError
  961. cmp bx, [__nheaptop]
  962. jae near reallocError
  963. test ax, 1
  964. jz sizeEven
  965. inc ax
  966. or ax, ax
  967. jz near reallocError
  968. sizeEven:
  969. add ax, 2
  970. sub bx, 2
  971. mov [bp][currentblock], bx
  972. mov di, bx
  973. mov [bp][newsize], ax
  974. mov bx, [di][nearFreeSize]
  975. mov [bp][oldsize], bx (* save old block size *)
  976. cmp ax, bx (* what needs doing ? *)
  977. ja reallocEnlarge (* enlarge current allocation *)
  978. je near reallocDone (* nothing to do *)
  979. reallocShrink: (* shrink current allocation *)
  980. sub bx, ax
  981. cmp bx, 6
  982. jb mergeDone
  983. mov [di][nearFreeSize], ax
  984. add di, ax
  985. mov [di][nearFreeSize], bx
  986. mov ax, di
  987. add ax, 2
  988. (*%F RegParam *)
  989. push ax
  990. (*%E *)
  991. (*%F NearCall *)
  992. call far __nfree
  993. (*%E *)
  994. (*%T NearCall *)
  995. call __nfree
  996. (*%E *)
  997. (*%F RegParam *)
  998. add sp, 2
  999. (*%E *)
  1000. mergeDone:
  1001. mov di, [bp][currentblock]
  1002. jmp near reallocDone
  1003. reallocEnlarge: (* enlarge allocation *)
  1004. sub dx, dx
  1005. sub bx, bx
  1006. mov ax, [__nfirstfree] (* find next free block *)
  1007. or ax, ax
  1008. je near reallocFindNew (* heap is full *)
  1009. mov cx, di
  1010. reallocLoop:
  1011. cmp ax, cx
  1012. ja reallocFoundNext
  1013. je near reallocError (* Error - block is already free *)
  1014. mov bx, dx
  1015. mov dx, ax
  1016. mov di, ax
  1017. mov ax, [di][nearNextBlock]
  1018. or ax, ax
  1019. jne reallocLoop
  1020. mov [bp][lowfree], bx
  1021. jmp reallocFindBelow (* there are no free blocks above *)
  1022. reallocFoundNext:
  1023. mov [bp][prevfree], dx
  1024. mov [bp][nextfree], ax
  1025. mov [bp][lowfree], bx
  1026. mov bx, [bp][oldsize] (* old block size *)
  1027. push cx
  1028. add cx, bx (* is next free block contiginous *)
  1029. cmp cx, ax
  1030. pop cx
  1031. jne reallocFindBelow (* no - find a block below *)
  1032. mov di, ax (* yes, but is it big enough *)
  1033. mov ax, [bp][newsize]
  1034. sub ax, bx (* we need ax more bytes *)
  1035. cmp ax, [di][nearFreeSize] (* are there enough here *)
  1036. je reallocExactFit
  1037. ja reallocFindBelow (* no *)
  1038. reallocGotEnough:
  1039. sub ax, [di][nearFreeSize]
  1040. neg ax
  1041. cmp ax, 4
  1042. jae reallocAboveSizeOK
  1043. add [bp][newsize], ax
  1044. jmp reallocExactFit
  1045. reallocAboveSizeOK:
  1046. mov di, [bp][nextfree] (* yes - *)
  1047. mov dx, [di][nearFreeSize]
  1048. mov cx, [di][nearNextBlock] (* save next free block *)
  1049. mov bx, [bp][currentblock]
  1050. mov ax, [bp][newsize]
  1051. mov di, bx
  1052. add dx, [di][nearFreeSize] (* dx is size of both blocks *)
  1053. sub dx, ax (* dx is size of new free *)
  1054. mov [di][nearFreeSize], ax (* set size to new *)
  1055. add ax, bx (* ax is now new free block *)
  1056. mov di, ax
  1057. mov [di][nearNextBlock], cx
  1058. mov [di][nearFreeSize], dx
  1059. reallocAdjust:
  1060. mov cx, [bp][prevfree] (* adjust previous free block *)
  1061. jcxz rFFree
  1062. mov di, cx
  1063. mov [di][nearNextBlock], ax
  1064. jmp near reallocDone (* block has been increased - success *)
  1065. reallocExactFit:
  1066. mov di, [bp][currentblock]
  1067. mov ax, [bp][newsize]
  1068. mov [di][nearFreeSize], ax (* merge blocks *)
  1069. mov di, [bp][nextfree]
  1070. mov ax, [di][nearNextBlock]
  1071. jmp reallocAdjust
  1072. rFFree: (* there wasn't one - set first free *)
  1073. mov [__nfirstfree], ax
  1074. jmp near reallocDone
  1075. reallocFindBelow:
  1076. or dx, dx (* is there a free block below *)
  1077. jz reallocFindNew
  1078. cmp dx, cx (* is free block below *)
  1079. ja reallocFindNew
  1080. mov [bp][nextfree], ax
  1081. mov di, dx
  1082. mov ax, [di][nearFreeSize]
  1083. add dx, ax
  1084. cmp dx, cx (* are blocks contiginous *)
  1085. jne reallocFindNew
  1086. mov bx, cx
  1087. add ax, [bx][nearFreeSize]
  1088. cmp ax, [bp][newsize]
  1089. jb reallocFindNew (* is combined size big enough *)
  1090. je reallocBelowExactFit
  1091. sub ax, [bp][newsize]
  1092. cmp ax, 4
  1093. jae reallocBelowSizeOK
  1094. add [bp][newsize], ax
  1095. jmp reallocBelowExactFit
  1096. reallocBelowSizeOK:
  1097. mov bx, ax
  1098. mov ax, [bp][newsize]
  1099. mov [di][nearFreeSize], ax
  1100. call reallocMove
  1101. mov cx, di
  1102. add di, ax
  1103. mov [di][nearFreeSize], bx
  1104. mov ax, [bp][nextfree]
  1105. mov [di][nearNextBlock], ax
  1106. mov ax, di
  1107. jmp reallocBelowSplice
  1108. reallocBelowExactFit:
  1109. mov ax, [bp][newsize]
  1110. mov [di][nearFreeSize], ax
  1111. call reallocMove
  1112. mov ax, [bp][nextfree]
  1113. mov cx, di
  1114. reallocBelowSplice:
  1115. mov bx, [bp][lowfree]
  1116. or bx, bx
  1117. jnz notLowFirst
  1118. mov [__nfirstfree], ax
  1119. jmp reallocBelowDone
  1120. notLowFirst:
  1121. mov [bx][nearNextBlock], ax
  1122. reallocBelowDone:
  1123. mov ax, cx
  1124. add ax, 2
  1125. jmp reallocExit
  1126. reallocFindNew: (* free this block and try to find new one *)
  1127. cmp byte [bp][expand], 0
  1128. jne reallocError (* if expand only give up here *)
  1129. (*%F RegParam *)
  1130. push [bp][size]
  1131. (*%E *)
  1132. (*%T RegParam *)
  1133. mov ax, [bp][size]
  1134. (*%E *)
  1135. (*%F NearCall *)
  1136. call far __nmalloc
  1137. (*%E *)
  1138. (*%T NearCall *)
  1139. call __nmalloc
  1140. (*%E *)
  1141. (*%F RegParam *)
  1142. add sp, 2
  1143. (*%E *)
  1144. or ax, ax (* malloc returned NULL - *)
  1145. je reallocError (* couldn't find a new one *)
  1146. push ax
  1147. mov di, ax
  1148. sub di, 2
  1149. call reallocMove
  1150. (* copy contents of old block *)
  1151. mov ax, [bp][currentblock]
  1152. add ax, 2
  1153. (*%F RegParam *)
  1154. push ax
  1155. (*%E *)
  1156. (*%F NearCall *)
  1157. call far __nfree
  1158. (*%E *)
  1159. (*%T NearCall *)
  1160. call __nfree
  1161. (*%E *)
  1162. (*%F RegParam *)
  1163. add sp, 2
  1164. (*%E *)
  1165. pop ax
  1166. jmp reallocExit
  1167. reallocDone: (* success *)
  1168. mov ax, [bp][buffer]
  1169. jmp reallocExit
  1170. reallocError: (* failure *)
  1171. mov word [_errno], ENOMEM
  1172. sub ax, ax (* return NULL *)
  1173. reallocExit:
  1174. (*%F SameDS *)
  1175. pop ds
  1176. (*%E *)
  1177. pop si
  1178. pop di
  1179. pop dx
  1180. pop cx
  1181. pop bx
  1182. mov sp, bp
  1183. pop bp
  1184. (*%F NearCall *)
  1185. ret far 0
  1186. (*%E *)
  1187. (*%T NearCall *)
  1188. ret 0
  1189. (*%E *)
  1190. reallocMove:
  1191. push di
  1192. mov cx, [bp][oldsize] (* number of bytes to move *)
  1193. shr cx, 1
  1194. mov si, [bp][currentblock]
  1195. add si, 2
  1196. add di, 2
  1197. push ds
  1198. pop es
  1199. rep ; movsw
  1200. pop di
  1201. ret 0
  1202. (* _realloc ENDP *)
  1203. (*%E *)
  1204. section
  1205. (***************************************************************************)
  1206. (*%F _OS2 *)
  1207. (*%F _DLLOVL *)
  1208. (* ------------------------------------------------------------------------
  1209. PROCEDURE - __initfmem.
  1210. PRECONDITIONS - __far_ss, __stklen and __psp must be initialised.
  1211. POSTCONDITIONS - Far heap set up. __fheapsetup = TRUE, _fheapstart and
  1212. __fheaptop mark bounding segments. __firstfree marks
  1213. first free block. __shr_mem contains address of heap
  1214. shrinking procedure.
  1215. Initial block is < 1000 paragraphs. Surplus memory is
  1216. returned to MSDOS.
  1217. IN PARAMETERS - None.
  1218. OUT PARAMETERS - None.
  1219. CALLING CONVENTION - Standard.
  1220. NOTES - Init code section brought in by reference to __fheapstart.
  1221. VERSION - MSDOS (Not DLLs).
  1222. ------------------------------------------------------------------------ *)
  1223. segment _INIT(INIT_CODE,28H)
  1224. segment _TEXT(CODE,28H)
  1225. segment _DATA(DATA, 28H)
  1226. extrn __shrink_mem
  1227. select _DATA
  1228. extrn __psp
  1229. extrn __far_ss
  1230. extrn __stklen
  1231. extrn __farstack
  1232. extrn __fmemsetup
  1233. extrn __firstfree
  1234. extrn __fheaptop
  1235. extrn __shr_mem
  1236. extrn __nheaptop
  1237. select _TEXT
  1238. do_initfmem : (* defined later on ! *)
  1239. select _INIT
  1240. initfmem : dw MAGIC_NUM
  1241. db PR1
  1242. (*%F NearCall *)
  1243. dd do_initfmem
  1244. (*%E *)
  1245. (*%T NearCall *)
  1246. dw do_initfmem
  1247. (*%E *)
  1248. select _DATA
  1249. public __fheapstart : dw 0, initfmem (* start of heap *)
  1250. select _TEXT
  1251. free = -2
  1252. newtop = -4
  1253. locals = 4
  1254. public __initfmem :
  1255. push bp
  1256. mov bp, sp
  1257. sub sp, locals
  1258. push ds
  1259. mov ax, _DATA
  1260. mov ds, ax
  1261. cmp byte [__fmemsetup], 0
  1262. jne near initmemDone
  1263. not byte [__fmemsetup]
  1264. mov word [__shr_mem], __shrink_mem
  1265. (*%F NearCall *)
  1266. mov word [__shr_mem][2], cs
  1267. (*%E *)
  1268. mov es, [__psp] (* get top of allocation *)
  1269. mov ax, es:[2]
  1270. mov bx, [__far_ss]
  1271. cmp word [__farstack], 0
  1272. jz gotStart (* near stack *)
  1273. mov dx, [__stklen]
  1274. add dx, 0FH
  1275. jnc sizeOK
  1276. mov dx, 1000H
  1277. jmp gotSize
  1278. sizeOK:
  1279. mov cx, 4
  1280. shr dx, cx
  1281. gotSize:
  1282. add bx, dx (* calc top of stack *)
  1283. gotStart:
  1284. mov [__fheapstart], bx
  1285. sub ax, bx
  1286. cmp ax, 1001H
  1287. jbe noneToFree
  1288. add bx, 1001H
  1289. mov [bp][newtop], bx (* free surplus memory *)
  1290. sub bx, [__psp]
  1291. mov ah, 4AH
  1292. int 21H
  1293. mov ax, [bp][newtop]
  1294. mov es:[2], ax
  1295. (* jc fatal error *)
  1296. mov ax, 1001H
  1297. noneToFree: (* set up first free block *)
  1298. mov es, [__fheapstart]
  1299. or ax, ax
  1300. je noHeap
  1301. mov word es:[farNextBlock], 0
  1302. dec ax
  1303. mov es:[farFreeSize], ax
  1304. mov [__firstfree], es
  1305. add ax, [__firstfree]
  1306. mov [__fheaptop], ax
  1307. jmp initmemDone
  1308. noHeap:
  1309. mov word [__firstfree], -1 (* no heap - firstfree is -1 *)
  1310. initmemDone:
  1311. pop ds
  1312. mov sp, bp
  1313. pop bp
  1314. (*%F NearCall *)
  1315. ret far 0
  1316. (*%E *)
  1317. (*%T NearCall *)
  1318. ret 0
  1319. (*%E *)
  1320. (*%E _DLLOVL *)
  1321. (*%E _OS2 *)
  1322. section
  1323. (***************************************************************************)
  1324. (*%F _OS2 *)
  1325. (*%F _DLL *)
  1326. (* ------------------------------------------------------------------------
  1327. PROCEDURE - __initnmem.
  1328. PRECONDITIONS - __heap_size initialised. __near_heap_start defined in
  1329. main module.
  1330. POSTCONDITIONS - Near heap set up. __nheapsetup = TRUE, _nheapstart and
  1331. __nheaptop mark bounding offsets. __nfirstfree marks
  1332. first free block.
  1333. No memory returnd to MSDOS.
  1334. IN PARAMETERS - None.
  1335. OUT PARAMETERS - None.
  1336. CALLING CONVENTION - Standard.
  1337. NOTES - Init code section brought in by reference to __nfirstfree.
  1338. VERSION - MSDOS (Not DLLs).
  1339. ------------------------------------------------------------------------ *)
  1340. segment _INIT(INIT_CODE,28H)
  1341. segment _TEXT(CODE,28H)
  1342. segment _DATA(DATA, 28H)
  1343. segment NEAR_HEAP(BSS, 28H)
  1344. select _DATA
  1345. extrn __nheapstart
  1346. extrn __nheaptop
  1347. extrn __bss_end
  1348. extrn __farstack
  1349. extrn __nmemsetup
  1350. extrn __near_heap_start
  1351. extrn __heap_size
  1352. extrn __psp
  1353. extrn __stklen
  1354. select _TEXT
  1355. do_initnmem : (* defined later on ! *)
  1356. select _INIT
  1357. initnmem : dw MAGIC_NUM
  1358. db PR1
  1359. (*%F NearCall *)
  1360. dd do_initnmem
  1361. (*%E *)
  1362. (*%T NearCall *)
  1363. dw do_initnmem
  1364. (*%E *)
  1365. select _DATA
  1366. public __nfirstfree : dw 0, initnmem
  1367. select _TEXT
  1368. public __initnmem :
  1369. push bp
  1370. mov bp, sp
  1371. push di
  1372. cmp byte [__nmemsetup], 0
  1373. jne ninitDone
  1374. not byte [__nmemsetup]
  1375. mov di, __near_heap_start
  1376. add di, 3
  1377. and di, ~1
  1378. mov dx, di
  1379. add dx, [__heap_size]
  1380. jnc sizeSet
  1381. mov dx, -1
  1382. sizeSet:
  1383. sub dx, 2
  1384. mov cx, dx
  1385. sub cx, 10H
  1386. cmp cx, di
  1387. jbe noHeap
  1388. mov [__nheaptop], dx
  1389. sub dx, di
  1390. mov [__nheapstart], di
  1391. mov [__nfirstfree], di
  1392. mov [di][nearFreeSize], dx
  1393. mov word [di][nearNextBlock], 0
  1394. ninitDone:
  1395. pop di
  1396. pop bp
  1397. (*%F NearCall *)
  1398. ret far 0
  1399. (*%E *)
  1400. (*%T NearCall *)
  1401. ret 0
  1402. (*%E *)
  1403. noHeap:
  1404. mov word [__nfirstfree], -1
  1405. jmp ninitDone
  1406. (*%E _DLL *)
  1407. (*%E _OS2 *)
  1408. section
  1409. (****************************************************************************)
  1410. (*%F _OS2 *)
  1411. (*%F _DLLOVL *)
  1412. (* ------------------------------------------------------------------------
  1413. PROCEDURE - __shrink_mem.
  1414. PRECONDITIONS - Far heap initialised.
  1415. POSTCONDITIONS - Last block of far heap shrunk to <= 2 paragraphs and
  1416. rest of memory returned to MSDOS.
  1417. IN PARAMETERS - None.
  1418. OUT PARAMETERS - Returns 0 if succesful.
  1419. CALLING CONVENTION - Standard.
  1420. NOTES -
  1421. VERSION - MSDOS (Not DLLS).
  1422. ------------------------------------------------------------------------ *)
  1423. segment _TEXT(CODE,28H)
  1424. segment _DATA(DATA,28H)
  1425. extrn __fheapstart
  1426. extrn __firstfree
  1427. extrn __fheaptop
  1428. extrn __psp
  1429. select _TEXT
  1430. public __shrink_mem :
  1431. push ds
  1432. mov ax, _DATA
  1433. (*%F SameDS *)
  1434. mov ds, ax
  1435. (*%E *)
  1436. mov es, ax
  1437. mov cx, es:[__firstfree]
  1438. jcxz shrinkDone
  1439. mov ds, cx
  1440. shrinkLoop: (* find end of heap *)
  1441. mov ax, [farNextBlock]
  1442. or ax, ax
  1443. je lastBlock
  1444. mov ds, ax
  1445. jmp shrinkLoop
  1446. lastBlock:
  1447. mov ax, [farFreeSize]
  1448. mov bx, ds
  1449. add bx, ax
  1450. cmp bx, es:[__fheaptop]
  1451. jne noneToFree (* return if the block is not the last one *)
  1452. cmp ax, 2 (* return if last block allocated or NearPtr *)
  1453. jb noneToFree
  1454. mov ax, 2 (* adjust last block in heap *)
  1455. mov [farFreeSize], ax
  1456. mov bx, ds (* adjust top of memory *)
  1457. add bx, ax
  1458. mov es:[__fheaptop], bx
  1459. mov ax, es:[__psp]
  1460. mov es, ax
  1461. inc bx
  1462. mov es:[2], bx
  1463. sub bx, ax
  1464. mov ah, 4AH
  1465. extrn @DosInterrupt
  1466. (*%F NearCall *)
  1467. call far @DosInterrupt
  1468. (*%E *)
  1469. (*%T NearCall *)
  1470. call @DosInterrupt
  1471. (*%E *)
  1472. jc shrinkError
  1473. noneToFree:
  1474. sub ax, ax
  1475. jmp shrinkDone
  1476. shrinkError:
  1477. mov ax, -1 (* error - either PSP corrupted or *)
  1478. shrinkDone: (* memory blocks damaged *)
  1479. pop ds
  1480. (*%F NearCall *)
  1481. ret far 0
  1482. (*%E *)
  1483. (*%T NearCall *)
  1484. ret 0
  1485. (*%E *)
  1486. (*%E _DLLOVL *)
  1487. (*%E _OS2 *)
  1488. section
  1489. (****************************************************************************)
  1490. (*%F _OS2 *)
  1491. (*%T _DLLOVL *)
  1492. (* ------------------------------------------------------------------------
  1493. PROCEDURE - __shrink_mem.
  1494. PRECONDITIONS - Far heap initialised.
  1495. POSTCONDITIONS - Last block of far heap shrunk to <= 2 paragraphs and
  1496. rest of memory returned to MSDOS.
  1497. IN PARAMETERS - None.
  1498. OUT PARAMETERS - Returns 0 if succesful.
  1499. CALLING CONVENTION - Near Call.
  1500. NOTES - Code in Loader accessed by interrupt.
  1501. VERSION - MSDOS DLLs.
  1502. ------------------------------------------------------------------------ *)
  1503. segment _TEXT(CODE,28H)
  1504. extrn Loader$ShrinkHeap
  1505. public __shrink_mem :
  1506. push bp
  1507. mov bp, sp
  1508. call far Loader$ShrinkHeap
  1509. xor ax, ax
  1510. pop bp
  1511. ret far 0
  1512. (*%E _DLLOVL*)
  1513. (*%E OS2 *)
  1514. section
  1515. (***************************************************************************)
  1516. (*%F _OS2 *)
  1517. (*%F _DLLOVL *)
  1518. (* ------------------------------------------------------------------------
  1519. PROCEDURE - calloc, _fcalloc.
  1520. PRECONDITIONS - far heap initialised.
  1521. POSTCONDITIONS - If successful, block of size*num bytes allocated and
  1522. cleared to zero.
  1523. If size = 0 or heap full, errno set to ENOMEM.
  1524. IN PARAMETERS - Number of blocks requested(size_t),
  1525. Size of block requested(size_t)
  1526. OUT PARAMETERS - If successful Near pointer to allocated block.
  1527. On error NULL pointer.
  1528. CALLING CONVENTION - Standard.
  1529. NOTES - Jumps to shared code in malloc.
  1530. VERSION - MSDOS.
  1531. ------------------------------------------------------------------------ *)
  1532. segment _TEXT(CODE,28H)
  1533. segment _DATA(DATA,28H)
  1534. extrn __fcallocEntry
  1535. extrn __fmallocError
  1536. extrn __core_lock
  1537. extrn __core_unlock
  1538. select _TEXT
  1539. public __fcalloc :
  1540. (*%F NearPtr *)
  1541. public _calloc :
  1542. (*%E *)
  1543. num = frame
  1544. size = 2+frame
  1545. currentblock = -2
  1546. newsize = -4
  1547. prevblock = -6
  1548. flag = -8
  1549. request = -10
  1550. locals = 10
  1551. push bp
  1552. mov bp, sp
  1553. sub sp, locals
  1554. push bx
  1555. push cx
  1556. (*%F SameDS *)
  1557. push ds
  1558. mov cx, _DATA
  1559. mov ds, cx
  1560. (*%E *)
  1561. (*%T MThread *)
  1562. call far [__core_lock]
  1563. (*%E *)
  1564. (*%F RegParam *)
  1565. mov ax, [bp][size]
  1566. (*%E *)
  1567. or ax, ax (* Error if size = 0 *)
  1568. je near __fmallocError
  1569. (*%F RegParam *)
  1570. mov dx, [bp][num]
  1571. (*%E *)
  1572. (*%T RegParam *)
  1573. mov dx, bx
  1574. (*%E *)
  1575. or dx, dx
  1576. je near __fmallocError
  1577. mul dx
  1578. or dx, dx
  1579. jne near __fmallocError (* over flow *)
  1580. mov byte [bp][flag], 1
  1581. jmp __fcallocEntry
  1582. (*%E _DLLOVL *)
  1583. (*%E _OS2 *)
  1584. section
  1585. (***************************************************************************)
  1586. (*%F _OS2 *)
  1587. (*%F _DLLOVL *)
  1588. (* ------------------------------------------------------------------------
  1589. PROCEDURE - halloc.
  1590. PRECONDITIONS - far heap initialised.
  1591. POSTCONDITIONS - If successful, huge block of size bytes allocated.
  1592. If size = 0 or heap full, errno set to ENOMEM.
  1593. IN PARAMETERS - Size of block requested(long)
  1594. OUT PARAMETERS - If successful Far pointer to allocated block.
  1595. On error NULL pointer.
  1596. CALLING CONVENTION - Standard.
  1597. NOTES - Jumps to shared code in malloc.
  1598. VERSION - MSDOS.
  1599. ------------------------------------------------------------------------ *)
  1600. segment _TEXT(CODE,28H)
  1601. segment _DATA(DATA, 28H)
  1602. extrn __hallocEntry
  1603. extrn __fmallocError
  1604. extrn __heap_align
  1605. extrn __core_lock
  1606. extrn __core_unlock
  1607. select _TEXT
  1608. currentblock = -2
  1609. newsize = -4
  1610. prevblock = -6
  1611. flag = -8
  1612. request = -10
  1613. locals = 10
  1614. public _halloc :
  1615. size = frame
  1616. push bp
  1617. mov bp, sp
  1618. sub sp, locals
  1619. push bx
  1620. push cx
  1621. (*%F SameDS *)
  1622. push ds
  1623. mov cx, _DATA
  1624. mov ds, cx
  1625. (*%E *)
  1626. (*%T MThread *)
  1627. call far [__core_lock]
  1628. (*%E *)
  1629. (*%F RegParam *)
  1630. mov ax, [bp][size]
  1631. call __heap_align
  1632. mov dx, [bp][size][2]
  1633. (*%E *)
  1634. (*%T RegParam *)
  1635. push bx
  1636. call __heap_align
  1637. pop dx
  1638. (*%E *)
  1639. mov cx, 12
  1640. shl dx, cx
  1641. add ax, dx (* number of paragraphs requested *)
  1642. or ax, ax
  1643. je near __fmallocError (* return NULL if size = 0 *)
  1644. mov byte [bp][flag], 0
  1645. mov [bp][request], ax
  1646. mov [bp][newsize], ax
  1647. jmp __hallocEntry
  1648. (*%E _DLLOVL *)
  1649. (*%E _OS2 *)
  1650. section
  1651. (***************************************************************************)
  1652. (*%F _OS2 *)
  1653. (*%F _DLLOVL *)
  1654. (* ------------------------------------------------------------------------
  1655. PROCEDURE - malloc, _nmalloc.
  1656. PRECONDITIONS - far heap initialised.
  1657. POSTCONDITIONS - If successful, block of size bytes allocated.
  1658. If size = 0 or heap full, errno set to ENOMEM.
  1659. IN PARAMETERS - Size of block requested(long)
  1660. OUT PARAMETERS - If successful Far pointer to allocated block.
  1661. On error NULL pointer.
  1662. CALLING CONVENTION - Standard.
  1663. NOTES - .
  1664. VERSION - MSDOS.
  1665. ------------------------------------------------------------------------ *)
  1666. segment _TEXT(CODE,28H)
  1667. segment _DATA(DATA,28H)
  1668. farFreeSize = 14
  1669. farNextBlock = 16
  1670. extrn _memset
  1671. extrn __core_lock
  1672. extrn __core_unlock
  1673. extrn __firstfree
  1674. extrn __fheapstart
  1675. extrn __fheaptop
  1676. extrn __psp
  1677. extrn __seterrno
  1678. extrn __heap_align
  1679. extrn __heap_alloc
  1680. select _TEXT
  1681. public __fmalloc :
  1682. (*%F NearPtr *)
  1683. public _malloc :
  1684. (*%E *)
  1685. size = frame
  1686. currentblock = -2
  1687. newsize = -4
  1688. prevblock = -6
  1689. flag = -8
  1690. request = -10
  1691. locals = 10
  1692. push bp
  1693. mov bp, sp
  1694. sub sp, locals
  1695. push bx
  1696. push cx
  1697. (*%F SameDS *)
  1698. push ds
  1699. mov cx, _DATA
  1700. mov ds, cx
  1701. (*%E *)
  1702. (*%T MThread *)
  1703. call far [__core_lock]
  1704. (*%E *)
  1705. (*%F RegParam *)
  1706. mov ax, [bp][size]
  1707. (*%E *)
  1708. or ax, ax
  1709. je near __fmallocError (* return NULL if size = 0 *)
  1710. mov byte [bp][flag], 0
  1711. public __fcallocEntry :
  1712. mov [bp][request], ax
  1713. call __heap_align (* adjust size to para and header *)
  1714. mov [bp][newsize], ax
  1715. public __hallocEntry :
  1716. mov bx, [__firstfree] (* get first free block *)
  1717. cmp bx, -1
  1718. je near __fmallocError (* no heap exists *)
  1719. or bx, bx
  1720. je mallocFull (* there are no free blocks *)
  1721. mov es, bx
  1722. mov word [bp][prevblock], 0
  1723. heapLoop: (* search for big enough block *)
  1724. cmp ax, es:[farFreeSize]
  1725. jbe near blockFound (* found a free block big enough *)
  1726. mov bx, es:[farNextBlock]
  1727. or bx, bx
  1728. je atHeapTop (* last free block *)
  1729. mov [bp][prevblock], es
  1730. mov es, bx
  1731. jmp heapLoop (* try next block *)
  1732. (* These paragraphs are concerned with getting morre memory from DOS *)
  1733. mallocFull: (* special case - full heap *)
  1734. mov [bp][prevblock], bx
  1735. call __heap_alloc (* extend heap *)
  1736. jcxz near __fmallocError (* failure - no more from DOS *)
  1737. mov es, [__fheaptop]
  1738. mov es:[farFreeSize], cx
  1739. mov word es:[farNextBlock], 0
  1740. mov [__firstfree], es
  1741. jmp newBlockDone
  1742. atHeapTop:
  1743. mov [bp][currentblock], es
  1744. call __heap_alloc (* get more from DOS *)
  1745. jcxz near __fmallocError (* failure - none left *)
  1746. mov es, [bp][currentblock]
  1747. mov ax, es:[farFreeSize]
  1748. add ax, [bp][currentblock] (* is this the old last block *)
  1749. cmp ax, [__fheaptop]
  1750. jne addNewBlock
  1751. extendBlock:
  1752. add es:[farFreeSize], cx (* yes - increase size of block *)
  1753. jmp newBlockDone
  1754. addNewBlock: (* no - add a new block *)
  1755. mov ax, [__fheaptop]
  1756. mov es:[farNextBlock], ax
  1757. mov es, ax (* new block in list *)
  1758. mov es:[farFreeSize], cx
  1759. mov word es:[farNextBlock], 0
  1760. newBlockDone:
  1761. add [__fheaptop], cx (* adjust heap top *)
  1762. mov ax, [bp][newsize]
  1763. cmp ax, es:[farFreeSize]
  1764. ja __fmallocError
  1765. (* once a suitable block is found it is spliced in here *)
  1766. blockFound: (* es is current block header *)
  1767. mov ax, [bp][newsize] (* Here the new block is *)
  1768. mov cx, es:[farNextBlock] (* spliced into the list *)
  1769. cmp ax, es:[farFreeSize] (* is block an exact fit ? *)
  1770. mov bx, es
  1771. je exactFit
  1772. mov dx, es:[farFreeSize]
  1773. mov es:[farFreeSize], ax (* size of allocated block *)
  1774. sub dx, ax (* size of new block *)
  1775. add ax, bx (* segment of new free block *)
  1776. mov es, ax
  1777. mov es:[farFreeSize], dx
  1778. mov es:[farNextBlock], cx
  1779. hsSetPrevious:
  1780. mov cx, [bp][prevblock]
  1781. jcxz hsFirst
  1782. mov es, cx
  1783. mov es:[farNextBlock], ax (* adjust previous block *)
  1784. jmp hsDone
  1785. hsFirst:
  1786. mov [__firstfree], ax
  1787. hsDone:
  1788. mov es, bx
  1789. jmp mallocDone
  1790. exactFit: (* special case - an exact fit *)
  1791. mov ax, cx
  1792. jmp hsSetPrevious
  1793. public __fmallocError : (* arrive here to return NULL *)
  1794. mov ax, ENOMEM
  1795. (*%F NearCall *)
  1796. call far __seterrno
  1797. (*%E *)
  1798. (*%T NearCall *)
  1799. call __seterrno
  1800. (*%E *)
  1801. sub ax, ax
  1802. cwd
  1803. jmp mallocExit
  1804. mallocDone:
  1805. mov cx, ax
  1806. mov dx, es
  1807. inc dx
  1808. sub ax, ax
  1809. cmp byte [bp][flag], 0
  1810. jz mallocExit
  1811. push di
  1812. sub di, di
  1813. mov es, dx
  1814. mov cx, [bp][request]
  1815. rep ; stosb
  1816. pop di
  1817. mallocExit:
  1818. (*%T MThread *)
  1819. call far [__core_unlock]
  1820. (*%E *)
  1821. (*%F SameDS *)
  1822. pop ds
  1823. (*%E *)
  1824. pop cx
  1825. pop bx
  1826. mov sp, bp
  1827. pop bp
  1828. (*%F NearCall *)
  1829. ret far 0
  1830. (*%E *)
  1831. (*%T NearCall *)
  1832. ret 0
  1833. (*%E *)
  1834. dw __fheapstart
  1835. (*%E _DLLOVL *)
  1836. (*%E _OS2 *)
  1837. section
  1838. (***************************************************************************)
  1839. (*%F _OS2 *)
  1840. (*%F _DLLOVL *)
  1841. (* ------------------------------------------------------------------------
  1842. PROCEDURE - _ffree, free, hfree.
  1843. PRECONDITIONS - Far heap initialised.
  1844. POSTCONDITIONS - block merged into free list.
  1845. IN PARAMETERS - Far pointer to block allocated from far heap.
  1846. OUT PARAMETERS - None.
  1847. CALLING CONVENTION - Standard.
  1848. NOTES - Always merges neighbouring free blocks.
  1849. VERSION - MSDOS.
  1850. ------------------------------------------------------------------------ *)
  1851. segment _TEXT(CODE,28H)
  1852. segment _DATA(DATA,28H)
  1853. farFreeSize = 14
  1854. farNextBlock = 16
  1855. extrn __core_lock
  1856. extrn __core_unlock
  1857. extrn __fheapstart
  1858. extrn __fheaptop
  1859. extrn __firstfree
  1860. extrn __psp
  1861. extrn __heap_norm
  1862. extrn __heap_merge
  1863. extrn __heap_free
  1864. select _TEXT
  1865. buffer = frame
  1866. currentblock = -2
  1867. locals =2
  1868. public __ffree :
  1869. public _hfree :
  1870. (*%F NearPtr *)
  1871. public _free :
  1872. (*%E *)
  1873. push bp
  1874. mov bp, sp
  1875. sub sp, locals
  1876. (*%F RegParam *)
  1877. push ax
  1878. push bx
  1879. (*%E *)
  1880. push cx
  1881. push dx
  1882. (*%F SameDS *)
  1883. push ds
  1884. mov cx, _DATA
  1885. mov ds, cx
  1886. (*%E *)
  1887. (*%T MThread *)
  1888. call far [__core_lock]
  1889. (*%E *)
  1890. (*%F RegParam *)
  1891. les bx, [bp][buffer] (* normalise and validate pointer *)
  1892. (*%E *)
  1893. (*%T RegParam *)
  1894. mov es, bx
  1895. mov bx, ax
  1896. (*%E *)
  1897. call __heap_norm
  1898. jc near freeError
  1899. freeValid: (* dx points to header *)
  1900. sub ax, ax
  1901. mov cx, [__firstfree]
  1902. cmp cx, -1
  1903. je near freeError (* there is no heap *)
  1904. jcxz freeFull (* heap is full *)
  1905. freeLoop:
  1906. cmp cx, dx (* are we past block ? *)
  1907. ja freeFound
  1908. je freeError (* block is already free *)
  1909. mov ax, cx (* save lower block *)
  1910. mov es, cx
  1911. mov cx, es:[farNextBlock]
  1912. jcxz freeFound
  1913. jmp freeLoop
  1914. freeFull: (* special case *)
  1915. mov [__firstfree], dx (* a new first free *)
  1916. mov word es:[farNextBlock], 0
  1917. jmp freeNoMerge
  1918. freeFound: (* ax is lower block *)
  1919. or ax, ax
  1920. jne notFirst
  1921. mov cx, [__firstfree]
  1922. mov [__firstfree], dx (* set a new first free block *)
  1923. mov es, dx
  1924. mov es:[farNextBlock], cx
  1925. jmp freeNoLower
  1926. notFirst:
  1927. mov es, ax
  1928. mov cx, es:[farNextBlock] (* splice free block into list *)
  1929. mov es:[farNextBlock], dx
  1930. mov es, dx
  1931. mov es:[farNextBlock], cx (* ax still lower block *)
  1932. mov es, ax
  1933. add ax, es:[farFreeSize]
  1934. cmp ax, dx (* is prev free contiginous *)
  1935. jne freeNoLower
  1936. call __heap_merge (* yes - merge *)
  1937. jmp freeLowDone
  1938. freeNoLower:
  1939. mov es, dx
  1940. freeLowDone:
  1941. cmp word es:[farNextBlock], 0 (* is there a lower block *)
  1942. je freeNoMerge
  1943. mov ax, es
  1944. add ax, es:[farFreeSize]
  1945. cmp ax, es:[farNextBlock] (* is next free contiginous *)
  1946. jne freeNoMerge
  1947. call __heap_merge (* yes - merge *)
  1948. freeNoMerge: (* are we in the last block ? *)
  1949. mov ax, es
  1950. add ax, es:[farFreeSize]
  1951. cmp ax, [__fheaptop]
  1952. jne freeDone
  1953. (*%F NearCall *)
  1954. call far __heap_free
  1955. (*%E *)
  1956. (*%T NearCall *)
  1957. call __heap_free
  1958. (*%E *)
  1959. freeDone:
  1960. freeError:
  1961. (*%T MThread *)
  1962. call far [__core_unlock]
  1963. (*%E *)
  1964. (*%F SameDS *)
  1965. pop ds
  1966. (*%E *)
  1967. pop dx
  1968. pop cx
  1969. (*%F RegParam *)
  1970. pop bx
  1971. pop ax
  1972. (*%E *)
  1973. mov sp, bp
  1974. pop bp
  1975. (*%F NearCall *)
  1976. ret far 0
  1977. (*%E *)
  1978. (*%T NearCall *)
  1979. ret 0
  1980. (*%E *)
  1981. (*%E _DLLOVL *)
  1982. (*%E _OS2 *)
  1983. section
  1984. (***************************************************************************)
  1985. (*%F _OS2 *)
  1986. segment _TEXT(CODE, 28H)
  1987. extrn __fheapstart
  1988. extrn __fheaptop
  1989. extrn __psp
  1990. (* This function validates the pointer. It only checks that it is aligned and
  1991. within the bounds of the heap. If the pointer refers to a block that has
  1992. already been freed, then this will be detected in the free function *)
  1993. public __heap_norm :
  1994. mov cx, 4 (* es:bx is pointer *)
  1995. shr bx, cx (* normalises pointer and sets to *)
  1996. jc validError (* error *)
  1997. mov dx, es (* block header *)
  1998. add dx, bx (* ax is now address of header *)
  1999. dec dx
  2000. cmp dx, [__fheapstart] (* is pointer within heap *)
  2001. jb validError
  2002. cmp dx, [__fheaptop]
  2003. jae validError
  2004. clc (* yes it is *)
  2005. validDone:
  2006. mov es, dx
  2007. ret 0
  2008. validError:
  2009. stc
  2010. jmp validDone
  2011. public __heap_alloc :
  2012. mov bx, [__fheaptop] (* try to get more from DOS *)
  2013. inc bx
  2014. sub bx, [__psp]
  2015. mov cx, 1000H
  2016. cmp ax, cx (* try for max(size, 1000H) *)
  2017. jb axNotBig
  2018. mov cx, ax
  2019. axNotBig:
  2020. mov es, [__psp]
  2021. add bx, cx
  2022. mov ah, 4AH
  2023. extrn @DosInterrupt
  2024. (*%F NearCall *)
  2025. call far @DosInterrupt
  2026. (*%E *)
  2027. (*%T NearCall *)
  2028. call @DosInterrupt
  2029. (*%E *)
  2030. jnc allocDone (* success *)
  2031. mov cx, bx
  2032. add cx, [__psp]
  2033. sub cx, [__fheaptop] (* get what there is from DOS *)
  2034. dec cx
  2035. jcxz allocFail
  2036. mov ah, 4AH
  2037. extrn @DosInterrupt
  2038. (*%F NearCall *)
  2039. call far @DosInterrupt
  2040. (*%E *)
  2041. (*%T NearCall *)
  2042. call @DosInterrupt
  2043. (*%E *)
  2044. jc allocFail
  2045. allocDone:
  2046. mov es, [__psp]
  2047. add es:[2], cx (* adjust ceiling *)
  2048. allocFail:
  2049. ret 0
  2050. public __heap_align :
  2051. add ax, 2
  2052. jc oflow
  2053. cmp ax, 0FFF0H
  2054. ja sizeBig
  2055. add ax, 0FH (* converts byte size to para size *)
  2056. mov cl, 4
  2057. shr ax, cx (* paragraph align *)
  2058. ret 0
  2059. oflow:
  2060. or ax, ax
  2061. jne sizeBigger
  2062. sizeBig:
  2063. mov ax, 1000H
  2064. ret 0
  2065. sizeBigger:
  2066. mov ax, 1001H
  2067. ret 0
  2068. (*%E _OS2 *)
  2069. section
  2070. (****************************************************************************)
  2071. (*%F _OS2 *)
  2072. segment _TEXT(CODE, 28H)
  2073. extrn __psp
  2074. extrn __fheaptop
  2075. public __heap_free :
  2076. mov ax, es:[farFreeSize]
  2077. mov dx, 1000H (* free if large amount of free stack *)
  2078. cmp ax, dx (* is it worth it ? *)
  2079. jb noFree
  2080. mov es:[farFreeSize], dx
  2081. inc dx
  2082. mov bx, es
  2083. add bx, dx
  2084. mov es, [__psp]
  2085. mov es:[2], bx (* new ceiling *)
  2086. mov [__fheaptop], bx
  2087. dec word [__fheaptop]
  2088. sub bx, [__psp]
  2089. mov ah, 4AH (* give surplus back to DOS *)
  2090. extrn @DosInterrupt
  2091. (*%F NearCall *)
  2092. call far @DosInterrupt
  2093. (*%E *)
  2094. (*%T NearCall *)
  2095. call @DosInterrupt
  2096. (*%E *)
  2097. noFree:
  2098. (*%F NearCall *)
  2099. ret far 0
  2100. (*%E *)
  2101. (*%T NearCall *)
  2102. ret 0
  2103. (*%E *)
  2104. public __heap_merge :
  2105. push ds (* merges two blocks *)
  2106. mov ds, es:[farNextBlock]
  2107. mov cx, [farNextBlock]
  2108. mov ax, [farFreeSize]
  2109. add es:[farFreeSize], ax
  2110. mov es:[farNextBlock], cx
  2111. pop ds
  2112. ret 0
  2113. (*%E _OS2 *)
  2114. section
  2115. (***************************************************************************)
  2116. (*%F _OS2 *)
  2117. (*%F _DLLOVL *)
  2118. (* ------------------------------------------------------------------------
  2119. PROCEDURE - coreleft, farcoreleft, _memavl.
  2120. PRECONDITIONS - Far heap initialised.
  2121. POSTCONDITIONS - None.
  2122. IN PARAMETERS - None.
  2123. OUT PARAMETERS - Returns number of unallocated bytes in far heap(long).
  2124. CALLING CONVENTION - Standard.
  2125. NOTES - Causes Far heap to be initialised.
  2126. VERSION - MSDOS except Modula-2 Overlay Loader.
  2127. ------------------------------------------------------------------------ *)
  2128. segment _TEXT(CODE,28H)
  2129. segment _DATA(DATA, 28H)
  2130. farFreeSize = 14
  2131. farNextBlock = 16
  2132. extrn __core_lock
  2133. extrn __core_unlock
  2134. select _DATA
  2135. extrn __firstfree
  2136. extrn __psp
  2137. extrn __fheapstart
  2138. select _TEXT
  2139. (*%F NearPtr *)
  2140. public _coreleft :
  2141. public __memavl :
  2142. (*%E *)
  2143. public _farcoreleft :
  2144. (*%T _DLLOVL *)
  2145. push bp
  2146. mov bp, sp
  2147. (*%E *)
  2148. push bx
  2149. push cx
  2150. (*%F SameDS *)
  2151. push ds
  2152. mov bx, _DATA
  2153. mov ds, bx
  2154. (*%E *)
  2155. (*%T MThread *)
  2156. call far [__core_lock]
  2157. (*%E *)
  2158. (*%T _DLLOVL *)
  2159. extrn __get_heapstate
  2160. call far __get_heapstate
  2161. (*%E *)
  2162. sub ax, ax
  2163. mov cx, [__firstfree]
  2164. cmp cx, -1
  2165. je chkEmpty (* no heap *)
  2166. chkLoop:
  2167. jcxz chkEnd
  2168. mov es, cx
  2169. add ax, es:[farFreeSize]
  2170. mov cx, es:[farNextBlock]
  2171. jmp chkLoop
  2172. chkEnd:
  2173. push ax
  2174. mov es, [__psp]
  2175. mov ah, 4AH (* what has DOS got *)
  2176. mov bx, 0FFFFH
  2177. extrn @DosInterrupt
  2178. (*%F NearCall *)
  2179. call far @DosInterrupt
  2180. (*%E *)
  2181. (*%T NearCall *)
  2182. call @DosInterrupt
  2183. (*%E *)
  2184. mov cx, es:[2]
  2185. mov ax, es
  2186. sub cx, ax
  2187. sub bx, cx
  2188. pop ax
  2189. add ax, bx
  2190. mov dx, 10H
  2191. mul dx
  2192. sub ax, 10H
  2193. sbb dx, 0
  2194. jnc chkDone
  2195. sub ax, ax
  2196. cwd
  2197. chkDone:
  2198. (*%T MThread *)
  2199. call far [__core_unlock]
  2200. (*%E *)
  2201. (*%F SameDS *)
  2202. pop ds
  2203. (*%E *)
  2204. pop cx
  2205. pop bx
  2206. (*%T _DLLOVL *)
  2207. pop bp
  2208. (*%E *)
  2209. (*%F NearCall *)
  2210. ret far 0
  2211. (*%E *)
  2212. (*%T NearCall *)
  2213. ret 0
  2214. (*%E *)
  2215. chkEmpty:
  2216. mov ax, cx
  2217. cwd
  2218. jmp chkDone
  2219. dw __fheapstart (* Ensure Heap initialization *)
  2220. (*%E _DLLOVL *)
  2221. (*%E _OS2 *)
  2222. section
  2223. (***************************************************************************)
  2224. (*%F _OS2 *)
  2225. (*%F _DLLOVL *)
  2226. (* ------------------------------------------------------------------------
  2227. PROCEDURE - _fblockavail.
  2228. PRECONDITIONS - Far heap initialised.
  2229. POSTCONDITIONS - None.
  2230. IN PARAMETERS - None.
  2231. OUT PARAMETERS - Returns size of largest unallocated block in bytes
  2232. in far heap(long).
  2233. CALLING CONVENTION - Standard.
  2234. NOTES - Causes Far heap to be initialised.
  2235. VERSION - MSDOS except Modula-2 Overlay Loader.
  2236. ------------------------------------------------------------------------ *)
  2237. segment _TEXT(CODE,28H)
  2238. segment _DATA(DATA, 28H)
  2239. farFreeSize = 14
  2240. farNextBlock = 16
  2241. extrn __core_lock
  2242. extrn __core_unlock
  2243. extrn __firstfree
  2244. extrn __psp
  2245. select _TEXT
  2246. public __fblockavail :
  2247. (*%T _DLLOVL *)
  2248. push bp
  2249. mov bp, sp
  2250. (*%E *)
  2251. push bx
  2252. push cx
  2253. (*%F SameDS *)
  2254. push ds
  2255. mov bx, _DATA
  2256. mov ds, bx
  2257. (*%E *)
  2258. (*%T MThread *)
  2259. call far [__core_lock]
  2260. (*%E *)
  2261. (*%T _DLLOVL *)
  2262. extrn __get_heapstate
  2263. call far __get_heapstate
  2264. (*%E *)
  2265. sub ax, ax
  2266. mov cx, [__firstfree]
  2267. cmp cx, -1
  2268. je chkDone (* no heap *)
  2269. chkLoop:
  2270. jcxz chkEnd
  2271. mov es, cx
  2272. cmp ax, es:[farFreeSize]
  2273. ja blockSmall
  2274. mov ax, es:[farFreeSize]
  2275. blockSmall:
  2276. mov cx, es:[farNextBlock]
  2277. jmp chkLoop
  2278. chkEnd:
  2279. push ax
  2280. mov es, [__psp]
  2281. mov ah, 4AH (* what has DOS got *)
  2282. mov bx, 0FFFFH
  2283. extrn @DosInterrupt
  2284. extrn @DosInterrupt
  2285. (*%F NearCall *)
  2286. call far @DosInterrupt
  2287. (*%E *)
  2288. (*%T NearCall *)
  2289. call @DosInterrupt
  2290. (*%E *)
  2291. mov cx, es:[2]
  2292. mov ax, es
  2293. sub cx, ax
  2294. sub bx, cx
  2295. pop ax
  2296. cmp ax, bx
  2297. ja gotLargest
  2298. mov ax, bx
  2299. gotLargest:
  2300. mov dx, 10H
  2301. mul dx
  2302. chkDone:
  2303. (*%T MThread *)
  2304. call far [__core_unlock]
  2305. (*%E *)
  2306. (*%F SameDS *)
  2307. pop ds
  2308. (*%E *)
  2309. pop cx
  2310. pop bx
  2311. (*%T _DLLOVL *)
  2312. pop bp
  2313. (*%E *)
  2314. (*%F NearCall *)
  2315. ret far 0
  2316. (*%E *)
  2317. (*%T NearCall *)
  2318. ret 0
  2319. (*%E *)
  2320. (*%E _DLLOVL *)
  2321. (*%E _OS2 *)
  2322. section
  2323. (***************************************************************************)
  2324. (*%F _OS2 *)
  2325. (*%F _DLLOVL *)
  2326. (* ------------------------------------------------------------------------
  2327. PROCEDURE - _expand, _fexpand, realloc, _frealloc, hrealloc.
  2328. PRECONDITIONS - Far heap initialised.
  2329. POSTCONDITIONS - If successful, block allocation changed.
  2330. On error errno set to ENOMEM.
  2331. IN PARAMETERS - Far pointer to memory block, block size(long).
  2332. OUT PARAMETERS - Returns far pointer to memory block.
  2333. CALLING CONVENTION - Standard.
  2334. NOTES - realloc changes size of block allocated from far heap. If the
  2335. block cannot be expanded it is freed and another block allocated.
  2336. The contents of the old block are copied.
  2337. If size is zero the block will be freed.
  2338. If the pointer is NULL a new block will be allocated.
  2339. _expand will attempt to change the allocation of the block without
  2340. moving it.
  2341. VERSION - MSDOS.
  2342. ------------------------------------------------------------------------ *)
  2343. segment _DATA(DATA, 28H)
  2344. segment _TEXT(CODE,28H)
  2345. farFreeSize = 14
  2346. farNextBlock = 16
  2347. extrn _halloc
  2348. extrn __fmalloc
  2349. extrn __ffree
  2350. extrn _hfree
  2351. extrn __heap_norm
  2352. extrn __heap_align
  2353. extrn __heap_alloc
  2354. extrn __fheapstart
  2355. extrn __psp
  2356. extrn __firstfree
  2357. extrn __fheaptop
  2358. extrn __seterrno
  2359. extrn __core_lock
  2360. extrn __core_unlock
  2361. buffer = frame
  2362. size = 4+frame
  2363. currentblock = -2
  2364. expand = -4
  2365. newsize = -6
  2366. prevfree = -8
  2367. nextfree = -10
  2368. oldsize = -12
  2369. locals = 12
  2370. public __fexpand :
  2371. (*%F NearPtr *)
  2372. public __expand :
  2373. (*%E *)
  2374. push bp
  2375. mov bp, sp
  2376. sub sp, locals
  2377. (*%F RegParam *)
  2378. push bx
  2379. push cx
  2380. (*%E *)
  2381. mov byte [bp][expand], 1
  2382. jmp near expandEntry
  2383. public _hexpand :
  2384. push bp
  2385. mov bp, sp
  2386. sub sp, locals
  2387. mov byte [bp][expand], 1
  2388. jmp hrEnt
  2389. public _hrealloc :
  2390. push bp
  2391. mov bp, sp
  2392. sub sp, locals
  2393. mov byte [bp][expand], 0
  2394. hrEnt:
  2395. (*%F RegParam *)
  2396. push bx
  2397. push cx
  2398. (*%E *)
  2399. push si
  2400. (*%F SameDS *)
  2401. push ds
  2402. mov si, _DATA
  2403. mov ds, si
  2404. (*%E *)
  2405. (*%T MThread *)
  2406. call far [__core_lock]
  2407. (*%E *)
  2408. (*%T _DLLOVL *)
  2409. extrn __get_heapstate
  2410. call far __get_heapstate
  2411. (*%E *)
  2412. (*%F RegParam *)
  2413. les bx, [bp][buffer]
  2414. mov ax, [bp][size]
  2415. mov dx, [bp][size][2]
  2416. (*%E *)
  2417. (*%T RegParam *)
  2418. mov es, bx
  2419. mov bx, ax
  2420. mov ax, cx
  2421. (*%E *)
  2422. mov si, ax
  2423. or dx, dx
  2424. jne dontFree (* size = 0 - use free *)
  2425. or ax, ax
  2426. jne dontFree (* size = 0 - use free *)
  2427. (*%F RegParam *)
  2428. push es
  2429. push bx
  2430. (*%E *)
  2431. (*%T RegParam *)
  2432. mov ax, bx
  2433. mov bx, es
  2434. (*%E *)
  2435. (*%T NearCall *)
  2436. call _hfree
  2437. (*%E *)
  2438. (*%F NearCall *)
  2439. call far _hfree
  2440. (*%E *)
  2441. (*%F RegParam *)
  2442. add sp, 4
  2443. (*%E *)
  2444. sub ax, ax
  2445. cwd
  2446. jmp near reallocExit
  2447. dontFree:
  2448. mov cx, es
  2449. or cx, cx
  2450. jne hreallocWanted (* buffer = NULL, use malloc *)
  2451. (*%F RegParam *)
  2452. push dx
  2453. push ax
  2454. (*%E *)
  2455. (*%F RegParam *)
  2456. mov bx, dx
  2457. (*%E *)
  2458. (*%T NearCall *)
  2459. call _halloc
  2460. (*%E *)
  2461. (*%F NearCall *)
  2462. call far _halloc
  2463. (*%E *)
  2464. (*%F RegParam *)
  2465. add sp, 4
  2466. (*%E *)
  2467. jmp near reallocExit
  2468. hreallocWanted: (* arrive here to change allocation *)
  2469. cmp word [__firstfree], -1
  2470. je near reallocError (* get out - no heap *)
  2471. push dx
  2472. call __heap_norm (* normalise pointer *)
  2473. pop dx
  2474. jc near reallocError
  2475. call __heap_align (* paragraph align size *)
  2476. mov cx, 12
  2477. shl dx, cx
  2478. add ax, dx (* number of paragraphs requested *)
  2479. jmp hreallocEntry
  2480. public __frealloc :
  2481. (*%F NearPtr *)
  2482. public _realloc :
  2483. (*%E *)
  2484. push bp
  2485. mov bp, sp
  2486. sub sp, locals
  2487. (*%F RegParam *)
  2488. push bx
  2489. push cx
  2490. (*%E *)
  2491. mov byte [bp][expand], 0
  2492. expandEntry: (* expand arrives here *)
  2493. push si
  2494. (*%F SameDS *)
  2495. push ds
  2496. mov si, _DATA
  2497. mov ds, si
  2498. (*%E *)
  2499. (*%T MThread *)
  2500. call far [__core_lock]
  2501. (*%E *)
  2502. (*%T _DLLOVL *)
  2503. extrn __get_heapstate
  2504. call far __get_heapstate
  2505. (*%E *)
  2506. (*%F RegParam *)
  2507. les bx, [bp][buffer]
  2508. mov ax, [bp][size]
  2509. (*%E *)
  2510. (*%T RegParam *)
  2511. mov es, bx
  2512. mov bx, ax
  2513. mov ax, cx
  2514. (*%E *)
  2515. or ax, ax
  2516. mov si, ax
  2517. jne hdontFree (* size = 0 - use free *)
  2518. (*%F RegParam *)
  2519. push es
  2520. push bx
  2521. (*%E *)
  2522. (*%T RegParam *)
  2523. mov ax, bx
  2524. mov bx, es
  2525. (*%E *)
  2526. (*%T NearCall *)
  2527. call __ffree
  2528. (*%E *)
  2529. (*%F NearCall *)
  2530. call far __ffree
  2531. (*%E *)
  2532. (*%F RegParam *)
  2533. add sp, 4
  2534. (*%E *)
  2535. sub ax, ax
  2536. cwd
  2537. jmp near reallocExit
  2538. hdontFree:
  2539. mov cx, es
  2540. or cx, cx
  2541. jne reallocWanted (* buffer = NULL, use malloc *)
  2542. (*%F RegParam *)
  2543. push ax
  2544. (*%E *)
  2545. (*%T NearCall *)
  2546. call __fmalloc
  2547. (*%E *)
  2548. (*%F NearCall *)
  2549. call far __fmalloc
  2550. (*%E *)
  2551. (*%F RegParam *)
  2552. add sp, 2
  2553. (*%E *)
  2554. jmp near reallocExit
  2555. reallocWanted: (* arrive here to change allocation *)
  2556. mov cx, _DATA
  2557. mov ds, cx
  2558. cmp word [__firstfree], -1
  2559. je near reallocError (* get out - no heap *)
  2560. call __heap_norm (* normalise pointer *)
  2561. jc near reallocError
  2562. call __heap_align (* paragraph align size *)
  2563. hreallocEntry:
  2564. mov cx, es
  2565. mov [bp][currentblock], es
  2566. mov [bp][newsize], ax
  2567. mov bx, es:[farFreeSize]
  2568. mov [bp][oldsize], bx (* save old block size *)
  2569. cmp ax, bx (* what needs doing ? *)
  2570. ja reallocEnlarge (* enlarge current allocation *)
  2571. je near reallocDone (* nothing to do *)
  2572. reallocShrink: (* shrink current allocation *)
  2573. mov es:[farFreeSize], ax
  2574. add cx, ax
  2575. mov es, cx
  2576. sub bx, ax
  2577. mov es:[farFreeSize], bx
  2578. (*%T _DLLOVL *)
  2579. extrn __set_heapstate
  2580. call far __set_heapstate
  2581. (*%E *)
  2582. (*%F RegParam *)
  2583. mov ax, es
  2584. inc ax
  2585. push ax
  2586. sub ax, ax
  2587. push ax
  2588. (*%E *)
  2589. (*%T RegParam *)
  2590. mov bx, es
  2591. inc bx
  2592. sub ax, ax
  2593. (*%E *)
  2594. (*%T NearCall *)
  2595. call __ffree
  2596. (*%E *)
  2597. (*%F NearCall *)
  2598. call far __ffree
  2599. (*%E *)
  2600. (* use _free to deallocate surplus block *)
  2601. (*%F RegParam *)
  2602. add sp, 4
  2603. (*%E *)
  2604. (*%T _DLLOVL *)
  2605. mov es, [bp][currentblock]
  2606. jmp near reallocDone2
  2607. (*%E *)
  2608. mergeDone:
  2609. mov es, [bp][currentblock]
  2610. jmp near reallocDone
  2611. reallocEnlarge: (* enlarge allocation *)
  2612. sub dx, dx
  2613. mov ax, [__firstfree] (* find next free block *)
  2614. or ax, ax
  2615. je near reallocFindNew (* heap is full *)
  2616. mov cx, es
  2617. reallocLoop:
  2618. cmp ax, cx
  2619. ja reallocFoundNext
  2620. je near reallocError (* Error - block is already free *)
  2621. mov dx, ax
  2622. mov es, ax
  2623. mov ax, es:[farNextBlock]
  2624. or ax, ax
  2625. jne reallocLoop
  2626. jmp near reallocFindNew (* there are no free blocks above *)
  2627. reallocFoundNext:
  2628. mov [bp][prevfree], dx
  2629. mov [bp][nextfree], ax
  2630. add cx, bx (* is next free block contiginous *)
  2631. cmp cx, ax
  2632. jne near reallocFindNew (* no - find a new block *)
  2633. mov es, ax (* yes, but is it big enough *)
  2634. mov ax, [bp][newsize]
  2635. sub ax, bx (* we need ax more bytes *)
  2636. cmp ax, es:[farFreeSize] (* are there enough here *)
  2637. je reallocExactFit
  2638. ja reallocTooSmall (* no *)
  2639. reallocGotEnough:
  2640. mov es, [bp][nextfree] (* yes - *)
  2641. mov dx, es:[farFreeSize]
  2642. mov cx, es:[farNextBlock] (* save next free block *)
  2643. mov bx, [bp][currentblock]
  2644. mov ax, [bp][newsize]
  2645. mov es, bx
  2646. add dx, es:[farFreeSize] (* dx is size of both blocks *)
  2647. sub dx, ax (* dx is size of new free *)
  2648. mov es:[farFreeSize], ax (* set size to new *)
  2649. add ax, bx (* ax is now new free block *)
  2650. mov es, ax
  2651. mov es:[farNextBlock], cx
  2652. mov es:[farFreeSize], dx
  2653. reallocAdjust:
  2654. mov cx, [bp][prevfree] (* adjust previous free block *)
  2655. jcxz rFFree
  2656. mov es, cx
  2657. mov es:[farNextBlock], ax
  2658. jmp near reallocDone (* block has been increased - success *)
  2659. reallocExactFit:
  2660. mov es, [bp][currentblock]
  2661. mov ax, [bp][newsize]
  2662. mov es:[farFreeSize], ax (* merge blocks *)
  2663. mov es, [bp][nextfree]
  2664. mov ax, es:[farNextBlock]
  2665. jmp reallocAdjust
  2666. rFFree: (* there wasn't one - set first free *)
  2667. mov [__firstfree], ax
  2668. jmp near reallocDone
  2669. reallocTooSmall: (* arrive here if higher block is too small *)
  2670. mov bx, es
  2671. add bx, es:[farFreeSize]
  2672. cmp bx, [__fheaptop] (* is it the last block *)
  2673. jne reallocFindNew (* no - find a new block *)
  2674. reallocExtendHeap:
  2675. mov bx, es:[farFreeSize] (* yes - extend the heap *)
  2676. sub ax, bx
  2677. push ax
  2678. call __heap_alloc (* ax is extra required *)
  2679. pop ax
  2680. jcxz reallocFindNew (* couldn't get any - find a new block *)
  2681. add [__fheaptop], cx
  2682. mov es, [bp][nextfree]
  2683. add es:[farFreeSize], cx
  2684. cmp cx, ax
  2685. jb reallocFindNew (* couldn't get enough - find a new block *)
  2686. jmp reallocGotEnough
  2687. reallocFindNew: (* free this block and try to find new one *)
  2688. (*%T _DLLOVL *)
  2689. extrn __set_heapstate
  2690. call far __set_heapstate
  2691. (*%E *)
  2692. cmp byte [bp][expand], 0
  2693. jne reallocError (* if expand only give up here *)
  2694. (*%F RegParam *)
  2695. push si
  2696. (*%E *)
  2697. (*%T RegParam *)
  2698. mov ax, si
  2699. (*%E *)
  2700. (*%T NearCall *)
  2701. call __fmalloc
  2702. (*%E *)
  2703. (*%F NearCall *)
  2704. call far __fmalloc
  2705. (*%E *)
  2706. (*%F RegParam *)
  2707. add sp, 2
  2708. (*%E *)
  2709. or dx, dx (* malloc returned NULL - *)
  2710. je reallocError (* couldn't find a new one *)
  2711. push di
  2712. mov bx, [bp][oldsize] (* number of bytes to move *)
  2713. mov cl, 4
  2714. shl bx, cl
  2715. mov cx, bx
  2716. mov es, dx (* destination *)
  2717. mov di, ax
  2718. push ds
  2719. inc word [bp][currentblock]
  2720. mov ds, [bp][currentblock]
  2721. mov si, ax
  2722. rep ; movsb
  2723. pop ds
  2724. pop di
  2725. push dx
  2726. (*%F RegParam *)
  2727. push [bp][currentblock]
  2728. sub ax, ax
  2729. push ax
  2730. (*%E *)
  2731. (*%T RegParam *)
  2732. mov bx, [bp][currentblock]
  2733. sub ax, ax
  2734. (*%E *)
  2735. (*%T NearCall *)
  2736. call __ffree
  2737. (*%E *)
  2738. (*%F NearCall *)
  2739. call far __ffree
  2740. (*%E *)
  2741. (*%F RegParam *)
  2742. add sp, 4
  2743. (*%E *)
  2744. pop dx (* free old block *)
  2745. jmp reallocMal
  2746. reallocDone: (* success *)
  2747. (*%T _DLLOVL *)
  2748. extrn __set_heapstate
  2749. call far __set_heapstate
  2750. reallocDone2: (* heap state reset by free *)
  2751. (*%E *)
  2752. mov dx, [bp][currentblock]
  2753. inc dx
  2754. reallocMal:
  2755. sub ax, ax
  2756. jmp reallocExit (* return address of block *)
  2757. reallocError: (* failure *)
  2758. mov ax, ENOMEM
  2759. (*%F NearCall *)
  2760. call far __seterrno
  2761. (*%E *)
  2762. (*%T NearCall *)
  2763. call __seterrno
  2764. (*%E *)
  2765. sub ax, ax (* return NULL *)
  2766. sub dx, dx
  2767. reallocExit:
  2768. (*%T MThread *)
  2769. call far [__core_unlock]
  2770. (*%E *)
  2771. (*%F SameDS *)
  2772. pop ds
  2773. (*%E *)
  2774. pop si
  2775. (*%F RegParam *)
  2776. pop cx
  2777. pop bx
  2778. (*%E *)
  2779. mov sp, bp
  2780. pop bp
  2781. (*%F NearCall *)
  2782. ret far 0
  2783. (*%E *)
  2784. (*%T NearCall *)
  2785. ret 0
  2786. (*%E *)
  2787. (*%E _DLLOVL *)
  2788. (*%E _OS2 *)
  2789. section
  2790. (***************************************************************************)
  2791. (*%F _OS2 *)
  2792. (*%F _DLLOVL *)
  2793. (* ------------------------------------------------------------------------
  2794. PROCEDURE - _msize, _fmsize.
  2795. PRECONDITIONS - Block must be allocated from far heap.
  2796. POSTCONDITIONS - None.
  2797. IN PARAMETERS - Far pointer to memory block.
  2798. OUT PARAMETERS - Returns size in bytes of memory block.
  2799. CALLING CONVENTION - Standard.
  2800. NOTES -
  2801. VERSION - MSDOS.
  2802. ------------------------------------------------------------------------ *)
  2803. segment _TEXT(CODE,28H)
  2804. segment _DATA(DATA, 28H)
  2805. farFreeSize = 14
  2806. select _TEXT
  2807. (*%F NearPtr *)
  2808. public __msize :
  2809. (*%E *)
  2810. public __fmsize :
  2811. (*%F RegParam *)
  2812. buffer = frame
  2813. push bp
  2814. mov bp, sp
  2815. mov ax, [bp][buffer][2]
  2816. dec ax
  2817. mov es, ax
  2818. mov bx, [bp][buffer]
  2819. (*%E *)
  2820. (*%T RegParam *)
  2821. (*%T _DLLOVL *)
  2822. push bp
  2823. mov bp, sp
  2824. (*%E *)
  2825. push cx
  2826. dec bx
  2827. mov es, bx
  2828. mov bx, ax
  2829. (*%E *)
  2830. mov ax, es:[bx][farFreeSize]
  2831. mov cl, 4
  2832. shl ax, cl
  2833. (*%T RegParam *)
  2834. pop cx
  2835. (*%T _DLLOVL *)
  2836. pop bp
  2837. (*%E *)
  2838. (*%E *)
  2839. (*%F RegParam *)
  2840. pop bp
  2841. (*%E *)
  2842. (*%F NearCall *)
  2843. ret far 0
  2844. (*%E *)
  2845. (*%T NearCall *)
  2846. ret 0
  2847. (*%E *)
  2848. (*%E _DLLOVL *)
  2849. (*%E _OS2 *)
  2850. section
  2851. (***************************************************************************)
  2852. (*%F _OS2 *)
  2853. (*%F _DLLOVL *)
  2854. (* ------------------------------------------------------------------------
  2855. PROCEDURE - _heapchk, _fheapchk, _heapset, _fheapset.
  2856. PRECONDITIONS - Far heap must be initialised.
  2857. POSTCONDITIONS - _heapset fills each free block with the parameter value.
  2858. IN PARAMETERS - _heapset takes fill value(int).
  2859. OUT PARAMETERS - Returns state of heap.
  2860. 0 _HEAPOK if OK
  2861. -1 _HEAPEMPTY if heap not initialised
  2862. -2 _HEAPBADBEGIN if initial header bad
  2863. -3 _HEAPBADNODE if heap is damaged
  2864. -4 _HEAPOVERFLOW if heap past ceiling
  2865. CALLING CONVENTION - Standard.
  2866. NOTES -
  2867. VERSION - MSDOS.
  2868. ------------------------------------------------------------------------ *)
  2869. segment _TEXT(CODE,28H)
  2870. segment _DATA(DATA, 28H)
  2871. extrn _memset
  2872. extrn __heap_val
  2873. extrn __heap_norm
  2874. extrn __core_lock
  2875. extrn __core_unlock
  2876. extrn __fheapstart
  2877. extrn __psp
  2878. extrn __fmemsetup
  2879. extrn __firstfree
  2880. extrn __fheaptop
  2881. select _TEXT
  2882. public __fheapchk :
  2883. (*%F NearPtr *)
  2884. public __heapchk :
  2885. (*%E *)
  2886. push bx
  2887. push cx
  2888. push dx
  2889. sub bx, bx (* dont fill *)
  2890. jmp hpShared
  2891. _HEAPOK = 0
  2892. _HEAPEMPTY = -1
  2893. _HEAPBADBEGIN = -2
  2894. _HEAPBADNODE = -3
  2895. _HEAPOVERFLOW = -4
  2896. mem_reg_saved = 6
  2897. fill = frame+mem_reg_saved
  2898. public __fheapset :
  2899. (*%F NearPtr *)
  2900. public __heapset :
  2901. (*%E *)
  2902. push bx
  2903. push cx
  2904. push dx
  2905. mov bh, 1
  2906. hpShared:
  2907. push bp
  2908. mov bp, sp
  2909. push di
  2910. (*%F SameDS *)
  2911. push ds
  2912. mov cx, _DATA
  2913. mov ds, cx
  2914. (*%E *)
  2915. (*%T MThread *)
  2916. call far [__core_lock]
  2917. (*%E *)
  2918. (*%T _DLLOVL *)
  2919. extrn __get_heapstate
  2920. call far __get_heapstate
  2921. (*%E *)
  2922. (*%F RegParam *)
  2923. mov al, [bp][fill]
  2924. (*%E *)
  2925. mov ah, bh
  2926. mov dx, [__firstfree]
  2927. cmp dx, -1
  2928. je chkEmpty (* no heap *)
  2929. mov bx, [__fheapstart]
  2930. or bx, bx (* heap unitialised *)
  2931. je chkBadStart
  2932. chkLoop:
  2933. mov es, bx (* check each block *)
  2934. cmp bx, dx (* is it free list *)
  2935. jne chkNotFree (* no - continue *)
  2936. mov cx, es:[farFreeSize]
  2937. mov dx, es:[farNextBlock] (* get next free *)
  2938. or ah, ah
  2939. je NodeOK (* fill if ah *)
  2940. shl cx, 1
  2941. shl cx, 1
  2942. shl cx, 1
  2943. sub cx, 2
  2944. push ax
  2945. mov ah, al
  2946. mov di, 12H
  2947. rep ; stosw
  2948. pop ax (* fill free block *)
  2949. jmp NodeOK
  2950. chkNotFree:
  2951. jb NodeOK
  2952. or dx, dx
  2953. jne chkBadNode (* bad heap node *)
  2954. NodeOK:
  2955. add bx, es:[farFreeSize]
  2956. cmp bx, [__fheaptop]
  2957. ja chkBadTop (* overflow *)
  2958. jb chkLoop
  2959. or dx, dx
  2960. je chkOK
  2961. chkBadTop:
  2962. mov ax, _HEAPOVERFLOW
  2963. jmp chkDone
  2964. chkEmpty:
  2965. mov ax, _HEAPEMPTY
  2966. jmp chkDone
  2967. chkBadStart:
  2968. mov ax, _HEAPBADBEGIN
  2969. jmp chkDone
  2970. chkBadNode:
  2971. mov ax, _HEAPBADNODE
  2972. jmp chkDone
  2973. chkOK:
  2974. sub ax, ax
  2975. chkDone:
  2976. (*%T MThread *)
  2977. call far [__core_unlock]
  2978. (*%E *)
  2979. (*%F SameDS *)
  2980. pop ds
  2981. (*%E *)
  2982. pop di
  2983. pop bp
  2984. pop dx
  2985. pop cx
  2986. pop bx
  2987. (*%F NearCall *)
  2988. ret far 0
  2989. (*%E *)
  2990. (*%T NearCall *)
  2991. ret 0
  2992. (*%E *)
  2993. (*%E _DLLOVL *)
  2994. (*%E _OS2 *)
  2995. section
  2996. (***************************************************************************)
  2997. (*%F _OS2 *)
  2998. (*%F _DLLOVL *)
  2999. (* ------------------------------------------------------------------------
  3000. PROCEDURE - _heapwalk, _fheapwalk.
  3001. PRECONDITIONS - Far heap must be initialised.
  3002. heapinfo structure initialised to NULL, or contains result
  3003. of a preevious call to _heapwalk.
  3004. POSTCONDITIONS - heapinfo structure contains details of current heap node.
  3005. IN PARAMETERS - Pointer to heapinfo structure
  3006. OUT PARAMETERS - Returns state of heap.
  3007. _HEAPOK = 0
  3008. _HEAPEMPTY = -1
  3009. _HEAPBADBEGIN = -2
  3010. _HEAPBADNODE = -3
  3011. _HEAPOVERFLOW = -4
  3012. _HEAPBADPTR = -6
  3013. CALLING CONVENTION - Standard.
  3014. NOTES -
  3015. VERSION - MSDOS.
  3016. ------------------------------------------------------------------------ *)
  3017. segment _TEXT(CODE,28H)
  3018. segment _DATA(DATA, 28H)
  3019. pentry = 0
  3020. size = 4
  3021. useflag = 6
  3022. _HEAPOK = 0
  3023. _HEAPEMPTY = -1
  3024. _HEAPBADBEGIN = -2
  3025. _HEAPBADNODE = -3
  3026. _HEAPOVERFLOW = -4
  3027. _HEAPEND = -5
  3028. _HEAPBADPTR = -6
  3029. select _DATA
  3030. extrn __fheapstart
  3031. extrn __fheaptop
  3032. extrn __firstfree
  3033. lastfree : dw 0, 0
  3034. select _TEXT
  3035. public __fheapwalk :
  3036. (*%F NearPtr *)
  3037. public __heapwalk :
  3038. (*%E *)
  3039. (*%F RegParam *)
  3040. entry = frame
  3041. dgroup = -2
  3042. locals = 2
  3043. (*%E *)
  3044. (*%T RegParam *)
  3045. entry = -4
  3046. dgroup = -6
  3047. locals = 6
  3048. (*%E *)
  3049. push bp
  3050. mov bp, sp
  3051. sub sp, locals
  3052. (*%F RegParam *)
  3053. push bx
  3054. push cx
  3055. push dx
  3056. (*%E *)
  3057. (*%T RegParam *)
  3058. (*%T NearPtr *)
  3059. push bx
  3060. (*%E *)
  3061. push cx
  3062. push dx
  3063. (*%F NearPtr *)
  3064. mov [bp][entry][2], bx
  3065. (*%E *)
  3066. mov [bp][entry], ax
  3067. (*%E *)
  3068. push di
  3069. push si
  3070. push ds
  3071. (*%F SameDS *)
  3072. mov cx, _DATA
  3073. mov ds, cx
  3074. (*%E *)
  3075. mov [bp][dgroup], ds
  3076. (*%T _DLLOVL *)
  3077. extrn __get_heapstate
  3078. call far __get_heapstate
  3079. (*%E *)
  3080. (*%F NearPtr *)
  3081. les bx, [bp][entry]
  3082. (*%E *)
  3083. (*%T NearPtr *)
  3084. mov bx, [bp][entry]
  3085. push ds
  3086. pop es
  3087. (*%E *)
  3088. mov cx, es:[bx][pentry][2]
  3089. mov es, [bp][dgroup]
  3090. or cx, cx
  3091. jnz notFirst
  3092. mov cx, es:[__firstfree]
  3093. cmp cx, -1
  3094. je near heapNotInit
  3095. mov es:[lastfree], cx
  3096. mov cx, es:[__fheapstart]
  3097. mov ds, cx
  3098. mov ax, [farFreeSize]
  3099. jmp storeNode
  3100. notFirst:
  3101. cmp cx, es:[__fheapstart]
  3102. jb near invalidPtr
  3103. cmp cx, es:[__fheaptop]
  3104. jae invalidPtr
  3105. mov ds, cx
  3106. add cx, [farFreeSize]
  3107. cmp cx, es:[__fheaptop]
  3108. je atHeapTop
  3109. mov ds, cx
  3110. mov ax, [farFreeSize]
  3111. storeNode:
  3112. (*%F NearPtr *)
  3113. mov es, [bp][entry][2]
  3114. (*%E *)
  3115. (*%T NearPtr *)
  3116. mov es, [bp][dgroup]
  3117. (*%E *)
  3118. mov word es:[bx][pentry], 0
  3119. mov word es:[bx][pentry][2], cx
  3120. mov dx, cx
  3121. mov cl, 4
  3122. shl ax, cl
  3123. jnc sizeOK
  3124. mov ax, -1 (* can only return MAX(CARDINAL) for a huge block *)
  3125. jmp gotSize
  3126. sizeOK:
  3127. sub ax, 2
  3128. gotSize:
  3129. mov es:[bx][size], ax
  3130. mov ax, 1
  3131. mov es, [bp][dgroup]
  3132. cmp dx, es:[lastfree]
  3133. jne notFree
  3134. sub ax, ax
  3135. mov cx, [farNextBlock]
  3136. mov es:[lastfree], cx
  3137. notFree:
  3138. ja badNode
  3139. (*%F NearPtr *)
  3140. mov es, [bp][entry][2]
  3141. (*%E *)
  3142. (*%T NearPtr *)
  3143. mov es, [bp][dgroup]
  3144. (*%E *)
  3145. mov es:[bx][useflag], ax
  3146. success:
  3147. mov ax, _HEAPOK
  3148. exit:
  3149. pop ds
  3150. pop si
  3151. pop di
  3152. (*%F RegParam *)
  3153. pop dx
  3154. pop cx
  3155. pop bx
  3156. (*%E *)
  3157. (*%T RegParam *)
  3158. pop dx
  3159. pop cx
  3160. (*%T NearPtr *)
  3161. pop bx
  3162. (*%E *)
  3163. (*%E *)
  3164. mov sp, bp
  3165. pop bp
  3166. (*%F NearCall *)
  3167. ret far 0
  3168. (*%E *)
  3169. (*%T NearCall *)
  3170. ret 0
  3171. (*%E *)
  3172. heapNotInit:
  3173. mov ax, _HEAPEMPTY
  3174. jmp exit
  3175. atHeapTop:
  3176. mov ds, [bp][dgroup]
  3177. cmp word [lastfree], 0
  3178. jne badNode
  3179. mov ax, _HEAPEND
  3180. jmp exit
  3181. badNode:
  3182. mov ax, _HEAPBADNODE
  3183. jmp exit
  3184. invalidPtr:
  3185. mov ax, _HEAPBADPTR
  3186. jmp exit
  3187. (*%E _DLLOVL *)
  3188. (*%E _OS2 *)
  3189. section
  3190. (****************************************************************************)
  3191. (*%T _OS2 *)
  3192. (* ------------------------------------------------------------------------
  3193. PROCEDURE - __initfmem.
  3194. PRECONDITIONS - None.
  3195. POSTCONDITIONS - __fmemsetup = TRUE.
  3196. IN PARAMETERS - None.
  3197. OUT PARAMETERS - None.
  3198. CALLING CONVENTION - Standard.
  3199. NOTES - .
  3200. VERSION - _OS2.
  3201. ------------------------------------------------------------------------ *)
  3202. segment _INIT(INIT_CODE,28H)
  3203. segment _TEXT(CODE,28H)
  3204. segment _DATA(DATA, 28H)
  3205. select _DATA
  3206. extrn __nheaptop
  3207. extrn __fmemsetup
  3208. select _TEXT
  3209. do_initfmem : (* defined later on ! *)
  3210. select _INIT
  3211. (*%F NearCall *)
  3212. initfmem : dw MAGIC_NUM
  3213. db PR1
  3214. dd do_initfmem
  3215. (*%E *)
  3216. (*%T NearCall *)
  3217. initfmem : dw MAGIC_NUM
  3218. db PR1
  3219. dw do_initfmem
  3220. (*%E *)
  3221. select _DATA
  3222. public __firstheap : dw 0, initfmem (* start of heap *)
  3223. select _TEXT
  3224. public __initfmem :
  3225. (*%F SameDS *)
  3226. push ds
  3227. mov ax, _DATA
  3228. mov ds, ax
  3229. (*%E *)
  3230. not byte [__fmemsetup]
  3231. (*%F SameDS *)
  3232. pop ds
  3233. (*%E *)
  3234. (*%F NearCall *)
  3235. ret far 0
  3236. (*%E *)
  3237. (*%T NearCall *)
  3238. ret 0
  3239. (*%E *)
  3240. (*%E _OS2 *)
  3241. section
  3242. (****************************************************************************)
  3243. (*%T _OS2 *)
  3244. (* ------------------------------------------------------------------------
  3245. PROCEDURE - __newheap, internal.
  3246. PRECONDITIONS - called from far heap function.
  3247. POSTCONDITIONS - A new heap segement is initialised.
  3248. Carry flag set if error.
  3249. IN PARAMETERS - None.
  3250. OUT PARAMETERS - es:di points to first free block in heap segment.
  3251. CALLING CONVENTION - Near Call, es:di return.
  3252. NOTES - Not called directly in XLarge model.
  3253. VERSION - _OS2.
  3254. ------------------------------------------------------------------------ *)
  3255. segment _TEXT(CODE, 28H)
  3256. extrn DOSALLOCSEG
  3257. extrn _memset
  3258. extrn __seterrno
  3259. extrn __osalloc
  3260. select _TEXT
  3261. SEG_GIVEABLE = 1
  3262. SEG_GETTABLE = 2
  3263. SEG_DISCARDABLE = 4
  3264. oldheap = sframe
  3265. public __newheap :
  3266. push bp
  3267. mov bp, sp
  3268. sub ax, ax (* get a new heap from OS *)
  3269. push ax
  3270. call __osalloc
  3271. add sp, 2
  3272. or dx, dx
  3273. jz nhError
  3274. mov es, dx
  3275. mov word es:[nextHeap], 0
  3276. mov word es:[statHeap], HEAP_ALLOCATED
  3277. mov di, [bp][oldheap]
  3278. mov es:[prevHeap], di
  3279. or di, di
  3280. jz noPrevHeap
  3281. mov bx, es
  3282. mov es, di
  3283. mov es:[nextHeap], bx
  3284. mov es, bx
  3285. noPrevHeap:
  3286. mov di, heapStart
  3287. mov es:[firstFree], di
  3288. mov word es:[di][OS2FreeSize], OS2MAXSIZE
  3289. mov word es:[di][OS2NextBlock], 0
  3290. clc
  3291. nhDone:
  3292. pop bp
  3293. ret 0 (* es:di is first free block *)
  3294. nhError:
  3295. stc
  3296. jmp nhDone
  3297. (*%E _OS2 *)
  3298. section
  3299. (****************************************************************************)
  3300. (*%T _OS2 *)
  3301. (* ------------------------------------------------------------------------
  3302. PROCEDURE - __newheapr, internal.
  3303. PRECONDITIONS - called from far heap function.
  3304. POSTCONDITIONS - A new heap segement is initialised.
  3305. Carry flag set if error.
  3306. IN PARAMETERS - None.
  3307. OUT PARAMETERS - es:di points to first free block in heap segment.
  3308. CALLING CONVENTION - Near Call, es:di return.
  3309. NOTES - XLarge model only. Attenpts to expand any inactive segments
  3310. before calling __newheap.
  3311. VERSION - _OS2.
  3312. ------------------------------------------------------------------------ *)
  3313. segment _TEXT(CODE, 28H)
  3314. extrn __newheap
  3315. extrn DOSREALLOCSEG
  3316. extrn __firstheap
  3317. select _TEXT
  3318. public __newheapr :
  3319. mov cx, [__firstheap]
  3320. heaprLoop:
  3321. jcxz allocateNewHeap
  3322. mov es, cx
  3323. cmp byte es:[statHeap], HEAP_FREE
  3324. je expandHeap
  3325. mov cx, es:[nextHeap]
  3326. jmp heaprLoop
  3327. expandHeap:
  3328. sub ax, ax
  3329. push ax
  3330. push es
  3331. call far DOSREALLOCSEG
  3332. or ax, ax
  3333. jnz nhError
  3334. mov word es:[statHeap], HEAP_ALLOCATED
  3335. mov di, heapStart
  3336. mov es:[firstFree], di
  3337. mov word es:[di][OS2FreeSize], OS2MAXSIZE
  3338. mov word es:[di][OS2NextBlock], 0
  3339. clc
  3340. jmp nhDone
  3341. allocateNewHeap:
  3342. push es
  3343. call __newheap
  3344. pop ax
  3345. nhDone:
  3346. ret 0 (* es:di is first free block *)
  3347. nhError:
  3348. stc
  3349. jmp nhDone
  3350. (*%E _OS2 *)
  3351. section
  3352. (****************************************************************************)
  3353. (*%T _OS2 *)
  3354. (* ------------------------------------------------------------------------
  3355. PROCEDURE - __osalloc, internal.
  3356. PRECONDITIONS - called from far heap function.
  3357. POSTCONDITIONS - Segment allocated from _OS2.
  3358. IN PARAMETERS - Size(int).
  3359. OUT PARAMETERS - Returns pointer to new segment.
  3360. CALLING CONVENTION - Near Call.
  3361. NOTES -
  3362. VERSION - _OS2 .
  3363. ------------------------------------------------------------------------ *)
  3364. segment _TEXT(CODE, 28H)
  3365. segment _DATA(DATA, 28H)
  3366. extrn DOSALLOCSEG
  3367. extrn _memset
  3368. extrn __seterrno
  3369. select _DATA
  3370. extrn __memtype
  3371. select _TEXT
  3372. size = sframe
  3373. sel = -2
  3374. locals = 2
  3375. SEG_GIVEABLE = 1
  3376. SEG_GETTABLE = 2
  3377. SEG_DISCARDABLE = 4
  3378. public __osalloc :
  3379. push bp
  3380. mov bp, sp
  3381. sub sp, locals
  3382. push [bp][size]
  3383. lea ax, [bp][sel]
  3384. push ss
  3385. push ax
  3386. mov ax, [__memtype]
  3387. push ax
  3388. call far DOSALLOCSEG
  3389. or ax, ax
  3390. jne osallocError
  3391. sub ax, ax
  3392. mov dx, [bp][sel]
  3393. osallocDone:
  3394. mov sp, bp
  3395. pop bp
  3396. ret 0
  3397. osallocError:
  3398. mov ax, ENOMEM
  3399. push ax
  3400. (*%F NearCall *)
  3401. call far __seterrno
  3402. (*%E *)
  3403. (*%T NearCall *)
  3404. call __seterrno
  3405. (*%E *)
  3406. sub ax, ax
  3407. cwd
  3408. jmp osallocDone
  3409. (*%E _OS2 *)
  3410. section
  3411. (***************************************************************************)
  3412. (*%T _OS2 *)
  3413. (* ------------------------------------------------------------------------
  3414. PROCEDURE - __osfree, internal.
  3415. PRECONDITIONS - called from far heap function.
  3416. POSTCONDITIONS - Segment returned to _OS2.
  3417. IN PARAMETERS - None.
  3418. OUT PARAMETERS - None.
  3419. CALLING CONVENTION - Standard Call.
  3420. NOTES - Not used in Xlarge model.
  3421. VERSION - _OS2 .
  3422. ------------------------------------------------------------------------ *)
  3423. segment _TEXT(CODE, 28H)
  3424. extrn DOSFREESEG
  3425. select _TEXT
  3426. public __osfree :
  3427. push ax
  3428. call far DOSFREESEG
  3429. (*%F NearCall *)
  3430. ret far 0
  3431. (*%E *)
  3432. (*%T NearCall *)
  3433. ret 0
  3434. (*%E *)
  3435. (*%E _OS2 *)
  3436. section
  3437. (***************************************************************************)
  3438. (*%T _OS2 *)
  3439. (* ------------------------------------------------------------------------
  3440. PROCEDURE - __osfreer, internal.
  3441. PRECONDITIONS - called from far heap function.
  3442. POSTCONDITIONS - Segment shrunk but not returned to _OS2.
  3443. IN PARAMETERS - None.
  3444. OUT PARAMETERS - None.
  3445. CALLING CONVENTION - Standard Call.
  3446. NOTES - Used in Xlarge model.
  3447. VERSION - _OS2 .
  3448. ------------------------------------------------------------------------ *)
  3449. segment _TEXT(CODE, 28H)
  3450. segment _DATA(DATA, 28H)
  3451. extrn DOSREALLOCSEG
  3452. select _TEXT
  3453. public __osfreer :
  3454. mov byte es:[statHeap], HEAP_FREE
  3455. mov word es:[firstFree], 0
  3456. mov bx, heapStart
  3457. push bx
  3458. push es
  3459. call far DOSREALLOCSEG
  3460. (*%F NearCall *)
  3461. ret far 0
  3462. (*%E *)
  3463. (*%T NearCall *)
  3464. ret 0
  3465. (*%E *)
  3466. (*%E _OS2 *)
  3467. section
  3468. (***************************************************************************)
  3469. (*%T _OS2 *)
  3470. (*%F _DLL *)
  3471. (* ------------------------------------------------------------------------
  3472. PROCEDURE - __initnmem.
  3473. PRECONDITIONS - __heap_size initialised. __near_heap_start defined in
  3474. main module.
  3475. POSTCONDITIONS - Near heap set up. __nheapsetup = TRUE, _nheapstart and
  3476. __nheaptop mark bounding offsets. __nfirstfree marks
  3477. first free block.
  3478. No memory returned to _OS2.
  3479. IN PARAMETERS - None.
  3480. OUT PARAMETERS - None.
  3481. CALLING CONVENTION - Standard.
  3482. NOTES - Init code section brought in by reference to __nfirstfree.
  3483. VERSION - _OS2 (Not DLLs).
  3484. ------------------------------------------------------------------------ *)
  3485. segment _INIT(INIT_CODE,28H)
  3486. segment _TEXT(CODE,28H)
  3487. segment _DATA(DATA, 28H)
  3488. freeSize = 0
  3489. nextBlock = 2
  3490. extrn DOSREALLOCSEG
  3491. select _DATA
  3492. extrn __nheaptop
  3493. extrn __near_heap_start
  3494. extrn __nheapstart
  3495. extrn _x_bss_end
  3496. extrn __farstack
  3497. extrn __nmemsetup
  3498. extrn __psp
  3499. extrn __stklen
  3500. extrn __heap_base
  3501. extrn __heap_size
  3502. extrn __SSisDS
  3503. select _TEXT
  3504. do_initnmem : (* defined later on ! *)
  3505. select _INIT
  3506. initnmem : dw MAGIC_NUM
  3507. db PR1
  3508. (*%F NearCall *)
  3509. dd do_initnmem
  3510. (*%E *)
  3511. (*%T NearCall *)
  3512. dw do_initnmem
  3513. (*%E *)
  3514. select _DATA
  3515. public __nfirstfree : dw 0, initnmem
  3516. select _TEXT
  3517. public __initnmem :
  3518. push bp
  3519. mov bp, sp
  3520. push di
  3521. cmp byte [__nmemsetup], 0
  3522. jne ninitDone
  3523. not byte [__nmemsetup]
  3524. mov di, __near_heap_start
  3525. add di, 3
  3526. and di, ~1
  3527. mov dx, di
  3528. add dx, [__heap_size]
  3529. jnc sizeSet
  3530. mov dx, -1
  3531. sizeSet:
  3532. sub dx, 2
  3533. mov cx, dx
  3534. sub cx, 10H
  3535. cmp cx, di
  3536. jbe noHeap
  3537. mov [__nheaptop], dx
  3538. sub dx, di
  3539. mov [__nheapstart], di
  3540. mov [__nfirstfree], di
  3541. mov [di][nearFreeSize], dx
  3542. mov word [di][nearNextBlock], 0
  3543. ninitDone:
  3544. pop di
  3545. pop bp
  3546. (*%F NearCall *)
  3547. ret far 0
  3548. (*%E *)
  3549. (*%T NearCall *)
  3550. ret 0
  3551. (*%E *)
  3552. noHeap:
  3553. mov word [__nfirstfree], -1
  3554. jmp ninitDone
  3555. (*%E _DLL *)
  3556. (*%E _OS2 *)
  3557. section
  3558. (***************************************************************************)
  3559. (*%T _OS2 *)
  3560. (* ------------------------------------------------------------------------
  3561. PROCEDURE - _expand, _fexpand, realloc, _frealloc, hrealloc.
  3562. PRECONDITIONS - Far heap initialised.
  3563. POSTCONDITIONS - If successful, block allocation changed.
  3564. On error errno set to ENOMEM.
  3565. IN PARAMETERS - Far pointer to memory block, block size(long).
  3566. OUT PARAMETERS - Returns far pointer to memory block.
  3567. CALLING CONVENTION - Standard.
  3568. NOTES - realloc changes size of block allocated from far heap. If the
  3569. block cannot be expanded it is freed and another block allocated.
  3570. The contents of the old block are copied.
  3571. If size is zero the block will be freed.
  3572. If the pointer is NULL a new block will be allocated.
  3573. _expand will attempt to change the allocation of the block without
  3574. moving it.
  3575. VERSION - _OS2.
  3576. ------------------------------------------------------------------------*)
  3577. segment _TEXT(CODE,28H)
  3578. segment _DATA(DATA, 28H)
  3579. extrn __fmalloc
  3580. extrn __ffree
  3581. extrn DOSEXITCRITSEC
  3582. extrn DOSENTERCRITSEC
  3583. extrn DOSREALLOCSEG
  3584. extrn __seterrno
  3585. select _DATA
  3586. extrn __fheapsem
  3587. extrn __firstheap
  3588. select _TEXT
  3589. (*%F RegParam *)
  3590. buffer = frame
  3591. size = 4+frame
  3592. oldsize = -2
  3593. locals = 2
  3594. (*%E *)
  3595. (*%T RegParam *)
  3596. size = -4
  3597. oldsize = -2
  3598. buffer = -8
  3599. locals = 8
  3600. (*%E *)
  3601. public __frealloc :
  3602. (*%F NearPtr *)
  3603. public _realloc :
  3604. (*%E *)
  3605. push bp
  3606. mov bp, sp
  3607. sub sp, locals
  3608. push bx
  3609. push cx
  3610. push di
  3611. push si
  3612. (*%F SameDS *)
  3613. push ds
  3614. mov si, _DATA
  3615. mov ds, si
  3616. (*%E *)
  3617. (*%F RegParam *)
  3618. mov ax, [bp][size]
  3619. les di, [bp][buffer]
  3620. (*%E *)
  3621. (*%T RegParam *)
  3622. mov di, ax
  3623. mov es, bx
  3624. mov ax, cx
  3625. mov [bp][size], cx
  3626. mov [bp][buffer], di
  3627. mov [bp][buffer][2], es
  3628. (*%E *)
  3629. mov cx, es
  3630. jcxz near reallocMalloc
  3631. or ax, ax
  3632. jz near reallocFree
  3633. or di, di
  3634. jz near reallocSys (* OS allocated block *)
  3635. sub di, 2
  3636. mov cx, es:[di]
  3637. mov [bp][oldsize], cx
  3638. test ax, 1
  3639. jz sizeEven
  3640. inc ax
  3641. jz near largeBlock
  3642. sizeEven:
  3643. add ax, 2
  3644. jc near largeBlock
  3645. cmp ax, OS2MAXSIZE
  3646. jae near largeBlock
  3647. cmp ax, cx
  3648. je near reallocExit
  3649. ja reallocExpand
  3650. reallocShrink:
  3651. sub cx, ax
  3652. cmp cx, 6
  3653. jb near reallocExit
  3654. mov es:[di], ax
  3655. add di, ax
  3656. mov es:[di], cx
  3657. add di, 2
  3658. (*%T RegParam *)
  3659. mov ax, di
  3660. mov bx, es
  3661. (*%E *)
  3662. (*%F RegParam *)
  3663. push es
  3664. push di
  3665. (*%E *)
  3666. (*%F NearCall *)
  3667. call far __ffree
  3668. (*%E *)
  3669. (*%T NearCall *)
  3670. call __ffree
  3671. (*%E *)
  3672. (*%F RegParam *)
  3673. add sp, 4
  3674. (*%E *)
  3675. jmp near reallocExit
  3676. reallocExpand:
  3677. mov si, es:[firstFree]
  3678. sub dx, dx
  3679. freeWalkLoop:
  3680. or si, si
  3681. jz largeBlock
  3682. cmp si, di
  3683. ja foundBlock
  3684. mov dx, si
  3685. mov si, es:[si][OS2NextBlock]
  3686. jmp freeWalkLoop
  3687. foundBlock:
  3688. mov bx, di
  3689. add bx, cx
  3690. cmp bx, si
  3691. jnz largeBlock
  3692. mov bx, es:[si][OS2FreeSize]
  3693. add bx, cx
  3694. cmp ax, bx
  3695. ja largeBlock
  3696. jb blockFits
  3697. exactFit:
  3698. mov es:[di][OS2FreeSize], ax
  3699. mov bx, es:[si][OS2NextBlock]
  3700. or dx, dx
  3701. jnz notFirst
  3702. mov es:[firstFree], bx
  3703. jmp reallocExit
  3704. notFirst:
  3705. mov si, dx
  3706. mov es:[si][OS2NextBlock], bx
  3707. jmp reallocExit
  3708. blockFits:
  3709. push bx
  3710. sub bx, ax
  3711. cmp bx, 6
  3712. pop bx
  3713. jae sizeOK
  3714. mov ax, bx
  3715. jmp exactFit
  3716. sizeOK:
  3717. mov es:[di][OS2FreeSize], ax
  3718. add di, ax
  3719. sub bx, ax
  3720. mov cx, es:[si][OS2NextBlock]
  3721. mov es:[di][OS2FreeSize], bx
  3722. mov es:[di][OS2NextBlock], cx
  3723. or dx, dx
  3724. jnz notFirst2
  3725. mov es:[firstFree], di
  3726. jmp reallocExit
  3727. notFirst2:
  3728. mov si, dx
  3729. mov es:[si][OS2NextBlock], di
  3730. jmp reallocExit
  3731. largeBlock:
  3732. mov ax, [bp][size]
  3733. (*%F RegParam *)
  3734. push ax
  3735. (*%E *)
  3736. (*%F NearCall *)
  3737. call far __fmalloc
  3738. (*%E *)
  3739. (*%T NearCall *)
  3740. call __fmalloc
  3741. (*%E *)
  3742. (*%F RegParam *)
  3743. add sp, 2
  3744. (*%E RegParam *)
  3745. or dx, dx
  3746. jz reallocError
  3747. reallocMove:
  3748. push dx
  3749. push ax
  3750. push ds
  3751. push si
  3752. mov es, dx
  3753. mov di, ax
  3754. lds si, [bp][buffer]
  3755. mov cx, [bp][oldsize]
  3756. rep ; movsb
  3757. pop si
  3758. pop ds
  3759. mov bx, [bp][buffer][2]
  3760. mov ax, [bp][buffer]
  3761. (*%F RegParam *)
  3762. push bx
  3763. push ax
  3764. (*%E *)
  3765. (*%F NearCall *)
  3766. call far __ffree
  3767. (*%E *)
  3768. (*%T NearCall *)
  3769. call __ffree
  3770. (*%E *)
  3771. (*%F RegParam *)
  3772. add sp, 4
  3773. (*%E *)
  3774. pop ax
  3775. pop dx
  3776. jmp reallocExit2
  3777. reallocExit:
  3778. mov dx, [bp][buffer][2]
  3779. mov ax, [bp][buffer]
  3780. reallocExit2:
  3781. (*%F SameDS *)
  3782. pop ds
  3783. (*%E *)
  3784. pop si
  3785. pop di
  3786. pop cx
  3787. pop bx
  3788. mov sp, bp
  3789. pop bp
  3790. (*%F NearCall *)
  3791. ret far 0
  3792. (*%E *)
  3793. (*%T NearCall *)
  3794. ret 0
  3795. (*%E *)
  3796. reallocError:
  3797. mov ax, ENOMEM
  3798. (*%F NearCall *)
  3799. call far __seterrno
  3800. (*%E *)
  3801. (*%T NearCall *)
  3802. call __seterrno
  3803. (*%E *)
  3804. sub ax, ax
  3805. cwd
  3806. jmp reallocExit2
  3807. reallocSys:
  3808. push [bp][size]
  3809. push [bp][buffer][2]
  3810. call far DOSREALLOCSEG
  3811. or ax, ax
  3812. jne reallocError
  3813. sub ax, ax
  3814. mov dx, [bp][buffer][2]
  3815. jmp reallocExit2
  3816. reallocFree:
  3817. (*%F RegParam *)
  3818. push es
  3819. push di
  3820. (*%E *)
  3821. (*%T RegParam *)
  3822. mov bx, es
  3823. mov ax, di
  3824. (*%E *)
  3825. (*%F NearCall *)
  3826. call far __ffree
  3827. (*%E *)
  3828. (*%T NearCall *)
  3829. call __ffree
  3830. (*%E *)
  3831. (*%F RegParam *)
  3832. add sp, 4
  3833. (*%E *)
  3834. sub ax, ax
  3835. cwd
  3836. jmp reallocExit2
  3837. reallocMalloc:
  3838. (*%F RegParam *)
  3839. push ax
  3840. (*%E *)
  3841. (*%F NearCall *)
  3842. call far __fmalloc
  3843. (*%E *)
  3844. (*%T NearCall *)
  3845. call __fmalloc
  3846. (*%E *)
  3847. (*%F RegParam *)
  3848. add sp, 2
  3849. (*%E RegParam *)
  3850. jmp reallocExit2
  3851. (*%E _OS2 *)
  3852. section
  3853. (***************************************************************************)
  3854. (*%T _OS2 *)
  3855. (*@@@ Should be moved to StdMem *)
  3856. (* ------------------------------------------------------------------------
  3857. PROCEDURE - _heapchk, _fheapchk, _heapset, _fheapset.
  3858. PRECONDITIONS - Far heap must be initialised.
  3859. POSTCONDITIONS - _heapset fills each free block with the parameter value.
  3860. IN PARAMETERS - _heapset takes fill value(int).
  3861. OUT PARAMETERS - Returns state of heap.
  3862. 0 _HEAPOK if OK
  3863. -1 _HEAPEMPTY if heap not initialised
  3864. -2 _HEAPBADBEGIN if initial header bad
  3865. -3 _HEAPBADNODE if heap is damaged
  3866. -4 _HEAPOVERFLOW if heap past ceiling
  3867. CALLING CONVENTION - Standard.
  3868. NOTES -
  3869. VERSION - _OS2.
  3870. ------------------------------------------------------------------------ *)
  3871. segment _TEXT(CODE,28H)
  3872. segment _DATA(DATA, 28H)
  3873. extrn DOSSEMREQUEST
  3874. extrn DOSSEMCLEAR
  3875. select _DATA
  3876. extrn __firstheap
  3877. extrn __fheapsem
  3878. select _TEXT
  3879. public __fheapchk :
  3880. (*%F NearPtr *)
  3881. public __heapchk :
  3882. (*%E *)
  3883. _HEAPOK = 0
  3884. _HEAPEMPTY = -1
  3885. _HEAPBADBEGIN = -2
  3886. _HEAPBADNODE = -3
  3887. _HEAPOVERFLOW = -4
  3888. push bx
  3889. push cx
  3890. push dx
  3891. sub bx, bx (* dont fill *)
  3892. jmp hpShared
  3893. mem_reg_saved = 6
  3894. fill = frame+mem_reg_saved
  3895. public __fheapset :
  3896. (*%F NearPtr *)
  3897. public __heapset :
  3898. (*%E *)
  3899. push bx
  3900. push cx
  3901. push dx
  3902. mov bh, 1
  3903. hpShared:
  3904. push bp
  3905. mov bp, sp
  3906. (*%F SameDS *)
  3907. push ds
  3908. mov cx, _DATA
  3909. mov ds, cx
  3910. (*%E *)
  3911. (*%T MThread *)
  3912. push ax
  3913. push ds
  3914. mov ax, __fheapsem
  3915. push ax
  3916. mov ax, -1
  3917. push ax
  3918. push ax
  3919. call far DOSSEMREQUEST
  3920. pop ax
  3921. (*%E *)
  3922. push di
  3923. (*%F RegParam *)
  3924. mov al, [bp][fill]
  3925. (*%E *)
  3926. mov ah, bh
  3927. mov dx, [__firstheap]
  3928. or dx, dx
  3929. je chkEmpty (* no heap *)
  3930. chkNext:
  3931. mov es, dx
  3932. mov cx, es:[statHeap]
  3933. jcxz chkOK
  3934. mov di, heapStart (* check each block *)
  3935. mov dx, es:[firstFree]
  3936. chkLoop:
  3937. cmp di, dx (* is it in free list *)
  3938. jne chkNotFree (* no - continue *)
  3939. mov cx, es:[di][OS2FreeSize]
  3940. mov dx, es:[di][OS2NextBlock] (* get next free *)
  3941. or ah, ah
  3942. je NodeOK (* fill if ah *)
  3943. push ax
  3944. mov ah, al
  3945. push di
  3946. add di, 4
  3947. sub cx, 4
  3948. rep ; stosb
  3949. pop di
  3950. pop ax (* fill free block *)
  3951. jmp NodeOK
  3952. chkNotFree:
  3953. jb NodeOK
  3954. or dx, dx
  3955. jne chkBadNode (* bad heap node *)
  3956. NodeOK:
  3957. add di, es:[di][OS2FreeSize]
  3958. cmp di, OS2HEAPTOP
  3959. ja chkBadTop (* overflow *)
  3960. jb chkLoop
  3961. or dx, dx
  3962. je chkOK
  3963. chkBadTop:
  3964. mov ax, _HEAPOVERFLOW
  3965. jmp chkDone
  3966. chkEmpty:
  3967. mov ax, _HEAPEMPTY
  3968. jmp chkDone
  3969. chkBadStart:
  3970. mov ax, _HEAPBADBEGIN
  3971. jmp chkDone
  3972. chkBadNode:
  3973. mov ax, _HEAPBADNODE
  3974. jmp chkDone
  3975. chkOK:
  3976. mov dx, es:[nextHeap]
  3977. or dx, dx
  3978. jnz chkNext
  3979. sub ax, ax
  3980. chkDone:
  3981. (*%T MThread *)
  3982. push ax
  3983. push ds
  3984. mov ax, __fheapsem
  3985. push ax
  3986. call far DOSSEMCLEAR
  3987. pop ax
  3988. (*%E *)
  3989. pop di
  3990. (*%F SameDS *)
  3991. pop ds
  3992. (*%E *)
  3993. pop bp
  3994. pop dx
  3995. pop cx
  3996. pop bx
  3997. (*%F NearCall *)
  3998. ret far 0
  3999. (*%E *)
  4000. (*%T NearCall *)
  4001. ret 0
  4002. (*%E *)
  4003. (*%E _OS2 *)
  4004. section
  4005. (***************************************************************************)
  4006. (*%T _OS2 *)
  4007. (*@@@ Should be in StdMem *)
  4008. (* ------------------------------------------------------------------------
  4009. PROCEDURE - _heapwalk, _fheapwalk.
  4010. PRECONDITIONS - Far heap must be initialised.
  4011. heapinfo structure initialised to NULL, or contains result
  4012. of a preevious call to _heapwalk.
  4013. POSTCONDITIONS - heapinfo structure contains details of current heap node.
  4014. IN PARAMETERS - Pointer to heapinfo structure
  4015. OUT PARAMETERS - Returns state of heap.
  4016. _HEAPOK = 0
  4017. _HEAPEMPTY = -1
  4018. _HEAPBADBEGIN = -2
  4019. _HEAPBADNODE = -3
  4020. _HEAPOVERFLOW = -4
  4021. _HEAPBADPTR = -6
  4022. CALLING CONVENTION - Standard.
  4023. NOTES -
  4024. VERSION - _OS2.
  4025. ------------------------------------------------------------------------ *)
  4026. segment _TEXT(CODE,28H)
  4027. segment _DATA(DATA, 28H)
  4028. select _DATA
  4029. extrn __firstheap
  4030. extrn __fheapsem
  4031. lastfree : dw 0, 0
  4032. select _TEXT
  4033. public __fheapwalk :
  4034. (*%F NearPtr *)
  4035. public __heapwalk :
  4036. (*%E *)
  4037. _HEAPOK = 0
  4038. _HEAPEMPTY = -1
  4039. _HEAPBADBEGIN = -2
  4040. _HEAPBADNODE = -3
  4041. _HEAPOVERFLOW = -4
  4042. _HEAPEND = -5
  4043. _HEAPBADPTR = -6
  4044. pentry = 0
  4045. size = 4
  4046. useflag = 6
  4047. (*%F RegParam *)
  4048. entry = frame
  4049. dgroup = -2
  4050. locals = 2
  4051. (*%E *)
  4052. (*%T RegParam *)
  4053. entry = -4
  4054. dgroup = -6
  4055. locals = 6
  4056. (*%E *)
  4057. push bp
  4058. mov bp, sp
  4059. sub sp, locals
  4060. (*%T RegParam *)
  4061. (*%T NearPtr *)
  4062. push bx
  4063. (*%E *)
  4064. push cx
  4065. push dx
  4066. (*%E *)
  4067. (*%F RegParam *)
  4068. push bx
  4069. push cx
  4070. push dx
  4071. (*%E *)
  4072. (*%T RegParam *)
  4073. (*%F NearPtr *)
  4074. mov [bp][entry][2], bx
  4075. (*%E *)
  4076. (*%T NearPtr *)
  4077. mov [bp][entry][2], ds
  4078. (*%E *)
  4079. mov [bp][entry], ax
  4080. (*%E *)
  4081. push si
  4082. push ds
  4083. (*%F SameDS *)
  4084. mov cx, _DATA
  4085. mov ds, cx
  4086. (*%E *)
  4087. mov [bp][dgroup], ds
  4088. (*%F NearPtr *)
  4089. les bx, [bp][entry]
  4090. (*%E *)
  4091. (*%T NearPtr *)
  4092. mov bx, [bp][entry]
  4093. mov es, [bp][dgroup]
  4094. (*%E *)
  4095. mov ax, es:[bx][pentry][2]
  4096. or ax, ax
  4097. jnz notFirst
  4098. mov es, [bp][dgroup]
  4099. mov dx, es:[__firstheap]
  4100. or dx, dx
  4101. je near heapEmpty (* no heap *)
  4102. mov si, heapStart
  4103. mov ds, dx
  4104. cmp byte [statHeap], HEAP_FREE
  4105. je getNextHeap
  4106. mov ax, [firstFree]
  4107. mov es:[lastfree], ax
  4108. mov ax, [si][OS2FreeSize]
  4109. jmp store
  4110. notFirst:
  4111. mov ds, ax
  4112. mov si, es:[bx][pentry]
  4113. mov ax, [si][OS2FreeSize]
  4114. add si, ax
  4115. mov ax, [si][OS2FreeSize]
  4116. cmp si, OS2HEAPTOP
  4117. ja badTop (* overflow *)
  4118. jb store
  4119. getNextHeap:
  4120. mov cx, [nextHeap]
  4121. jcxz atHeapTop
  4122. mov ds, cx
  4123. cmp byte [statHeap], HEAP_FREE
  4124. je getNextHeap
  4125. mov es, [bp][dgroup]
  4126. mov ax, [firstFree]
  4127. mov es:[lastfree], ax
  4128. mov si, heapStart
  4129. mov ax, [si][OS2FreeSize]
  4130. store:
  4131. (*%F NearPtr *)
  4132. mov es, [bp][entry][2]
  4133. (*%E *)
  4134. (*%T NearPtr *)
  4135. mov es, [bp][dgroup]
  4136. (*%E *)
  4137. mov es:[bx][pentry], si
  4138. mov es:[bx][pentry][2], ds
  4139. sub ax, 2
  4140. mov es:[bx][size], ax
  4141. mov ax, 1
  4142. mov cx, ds
  4143. mov es, [bp][dgroup]
  4144. cmp si, es:[lastfree]
  4145. jne notFree
  4146. sub ax, ax
  4147. mov es, [bp][dgroup]
  4148. mov cx, [si][OS2NextBlock]
  4149. mov es:[lastfree], cx
  4150. notFree:
  4151. ja badNode
  4152. (*%F NearPtr *)
  4153. mov es, [bp][entry][2]
  4154. (*%E *)
  4155. (*%T NearPtr *)
  4156. mov es, [bp][dgroup]
  4157. (*%E *)
  4158. mov es:[bx][useflag], ax
  4159. success:
  4160. mov ax, _HEAPOK
  4161. exit:
  4162. pop ds
  4163. pop si
  4164. (*%F RegParam *)
  4165. pop dx
  4166. pop cx
  4167. pop bx
  4168. (*%E *)
  4169. (*%T RegParam *)
  4170. pop dx
  4171. pop cx
  4172. (*%T NearPtr *)
  4173. pop bx
  4174. (*%E *)
  4175. (*%E *)
  4176. mov sp, bp
  4177. pop bp
  4178. (*%F NearCall *)
  4179. ret far 0
  4180. (*%E *)
  4181. (*%T NearCall *)
  4182. ret 0
  4183. (*%E *)
  4184. badTop:
  4185. mov ax, _HEAPOVERFLOW
  4186. jmp exit
  4187. heapEmpty:
  4188. mov ax, _HEAPEMPTY
  4189. jmp exit
  4190. badStart:
  4191. mov ax, _HEAPBADBEGIN
  4192. jmp exit
  4193. badNode:
  4194. mov ax, _HEAPBADNODE
  4195. jmp exit
  4196. atHeapTop:
  4197. mov ax, _HEAPEND
  4198. jmp exit
  4199. (*%E _OS2 *)
  4200. section
  4201. (***************************************************************************)
  4202. (*%T _OS2 *)
  4203. (* ------------------------------------------------------------------------
  4204. PROCEDURE - hrealloc.
  4205. PRECONDITIONS - Block allocated by halloc.
  4206. POSTCONDITIONS - If successful, block allocation changed.
  4207. On error errno set to ENOMEM.
  4208. IN PARAMETERS - Far pointer to memory block, block size(long).
  4209. OUT PARAMETERS - Returns far pointer to memory block.
  4210. CALLING CONVENTION - Standard.
  4211. NOTES - If size is zero the block will be freed.
  4212. If the pointer is NULL a new block will be allocated.
  4213. VERSION - _OS2.
  4214. ------------------------------------------------------------------------*)
  4215. segment _TEXT(CODE,28H)
  4216. segment _DATA(DATA, 28H)
  4217. extrn DOSREALLOCHUGE
  4218. extrn __seterrno
  4219. extrn _halloc
  4220. extrn _hfree
  4221. select _DATA
  4222. extrn __memtype
  4223. select _TEXT
  4224. public _hrealloc :
  4225. buffer = frame
  4226. size = 4+frame
  4227. push bp
  4228. mov bp, sp
  4229. (*%F RegParam *)
  4230. push bx
  4231. push cx
  4232. (*%E *)
  4233. (*%T RegParam *)
  4234. push cx
  4235. (*%E *)
  4236. (*%F RegParam *)
  4237. mov ax, [bp][size] (* dx = sel, ax = seg size, bx = segs *)
  4238. mov bx, [bp][size][2]
  4239. mov dx, [bp][buffer][2]
  4240. (*%E *)
  4241. (*%T RegParam *)
  4242. mov ax, cx
  4243. xchg bx, dx
  4244. (*%E *)
  4245. or dx, dx
  4246. jz hreallocAlloc
  4247. or ax, ax
  4248. jnz hreallocSOK
  4249. or bx, bx
  4250. jz hreallocFree
  4251. hreallocSOK:
  4252. push dx
  4253. push bx
  4254. push ax
  4255. push dx
  4256. call far DOSREALLOCHUGE
  4257. pop dx
  4258. or ax, ax
  4259. jnz hreallocError
  4260. hreallocDone:
  4261. (*%F RegParam *)
  4262. pop cx
  4263. pop bx
  4264. (*%E *)
  4265. (*%T RegParam *)
  4266. pop cx
  4267. (*%E *)
  4268. mov sp, bp
  4269. pop bp
  4270. (*%F NearCall *)
  4271. ret far 0
  4272. (*%E *)
  4273. (*%T NearCall *)
  4274. ret 0
  4275. (*%E *)
  4276. hreallocError:
  4277. mov ax, ENOMEM
  4278. push ax
  4279. (*%F NearCall *)
  4280. call far __seterrno
  4281. (*%E *)
  4282. (*%T NearCall *)
  4283. call __seterrno
  4284. (*%E *)
  4285. sub ax, ax
  4286. cwd
  4287. jmp hreallocDone
  4288. hreallocAlloc:
  4289. (*%F RegParam *)
  4290. push bx
  4291. push ax
  4292. (*%E *)
  4293. (*%F NearCall *)
  4294. call far _halloc
  4295. (*%E *)
  4296. (*%T NearCall *)
  4297. call _halloc
  4298. (*%E *)
  4299. (*%F RegParam *)
  4300. add sp, 4
  4301. (*%E *)
  4302. jmp hreallocDone
  4303. hreallocFree:
  4304. (*%F RegParam *)
  4305. push dx
  4306. sub cx, cx
  4307. push cx
  4308. (*%E *)
  4309. (*%T RegParam *)
  4310. mov bx, dx
  4311. sub ax, ax
  4312. (*%E *)
  4313. (*%F NearCall *)
  4314. call far _hfree
  4315. (*%E *)
  4316. (*%T NearCall *)
  4317. call _hfree
  4318. (*%E *)
  4319. (*%F RegParam *)
  4320. add sp, 4
  4321. (*%E *)
  4322. jmp hreallocDone
  4323. (*%E _OS2 *)
  4324. section
  4325. (*%T _DLLOVL *)
  4326. (***********************************************************************)
  4327. (* __fmalloc - C Far Heap Allocation *)
  4328. (* *)
  4329. (* void far *_fmalloc(size_t size) *)
  4330. (* *)
  4331. (* DLL Memory Models + C Stack Convention *)
  4332. (* *)
  4333. (* Internal Procedure *)
  4334. (* Parameters: *)
  4335. (* ax - Request Size *)
  4336. (* Trashes: *)
  4337. (* es *)
  4338. (* Return: *)
  4339. (* dx:ax - Address of Huge Allocation *)
  4340. (* Aliases: *)
  4341. (* _malloc - in Far Pointer Models *)
  4342. (* *)
  4343. (***********************************************************************)
  4344. segment _TEXT(CODE,48H)
  4345. extrn Loader$AllocMem
  4346. Size = Frame
  4347. public __fmalloc :
  4348. public _malloc :
  4349. push bp
  4350. mov bp, sp
  4351. push bx
  4352. (*%F _jpicall *)
  4353. mov ax, [bp][Size]
  4354. (*%E *)
  4355. or ax, ax
  4356. jz $$Invalid
  4357. add ax, 2
  4358. jc $$Invalid
  4359. push ax
  4360. call far Loader$AllocMem
  4361. mov es, dx
  4362. mov bx, ax
  4363. or ax, dx
  4364. jz $$Failed
  4365. pop es:[bx]
  4366. mov ax, bx
  4367. inc ax
  4368. inc ax
  4369. $$Return:
  4370. pop bx
  4371. pop bp
  4372. ret far 0
  4373. $$Invalid:
  4374. xor ax, ax
  4375. cwd
  4376. jmp $$Return
  4377. $$Failed:
  4378. pop bx
  4379. jmp $$Return
  4380. (*%E _DLLOVL *)
  4381. section
  4382. (*%T _DLLOVL *)
  4383. (***********************************************************************)
  4384. (* __fcalloc - C Far Heap Initialized Allocation *)
  4385. (* *)
  4386. (* void far *_fcalloc(size_t number,size_t size) *)
  4387. (* *)
  4388. (* DLL Memory Models + C Stack Convention *)
  4389. (* *)
  4390. (* Internal Procedure *)
  4391. (* Parameters: *)
  4392. (* ax - Number of units requested *)
  4393. (* bx - Unit Size *)
  4394. (* Trashes: *)
  4395. (* es *)
  4396. (* Return: *)
  4397. (* dx:ax - Address of Allocation *)
  4398. (* Aliases: *)
  4399. (* _calloc *)
  4400. (* *)
  4401. (***********************************************************************)
  4402. segment _TEXT(CODE,48H)
  4403. extrn Loader$ClearAllocMem
  4404. Size = Frame
  4405. Num = Frame + 2
  4406. public __fcalloc :
  4407. public _calloc :
  4408. push bp
  4409. mov bp, sp
  4410. (*%F _jpicall *)
  4411. mov ax, [bp][Num]
  4412. mov bx, [bp][Size]
  4413. (*%E *)
  4414. mul bx
  4415. jo $$Invalid
  4416. or ax, ax
  4417. jz $$Invalid
  4418. add ax, 2
  4419. jc $$Invalid
  4420. push ax
  4421. mov bx,1
  4422. call far Loader$ClearAllocMem
  4423. mov es, dx
  4424. mov bx, ax
  4425. or ax, dx
  4426. jz $$Failed
  4427. pop es:[bx]
  4428. mov ax, bx
  4429. inc ax
  4430. inc ax
  4431. $$Return:
  4432. pop bp
  4433. ret far 0
  4434. $$Invalid:
  4435. xor ax, ax
  4436. cwd
  4437. jmp $$Return
  4438. $$Failed:
  4439. pop bx
  4440. jmp $$Return
  4441. (*%E _DLLOVL *)
  4442. section
  4443. (*%T _DLLOVL *)
  4444. (***********************************************************************)
  4445. (* __frealloc - C Far Heap Change Allocation *)
  4446. (* *)
  4447. (* void far *_frealloc(void far *buffer,size_t size) *)
  4448. (* *)
  4449. (* DLL Memory Models + C Stack Convention *)
  4450. (* *)
  4451. (* Internal Procedure *)
  4452. (* Parameters: *)
  4453. (* bx:ax - Buffer address *)
  4454. (* cx - New Buffer Size *)
  4455. (* Trashes: *)
  4456. (* es *)
  4457. (* Return: *)
  4458. (* dx:ax - New Buffer address *)
  4459. (* Aliases: *)
  4460. (* _realloc *)
  4461. (* *)
  4462. (***********************************************************************)
  4463. segment _DATA(DATA,48H)
  4464. segment _TEXT(CODE,48H)
  4465. extrn _errno
  4466. extrn Loader$ExpandMem
  4467. extrn __ffree
  4468. extrn __fmalloc
  4469. Size = Frame
  4470. Buff = Frame + 2
  4471. public __frealloc :
  4472. public _realloc :
  4473. push bp
  4474. mov bp, sp
  4475. push ds
  4476. push di
  4477. push si
  4478. (*%F _jpicall *)
  4479. les ax, [bp][Buff]
  4480. mov bx, es
  4481. mov cx, [bp][Size]
  4482. (*%E *)
  4483. or cx, cx
  4484. jnz $$GoodSize
  4485. call far __ffree
  4486. $$RetNull:
  4487. xor ax, ax
  4488. cwd
  4489. jmp $$Return
  4490. $$GoodSize:
  4491. (*%T _jpicall *)
  4492. mov es, bx
  4493. (*%E *)
  4494. mov si, ax
  4495. or ax, bx
  4496. jnz $$GoodPtr
  4497. mov ax, cx
  4498. call far __fmalloc
  4499. jmp $$Return
  4500. $$GoodPtr:
  4501. add cx, 2
  4502. jc $$RetNull
  4503. push cx
  4504. dec si
  4505. dec si
  4506. mov di, es
  4507. mov ax, si
  4508. call far Loader$ExpandMem
  4509. pop cx
  4510. mov bx, di
  4511. mov di, ax
  4512. or ax, dx
  4513. jnz $$Exit
  4514. mov ax, cx
  4515. call far __fmalloc
  4516. mov di, ax
  4517. or ax, dx
  4518. jnz $$MallocGood
  4519. mov ax, _DATA
  4520. mov ds, ax
  4521. mov word [_errno], ERROR_NOMEMORY
  4522. jmp $$Return
  4523. $$Exit:
  4524. mov ds, dx
  4525. mov [di], cx
  4526. inc di
  4527. inc di
  4528. mov ax, di
  4529. jmp $$Return
  4530. $$MallocGood:
  4531. push dx
  4532. push di
  4533. inc si
  4534. inc si
  4535. push bx
  4536. push si
  4537. push ds
  4538. mov ds, bx
  4539. mov ax, [si][-2]
  4540. cmp ax, cx
  4541. jae $$Copy
  4542. mov cx, ax
  4543. $$Copy:
  4544. mov es, dx
  4545. test di, 1
  4546. je $$CopyEven
  4547. movsb
  4548. dec cx
  4549. $$CopyEven:
  4550. shr cx, 1
  4551. rep; movsw
  4552. adc cx, cx
  4553. rep; movsb
  4554. pop ds
  4555. pop ax
  4556. pop bx
  4557. call far __ffree
  4558. pop ax
  4559. pop dx
  4560. $$Return:
  4561. pop si
  4562. pop di
  4563. pop ds
  4564. pop bp
  4565. ret far 0
  4566. (*%E _DLLOVL *)
  4567. section
  4568. (*%T _DLLOVL *)
  4569. (***********************************************************************)
  4570. (* __fexpand - C Far Heap Change Allocation *)
  4571. (* *)
  4572. (* void far *_fexpand(void far *buffer,size_t size) *)
  4573. (* *)
  4574. (* DLL Memory Models + C Stack Convention *)
  4575. (* *)
  4576. (* Internal Procedure *)
  4577. (* Parameters: *)
  4578. (* bx:ax - Buffer address *)
  4579. (* cx - New Buffer Size *)
  4580. (* Trashes: *)
  4581. (* es *)
  4582. (* Return: *)
  4583. (* dx:ax - New Buffer address *)
  4584. (* Aliases: *)
  4585. (* __expand *)
  4586. (* *)
  4587. (***********************************************************************)
  4588. segment _TEXT(CODE,48H)
  4589. extrn Loader$ExpandMem
  4590. Size = Frame
  4591. Buff = Frame + 2
  4592. public __fexpand :
  4593. public __expand :
  4594. push bp
  4595. mov bp, sp
  4596. (*%F _jpicall *)
  4597. les ax, [bp][Buff]
  4598. mov bx, es
  4599. mov cx, [bp][Size]
  4600. (*%E *)
  4601. push si
  4602. add cx, 2
  4603. jc $$Failure
  4604. push cx
  4605. dec ax
  4606. dec ax
  4607. mov si, ax
  4608. call far Loader$ExpandMem
  4609. pop cx
  4610. mov si, ax
  4611. or ax, dx
  4612. jz $$Return
  4613. mov es, dx
  4614. mov es:[si], cx
  4615. mov ax, si
  4616. inc ax
  4617. inc ax
  4618. $$Return:
  4619. pop si
  4620. pop bp
  4621. ret far 0
  4622. $$Failure:
  4623. xor ax, ax
  4624. cwd
  4625. jmp $$Return
  4626. (*%E _DLLOVL *)
  4627. section
  4628. (*%T _DLLOVL *)
  4629. (***********************************************************************)
  4630. (* __ffree - C Far Heap Deallocation *)
  4631. (* *)
  4632. (* void _ffree(void far *buffer) *)
  4633. (* *)
  4634. (* DLL Memory Models + C Stack Convention *)
  4635. (* *)
  4636. (* Internal Procedure *)
  4637. (* Parameters: *)
  4638. (* bx:ax - Address of buffer *)
  4639. (* Trashes: *)
  4640. (* es *)
  4641. (* Return: *)
  4642. (* none *)
  4643. (* Aliases: *)
  4644. (* _free *)
  4645. (* *)
  4646. (***********************************************************************)
  4647. segment _TEXT(CODE,48H)
  4648. extrn Loader$FreeMem
  4649. Buffer = Frame
  4650. public _free :
  4651. public __ffree :
  4652. push bp
  4653. mov bp, sp
  4654. (*%F _jpicall *)
  4655. les ax, [bp][Buffer]
  4656. mov bx, es
  4657. (*%E *)
  4658. dec ax
  4659. dec ax
  4660. call far Loader$FreeMem
  4661. pop bp
  4662. ret far 0
  4663. (*%E _DLLOVL *)
  4664. section
  4665. (*%T _DLLOVL *)
  4666. (***********************************************************************)
  4667. (* __fmsize - C Query Size of Far Heap Allocation *)
  4668. (* *)
  4669. (* int _fmsize(void far *buffer) *)
  4670. (* *)
  4671. (* DLL Memory Models + C Stack Convention *)
  4672. (* *)
  4673. (* Internal Procedure *)
  4674. (* Parameters: *)
  4675. (* bx:ax - Address of buffer *)
  4676. (* Trashes: *)
  4677. (* es *)
  4678. (* Return: *)
  4679. (* ax - Size of Original Allocation *)
  4680. (* Aliases: *)
  4681. (* __msize - in Far Pointer Models *)
  4682. (* *)
  4683. (***********************************************************************)
  4684. segment _TEXT(CODE,48H)
  4685. Buff = Frame
  4686. public __fmsize :
  4687. public __msize :
  4688. push bp
  4689. mov bp, sp
  4690. (*%F _jpicall *)
  4691. les bx, [Buff]
  4692. (*%E *)
  4693. (*%T _jpicall *)
  4694. mov es, bx
  4695. mov bx, ax
  4696. (*%E *)
  4697. mov ax, es:[bx][-2]
  4698. dec ax
  4699. dec ax
  4700. pop bp
  4701. ret far 0
  4702. (*%E _DLLOVL *)
  4703. section
  4704. (*%T _DLLOVL *)
  4705. (***********************************************************************)
  4706. (* _farcoreleft - C Query Far Heap Available *)
  4707. (* *)
  4708. (* unsigned long farcoreleft(void) *)
  4709. (* *)
  4710. (* DLL Memory Models + C Stack Convention *)
  4711. (* *)
  4712. (* Internal Procedure *)
  4713. (* Parameters: *)
  4714. (* none *)
  4715. (* Trashes: *)
  4716. (* none *)
  4717. (* Return: *)
  4718. (* dx:ax - Bytes left on Far Heap *)
  4719. (* Aliases: *)
  4720. (* _coreleft *)
  4721. (* *)
  4722. (***********************************************************************)
  4723. segment _DATA(DATA,48H)
  4724. segment _TEXT(CODE,48H)
  4725. extrn __core_lock
  4726. extrn __core_unlock
  4727. extrn Loader$TotalAvail
  4728. extrn F$LngShl
  4729. public _farcoreleft :
  4730. public _coreleft :
  4731. push bp
  4732. mov bp, sp
  4733. push cx
  4734. push ds
  4735. mov cx, _DATA
  4736. mov ds, cx
  4737. call far [__core_lock]
  4738. call far Loader$TotalAvail
  4739. call far [__core_unlock]
  4740. xor dx, dx
  4741. mov cl, 4
  4742. call far F$LngShl
  4743. pop ds
  4744. pop cx
  4745. pop bp
  4746. ret far 0
  4747. (*%E _DLLOVL *)
  4748. section
  4749. (*%T _DLLOVL *)
  4750. (***********************************************************************)
  4751. (* __fblockavail - C Query Far Heap Largest Block Available *)
  4752. (* *)
  4753. (* unsigned long _fblockavail(void) *)
  4754. (* *)
  4755. (* DLL Memory Models + C Stack Convention *)
  4756. (* *)
  4757. (* Internal Procedure *)
  4758. (* Parameters: *)
  4759. (* none *)
  4760. (* Trashes: *)
  4761. (* none *)
  4762. (* Return: *)
  4763. (* dx:ax - Largest Block Available *)
  4764. (* *)
  4765. (***********************************************************************)
  4766. segment _DATA(DATA,48H)
  4767. segment _TEXT(CODE,48H)
  4768. extrn __core_lock
  4769. extrn __core_unlock
  4770. extrn Loader$Avail
  4771. extrn F$LngShl
  4772. public __fblockavail :
  4773. push bp
  4774. mov bp, sp
  4775. push cx
  4776. push ds
  4777. mov cx, _DATA
  4778. mov ds, cx
  4779. call far [__core_lock]
  4780. call far Loader$Avail
  4781. call far [__core_unlock]
  4782. xor dx, dx
  4783. mov cl, 4
  4784. call far F$LngShl
  4785. pop ds
  4786. pop cx
  4787. pop bp
  4788. ret far 0
  4789. (*%E _DLLOVL *)
  4790. section
  4791. (*%T _DLLOVL *)
  4792. (***********************************************************************)
  4793. (* _halloc - C Huge Far Heap Allocation *)
  4794. (* *)
  4795. (* void huge *halloc(unsigned long size) *)
  4796. (* *)
  4797. (* DLL Memory Models + C Stack Convention *)
  4798. (* *)
  4799. (* Internal Procedure *)
  4800. (* Parameters: *)
  4801. (* bx:ax - Request Size *)
  4802. (* Trashes: *)
  4803. (* none *)
  4804. (* Return: *)
  4805. (* dx:ax - Address of Huge Allocation *)
  4806. (* *)
  4807. (***********************************************************************)
  4808. segment _TEXT(CODE,48H)
  4809. extrn Loader$HugeAllocMem
  4810. Size = Frame
  4811. public _halloc :
  4812. push bp
  4813. mov bp, sp
  4814. (*%F _jpicall *)
  4815. les ax, [bp][Size]
  4816. mov bx, es
  4817. (*%E *)
  4818. call far Loader$HugeAllocMem
  4819. pop bp
  4820. ret far 0
  4821. (*%E _DLLOVL *)
  4822. section
  4823. (*%T _DLLOVL *)
  4824. (***********************************************************************)
  4825. (* _hfree - C Huge Far Heap Deallocation *)
  4826. (* *)
  4827. (* void hfree(void far *buffer) *)
  4828. (* *)
  4829. (* DLL Memory Models + C Stack Convention *)
  4830. (* *)
  4831. (* Internal Procedure *)
  4832. (* Parameters: *)
  4833. (* bx:ax - Address of buffer *)
  4834. (* Trashes: *)
  4835. (* es *)
  4836. (* Return: *)
  4837. (* none *)
  4838. (* *)
  4839. (***********************************************************************)
  4840. segment _TEXT(CODE,48H)
  4841. extrn Loader$FreeMem
  4842. Buffer = Frame
  4843. public _hfree :
  4844. push bp
  4845. mov bp, sp
  4846. (*%F _jpicall *)
  4847. les ax, [bp][Buffer]
  4848. mov bx, es
  4849. (*%E *)
  4850. call far Loader$FreeMem
  4851. pop bp
  4852. ret far 0
  4853. (*%E _DLLOVL *)
  4854. section
  4855. (*%T _DLLOVL *)
  4856. (***********************************************************************)
  4857. (* _hrealloc - C Far Heap Huge Change Allocation *)
  4858. (* *)
  4859. (* void huge *hrealloc(void huge *buffer,unsigned long size) *)
  4860. (* *)
  4861. (* DLL Memory Models + C Stack Convention *)
  4862. (* *)
  4863. (* Internal Procedure *)
  4864. (* Parameters: *)
  4865. (* bx:ax - Buffer address *)
  4866. (* dx:cx - New Buffer Size *)
  4867. (* Trashes: *)
  4868. (* es *)
  4869. (* Return: *)
  4870. (* dx:ax - New Buffer address *)
  4871. (* *)
  4872. (***********************************************************************)
  4873. segment _DATA(DATA,48H)
  4874. segment _TEXT(CODE,48H)
  4875. extrn _errno
  4876. extrn Loader$HugeExpandMem
  4877. extrn _hfree
  4878. extrn _halloc
  4879. (*%F _jpicall *)
  4880. Size = Frame
  4881. Buff = Frame + 4
  4882. (*%E *)
  4883. (*%T _jpicall *)
  4884. Size = -4
  4885. Buff = -8
  4886. Locals = 8
  4887. (*%E *)
  4888. public _hexpand :
  4889. public _hrealloc :
  4890. push bp
  4891. mov bp, sp
  4892. (*%T _jpicall *)
  4893. sub sp, Locals
  4894. (*%E *)
  4895. push ds
  4896. push di
  4897. push si
  4898. (*%F _jpicall *)
  4899. les ax, [bp][Buff]
  4900. mov bx, es
  4901. les cx, [bp][Size]
  4902. mov dx, es
  4903. (*%E *)
  4904. (*%T _jpicall *)
  4905. mov [bp][Buff], ax
  4906. mov [bp][Buff][2], bx
  4907. mov [bp][Size], cx
  4908. mov [bp][Size][2], dx
  4909. (*%E *)
  4910. mov di, dx
  4911. or di, cx
  4912. jnz $$GoodSize
  4913. call far _hfree
  4914. $$RetNull:
  4915. xor ax, ax
  4916. cwd
  4917. jmp $$Return
  4918. $$GoodSize:
  4919. mov di, ax
  4920. or di, bx
  4921. jnz $$GoodPtr
  4922. mov ax, cx
  4923. mov bx, dx
  4924. call far _halloc
  4925. jmp $$Return
  4926. $$GoodPtr:
  4927. call far Loader$HugeExpandMem
  4928. mov di, ax
  4929. or di, dx
  4930. jz $$hExpandFailed
  4931. $$Return:
  4932. pop si
  4933. pop di
  4934. pop ds
  4935. (*%T _jpicall *)
  4936. mov sp, bp
  4937. (*%E *)
  4938. pop bp
  4939. ret far 0
  4940. $$hExpandFailed:
  4941. les ax, [bp][Size]
  4942. mov bx, es
  4943. call far _halloc
  4944. mov di, ax (* dx:di = New Address *)
  4945. or ax, dx
  4946. jnz $$HallocGood
  4947. mov ax, _DATA
  4948. mov ds, ax
  4949. mov word [_errno], ERROR_NOMEMORY
  4950. jmp $$Return
  4951. $$HallocGood:
  4952. push dx (* Save new Address for later *)
  4953. push di
  4954. push ds
  4955. lds si, [bp][Buff] (* ds:si = Old Address *)
  4956. mov es, dx (* es:di = New Address *)
  4957. mov cx, [bp][Size] (* dx:cx = Copy Count *)
  4958. mov dx, [bp][Size][2]
  4959. inc dx
  4960. $$Copy:
  4961. test di, 1
  4962. je $$CopyEven
  4963. movsb
  4964. dec cx
  4965. $$CopyEven:
  4966. shr cx, 1
  4967. rep; movsw
  4968. adc cx, cx
  4969. rep; movsb
  4970. $$CopySegs:
  4971. dec dx
  4972. jz $$CopyDone
  4973. mov cx, 08000H
  4974. rep; movsw
  4975. jmp $$CopySegs
  4976. $$CopyDone:
  4977. lds ax, [bp][Buff]
  4978. mov bx, ds
  4979. pop ds
  4980. call far _hfree
  4981. pop ax
  4982. pop dx
  4983. jmp $$Return
  4984. (*%E _DLLOVL *)
  4985. section
  4986. (*%T _DLLOVL *)
  4987. (***********************************************************************)
  4988. (* __fheapchk - C Far Heap Check *)
  4989. (* *)
  4990. (* int _fheapchk(void) *)
  4991. (* *)
  4992. (* DLL Memory Models + C Stack Convention *)
  4993. (* *)
  4994. (* Internal Procedure *)
  4995. (* Parameters: *)
  4996. (* none *)
  4997. (* Trashes: *)
  4998. (* none *)
  4999. (* Return: *)
  5000. (* ax - Status Code *)
  5001. (* Aliases: *)
  5002. (* __heapchk *)
  5003. (* *)
  5004. (***********************************************************************)
  5005. segment _TEXT(CODE,48H)
  5006. extrn Loader$HeapCheck
  5007. public __heapchk :
  5008. public __fheapchk :
  5009. push bx
  5010. xor bx, bx
  5011. call far Loader$HeapCheck
  5012. pop bx
  5013. ret far 0
  5014. (*%E _DLLOVL *)
  5015. section
  5016. (*%T _DLLOVL *)
  5017. (***********************************************************************)
  5018. (* __fheapset - C Far Heap Check & Fill *)
  5019. (* *)
  5020. (* int _fheapset(int fill) *)
  5021. (* *)
  5022. (* DLL Memory Models + C Stack Convention *)
  5023. (* *)
  5024. (* Internal Procedure *)
  5025. (* Parameters: *)
  5026. (* ax - Fill Value *)
  5027. (* Trashes: *)
  5028. (* none *)
  5029. (* Return: *)
  5030. (* ax - Status Code *)
  5031. (* Aliases: *)
  5032. (* __heapset *)
  5033. (* *)
  5034. (***********************************************************************)
  5035. segment _TEXT(CODE,48H)
  5036. extrn Loader$HeapCheck
  5037. public __heapset :
  5038. public __fheapset :
  5039. push bx
  5040. mov bx, TRUE
  5041. call far Loader$HeapCheck
  5042. pop bx
  5043. ret far 0
  5044. (*%E _DLLOVL *)
  5045. section
  5046. (*%T _DLLOVL *)
  5047. (***********************************************************************)
  5048. (* __fheapwalk - C Far Heap Check *)
  5049. (* *)
  5050. (* int _fheapwalk(struct _heapinfo *entry) *)
  5051. (* *)
  5052. (* DLL Memory Models + C Stack Convention *)
  5053. (* *)
  5054. (* Internal Procedure *)
  5055. (* Parameters: *)
  5056. (* bx:ax - pointer to heapinfo structure *)
  5057. (* Trashes: *)
  5058. (* none *)
  5059. (* Return: *)
  5060. (* ax - Status Code *)
  5061. (* Aliases: *)
  5062. (* __heapwalk *)
  5063. (* *)
  5064. (***********************************************************************)
  5065. segment _TEXT(CODE,48H)
  5066. extrn Loader$HeapWalk
  5067. public __heapwalk :
  5068. public __fheapwalk :
  5069. call far Loader$HeapWalk
  5070. ret far 0
  5071. (*%E _DLLOVL *)
  5072. section
  5073. (*%F _OS2 *)
  5074. (*%T _DLL *)
  5075. (***********************************************************************)
  5076. (* Dummy procedures to satisfy DynaLink Export File. *)
  5077. (* __get_heapstate *)
  5078. (* __memavl - shouldn't even be in Export File (near heap only) *)
  5079. (* *)
  5080. (* Dummy data to satisfy DynaLink Export File. *)
  5081. (* __fheapstart *)
  5082. (* *)
  5083. (* void _get_heapstate *)
  5084. (* *)
  5085. (* DOS DynaLink Memory Model Only *)
  5086. (* *)
  5087. (* Internal Procedure *)
  5088. (* Parameters: *)
  5089. (* none *)
  5090. (* Trashes: *)
  5091. (* none *)
  5092. (* Return: *)
  5093. (* none *)
  5094. (* *)
  5095. (***********************************************************************)
  5096. segment _TEXT(CODE,28H)
  5097. public __get_heapstate :
  5098. public __memavl :
  5099. ret far 0
  5100. segment _DATA(DATA,28H)
  5101. public __fheapstart : org 0
  5102. (*%E _DLL *)
  5103. (*%E _OS2 *)
  5104. end
  5105.