From b1535620486d6df15b0434c64724412e73565a15 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Sat, 27 Jun 2015 12:15:50 -0500 Subject: [PATCH] 16_mm.c added! Signed-off-by: sparky4 --- 16.LIB | Bin 54784 -> 74752 bytes 16.exe | Bin 45460 -> 45556 bytes 16/cawat/lib_head.h | 21 +- GFX.LIB | Bin 27136 -> 28160 bytes emmtest.exe | Bin 32616 -> 32680 bytes emsdump.exe | Bin 30930 -> 30994 bytes fmemtest.exe | Bin 25450 -> 25482 bytes fonttest.exe | Bin 24122 -> 24154 bytes inputest.exe | Bin 9792 -> 9824 bytes makefile | 43 +- maptest.exe | Bin 45920 -> 46016 bytes maptest0.exe | Bin 47011 -> 47107 bytes palettec.exe | Bin 33602 -> 33666 bytes pcxtest.exe | Bin 62221 -> 62253 bytes scroll.exe | Bin 58743 -> 58903 bytes src/exmmtest.c | 31 + {16/cawat => src/lib}/16_mm.c | 2263 +++++++++++++++++---------------- {16/cawat => src/lib}/16_mm.h | 255 ++-- test.exe | Bin 34003 -> 34035 bytes test2.exe | Bin 38797 -> 38829 bytes 20 files changed, 1344 insertions(+), 1269 deletions(-) create mode 100644 src/exmmtest.c rename {16/cawat => src/lib}/16_mm.c (85%) rename {16/cawat => src/lib}/16_mm.h (91%) diff --git a/16.LIB b/16.LIB index d273cb59f7a2bc5a7f15f6bb82c48a506257b27f..e78e27b08f3f1d7c6370b2ddecffbdc094a1e93c 100644 GIT binary patch delta 27039 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 +#include #include -#include -#include -#include -#include -//#include -#include "types.h" - -dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */ - +#include +#include +#include +#include +#include +//#include +#include "../../src/lib/types.h" + +dword far* clockdw= (dword far*) 0x046C; /* 18.2hz clock */ + #define peekb(segm,ofs) (*(byte far*)MK_FP((segm),(ofs))) #define peekw(segm,ofs) (*(word far*)MK_FP((segm),(ofs))) #define pokeb(segm,ofs,value) (peekb((segm),(ofs)) = (byte)(value)) diff --git a/GFX.LIB b/GFX.LIB index a23acc9817ff3b12f62bb95e4e7e14a0d9a101c0..8a1b04b40875e21ffddfd344c85bd24648345219 100644 GIT binary patch delta 9534 zcmb_i3wTu3wcd}+%sF$;gv1aM-bo-35(s$_knjjkc?ZalC`Q60nL|R7nK&6BLAit0 z(m}Z@9*ZyVBZ?ItSTVL(puUJDRSQ;IT8gcDOKrVYq!nMisP|uIW=KNO+V9?(Z=d?^a1f8!l zU2%KNAI=?+c*&vWwPwf48wK*ZYkc0iv?jlAjd|Qwu=rYJq;9r-3EW4jva<%f|zVBv8PU%3%8WYpqjn2`=D9ucu%LyFo*d=4Kqi{9CaRW9D9Zte*@TtFEjoJ=*Rft z6Xr#jIEb!SGN%>-zQkSuTjSQ~+ya>OiYU64Gnd{dL|}E$$D?Yn))CUQ!JXfsb{4qdN)$5S*4yCNJ!%?o;BX; zAe#;%%s;`C-)+`9C#O)Z@i87JSUfZc^F?0IdgMLr9Fs|T-Mj^|jhV26*D>roH{cDf z3;3A0&1%B<%oN(kWo5`7#tqKa?^IbA!zc?kA5FR}M2;Kj(GCZ*6JY;C?9Wj33Q%8c zyNva-27igSEw~g)=2f#>%$4OM2IR_%R^SCM1Jj=#?{igBTZ`Sid%2r$G4u7KBNAD> zRabeve*@K3%?@=OWOiyO%wNJ29UJQ!KZAPH&D%ixXcD@4J75#ROZKq~;_LbI*6_4J zPt5U7SH4cQ7&Jz|5YTcL%5?KOOHIN?BjlEgm1sQ7pRvk7yEy4I)02`+ zU&4^V)=D^loEp($Ns*@3avIqAP{KgYkC@LT7G2eABqD8GXrh~MK+DY$Zari2jtmhY zYW+?AfW?TjT3Kjg?0T_88Vdk)siRvg$y{{VNcAAvUj$~U*?!rGP$pC)$3g3=XT336 zU=~T1=VcE;TZ^3SH9YH@ESq3tuog3BC6@8@;pDNG(6GgdO}{m|7H6r)x6}rMU`=LP zQvX~UF^fN|$?FL$_pWL1``E{rGI&z^@QxRlowN=^G1iRPs7Wde(ejL#OjFN5S)-G{ zX%w=*Knd=Qt>?Uq4$#Fsx>^e^TCGJ<8ZOow40@R;j>`KDqt%P$99ivHw~>vhS_B>D zfc~dK4mdsbFse@A)L=KSX~z1bxzUl+&0AXn4XBSek;(CbT_cq^qYl83&C)2dfFYSt zYoP{d)Wle*oNe7XhIQp*2^S(wMw)^&3u%sJl_;pv3K+wjcC6H9Rp? zl_`0XzsaU7b$K%>YaGX;f7}?%MVQlQq4*0a#R(S`f1uNmx}S%JI;eZStTR9hBWj)j z@O$ht0K=vJN9HLIv0ZzFiVc@yX|Ms67R4o_?MKO%tUxC#-Fy=*&ex$_8?ry!Hh?8H z`^|}iQgos%qu@|=<)GrwMXL7FFEx&Ols!a&l5qI6>tmMlGG0R!7px-Y(qle6=F?lE zRulESm>PV=KtA|%k1OPS^}pwqjtfYiDgva zk!~AnGgbg(+p?hfr~D9pR?M3)~OT==ag z_Xvs<*sefRVNSh9@suH#J0c^t*{mG$VMtRk#Hcvx-Tt5F)`!}c+e$Hw@6p_@LKj!N zc_Vf4XVg6v-a_r{9{Lp5{SXcFbeuAv<(ABxx5>xs^1vwg@aTQnfjwA4CSGi7=2zHS_ySviud)UCcWkYEt8E>>!-kF9wt?SoYvYgE+WCvN zjr^GHdj1>RfACYbAMsNAPx(Cii@ef)gkNj#;@j*m@g4S`@jdpV{3&}kf7bqU{(}8w z{%iZI{Etrimwb{#ic&|WnV6ns9~~K;>FMLsBYlavE{qVFy0HNQa~!MDmB-B6(uYhK z0lE!o_qGJ)vYhQ)Po1~SFsj*7oJQ5BVT4lFj+C2*kCie-${ZP2Yn~YC<>-HA8lPxh zlR0$iz@E}gp4R#@Up31^X~!XyCLir@s+%3~Y?uizNPfs_C&qZq{3?BbXmgmW2PG$y zAz#QXk9f&0b4JF%1vLAS&A{K%PN#(Zlh90CoF8?1@W(k$Wg8F?cvEj$_mw>b7#!h1W*MhI@tjg+Yzng2DzzZnAi97j=R zsQJjqA!;`08<1}8yd_g`onV+3>Q>A5j2aiJ!2ou115*N4;}gh+T?ajZAV^aKYUmT;vUmc^xSx1gI=NKzKcZ?JNaO8?qB~J`f#*1_%Ut}r;Vze?* zj8!I!NlJ+*QKpDF%2cs@rZP>qm6>9tGFz-tt`LSYPpnnui=eVtY*dzs%}Ry1S*aAa zD_09sStWKT)#3qVwfKSJ5&IRdIH25TYB}jyQ_!U?%5lY50AMPn!VEXi0p$SDDxhwq z8^d$bbmwHHO#)qwbU&R>39xs`P5uF+xEj=F=FXfVoluy+iYEs1&785NDkGCqBH#Tda4RDY;#&W<^$~vLirStop zTgR^8yubO@xJ+$2go@Nz5c-kXFL#KlfG$OP-z>__(FxJ6Tt~Cqn42G>tv$hd8SCZ^ zROu#2bn|QJMJDROJ=aDLT2Vi4aOkv5{ZzwiFs;c8ufZOA&6Phw1;$A{?o{tonej)U zUFt5N4}kWm`+%T;{jj=ZX9?>ZJYM4=L;OTpBc4<0MYpn6ysR{evO#>Jw2AY|bwa4u3sv1D;?)~PfAu?Jkb09CqlQJUx>XdZH;Y;7ZDO9fT~w%d zh*hd7YSkUWQ12Fg^&SyW?-On6PO)9RU)-tg7Wb+Th+QG|A@P8^N9<7_5s#>k2`DKJ zt51mI>W{^T>Omo#hefXQfGBc4FQz)56Q#}7OEO*PB~9GajXSO(?)4V4ZuhM$Zr4~rB!RjdVp#G z(#&`a#9r-F&Da63Uwc+Fz7Oy$05W&?V@d3oc1&Z&qu_oFIh2`Y-dI$hwhz5|9L$rn zVhFIiXvNGVa{x8VbWZp@M4Lin!-#BMj2wS22DT7#$QEa*r>UIYe#o&|j3r*Y!8S2+ zaTdME@2LZ0E|#0MC@m%xi7{zq#;Tgx z2ktzAwephK?);fBoiB?W&R4`e&R>YV&ST<`^Vi~(^Q1WAJS7HcCq$a|mKdeIEhcO4 zh$-5CiE8bS!lV6J)P=PF7C!9*ah>)zu}wQ8Zr9F<2enVcUhQ+SPy1Bt*Zv`XqJ1Hr z)w1L>-MzI;zBl%HzF@=NV<>Ch)jmtG=?K22uo)8%NrRA%clWu87u zmguwPRQ(D$TVEjO>kDO>zDO?Dmq@Q(CWo!nuiK_DTfpP1t7f$n2%xzMb0qd=ifc)nZBQJFZIe__kNH;1WwN_sXc@NMg zeUr|L&4rVeCK1WrA&Zy;RD%>YpO|zci4c36_)ef&q!&AHy8H;&30iL!q*!@Lj^)GP zvU^`aYNOceL?=eiqtd!|xET zhg}ABB+0eMWyB)}nd8cJF#|%I_PFF8SMnWG7KKv4XW681KcG}3J6SvdHip>eAwLk* zKw=YMS;YPb>_MQ?iA{i6!JxOn9t^6G*aX-plKu_YLqL@fn*hrswl{%JGaw%~U!U?q zXsK+{mr1`~F57gs+@!CNA^j?OlYWi7TVEx2>8s^#-6J2@YvcjFPX1aqQ-Mmr1V8GRJkJ%yoTV`dxR)HrL&9i|YsI{KN8L*Iv2L z^@x1Z^{71TdQ2W2=GrI!cXdh@e?U6p56b@W)6BeSyLD1F%$xDV zG`=}4JFSU26W>4H@BldDo$-j=0QCn88EmULYI@#iA2?mqbpq^-jxbY)V-J#Yx{NE6 zn+8jJWxABZ&F1L=e$sqI-f-@1FrIQ>!vNKd_<2KUa z4Rh;^4BIX=w9kBU#%kM{leeyT+I+Hd>HajyLz}bNw~d+CD*qhv|99i=wR+zOdg$WI zh2C-Zo>=|Aer$BVyeMjN2T$5tx7*fqA$QSmusjNAdrk zpyo@(|3fXvh=!?e229O6N6%t<=FnXMZ>epYhl>sv(PkctUQ=!{Uyn;53Z9Alj0nT) ztM%74_|{NJJHn}HX=M&CC4d5u698&`o! z;AA-2#{hc=R0E(dgw6_L))2k^DC(KfSU@!*-xE-!sbk&?5!E1Tv)ZC&y2(@!Yes{< z--9+B2ueEGLL3AD7UGM*HU-QcLKNv?q$iM`bn`jnwMmv;L4Cgo9a2F3w9~Wb2Cfqf z^R0MdD$gt~D5K8(Q&VB&UxmvvqZQyL_7F1y01x5|J-!F{FlBB5IEXKO!W>b+Hh#?X zFBxOI3XJ&9T}$#s(zB51`$G1N`Oea$Mbtxsf_|^E`?&Ebq&~nGuPk7V;-fe-#sC%Y z05|#r%-}P?8V0n0F96B{YUa&k<}A-FT~?~yf+}*ry?xsN^LRzFxqF#CM05hDG0)x# z*n8qAtC;(OIJ#ox#%3-U4RXe2E*Oh~#+(3_Kx8T>Wl*)S8mk6x5WUYwm0?aJgUA;a zjx;luPe`G#{_7MOy}lx`>t0OJPB)+3aoDUXPtP8A$=jq$I?=nzuXSBbF~dc;TUzGk zVbj0-{mv2YTwe7S8tdj!)nP1TQ=nsUJ>Eo&i|>#~L!$sbejl$C#%O@o_-h#0e4t`c z45MM+#SN*sIyrUeV6vn8P@oW*>&d(b;CKZ#okoj5sl+D0Qagq*l`bD!q#PkPrld*x z#H`heq)Zxzcp9!r_u{zF-yB?VbuO78(J!qv5$8AjzYGe19dn%f3q+hBz zpfbbuGI%$dQ!9PFPYEsG?vxPS?rI(Xhf_kV4z2Gl`;DiB3)^hpGT*c_|GNi^(%yeH z_?9P&J_if@2LM4F7`LwR!`A)(_Nz*iJ22Y)G?<+$F2#KRs#{79VcQ0e3Zz4iHmm;8X{ym8$VVenw?;(BHoK}^dL+GN*61XxbM;Um%vMDORmt=5Hs@DuO zAFR5}n~PEH?X0K=7Zfb$s~~pEs4g+rRGbl!@7ZNYfJVmpKM6e5Z$T%TgRc4O@~LPk zfm3_9ok63G#OUKIcq3_NYz1FqK4ydg#WJ z=GIkz(+Pz+oizBp=9cOSg``h6zu=&JL|>{=fg&OHbLaahxp>Nn6}4w_}m1f6r_P}-a%93f=m_CJMdaI0_+^I$(daP z>NK$lu#e0`o-)4M)M^IhQa2(dY+ZVJn(#jsOj{qOffE{vk&h~`X}6IsADO?b8LZrm ze}CX}tLcm%^ez1Ug{6{JyV!NMkKezsc2#eWw~#+o_o3wDI?t{VJb4^TyjaERab{`N LKt67J;#>aolU1o9#zAw&$Xgh!A!h7b^urb+iDfus|Y1`?2I zaA%kv#Z@c@9fVnI@D2n3D{^xdg2$9)u_WL&d z-OGPYovJ#g>eQ*ar`Yf(zTs`Ip8bw9lQGfJyY_RwCEf1bkjDB=DqXy2abd~gmgbtp z^>xb@&zduN%EH2u{7HeZ!Zx&5g;loU-h!4ne&6H z+EeTI`toZ{tDWY{+vydttEt`_@HXey3OW9Ue0jgps(N}e<}&!hGQA>2md1@yw+O}( z4E`gzK5iF(PNq*y>U-s(k-cx+IMf!WtqQc%Ef4s8>Gh3)0mkI(Hx8GLcH1m3 zV=QHZ{eArN7Uzl+|FU31QD6-UQ_1_)-q8V zC2Re4%WH#7jJ0UCi_9oM)i53@|D=7|kC4uryvzNbAR9qN`~$psSia{hO{P-weY}3p z;-Nv9&-8m&qpVoZ&ZM$V-UQi|Ntn;ya?W^uvp=}1Il#mnRu|?y@)rHe(g`RY$W6{R z?aH961|^g6yw>hub^=T%_FvKT6i@@?9j+tAZq};-F4j8R-x{0?MGHJE z-eSzFZCpbP4|}V9KeJPfF#i?a(6B9jL^-L|$y-4OXf!){8(=-bD=PaW#8>kdEIX+) zOxEf6LW5c{$=EmfAUU*GmS{g9Kda108>sYLyZ2(Wp?ej4aIJU^9_5^@Ye zVZJyH_RN=U2?Zk}roum9>+Pu1$$gfwgv}cuS1A_3gfQO|sq@E#QE8UnKLmQ2XtK)4 zN^3>^ts|>35&mb)76#>Uvq zVzy$I0vL)xW<4N}Uo}MgCHfx==2Cg_s==Wo3_e8xT3pr?PYDG5&5Tx=MUwmZ*-xRZ zMNamc-c|LMQ!w&ciy3nh%Y!cC6tG{RV~Z7Y9cxT2&RlO`?o>Dvqfw2>`0M>O!MO;w zen!J)F(=jgz0H;W<#mk#whi-!C}|%=p^uCRLr>O#DS1C}WQdk*#QW+mjhi)C3H*J? z<$Qt~+!#9liTL#|?sE{sP_@j}yrSrT?2BSvv6s(#U)sRr z)zV-&8ZC}XLf^TxWalGbEvVw_X&Jr*0z(5 zKgaAOVmSkc_V1*YgnDQn4Mo&>N*o!PW2n#@!Jqba%x;1E1vJs+4YBYZi|4WU-W2tg zXnaQ?w-oU#gC;@t3Yyrm!^Jw|$5vl;I1gszSMl51^O=1RdQ0HcXVf2f1F_5syfSQg zHggIt;IgoPqTJWt?T9o}C{Of16Z#gS-QrodsPq3Z$4fNCL|YlAa~;j`5)97LD!!8D z_$hSk(V$}X=46?k*|(!+;C6nM2NlA+H;x*yLx*f1+*f9%r$r|hr%sdwA||wu=GIoz z$y-SEhR6;?5t>{wN<|zrE<#1-l8WsSMs&7`qY}qVK<{(yqb=t;y(0+|Tb*=xxO_f+ zW@s@_vMuEUZ8bc@X7U`{a-L^f$@6Uuyu=pZQ*Af#>9!WW#I}n6n=QzHVq4AcvaR9w z*jo9|ZEgHv+gkpTZ5=;mThISs3-Ob-XL*_ZMSiXQ6~4fJgx_TE1{-XUD|DF8}{+`n=#At^@lsWz=w`OG7ldW-*FJ+7fMQn-1EsPNPySW?! zQyfcS%C}^QTHW{XAk0Aqo*8&%Rq;R2TqHuQ7S9Wt2QilwfGfN{{~QwwElSpVTWaS7 zK(-%X4xB%&-K4SJN6T^|Lfw1{L{`lhhhkE9Ml_n!n(bnDEojT>yV&z0!SYE}-q$~c zd*pqClZ(hDECEZifTivw+B9)Ec?J;yQV555W5t{vT#$9;VR;?`b&ieJ45#RpaQTpe z!B-YehQMu(U6$~|j;%ukw-1cfNtBOe4$Qc6y(S3lbsQmk<)@kbd#8fF3D2WAMQOjn z5Xu_2pXbY0-RZnk{>?q0cfn#MZcxEeB`&SN2Q=lSj>MsY8&oOG2OE~28N-H$Dp9$U zo0uZ7R{k8taQ~pUIS4WkA+g!uWDr{$m)xSkatk-wddo3PH7}s<2adlwn3)0Ar;be3 zOb0mY_{L!-S>PtRr57~wdz``jjmva6$tE# zQ@&Y}D81Q(29SJ$wQ1pC9Nnm4c!CQK|7pk0>`^?VifIl_EOoeq&k-*g9KFOwN21u| z=p*iMB#B*)eqxU!RqS)5i6f3d;;17-oNx>g?>I8WUmQcl2aasr;Zn+)d^yZS|+Bb<)U(;I#E=q6=IQk ztyrSY5T-g)tWal(pn9EHtIii2)J5V}^#*aL>Jd_1Cbp?H;(pa99#s8epIRrLR!>Tq zn~{|VlQyZxRkIX8s#0a^!aQV;Il5 zpi<PVWm~bEYQ?5(K}YZ5^Er=`%kwh}M#N*k*Cs*ecNB|Qb@t(Yh(T$1 zqThdR()Vk$RRB>#9?Z`*2+{yX!XjJSEb_J6MX~npVv;7swc1ZbwYE(x(e4&C+IC@TJ4BT?p}-?*QC?D0Q!t}2KKtZ zDt3-@ng+la0E|!uV3~7^(@gJ$ps@uAp2MD(PZy5W{*0P~QC`?_vG5R2-fS?frgo+E zdE#LYw;yC$9fnZ;cI1O0MVX+)%~95;DfR^!iZUqN9%6Q?Yu4el$LZ6}T7UyiuWn8N zIO#m;#EBRvT_38Ol>kEkAio@NsP55C6TkyN`k42E*rR`?o0|ak>4$XlM*xQaPbzWvuSRdT-52 zMvE-QSx`%#5VRs~eS$K6~Xwue~u?AihTb!>6={zR3Igg80gS?`sdIio+PM zxQq!(f>Exd8WWXFW0Eq=n5^U&6-t3IRT*PktBf;dD3guZ$~0q+GRK&!R2r3v-~;-T5qg3*ai94=(&kRvd?JBM*&sh*&|D?c{z~~ zJ4^g;(7`-V?{yfZFLQ&S_4PrDog9;Eg(gIzOF_v?F)0$Cyo4Jfcx~ix8X*wFaPW*H z!lc>UY<%G|k>p{gjlC}OztP7h##v~Kjed)8J>)XUkVMxmm-%;;<+}1+IIzNyT`pyp z>kl$Kc4o+dG$kt~jsJlX71S{DX#(sTVt)*_2I?AO6JVo>{T|p(Q02rXz^*3t8({08 z<`J6!DW%qIqp?6~H5MxCjq8<=aij7> z!>in5EK_zGKIJ~cuRLOy%F{-z@;hUN@~+XWd|<3pP8(~KPmDI@tZ}n)(O9bp*AEoU zwO&bd{ZPquZBp`GKT{fA_bRQf9m*!xFJb+|%0sS4l)bLK%Hys_m4mLwlp_OO`;_-x zPbgWO(8aD9-ppN+0A}pBaCjLCS{tjd)`oeG_uh7n3pZed5jQ0G#p8 zc;t3~`hbN3c3M6L6U~K4aBxv#3ysMb=RS zY(g|B;jIl`fHIK4Frl@6?6tPkv ziaPO3_cM{Z${)Vr8jA=nZGN)8DzCqU(`(} zhw~s2j1B{@gEqgy%fV(~>jjvBAHpVG>+Hsn{vkY%;(5G^PoXeLvTPyQ9)v+(gZgvF zUuJIP2Ej0Ii$kj`WMFpD95U{EUA3b8dUlYRH2^xQ}n{D?JO6WO}7N zM05hDG0$lO>^^Z+RKf#6oCC3zV>1_wrXFK67mQ71Bt9UM8Jo({ZfX`@W3}K9!ukv} z8Rj%HoO;s~xw~>y5+&Jhp?u}d)x8gI#}w_T;*;h6c^`@P{dDD$I^cU(E?x0-?7W-O zniOTQvNkzgv0t6Fbf%Tp8;k3f@+!WkV|P_Pzy3J->f}+);Va})pksM9UQdjkcSEG0 z=|-5}%NGbU8Q=~62F5i5s6>>&XV{lAuR49)Z4ev`<~H&w0xX-nijI9lK=mUw0hZOC zz_cd;6eV#u?uHoW{p8)%jrrtjk@Wq{Mz3#fO)L8e+PsWYWz7QWvS(%Sf(9FDktH8o z;I@%--6daN5U_oX-T4_=ws7thcjmb>%V(EY=1J8`(CWhhyTLX*lqLn^w^m% z-GE=(y?coKpEhsYe@m5CrJ?hq*4_7KH;hql!9euV`90W$ljV%Xx8)whO)+>hQ+V6) z@2;L#cQFHLUmo+lec2h=mz}3Ft5odEI`(DPFP_x9U4@@RxTG1tEA zL07=HA**d&gU_kvTiWB9tr6mg^i+$@hhN%?fY#vIEgxNykxQt@^+6$637iVTJXli9 z_^l*^bl1(kelpQ>m46^cvU{K)3%V36>Y-q9Ou<-KC~-&RFGYAuw{8Kx6YX7)w|YLV z9FCq6IQ56?1a!KR7?&+nzLK;v+rZaZfSIiTBUl|mFhDi)AOr&}!O!}eDm#~EX?LN@ zTCmIIg{7Yvgu?tB-uza1-aBd}>C+h-VT22!uhi-1s1jnYA|ea9WLb(hCuHlg9R9bC z2bK-y{(Sgn6X|RzI0Mx0*?DG82RMTt{%)tODIW1I0Z%d>WS`n;ioQd`Ga)AsI&1`3 z9I+{)%mVcVu?a9m=KALFJLNiGYCf6K?Hb5ikN>T~zP+4j;=F`vj7^g-``T=ziz3VY zX=)h%2?BpVkjIVGD}>vwWwOUV%XJ4`oWugG6y_4!HwZjWA@HOHY5i03+$=Gynhq diff --git a/emmtest.exe b/emmtest.exe index 1afe9df7ab0f53fa981d5d4e8988f04372d9ba45..fb51561fba2318cd5e9c911d768dcabbfcce7c56 100644 GIT binary patch delta 2842 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 F`ft>pHgNy| diff --git a/emsdump.exe b/emsdump.exe index e19947ac5a5e6184e767a84144a91290af1f0874..9dac2237052d4c64943dd884961a976d3fd17ac3 100644 GIT binary patch delta 2429 zcmai04Nz276u$TFuL6o<;Lpga1h|06e`;YVqO7p;vxq}2GTZKZz_5S3x9fysLRh%j zRK~GsaI}e;v~+UHaK?1Rs5I%%CTS+kF)b&xKhwq;qf$HfKAdDseGKP*=R4m$=iK++ zz59+`rd@x~cRnqlKf`AwNwgDwFG;11kYGzSuvvtB14XtZdIB13sVpN4Hri4QnOTIG zVL@>m9JR%=f-E>=i_c$631Ng^%=i@IqIu5cs-&n+M<}33&Y;s1P@UNYPE~O`C7%lpEbPJQgOut<=jjPq;0`sdl8WtRO=^hfbVN6FYqZ#IcSsG$x9j?m zk5IALet5YoFM$(U>ntAcT!bFR9%&DpDa%aYCFDcsTUnlnMWe-7vOQ~>h()1a#9Gjf zS`}#W5EIU?!!lk--iq3Jx(dC#7D0`!R!8Irq7AwYh`JCR)g48&1yQm-8SgmO zABO|wS)+lKXDrfsxLMABTRGayDLEErdGx#V@>m32`b}D{dY%jKno^!IUC34<@u9xb zAlD(tG~^gW$@5&+1Min-)M@1$A(s+DPL#XbVu!1r!vt=_C4+nt!C}K;1Cf73blUKX zR-hUO-bYErtcUMiL3VJt(QTBg5V(vkqv&#gvpuk8+UupD-)$^5@wEH3*kEOr7Tbq@tw|LzGg^H0 zCRaV6Z4VRrou=1BY=stUteT_6YS4ez^tp)b;jtdrTa}x}JN>_v^`hjA=^r6aH4FI! zM|z32u(CiyMFVm-A7*2#aBqKehi_8~CKzwdLmQ#%v}EfYId`nxfszulEacy5^0SWY zJIYU?WQ}=~kk7?a3RgD2Iy?PNE1QFoo#sPA{xp~4GuvF9Yvg))UGHG^-}kj$M(lGn z`EelRBm8HigA#H9?|nXw#de!t4iJ7i729hhh48beJSh3`03#D{n-+NkDxPw7!Vei7 zZGJW6@_Ho?;U@_aMR>}WNpgtX(0mLA+=L$#7_3?(X+Gb$=r2|ziSUhQcLmWUd~+@L z`!t7d1pMjXJb#@XE`Ge)iP;1%HRsa~IMSTN%u(=bb0W=xD6fUOARX;`C`G#yn!QWt zRp|BR($#R@TgalvK#DIh#x{l!JzImzD$=LHIA2`M$74Cu8N=^Ll3?OvIkQ7B>4JGg zFkcJiFV2`w3T8V@55+;dYNF%doG+1Pg28X4dtf%&vry}|(D~4c)&t#WH^M%&FTx45 zdtu0LjkyuWD{aBb9=%cIeP{w_c8a{$eMZ^@?tqoH!1DnMeG7J>{Sv-F#sOCYx%3jG z2Q4%eN`uyz%?W&FR5oA752EW6g85A_wSsA!$Tf>|xTan(U4q#rm{P&)7tAHWToBAf z!5q)!vnFzeStdb2OCntY%Ug1>t!G;-^f>H5Tmh#LN8lRTKA5Ul=s74x|nzBYM9LUt#+9@GI(H4uD&L delta 2364 zcmai0eQZ-z6uzNB{**M09{G3Mldi;Uh7Q$fpnl0rA}XMjRs2W#|3Q@BHpL z=idA7&FlP~9=Sq$4!Y?@3?e zGlBA>lp2N>83`%&#~WJ%F1frh7AFP+F`OG5b;)vdAc*{OLl5%pR7|c1c9a*TaYApE zrQ*u8(;e6oO?1k6X}p5+DY|x6Bto}E2wZahI1#&rzLPa$Y)EUQv4NOzxQrgXP2nAR z{DgAE%h&;?lp)y4_A+HQf<0^xT3)IPpELm{<*9nD_s~De&Y*3l=Xk6K>~o&W5H0qj zf01Pwa4Q(^qn*Bun4W{SIZwCoZhEQPr#6HFxGzn>RA6H;-b*Wd!9Wa!A+EV^n+9aO zkn$F4ryDAaii%*Kq1Hf@MTj~K9f)2-)Mw~Jv>H*CF$)(Q>r;GCo^=?E_vV)9J=`m& zK2VM}aY`XLs=>I$sNBU|oyN6#E-%l8tJdkweM-pYAn}#4(xk`;@=S#$QSvyKCE%1d zw_Yz-9rtN*E<;$g2 zVyK@FO+a^Lq5gU;K)*|JnR(i7J$AJ+Uyp4@zt$WRu^T+r1JkRf>8Ill^jDZSh}bN& z7;CS3R*#jU|B3lK5&MY85^%iAF^PBjUo-mmV&L9r^8dZD{vJd|m(eNnuxA3#JTSjgA~9h|7ZL7m_}~{OsU^MstSU9S!rEtuz~2 znjP5H=4Kn+1qTr4!yUv6Aw#p#bua_%H&CzH*yVIsrdeq!tV5~<_M&|QPNHRS2kkV- zh}ozgW}r<#J=!nfm6)BHU=!lW@GasG;0oei7!kLz>lsiOpGZ}BA?{!|t*{22H(__& zMi0P=xZRRGj!)AxlXtvC%)up?Ho>%UX6$;w{3RHCDF*#shWeKDv~8;n8aZx@Ye*@)IK_vhH diff --git a/fmemtest.exe b/fmemtest.exe index 7904c7d68723ec8cab90dcb366ae7f50c3d64091..951d244027f6f6ae31868851c8f7a59e8a254534 100644 GIT binary patch delta 723 zcma*lPe_wt90&0C_vn^X$ZWd8#HTiL?@J=q!a^3jvmzo3OUmutySZsw5gY1W35-s4 zDKW6V5nAA(lcyT3QVOI)n1`ZyD0b0PL`lWy5Y-|2y&iV%clhx8^E}Vtd7iaJ8h=gs zZk;?hq5J4DMsz>D#kB5s_`Hge#&Xb&lJ0Wc;A+OMZiigtM_tJ8P<@J0y}qD_d#y-@ zwsxE)MG=Y}!WrTGP^WpuO64rGcXTM1GKbA`LzcOx!?bdPW;&b7j;5^9wn5B<7M)>U zPCsz5OWk#k_q(e4)@|eV5+!rzFDZ&M1CfQ;$E|cCq>q@2NZN^cb_6B%K7O$s*k(v7-~hXVupxzW1I7%MCh)+}=mp;Jz=N-B z5SyctvS?+e(alaF!@k5sR1-BDF&Ay7Bly6r9DYVMx{MvBq^Ho?5)!6HCdSPG{l)@! zny||D;xG3Xp~j?e)Z$pIneO01Owt0bv!5`_He!iAj?b)xns|VZ3&y3Wb|DtuOII)% zm-GaA_6v&a7L?f_T>X*;(9TYxhb>~5J&8&78uIKT6xkJ&`=!|AMqNUsQ|L@c8iSG0 zLf_o{vO?c)zhje4CG1Kl_4W3Amh*g7OJ!y!b|sW9yh>>F9N!ZGz8Y^*qh)j_B{d+! sxrw`+-@>z`+`i_qPnzkp_tx4}VgTi2qq@85|9()xJ8+n)AM%g<2c}Tc=Kufz delta 688 zcmZwFUr19?90&0GJ8m}%v)TG1DW1xjyAWX;S(wGWGo8r>ViInF#n8L$w2b?`jns+xUP&3O^oHp*nqol;AsstT3z&>a zszQmi@r}KS^0*`){OluiuyeQ&m*SU-(YT+on2Brj9G`fg;tzWOwFyZ{w6LQv*&E2R z)3}$=#Og*A6LoYLU%Ax>)zm1BMpM!gbg?B|;6BgNHSY`WBoeJ`Ck(3lawqPg~pg~NeBt1r+{eUG_38a=~bE66`4U~BXSrY*^hEawqC<@_27wygQM!#QcZ d+1Xp^upZsHzFpNdW&eLJv!T9|_?!x{Uelzni^X)#KquLxz zt8watBi`l;`4lC9zHSc^@zrD^72o8#)TSs=;X1b~ilXwXC{A_fHY-ytRI1j1U9J?Y zVQZ*dwZdIiwK8ZG%cpI-P_;vYn2sNf+W*;hvUHqJunT9o@nN**bqnpn@<4>HV@ujl zR}gY(KhJqCt zmPSx4Hg0;fSe>Zxx`i1NH63|r?n<+DmGJ+b4IHRSi8D^MwoX{D=vWD9en^9B=2~~C zUX&zJwtSi?<6mA;PM9%0bP>oJs=EPCvzsY}uUUi6qxpbN9}s5#K_4@S5oQ46%zn%; zC$Pwz#ZTrJG@CkA5N6&+A9EffW`uTNlH(FynFd|OcaEQ->0m_L$a^@|dP5A+D{o?t zG%0DCq_L$rEX|O-o43-u2#Bs$S+gunJ1NSP!zqlryGfk9AMdk1D!`F5=oC6~I^DxQ zjuSY;oWPwNFT4f|IX@+_#OYx)9unU&$Xvi)=5L%}wqule3=f#2c*lH%C1wqcmO(|t zm^B<>_T#dp(*@jTKF2&Wfp5$r8uB`g!C=l}cizyFEn>uAmsn%H`~p{iyg`e2lGoL` NR(#Bx&Nuw4{{;@e@+u5Hp3mh3K?1?3Y) zv`VfQ_Q-X^Xvzm@68XHT{njy=&luOZp=%k{o|A23Rhjq7BvEz(M*Rkv33}xeH)Uqu zVP$5OIan+Gzh?&*n&{?^uC3Qg8KWN-ddlGbmErVXrxsAD=6cHH77u) zvDjy6pL}@Rw})Eb?YC$U@qUw*kYm2X7_%DF%uOgWTd~HRz)$83>Kv1vBF;R49P={9 znDdx+64ZoeTzBJxW6=fp2TZz$mVtz!^Eq_QXUR=;shen4Caa8J8C#h_WlHL99xAii zEJrn{%xh)#k`QxMx-{Mfznr-j-}@S=1CfG7J?JTzbRDByhjE8FfhPq%a2>uC!W2dI zDU*&P#+<@2=3|U7U*QI`29KCW@sc@$ugu%1c1@}v=33N=JhOr;%vQ{^AHoafeSBty wv9V}!#$t}5n>mBwqGd!wa*MGxd5mr93!KAZ(V{Zm6iw}82!D!>{(yhwzu|DThX4Qo diff --git a/inputest.exe b/inputest.exe index c7826587bc31c554e0b79664f54f0f5b3717e5b3..97ba47cdcff5aa05fbb004dc476011f5d49832a9 100644 GIT binary patch delta 1607 zcma)6U1%It6uxI>e@s#~n{IYHHMYs_*2YAXrmfo~REga*P1>~$tZ5QiwUeFM?wIY& zIy0MOpElx4ihWQHLMeiU6d$BuHLZUr3KsQ22-rT9K1fPI=tC*`AXX@P?(B~{#Ro6U znR~zQyXV|{?%{l!+DKhW1mFzr3&g!ogc$2W*c9s6#ux+o>LZD7270|8MHqXT^P2~W zXy!Lt{4c7uBpL7mmuOREvos zg9ra5%4<2hE?H(Vx=0%=8m7WlNZmh3=K(1JuNmbRG<}8%yJ81PQU_+4u$u!FLhQV$ zTKTGKZ%x&}NSJVA@)CI)d>A9$a1G-j9npRlK#J#@fKtJpNwMR?h#Q+tG2wt4ni*%p zs2iFkXv~4=(ua+*Woy~_Q8mXV>5h^xi0^kuj~u2H@YLcr9bG<+79*>;(b3&|ri!o9 z&q?_@Zp{R@(SN}c2pfv$=CEGUiUA!QM z2&w}EOcMzQdm3|7JDDePZw;tQpQ){?WQ9tmx>Ye2^{QfD6T-{q zU%uvW$bsnC^{3#^IZh{(fFHe)jw5plF+BSR8F(2R+fBxu;m4teu*Qywqp4TP>9}Fc z)2;&W4U({mA9g)@(@lx*40 zr;`&COtUD@*~LR$pvEccZtuftv!g` zYXKSW_UwmGu|IkUZlM|70}6f+?S{+vJ=tIISF&aF#k&1}v{Bm=#_@b?EA-%4tQ#gU z7wdy{e4FeR{F0Ct@g~_f@UK{3^mKshZ&3W3wYEr8XY3>^u&X#4?}L|6CwmFc#(A{Q z$!^CRWZ%O-<9*TFLGB|+kr|tD_SQ|+hlB@q#FMiG3XG)G$N%=UQXK#_0B1ZY{=Y7~ Nc6P@F@SLMw{tq>fV+;TQ delta 1608 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 delta 3661 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 Ko6N_N?WJdCLs@# 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 diff --git a/pcxtest.exe b/pcxtest.exe index 80badb00b632c1dd65e07c6b549e1af10c23c225..57294369fb8d0b5ca2bdecabd2374b6b01e80ab8 100644 GIT binary patch delta 1379 zcma)+ZA?>F7{||ZTfm`}A~-D|cWxrwxq;9KgNVep4PDR>qjj^OtU&ArD{0AO$uh^6 zsRSqHPwgb`g~UmwbJd`mejv+0+!ErVS;97l8FOxr5C>6yG6_w7tG0L_TKuccsg**o zOUCzpYmCk}R+P6TVa{)*9MGv{>v~BDO~^xw?dQC?$hq5B<7@5hsq)4ZfqTs0ipU_Hj%VgH-!Ihd22YwQZa};8WCga2n)O z)Sl&JBO8g@FFEB=9;a)ZN~x4nFM0#{6zF~!s7R!&ZpY`VVky%7PB4_EYdq+`{grX7 zuX6Jed{pwU*Tl{4rk|@c%D~;bMe*BhLj1+0Hp1K`8w!RTbQ33r3@%?EGIUwiv;#}z zAglTI0<-EPL=j&#@gZoqn0BCKSf@tpXP&`fHreRmyceP2muNjQLI(9>Co>Cghje-k zr#U}BAF~7ZnR8e+qSL!5VBUda#Gox`=3IwP&X+O3`6t|C=3!x2ry$la=kapbu$(u9 zFl!xUa$_4%6;7fM{9H}J)v!U^5axUq|1f`tKB`kXN|@KNpE-fUqq?@}Iea>rPKEep z)Sz)hS;an&__1_a3u8>DN^E0(3^y|k$HojxRkmDn-|ok2TIQ5Ft;}M%3rk9l9Mh#t z6yHuKFH)k-Atz<1A+5?>Ri<2-0cB$M$}uOE`9qn2GWp6Bu9b~%DYI0W1ImmmQ>RR; zGCN+8eV$b2iZa#8yr9g8GG~;@Q6@H5b{0V%L zK+`&H$4aIb8=2=&#ry%y%s1J(mfhnA2P!(_@w?YSv7nx{>BA(1A=G6=jc_i`uc@xd&aG)aR9~~DxN_U`FKx># zMp@72*)3e-FoMi+B3sP$6(s8SdFo$n5jNWww%hCBp@Kb_ozIOAwHN<6q z>rZtCC1T;{{FwY?A(nWklinFhM#*Fj8kM>c=K#5W8li*(Zgt8+~PJV}&?46HlY~ zkVj*1ZAMZae&gJY*nmZ|$YQQSIdcFW<~TY6mhtzKxEOGf#8^Pm4gAIG?mDCdo%9g$ zf);H?74sBcXRbtVP?{B)YRz5S@2_bFwCUAmmD+_Flcj3TX%j)(T)eqeo6enTR=Tb^ zs?CTt71~_YCaO}^bZIlMjZd3gZRAs`^Qbn7+HBG07j5=wb5xtnRjSV#Z9dS(t<6Sl zzSHKcHd)%-)#e**BHB2!)moRTRi7Og;!n2($8JfwiVL^Y35+sVW0AQL=Bzrg^~@6} zV;)D-tfX(@;~b4EoX;XS>mowpoMmR_sLp1i>Kv;(S7Q5|BtPDmQ=R*nPvBEF2NB`? z5u!sDACC-4v-TM^x2#FceNfLmj^>ag2j1nHLVV0Tf$5No5)e0UQ9iPndr-mb!9nIH z=wdElXx?S+;V-k@@Of0XBz;nS+6*30rdjtNLwZJ=(izZ#Mc*Thc?3nwbEsQznMRS? z%V3*YIaZwj6<~x%&)|mzSL({=)aXRJ8ckEUe;vb%cT(1-*#7q)%ZXx~! Dab&2< diff --git a/scroll.exe b/scroll.exe index 9da91bdd00ee9a8585f985ca9f9b0898618fb7cb..4180b96fc72ba35d9bba12521956c9e26b649922 100644 GIT binary patch delta 6485 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 delta 6325 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 D()r(# diff --git a/src/exmmtest.c b/src/exmmtest.c new file mode 100644 index 00000000..2124d3f9 --- /dev/null +++ b/src/exmmtest.c @@ -0,0 +1,31 @@ +/* Project 16 Source Code~ + * Copyright (C) 2012-2015 sparky4 & pngwen & andrius4669 + * + * This file is part of Project 16. + * + * Project 16 is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * Project 16 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see , or + * write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301 USA. + * + */ +/* + input test +*/ +#include "src/lib/16_mm.h" + +void +main(int argc, char *argv[]) +{ + +} diff --git a/16/cawat/16_mm.c b/src/lib/16_mm.c similarity index 85% rename from 16/cawat/16_mm.c rename to src/lib/16_mm.c index 8c28277a..570ec346 100644 --- a/16/cawat/16_mm.c +++ b/src/lib/16_mm.c @@ -1,1114 +1,1149 @@ -/* Catacomb Armageddon Source Code - * Copyright (C) 1993-2014 Flat Rock Software - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -// NEWMM.C - -/* -============================================================================= - - ID software memory manager - -------------------------- - -Primary coder: John Carmack - -RELIES ON ---------- -Quit (char *error) function - - -WORK TO DO ----------- -MM_SizePtr to change the size of a given pointer - -Multiple purge levels utilized - -EMS / XMS unmanaged routines - -============================================================================= -*/ - -//#include "LIB_HEAD.H" -#include "16_mm.h" - -/* -============================================================================= - - LOCAL INFO - -============================================================================= -*/ - -#define LOCKBIT 0x80 // if set in attributes, block cannot be moved -#define PURGEBITS 3 // 0-3 level, 0= unpurgable, 3= purge first -#define PURGEMASK 0xfffc -#define BASEATTRIBUTES 0 // unlocked, non purgable - -#define MAXUMBS 10 - -typedef struct mmblockstruct -{ - unsigned start,length; - unsigned attributes; - memptr *useptr; // pointer to the segment start - struct mmblockstruct far *next; -} mmblocktype; - - -//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!");mmfree=mmfree->next;} -#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;} -#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;} - -/* -============================================================================= - - GLOBAL VARIABLES - -============================================================================= -*/ - -mminfotype mminfo; -memptr bufferseg; -boolean mmerror; - -void (* beforesort) (void); -void (* aftersort) (void); - -/* -============================================================================= - - LOCAL VARIABLES - -============================================================================= -*/ - -boolean mmstarted; - -void huge *hugeheap; -void far *farheap; -void *nearheap; - -mmblocktype far mmblocks[MAXBLOCKS] - ,far *mmhead,far *mmfree,far *mmrover,far *mmnew; - -boolean bombonerror; - -unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; - -void (* XMSaddr) (void); // far pointer to XMS driver - -unsigned numUMBs,UMBbase[MAXUMBS]; - - -/* -====================== -= -= MML_CheckForEMS -= -= Routine from p36 of Extending DOS -= -======================= -*/ - -boolean MML_CheckForEMS (void) -{ - boolean emmcfems; - char emmname[] = "EMMXXXX0"; -// mov dx,OFFSET emmname - __asm { - LEA DX, emmname //fix by andrius4669 - mov ax,0x3d00 - int 0x21 // try to open EMMXXXX0 device - jc error - - mov bx,ax - mov ax,0x4400 - - int 0x21 // get device info - jc error - - and dx,0x80 - jz error - - mov ax,0x4407 - - int 0x21 // get status - jc error - or al,al - jz error - - mov ah,0x3e - int 0x21 // close handle - jc error - // - // EMS is good - // - mov emmcfems,1 - jmp End - error: - // - // EMS is bad - // - mov emmcfems,0 - End: - } - return(emmcfems); -} - - -/* -====================== -= -= MML_SetupEMS -= -======================= -*/ - -void MML_SetupEMS (void) -{ - char str[80],str2[10]; - unsigned err; - struct REGS CPURegs; - - totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0; - - __asm - { - mov ah,EMS_STATUS - int EMS_INT // make sure EMS hardware is present - or ah,ah - jnz error - - mov ah,EMS_VERSION - int EMS_INT - or ah,ah - jnz error - cmp al,0x32 // only work on ems 3.2 or greater - jb error - - mov ah,EMS_GETFRAME - int EMS_INT // find the page frame address - or ah,ah - jnz error - mov [EMSpageframe],bx - - mov ah,EMS_GETPAGES - int EMS_INT // find out how much EMS is there - or ah,ah - jnz error - mov [totalEMSpages],dx - mov [freeEMSpages],bx - or bx,bx - jz noEMS // no EMS at all to allocate - - cmp bx,4 - jle getpages // there is only 1,2,3,or 4 pages - mov bx,4 // we can't use more than 4 pages - -getpages: - mov [EMSpagesmapped],bx - mov ah,EMS_ALLOCPAGES // allocate up to 64k of EMS - int EMS_INT - or ah,ah - jnz error - mov [EMShandle],dx - jmp End -error: -// err = CPURegs.h.ah; -// strcpy (str,"MML_SetupEMS: EMS error 0x"); -// itoa(err,str2,16); -// strcpy (str,str2); -// printf("%s\n",str); - jmp End -noEMS: -End: - } -} - - -/* -====================== -= -= MML_ShutdownEMS -= -======================= -*/ - -void MML_ShutdownEMS (void) -{ - if (!EMShandle) - return; - - __asm - { - mov ah,EMS_FREEPAGES - mov dx,[EMShandle] - int EMS_INT - or ah,ah - jz ok - printf("MML_ShutdownEMS: Error freeing EMS!"); - ok: - } -} - -/* -==================== -= -= MM_MapEMS -= -= Maps the 64k of EMS used by memory manager into the page frame -= for general use. This only needs to be called if you are keeping -= other things in EMS. -= -==================== -*/ - -void MM_MapEMS (void) -{ - char str[80],str2[10]; - unsigned error; - int i; - - for (i=0;istart+scan->length < segstart) - { - last = scan; - scan = scan->next; - } - -// -// take the given range out of the block -// - oldend = scan->start + scan->length; - extra = oldend - (segstart+seglength); - if (extra < 0) - Quit ("MML_UseSpace: Segment spans two blocks!"); - - if (segstart == scan->start) - { - last->next = scan->next; // unlink block - FREEBLOCK(scan); - scan = last; - } - else - scan->length = segstart-scan->start; // shorten block - - if (extra > 0) - { - GETNEWBLOCK; - mmnew->next = scan->next; - scan->next = mmnew; - mmnew->start = segstart+seglength; - mmnew->length = extra; - mmnew->attributes = LOCKBIT; - } - -} - -//========================================================================== - -/* -==================== -= -= MML_ClearBlock -= -= We are out of blocks, so free a purgable block -= -==================== -*/ - -void MML_ClearBlock (void) -{ - mmblocktype far *scan,far *last; - - scan = mmhead->next; - - while (scan) - { - if (!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) ) - { - MM_FreePtr(scan->useptr); - return; - } - scan = scan->next; - } - - Quit ("MM_ClearBlock: No purgable blocks!"); -} - - -//========================================================================== - -/* -=================== -= -= MM_Startup -= -= Grabs all space from turbo with malloc/farmalloc -= Allocates bufferseg misc buffer -= -=================== -*/ - -static char *ParmStrings[] = {"noems","noxms",""}; - -void MM_Startup (void) -{ - int i; - unsigned long length; - void far *start; - unsigned segstart,seglength,endfree; - - if (mmstarted) - MM_Shutdown (); - - - mmstarted = true; - bombonerror = true; -// -// set up the linked list (everything in the free list; -// - mmhead = NULL; - mmfree = &mmblocks[0]; - for (i=0;istart = 0; - mmnew->length = 0xffff; - mmnew->attributes = LOCKBIT; - mmnew->next = NULL; - mmrover = mmhead; - - -// -// get all available near conventional memory segments -// - length=coreleft(); - start = (void far *)(nearheap = malloc(length)); - - length -= 16-(FP_OFF(start)&15); - length -= SAVENEARHEAP; - seglength = length / 16; // now in paragraphs - segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; - MML_UseSpace (segstart,seglength); - mminfo.nearheap = length; - -// -// get all available far conventional memory segments -// - length=farcoreleft(); - start = farheap = farmalloc(length); - length -= 16-(FP_OFF(start)&15); - length -= SAVEFARHEAP; - seglength = length / 16; // now in paragraphs - segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; - MML_UseSpace (segstart,seglength); - mminfo.farheap = length; - mminfo.mainmem = mminfo.nearheap + mminfo.farheap; - - -// -// detect EMS and allocate up to 64K at page frame -// - mminfo.EMSmem = 0; - for (i = 1;i < _argc;i++) - { - if ( US_CheckParm(_argv[i],ParmStrings) == 0) - goto emsskip; // param NOEMS - } - - if (MML_CheckForEMS()) - { - MML_SetupEMS(); // allocate space - MML_UseSpace (EMSpageframe,EMSpagesmapped*0x400); - MM_MapEMS(); // map in used pages - mminfo.EMSmem = EMSpagesmapped*0x4000l; - } - -// -// detect XMS and get upper memory blocks -// -emsskip: - mminfo.XMSmem = 0; - for (i = 1;i < _argc;i++) - { - if ( US_CheckParm(_argv[i],ParmStrings) == 0) - goto xmsskip; // param NOXMS - } - - if (MML_CheckForXMS()) - MML_SetupXMS(); // allocate as many UMBs as possible - -// -// allocate the misc buffer -// -xmsskip: - mmrover = mmhead; // start looking for space after low block - - MM_GetPtr (&bufferseg,BUFFERSIZE); -} - -//========================================================================== - -/* -==================== -= -= MM_Shutdown -= -= Frees all conventional, EMS, and XMS allocated -= -==================== -*/ - -void MM_Shutdown (void) -{ - if (!mmstarted) - return; - - farfree (farheap); - free (nearheap); - MML_ShutdownEMS (); - MML_ShutdownXMS (); -} - -//========================================================================== - -/* -==================== -= -= MM_GetPtr -= -= Allocates an unlocked, unpurgable block -= -==================== -*/ - -void MM_GetPtr (memptr *baseptr,unsigned long size) -{ - mmblocktype far *scan,far *lastscan,far *endscan - ,far *purge,far *next; - int search; - unsigned needed,startseg; - - needed = (size+15)/16; // convert size from bytes to paragraphs - - GETNEWBLOCK; // fill in start and next after a spot is found - mmnew->length = needed; - mmnew->useptr = baseptr; - mmnew->attributes = BASEATTRIBUTES; - - for (search = 0; search<3; search++) - { - // - // first search: try to allocate right after the rover, then on up - // second search: search from the head pointer up to the rover - // third search: compress memory, then scan from start - if (search == 1 && mmrover == mmhead) - search++; - - switch (search) - { - case 0: - lastscan = mmrover; - scan = mmrover->next; - endscan = NULL; - break; - case 1: - lastscan = mmhead; - scan = mmhead->next; - endscan = mmrover; - break; - case 2: - MM_SortMem (); - lastscan = mmhead; - scan = mmhead->next; - endscan = NULL; - break; - } - - startseg = lastscan->start + lastscan->length; - - while (scan != endscan) - { - if (scan->start - startseg >= needed) - { - // - // got enough space between the end of lastscan and - // the start of scan, so throw out anything in the middle - // and allocate the new block - // - purge = lastscan->next; - lastscan->next = mmnew; - mmnew->start = *(unsigned *)baseptr = startseg; - mmnew->next = scan; - while ( purge != scan) - { // free the purgable block - next = purge->next; - FREEBLOCK(purge); - purge = next; // purge another if not at scan - } - mmrover = mmnew; - return; // good allocation! - } - - // - // if this block is purge level zero or locked, skip past it - // - if ( (scan->attributes & LOCKBIT) - || !(scan->attributes & PURGEBITS) ) - { - lastscan = scan; - startseg = lastscan->start + lastscan->length; - } - - - scan=scan->next; // look at next line - } - } - - if (bombonerror) - Quit (OUT_OF_MEM_MSG,(size-mminfo.nearheap)); - else - mmerror = true; -} - -//========================================================================== - -/* -==================== -= -= MM_FreePtr -= -= Allocates an unlocked, unpurgable block -= -==================== -*/ - -void MM_FreePtr (memptr *baseptr) -{ - mmblocktype far *scan,far *last; - - last = mmhead; - scan = last->next; - - if (baseptr == mmrover->useptr) // removed the last allocated block - mmrover = mmhead; - - while (scan->useptr != baseptr && scan) - { - last = scan; - scan = scan->next; - } - - if (!scan) - Quit ("MM_FreePtr: Block not found!"); - - last->next = scan->next; - - FREEBLOCK(scan); -} -//========================================================================== - -/* -===================== -= -= MM_SetPurge -= -= Sets the purge level for a block (locked blocks cannot be made purgable) -= -===================== -*/ - -void MM_SetPurge (memptr *baseptr, int purge) -{ - mmblocktype far *start; - - start = mmrover; - - do - { - if (mmrover->useptr == baseptr) - break; - - mmrover = mmrover->next; - - if (!mmrover) - mmrover = mmhead; - else if (mmrover == start) - Quit ("MM_SetPurge: Block not found!"); - - } while (1); - - mmrover->attributes &= ~PURGEBITS; - mmrover->attributes |= purge; -} - -//========================================================================== - -/* -===================== -= -= MM_SetLock -= -= Locks / unlocks the block -= -===================== -*/ - -void MM_SetLock (memptr *baseptr, boolean locked) -{ - mmblocktype far *start; - - start = mmrover; - - do - { - if (mmrover->useptr == baseptr) - break; - - mmrover = mmrover->next; - - if (!mmrover) - mmrover = mmhead; - else if (mmrover == start) - Quit ("MM_SetLock: Block not found!"); - - } while (1); - - mmrover->attributes &= ~LOCKBIT; - mmrover->attributes |= locked*LOCKBIT; -} - -//========================================================================== - -/* -===================== -= -= MM_SortMem -= -= Throws out all purgable stuff and compresses movable blocks -= -===================== -*/ - -void MM_SortMem (void) -{ - mmblocktype far *scan,far *last,far *next; - unsigned start,length,source,dest,oldborder; - int playing; - - // - // lock down a currently playing sound - // - playing = SD_SoundPlaying (); - if (playing) - { - switch (SoundMode) - { - case sdm_PC: - playing += STARTPCSOUNDS; - break; - case sdm_AdLib: - playing += STARTADLIBSOUNDS; - break; - } - MM_SetLock(&(memptr)audiosegs[playing],true); - } - - - SD_StopSound(); -// oldborder = bordercolor; -// VW_ColorBorder (15); - - if (beforesort) - beforesort(); - - scan = mmhead; - - last = NULL; // shut up compiler warning - - while (scan) - { - if (scan->attributes & LOCKBIT) - { - // - // block is locked, so try to pile later blocks right after it - // - start = scan->start + scan->length; - } - else - { - if (scan->attributes & PURGEBITS) - { - // - // throw out the purgable block - // - next = scan->next; - FREEBLOCK(scan); - last->next = next; - scan = next; - continue; - } - else - { - // - // push the non purgable block on top of the last moved block - // - if (scan->start != start) - { - length = scan->length; - source = scan->start; - dest = start; - while (length > 0xf00) - { - movedata(source,0,dest,0,0xf00*16); - length -= 0xf00; - source += 0xf00; - dest += 0xf00; - } - movedata(source,0,dest,0,length*16); - - scan->start = start; - *(unsigned *)scan->useptr = start; - } - start = scan->start + scan->length; - } - } - - last = scan; - scan = scan->next; // go to next block - } - - mmrover = mmhead; - - if (aftersort) - aftersort(); - -// VW_ColorBorder (oldborder); - - if (playing) - MM_SetLock(&(memptr)audiosegs[playing],false); -} - - -//========================================================================== - -#if 0 -/* -===================== -= -= MM_ShowMemory -= -===================== -*/ - -void MM_ShowMemory (void) -{ - mmblocktype far *scan; - unsigned color,temp; - long end,owner; - char scratch[80],str[10]; - - VW_SetDefaultColors(); - VW_SetLineWidth(40); - temp = bufferofs; - bufferofs = 0; - VW_SetScreen (0,0); - - scan = mmhead; - - end = -1; - -//CA_OpenDebug (); - - while (scan) - { - if (scan->attributes & PURGEBITS) - color = 5; // dark purple = purgable - else - color = 9; // medium blue = non purgable - if (scan->attributes & LOCKBIT) - color = 12; // red = locked - if (scan->start<=end) - Quit ("MM_ShowMemory: Memory block order currupted!"); - end = scan->start+scan->length-1; - VW_Hlin(scan->start,(unsigned)end,0,color); - VW_Plot(scan->start,0,15); - if (scan->next->start > end+1) - VW_Hlin(end+1,scan->next->start,0,0); // black = free - -#if 0 -strcpy (scratch,"Size:"); -ltoa ((long)scan->length*16,str,10); -strcat (scratch,str); -strcat (scratch,"\tOwner:0x"); -owner = (unsigned)scan->useptr; -ultoa (owner,str,16); -strcat (scratch,str); -strcat (scratch,"\n"); -write (debughandle,scratch,strlen(scratch)); -#endif - - scan = scan->next; - } - -//CA_CloseDebug (); - - IN_Ack(); - VW_SetLineWidth(64); - bufferofs = temp; -} -#endif - -//========================================================================== - - -/* -====================== -= -= MM_UnusedMemory -= -= Returns the total free space without purging -= -====================== -*/ - -long MM_UnusedMemory (void) -{ - unsigned free; - mmblocktype far *scan; - - free = 0; - scan = mmhead; - - while (scan->next) - { - free += scan->next->start - (scan->start + scan->length); - scan = scan->next; - } - - return free*16l; -} - -//========================================================================== - - -/* -====================== -= -= MM_TotalFree -= -= Returns the total free space with purging -= -====================== -*/ - -long MM_TotalFree (void) -{ - unsigned free; - mmblocktype far *scan; - - free = 0; - scan = mmhead; - - while (scan->next) - { - if ((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT)) - free += scan->length; - free += scan->next->start - (scan->start + scan->length); - scan = scan->next; - } - - return free*16l; -} - -//========================================================================== - -/* -===================== -= -= MM_BombOnError -= -===================== -*/ - -void MM_BombOnError (boolean bomb) -{ - bombonerror = bomb; -} - - +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// NEWMM.C + +/* +============================================================================= + + ID software memory manager + -------------------------- + +Primary coder: John Carmack + +RELIES ON +--------- +Quit (char *error) function + + +WORK TO DO +---------- +MM_SizePtr to change the size of a given pointer + +Multiple purge levels utilized + +EMS / XMS unmanaged routines + +============================================================================= +*/ + +#include "src/lib/16_mm.h" + +/* +============================================================================= + + LOCAL INFO + +============================================================================= +*/ + +#define LOCKBIT 0x80 // if set in attributes, block cannot be moved +#define PURGEBITS 3 // 0-3 level, 0= unpurgable, 3= purge first +#define PURGEMASK 0xfffc +#define BASEATTRIBUTES 0 // unlocked, non purgable + +#define MAXUMBS 10 + +typedef struct mmblockstruct +{ + unsigned start,length; + unsigned attributes; + memptr *useptr; // pointer to the segment start + struct mmblockstruct far *next; +} mmblocktype; + + +//#define GETNEWBLOCK {if(!(mmnew=mmfree))Quit("MM_GETNEWBLOCK: No free blocks!");mmfree=mmfree->next;} +#define GETNEWBLOCK {if(!mmfree)MML_ClearBlock();mmnew=mmfree;mmfree=mmfree->next;} +#define FREEBLOCK(x) {*x->useptr=NULL;x->next=mmfree;mmfree=x;} + +/* +============================================================================= + + GLOBAL VARIABLES + +============================================================================= +*/ + +mminfotype mminfo; +memptr bufferseg; +boolean mmerror; + +void (* beforesort) (void); +void (* aftersort) (void); + +/* +============================================================================= + + LOCAL VARIABLES + +============================================================================= +*/ + +boolean mmstarted; + +void huge *hugeheap; +void far *farheap; +void *nearheap; + +mmblocktype far mmblocks[MAXBLOCKS] + ,far *mmhead,far *mmfree,far *mmrover,far *mmnew; + +boolean bombonerror; + +unsigned totalEMSpages,freeEMSpages,EMSpageframe,EMSpagesmapped,EMShandle; + +void (* XMSaddr) (void); // far pointer to XMS driver + +unsigned numUMBs,UMBbase[MAXUMBS]; + + +/* +====================== += += MML_CheckForEMS += += Routine from p36 of Extending DOS += +======================= +*/ + +boolean MML_CheckForEMS (void) +{ + boolean emmcfems; + char emmname[] = "EMMXXXX0"; +// mov dx,OFFSET emmname + __asm { + LEA DX, emmname //fix by andrius4669 + mov ax,0x3d00 + int 0x21 // try to open EMMXXXX0 device + jc error + + mov bx,ax + mov ax,0x4400 + + int 0x21 // get device info + jc error + + and dx,0x80 + jz error + + mov ax,0x4407 + + int 0x21 // get status + jc error + or al,al + jz error + + mov ah,0x3e + int 0x21 // close handle + jc error + // + // EMS is good + // + mov emmcfems,1 + jmp End + error: + // + // EMS is bad + // + mov emmcfems,0 + End: + } + return(emmcfems); +} + + +/* +====================== += += MML_SetupEMS += +======================= +*/ + +void MML_SetupEMS (void) +{ + char str[80],str2[10]; + unsigned err; + boolean errorflag=false; + union REGS CPURegs; + + totalEMSpages = freeEMSpages = EMSpageframe = EMSpagesmapped = 0; + + __asm + { + mov ah,EMS_STATUS + int EMS_INT // make sure EMS hardware is present + or ah,ah + jnz error + + mov ah,EMS_VERSION + int EMS_INT + or ah,ah + jnz error + cmp al,0x32 // only work on ems 3.2 or greater + jb error + + mov ah,EMS_GETFRAME + int EMS_INT // find the page frame address + or ah,ah + jnz error + mov [EMSpageframe],bx + + mov ah,EMS_GETPAGES + int EMS_INT // find out how much EMS is there + or ah,ah + jnz error + mov [totalEMSpages],dx + mov [freeEMSpages],bx + or bx,bx + jz noEMS // no EMS at all to allocate + + cmp bx,4 + jle getpages // there is only 1,2,3,or 4 pages + mov bx,4 // we can't use more than 4 pages + +getpages: + mov [EMSpagesmapped],bx + mov ah,EMS_ALLOCPAGES // allocate up to 64k of EMS + int EMS_INT + or ah,ah + jnz error + mov [EMShandle],dx + jmp End +error: + mov errorflag,1 + jmp End +noEMS: +End: + } + if(errorflag==true) + { + err = CPURegs.h.ah; + strcpy(str,"MML_SetupEMS: EMS error 0x"); + itoa(err,str2,16); + strcpy(str,str2); + printf("%s\n",str); + } +} + + +/* +====================== += += MML_ShutdownEMS += +======================= +*/ + +void MML_ShutdownEMS (void) +{ + boolean errorflag=false; + if (!EMShandle) + return; + __asm + { + mov ah,EMS_FREEPAGES + mov dx,[EMShandle] + int EMS_INT + or ah,ah + jz ok + mov errorflag,1 + ok: + } + if(errorflag==true) printf("MML_ShutdownEMS: Error freeing EMS!"); //++++ add something +} + +/* +==================== += += MM_MapEMS += += Maps the 64k of EMS used by memory manager into the page frame += for general use. This only needs to be called if you are keeping += other things in EMS. += +==================== +*/ + +void MM_MapEMS (void) +{ + char str[80],str2[10]; + unsigned err; + boolean errorflag=false; + int i; + union REGS CPURegs; + + for (i=0;istart+scan->length < segstart) + { + last = scan; + scan = scan->next; + } + +// +// take the given range out of the block +// + oldend = scan->start + scan->length; + extra = oldend - (segstart+seglength); + if (extra < 0) + { + printf("MML_UseSpace: Segment spans two blocks!"); + return; + } + + + if (segstart == scan->start) + { + last->next = scan->next; // unlink block + FREEBLOCK(scan); + scan = last; + } + else + scan->length = segstart-scan->start; // shorten block + + if (extra > 0) + { + GETNEWBLOCK; + mmnew->next = scan->next; + scan->next = mmnew; + mmnew->start = segstart+seglength; + mmnew->length = extra; + mmnew->attributes = LOCKBIT; + } + +} + +//========================================================================== + +/* +==================== += += MML_ClearBlock += += We are out of blocks, so free a purgable block += +==================== +*/ + +void MML_ClearBlock (void) +{ + mmblocktype far *scan,far *last; + + scan = mmhead->next; + + while (scan) + { + if (!(scan->attributes&LOCKBIT) && (scan->attributes&PURGEBITS) ) + { + MM_FreePtr(scan->useptr); + return; + } + scan = scan->next; + } + + printf("MM_ClearBlock: No purgable blocks!"); +} + + +//========================================================================== + +/* +=================== += += MM_Startup += += Grabs all space from turbo with malloc/farmalloc += Allocates bufferseg misc buffer += +=================== +*/ + +static char *ParmStringsexmm[] = {"noems","noxms",""}; + +void MM_Startup (void) +{ + int i; + dword length; + void far *start; + unsigned segstart,seglength,endfree; + + if (mmstarted) + MM_Shutdown (); + + + mmstarted = true; + bombonerror = true; +// +// set up the linked list (everything in the free list; +// + mmhead = NULL; + mmfree = &mmblocks[0]; + for (i=0;istart = 0; + mmnew->length = 0xffff; + mmnew->attributes = LOCKBIT; + mmnew->next = NULL; + mmrover = mmhead; + + +// +// get all available near conventional memory segments +// +//---- length=coreleft(); + length=_memavl(); + start = (void far *)(nearheap = malloc(length)); + + length -= 16-(FP_OFF(start)&15); + length -= SAVENEARHEAP; + seglength = length / 16; // now in paragraphs + segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; + MML_UseSpace (segstart,seglength); + mminfo.nearheap = length; + +// +// get all available far conventional memory segments +// +//---- length=farcoreleft(); + length=_memmax(); + start = farheap = _fmalloc(length); + length -= 16-(FP_OFF(start)&15); + length -= SAVEFARHEAP; + seglength = length / 16; // now in paragraphs + segstart = FP_SEG(start)+(FP_OFF(start)+15)/16; + MML_UseSpace (segstart,seglength); + mminfo.farheap = length; + mminfo.mainmem = mminfo.nearheap + mminfo.farheap; + + +// +// detect EMS and allocate up to 64K at page frame +// + mminfo.EMSmem = 0; + for (i = 1;i < __argc;i++) + { + if ( US_CheckParm(__argv[i],ParmStringsexmm) == 0) + goto emsskip; // param NOEMS + } + + if (MML_CheckForEMS()) + { + MML_SetupEMS(); // allocate space + MML_UseSpace (EMSpageframe,EMSpagesmapped*0x400); + MM_MapEMS(); // map in used pages + mminfo.EMSmem = EMSpagesmapped*0x4000l; + } + +// +// detect XMS and get upper memory blocks +// +emsskip: + mminfo.XMSmem = 0; + for (i = 1;i < __argc;i++) + { + if ( US_CheckParm(__argv[i],ParmStringsexmm) == 0) + goto xmsskip; // param NOXMS + } + + if (MML_CheckForXMS()) + MML_SetupXMS(); // allocate as many UMBs as possible + +// +// allocate the misc buffer +// +xmsskip: + mmrover = mmhead; // start looking for space after low block + + MM_GetPtr (&bufferseg,BUFFERSIZE); +} + +//========================================================================== + +/* +==================== += += MM_Shutdown += += Frees all conventional, EMS, and XMS allocated += +==================== +*/ + +void MM_Shutdown (void) +{ + if (!mmstarted) + return; + + _ffree (farheap); + free (nearheap); + hfree(hugeheap); + MML_ShutdownEMS (); + MML_ShutdownXMS (); +} + +//========================================================================== + +/* +==================== += += MM_GetPtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_GetPtr (memptr *baseptr,dword size) +{ + mmblocktype far *scan,far *lastscan,far *endscan + ,far *purge,far *next; + int search; + unsigned needed,startseg; + + needed = (size+15)/16; // convert size from bytes to paragraphs + + GETNEWBLOCK; // fill in start and next after a spot is found + mmnew->length = needed; + mmnew->useptr = baseptr; + mmnew->attributes = BASEATTRIBUTES; + + for (search = 0; search<3; search++) + { + // + // first search: try to allocate right after the rover, then on up + // second search: search from the head pointer up to the rover + // third search: compress memory, then scan from start + if (search == 1 && mmrover == mmhead) + search++; + + switch (search) + { + case 0: + lastscan = mmrover; + scan = mmrover->next; + endscan = NULL; + break; + case 1: + lastscan = mmhead; + scan = mmhead->next; + endscan = mmrover; + break; + case 2: + MM_SortMem (); + lastscan = mmhead; + scan = mmhead->next; + endscan = NULL; + break; + } + + startseg = lastscan->start + lastscan->length; + + while (scan != endscan) + { + if (scan->start - startseg >= needed) + { + // + // got enough space between the end of lastscan and + // the start of scan, so throw out anything in the middle + // and allocate the new block + // + purge = lastscan->next; + lastscan->next = mmnew; + mmnew->start = *(unsigned *)baseptr = startseg; + mmnew->next = scan; + while ( purge != scan) + { // free the purgable block + next = purge->next; + FREEBLOCK(purge); + purge = next; // purge another if not at scan + } + mmrover = mmnew; + return; // good allocation! + } + + // + // if this block is purge level zero or locked, skip past it + // + if ( (scan->attributes & LOCKBIT) + || !(scan->attributes & PURGEBITS) ) + { + lastscan = scan; + startseg = lastscan->start + lastscan->length; + } + + + scan=scan->next; // look at next line + } + } + + if (bombonerror) + printf(OUT_OF_MEM_MSG,(size-mminfo.nearheap)); + else + mmerror = true; +} + +//========================================================================== + +/* +==================== += += MM_FreePtr += += Allocates an unlocked, unpurgable block += +==================== +*/ + +void MM_FreePtr (memptr *baseptr) +{ + mmblocktype far *scan,far *last; + + last = mmhead; + scan = last->next; + + if (baseptr == mmrover->useptr) // removed the last allocated block + mmrover = mmhead; + + while (scan->useptr != baseptr && scan) + { + last = scan; + scan = scan->next; + } + + if (!scan) + { + printf("MM_FreePtr: Block not found!"); + return; + } + + last->next = scan->next; + + FREEBLOCK(scan); +} +//========================================================================== + +/* +===================== += += MM_SetPurge += += Sets the purge level for a block (locked blocks cannot be made purgable) += +===================== +*/ + +void MM_SetPurge (memptr *baseptr, int purge) +{ + mmblocktype far *start; + + start = mmrover; + + do + { + if (mmrover->useptr == baseptr) + break; + + mmrover = mmrover->next; + + if (!mmrover) + mmrover = mmhead; + else if (mmrover == start) + { + printf("MM_SetPurge: Block not found!"); + return; + } + + } while (1); + + mmrover->attributes &= ~PURGEBITS; + mmrover->attributes |= purge; +} + +//========================================================================== + +/* +===================== += += MM_SetLock += += Locks / unlocks the block += +===================== +*/ + +void MM_SetLock (memptr *baseptr, boolean locked) +{ + mmblocktype far *start; + + start = mmrover; + + do + { + if (mmrover->useptr == baseptr) + break; + + mmrover = mmrover->next; + + if (!mmrover) + mmrover = mmhead; + else if (mmrover == start) + { + printf("MM_SetLock: Block not found!"); + return; + } + + } while (1); + + mmrover->attributes &= ~LOCKBIT; + mmrover->attributes |= locked*LOCKBIT; +} + +//========================================================================== + +/* +===================== += += MM_SortMem += += Throws out all purgable stuff and compresses movable blocks += +===================== +*/ + +void MM_SortMem (void) +{ + mmblocktype far *scan,far *last,far *next; + unsigned start,length,source,dest,oldborder; + int playing; + + // + // lock down a currently playing sound + // +/*++++ playing = SD_SoundPlaying (); + if (playing) + { + switch (SoundMode) + { + case sdm_PC: + playing += STARTPCSOUNDS; + break; + case sdm_AdLib: + playing += STARTADLIBSOUNDS; + break; + } + MM_SetLock(&(memptr)audiosegs[playing],true); + } + + + SD_StopSound();*/ +// oldborder = bordercolor; +// VW_ColorBorder (15); + + if (beforesort) + beforesort(); + + scan = mmhead; + + last = NULL; // shut up compiler warning + + while (scan) + { + if (scan->attributes & LOCKBIT) + { + // + // block is locked, so try to pile later blocks right after it + // + start = scan->start + scan->length; + } + else + { + if (scan->attributes & PURGEBITS) + { + // + // throw out the purgable block + // + next = scan->next; + FREEBLOCK(scan); + last->next = next; + scan = next; + continue; + } + else + { + // + // push the non purgable block on top of the last moved block + // + if (scan->start != start) + { + length = scan->length; + source = scan->start; + dest = start; + while (length > 0xf00) + { + movedata(source,0,dest,0,0xf00*16); + length -= 0xf00; + source += 0xf00; + dest += 0xf00; + } + movedata(source,0,dest,0,length*16); + + scan->start = start; + *(unsigned *)scan->useptr = start; + } + start = scan->start + scan->length; + } + } + + last = scan; + scan = scan->next; // go to next block + } + + mmrover = mmhead; + + if (aftersort) + aftersort(); + +// VW_ColorBorder (oldborder); + +/*++++ if (playing) + MM_SetLock(&(memptr)audiosegs[playing],false);*/ +} + + +//========================================================================== + +//**** +#if 0 +/* +===================== += += MM_ShowMemory += +===================== +*/ + +void MM_ShowMemory (void) +{ + mmblocktype far *scan; + unsigned color,temp; + long end,owner; + char scratch[80],str[10]; + +//**** VW_SetDefaultColors(); +//**** VW_SetLineWidth(40); + temp = bufferofs; + bufferofs = 0; +//**** VW_SetScreen (0,0); + + scan = mmhead; + + end = -1; + +//CA_OpenDebug (); + + while (scan) + { + if (scan->attributes & PURGEBITS) + color = 5; // dark purple = purgable + else + color = 9; // medium blue = non purgable + if (scan->attributes & LOCKBIT) + color = 12; // red = locked + if (scan->start<=end) + { + printf("MM_ShowMemory: Memory block order currupted!"); + return; + } + end = scan->start+scan->length-1; +//**** VW_Hlin(scan->start,(unsigned)end,0,color); +//**** VW_Plot(scan->start,0,15); +//**** if (scan->next->start > end+1) +//**** VW_Hlin(end+1,scan->next->start,0,0); // black = free + +//****#if 0 +strcpy (scratch,"Size:"); +ltoa ((long)scan->length*16,str,10); +strcat (scratch,str); +strcat (scratch,"\tOwner:0x"); +owner = (unsigned)scan->useptr; +ultoa (owner,str,16); +strcat (scratch,str); +strcat (scratch,"\n"); +//++++write (debughandle,scratch,strlen(scratch)); +//****#endif + + scan = scan->next; + } + +//CA_CloseDebug (); + + IN_Ack(); +//**** VW_SetLineWidth(64); + bufferofs = temp; +} +//**** +#endif + +//========================================================================== + + +/* +====================== += += MM_UnusedMemory += += Returns the total free space without purging += +====================== +*/ + +long MM_UnusedMemory (void) +{ + unsigned free; + mmblocktype far *scan; + + free = 0; + scan = mmhead; + + while (scan->next) + { + free += scan->next->start - (scan->start + scan->length); + scan = scan->next; + } + + return free*16l; +} + +//========================================================================== + + +/* +====================== += += MM_TotalFree += += Returns the total free space with purging += +====================== +*/ + +long MM_TotalFree (void) +{ + unsigned free; + mmblocktype far *scan; + + free = 0; + scan = mmhead; + + while (scan->next) + { + if ((scan->attributes&PURGEBITS) && !(scan->attributes&LOCKBIT)) + free += scan->length; + free += scan->next->start - (scan->start + scan->length); + scan = scan->next; + } + + return free*16l; +} + +//========================================================================== + +/* +===================== += += MM_BombOnError += +===================== +*/ + +void MM_BombOnError (boolean bomb) +{ + bombonerror = bomb; +} + + diff --git a/16/cawat/16_mm.h b/src/lib/16_mm.h similarity index 91% rename from 16/cawat/16_mm.h rename to src/lib/16_mm.h index 622a2b4d..e864d042 100644 --- a/16/cawat/16_mm.h +++ b/src/lib/16_mm.h @@ -1,136 +1,135 @@ -/* Catacomb Armageddon Source Code - * Copyright (C) 1993-2014 Flat Rock Software - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - +/* Catacomb Armageddon Source Code + * Copyright (C) 1993-2014 Flat Rock Software + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + // ID_MM.H -#ifndef __ID_EXMM__ -#define __ID_EXMM__ - -#include "lib_head.h" -//#pragma hdrstop - -//#pragma warn -pro -//#pragma warn -use - -#if 1 // 1 == Debug/Dev ; 0 == Production/final -#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes" -#else +#ifndef __16_EXMM__ +#define __16_EXMM__ + +#include +#include +#include "src/lib/lib_head.h" +#include "src/lib/16_in.h" + +#if 1 // 1 == Debug/Dev ; 0 == Production/final +#define OUT_OF_MEM_MSG "MM_GetPtr: Out of memory!\nYou were short :%ld bytes" +#else #define OUT_OF_MEM_MSG "\npee\n" -#endif - - -#define SAVENEARHEAP 0x400 // space to leave in data segment -#define SAVEFARHEAP 0 // space to leave in far heap - -#define BUFFERSIZE 0x1000 // miscelanious, allways available buffer - -#define MAXBLOCKS 600 - - -//-------- - -#define EMS_INT 0x67 - -#define EMS_STATUS 0x40 -#define EMS_GETFRAME 0x41 -#define EMS_GETPAGES 0x42 -#define EMS_ALLOCPAGES 0x43 -#define EMS_MAPPAGE 0x44 -#define EMS_FREEPAGES 0x45 -#define EMS_VERSION 0x46 - -//-------- - -#define XMS_VERSION 0x00 - -#define XMS_ALLOCHMA 0x01 -#define XMS_FREEHMA 0x02 - -#define XMS_GENABLEA20 0x03 -#define XMS_GDISABLEA20 0x04 -#define XMS_LENABLEA20 0x05 -#define XMS_LDISABLEA20 0x06 -#define XMS_QUERYA20 0x07 - -#define XMS_QUERYREE 0x08 -#define XMS_ALLOC 0x09 -#define XMS_FREE 0x0A -#define XMS_MOVE 0x0B -#define XMS_LOCK 0x0C -#define XMS_UNLOCK 0x0D -#define XMS_GETINFO 0x0E -#define XMS_RESIZE 0x0F - -#define XMS_ALLOCUMB 0x10 -#define XMS_FREEUMB 0x11 - -//========================================================================== - -typedef void /*_seg*/ * memptr; - -typedef struct -{ - long nearheap,farheap,EMSmem,XMSmem,mainmem; -} mminfotype; - -//========================================================================== - -extern mminfotype mminfo; -extern memptr bufferseg; -extern boolean mmerror; - -extern void (* beforesort) (void); -extern void (* aftersort) (void); - -//========================================================================== - -void MM_Startup (void); -void MM_Shutdown (void); -void MM_MapEMS (void); - -void MM_GetPtr (memptr *baseptr,unsigned long size); -void MM_FreePtr (memptr *baseptr); - -void MM_SetPurge (memptr *baseptr, int purge); -void MM_SetLock (memptr *baseptr, boolean locked); -void MM_SortMem (void); - -void MM_ShowMemory (void); - -long MM_UnusedMemory (void); -long MM_TotalFree (void); - +#endif + + +#define SAVENEARHEAP 0x400 // space to leave in data segment +#define SAVEFARHEAP 0 // space to leave in far heap + +#define BUFFERSIZE 0x1000 // miscelanious, allways available buffer + +#define MAXBLOCKS 600 + + +//-------- + +#define EMS_INT 0x67 + +#define EMS_STATUS 0x40 +#define EMS_GETFRAME 0x41 +#define EMS_GETPAGES 0x42 +#define EMS_ALLOCPAGES 0x43 +#define EMS_MAPPAGE 0x44 +#define EMS_FREEPAGES 0x45 +#define EMS_VERSION 0x46 + +//-------- + +#define XMS_VERSION 0x00 + +#define XMS_ALLOCHMA 0x01 +#define XMS_FREEHMA 0x02 + +#define XMS_GENABLEA20 0x03 +#define XMS_GDISABLEA20 0x04 +#define XMS_LENABLEA20 0x05 +#define XMS_LDISABLEA20 0x06 +#define XMS_QUERYA20 0x07 + +#define XMS_QUERYREE 0x08 +#define XMS_ALLOC 0x09 +#define XMS_FREE 0x0A +#define XMS_MOVE 0x0B +#define XMS_LOCK 0x0C +#define XMS_UNLOCK 0x0D +#define XMS_GETINFO 0x0E +#define XMS_RESIZE 0x0F + +#define XMS_ALLOCUMB 0x10 +#define XMS_FREEUMB 0x11 + +//========================================================================== + +typedef void /*_seg*/ * memptr; + +typedef struct +{ + long nearheap,farheap,EMSmem,XMSmem,mainmem; +} mminfotype; + +//========================================================================== + +extern mminfotype mminfo; +extern memptr bufferseg; +extern boolean mmerror; + +extern void (* beforesort) (void); +extern void (* aftersort) (void); + +//========================================================================== + +void MM_Startup (void); +void MM_Shutdown (void); +void MM_MapEMS (void); + +void MM_GetPtr (memptr *baseptr,dword size); +void MM_FreePtr (memptr *baseptr); + +void MM_SetPurge (memptr *baseptr, int purge); +void MM_SetLock (memptr *baseptr, boolean locked); +void MM_SortMem (void); + +void MM_ShowMemory (void); + +long MM_UnusedMemory (void); +long MM_TotalFree (void); + void MM_BombOnError (boolean bomb); -//========================================================================== - -// -// local prototypes -// - -boolean MML_CheckForEMS (void); -void MML_ShutdownEMS (void); -void MM_MapEMS (void); -boolean MML_CheckForXMS (void); -void MML_ShutdownXMS (void); -void MML_UseSpace (unsigned segstart, unsigned seglength); -void MML_ClearBlock (void); - +//========================================================================== + +// +// local prototypes +// + +boolean MML_CheckForEMS (void); +void MML_ShutdownEMS (void); +void MM_MapEMS (void); +boolean MML_CheckForXMS (void); +void MML_ShutdownXMS (void); +void MML_UseSpace (unsigned segstart, unsigned seglength); +void MML_ClearBlock (void); + //========================================================================== #endif diff --git a/test.exe b/test.exe index c5c68fdb5e3edbfb2763e0acad280055ede3e296..262cd0229d6bdd75e63b36b5913fea8142c79a6b 100644 GIT binary patch delta 992 zcmaizTWC~Q6o&WOGsz^=HbjC>q;WQr(2OUF7$XK#YovB2r4doYcwtaVCZpnIWM(oa znal-g8sa#Stuwk&=Cq2S)VFZjXru?aV`{eU2IlZ|HW)P3zZjL zZdR%UvsPE2DqLRlJFSFcEjb}dY2_?ke2RK?Q)FYZBaw`3NW~K!k^PZqJQ=B97D*=B zBdLyLYEe64;VYhR8Bne#vAD(8{F3?uiQ4f*RGpjg`C_Ctz524 zQp1DNbbMD-dDKBUNlQLQZ;PoPruh#Fc#CKXw<3h^PWfgds3d?dV>@G^@2Pbs%PQR(D$dVIfXDYZI|RN9iq z7)Tpw!WbFF1UZd2WEOtg$PiYNe_8(mt3X?unIf)!mxZX(iU z@u6PoVGNNsaEFehhDmD49y&0Bmcl7@;Qn#PR&{} zgfO`ev5dvwA2LRl1aLOv=V-3ebpWq2#xoXhF8vekX6DLzH1!zy8C!d-z`bh6|9XKl zgw5|KLG^AJb8xK3Vu?Q)F^Ea>SCnO)HWpwv2OB#Ys;5SW(7b;~F+Hy|DG$0VYTbZ^*sy7YyIQ%7P^o*h#$>2McD)FmLSE1FM|o kIGTU0Bh*@zlcJ{GUL{=r90y(h|4)rPE!=UtTUROd7X6SDt^fc4 delta 960 zcmZXTZD`F=9LLY^+&ht>_qWn&M`kwFko%1{A*Z==%pYGnLFJ}hi z7CeE8vIcVletCm+0e^}oU#Sr|LN^;%1Aa$afx@x{qwzW5PB~kk)Iba`8i{em?v#t1 z)!DNNCq*f(?9c;FQy1k0R|co$2Dj9e2TKFXOLK}4F23ceXM$TlLt#lq!CUIVQW2@G zt5D~D`7Unk7ICBwaVk|_Ra?HPBBC6Q8#0m$gTl3y70RXd$|=rdI$BE1v{uToDoa9k z{Z8eQP@Lj6hYIbcddi_fhpFCisL%<#E}13UI=l;AS%${%DiM{(jOw+OHFT6(&4*~! z*0G>&mzFl%ueWsn2z;q877KG4jFcnTVCmjb*wf$@AI>*eY~lmbgFY@_z?iVned)*# zPw`b}DCN|bGVOCOvB=+;OsUl|>y1eC9k7~e2IhP zP_&cz=ptk2i5T5G7Q-6n$N?;AG;$YJjTVzys9VuV-oaxs4PVJhq&FD>a>++1Ycjgu zi%64K3eiGqJvx6aKPIo?EBOlPQM+a?ITK~%YJ{T}H=l_b{cSvMM!js!3tF3z8Z)kT zpZ(~gcpvr1d@PO`*^iAe%lB}C?SIdJS3Bu zQi4#zK5;jB4Cl#vxRWsYgCB1a)1?e!nvHBnUh@pyHwCrLUVe24X{|>)33QR&=pj8w zOBz{)9P$8`CM|KGk$N7EC(WW(zSyZx7ur{2YyOD@wN`FY)DLH>62_n949EZfP=|Z# KbEh-AP^q6sE(jX{ diff --git a/test2.exe b/test2.exe index 0b07453824bc80c9c9ff05a103753fc4015d38ec..c9f12fc11ae1ea3a9364ce46b0cffccc666afd37 100644 GIT binary patch delta 1058 zcma)*UrbYX6vxlG1vDOll!^f-}ju~ zIp>#~Upi-;&lwlD2KYNP1y->_Z@|l&kqvkYUpEoe;j*|J@gU%JG`0{rw^g9hD&=PQ zEN@|Z3sDsP+sgf?n8+ag7)7T=H`WE)VqMW#aOXfI+7&z)3`b%?-^O4p8VU|{#Rh8E zg#hcCGa)-ljc3@sefiN>qDweD7>S1IciUefmHuXSEc&v5D6~Hk+7})qhhvAaS^~v~ zBE4a9(lMTt6*me>9E*q!boTZU6U*AjE-s}h`F`)|o{;rQ0(I+AH_&I)ebN^7)IDws zyx3mLz4`>g`DR|?ic&%}_csLlZ<~~fs6_4XmyjcRAQ2ZF4gvq;L318z|aoTZ0^e?y~dNb~c zzKP=D2JS%fu;L_ohE2YYtY|l8ga zHfr*}s2??54b{5ZC(@T_iCwJ+iBaXs+5TFu_N%n-nzx-Dwv*M)2Zg5I`@oC7%nJ6S zFsWQI+ge_ux1Gn39AE)WNs}uPNh&^!jPPgVglBL|{3m#sRL-i8b)k!x8!LCp>EsX1 zVoS>8tq2Kckrp=MkCfv5xGnqv|D^ov!P+s!O|XO!>=T|rO86&!6~4d?p$AWedr^`$ zUAYaq%a(dQ+t>Dy9@k7Z6{m#Ga=s3#8%5foG#4k~N z+|T`JIIegayM=dgMEDVY6z;)g;W^w9F5r#O4R=Pdg@%mD*U%&SEk-hGW$;towL&g0 dkw@eG(}k;<538yj|KoDzpJyhV1@m&h-vJ_kFeU&1 delta 1025 zcmZvbT}+c#7{{OIEm8&Rida#IIdq`qW$J*6L>o=e^jKZ_?lUKfm*w z=bSg`S-5N@E*n?&`gs6#{u2HG-F^?3A?5chdsRnNj@x3_BIEbiN&`iIZk%GFn zYVt!&OLkyU_ysb;Veqix58)P0p;owr(6Dm+T}qT?Tvht0Ytc89&xM$l*?BAqpCThQ z?>6e1`C?u3u~p-NdqnYPs1=SQB)pD6;d4w23$ZAyMMiiE98)|4cg*D9(HJuwTgr5| zZPJrymDQ~c=VQt-W%-Xh+Hcg}v1FNM%cQhf{*Prc9-L0D;}W<=m7~Md?F!2EvIV5% z12SkGHQ9+Xql%AWN|?f3;RIfae~uMn%I?~%S6x9So^RhID-D{%Cu1gW!+>xO-wD0= zc}#H-zX{L59`|w{d~wCqXcr#ADd7Yz32))1@K?ML=HXxA0Td-n$5e&hWrt6n?SS=3 zPb`zN%my)QR$AgmOMIzIxB{~Y-QZrrYrkEo8(e@po{u|;Z2kl5$GsdvU|jJedW83p z5U$38a36jVeuLM-3>-=Q57;8~A&@jVjj-f5_&TYInyPhQm)un%x5ocZD;^~aUF&S` Qxr=G%#H2mzhFstO0Gb^h`~Uy| -- 2.39.5