From b2069fd60625ac26ec21a5c35568b99f331c6d34 Mon Sep 17 00:00:00 2001 From: sparky4 Date: Wed, 10 Dec 2014 01:44:46 -0600 Subject: [PATCH] modified: scroll.exe new file: src/lib/xmem/xmem.asm new file: src/lib/xmem/xmem.h new file: src/lib/xmem/xmem.txt new file: src/lib/xmem/xmemc.c modified: src/scroll.c --- scroll.exe | Bin 52118 -> 52118 bytes src/lib/xmem/xmem.asm | 753 ++++++++++++++++++++++++++++++++++++++++++ src/lib/xmem/xmem.h | 79 +++++ src/lib/xmem/xmem.txt | 33 ++ src/lib/xmem/xmemc.c | 316 ++++++++++++++++++ src/scroll.c | 8 +- 6 files changed, 1185 insertions(+), 4 deletions(-) create mode 100644 src/lib/xmem/xmem.asm create mode 100644 src/lib/xmem/xmem.h create mode 100644 src/lib/xmem/xmem.txt create mode 100644 src/lib/xmem/xmemc.c diff --git a/scroll.exe b/scroll.exe index 8912afb4be416bc624556647bd611d1efe2c8da9..b34a5be59dbc8c0eec6409340fc0a19ca36b3428 100644 GIT binary patch delta 4818 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 delta 4771 zcmZu!2~<#~Tk?soANb>nXhm zEs|OE4R|2Qqkb@lCD3uOp2Zo*7^>fQcbFcT9j0EhYaYStZ)QFYRS)jo0?WeOx%1As zt`NQvK4U3#7RaR0&peE&yVB5JUwH>F*Xxhj`(DF8{z3$2`om%RgD;J6%=*J6CA==2 zzY*!8gfEWf_XYBoA{{24*F-sH@q+bYSpBhOef$O}l_t{n;8m&FJI6oeX38~(=>b0l z9!U#nAr!djB~2b%Z&(bScMyVVN zA2=pT_&)-Lxx5p#p}oYty0V#+u)F0RuBQp#f|A|KHC4FFQ1^Gk=gCh<39bj9?Ja@_ z{ABNe9I`;DlBt2pY+g?P0c|Bz%BIjPxF9nm-Wx3TuYe9y6TvJsnVhN4VXEa!4MK(O z5n?T@x*5Ve-VLAYH&E-A=RmDbJqPl-1;AR*5RiHndmZ*2&mbtW-LP3c1DQYd7|49lV<12RKY7)8zcYAK`TlU}~M+F<`*48~VJ1y|;#nnazZ+g=n95!*jd_GEZ|K$o!Q1KmhT>IR}E&cY&nd7Y_Rb zLcX`J%8(If3dq}<0Po@9~t#84My^d0|!pkQpMwgX?8^sz8b#u9}@9_hBI|`1v^YVzgv4# zu8CRrZtfFQxrO&2MV?kA37s?J+3Z=fXL8@Ky(cG}>DLa^BRmmF-5c5~{ajvzpP_Lq z{FR$1=~AEcBADblUxq0hrN44n5@DP#<%!@dcX<##R&aJ$B%G`(^JOx2QC5T4j?A7nlkr2dnf!4wK*2+gERMrbk_#z2k#(f~~>j!PS+&u`;t` z;cr*JP40Um-dPAeROW{FsHeCf1hGf$b&^%-Wt%0jU zj?)0(o@k(7fI4LhT?hM9qG%d?l#+?dasb#bex>Hxu3-ElJKIDdi zJ3G3suSAJYN^EQ@UKZxgJI8+xd(y(G4o;^npr1h4(5=1`71foGh~2}H<-yzF)X?;R z6$-ASYv&B^9KWiMJByno3*3giN_WG)VN=yTcx2a1caQ4oUg z|KxC7uB}g+>7VfZlNL>=4|it6g%UUJmxN~?ap%R1_}b&H@WEio$fDQazcLc&X1J1} zRpxtRonWkMStz_2agLqfHqw%z@WR7H$ZuIPsoi(Y5?POUw$@CO(bi8g@ECS;J^XlI z?yR_oq662BRw;kRxoc!9bzUB|o#AtES>`iT2FG#y8QjNN=w_#NToR*mU~ATjpc_AM zA7J&66O44VyF$qcmdXDE0w+{blM^P?NxWOX#YGgs-h{*}<|qiUUPM@-xUR5%h@f8Kf-$xvc2`jf1-5wBt0;gLo0dff6hONzft3by z!hO`afIFbEYuP@$X4;L?&VV8%6x#G2Q+)~fPrx!I?6if;rXUGdE`!td1Zj~HUqXV% zMHH)*G*I;T5XqZL3S&z2QqMp`5bP*T_OM#~2+;&a!7C-H>|UT3Tq`j$L(ndGRAOc$ zf|}sj(g|!=&^Xv$I*uI-8VR>bwLZTD=~dQk{)GG<6basCMmA1$7adYyS(%(=tGvvm=;(-t+JomRv9&I5pp+YPystA&emJ)I)L<8Ox zBUw!7A(&i|!qP+Ego=vM>`-VGoT>QuHX;xgn`SF?i=A2@GU2UB)A z@=xelU&p?Vd;@KO~--z1hsGW$u0Y^8*v2UWQ;P$3m_8@u{jIPlcy|e*ZVm*KzS8L0(*0&Mp zwDYyry$CY3lhC#wQI2*#)Yc@jD(wYmtqBhWZM*gwrGzXelE%t3PHhj&0gfZiFZK8Od7U67G(-q=;GL`uALg&=|pZghxa*=MGj#$Sc z+OFFV5p_v1ZMvWP^S*@QW!(=t>jnhZb=T2vGotTw-#H8Fs;T^EUAh<}t!c@=G(v|%)s1uehK|;u0{bG2oA<*|N{Xg}@8jngRDr*}?v;5dLIMWc% z*2FrU_Zv1!SX->#S=N|Ir60$J8^F9Z8ot^xipdP&pn*iDH{60LcpYK*3|2v0RI%Y5 zgLNOC0?zQd0gIhRc*yXX!Fme8Ny8;LgU+`MYUqX$tlJ=mgssIxJ>tURi1l?hLbBp= z5nV=Pi8~i(ZAGv$t`enlh}Oi_BD#cVU)&M6x^*{G8>7MY@@!@_YT(k#6MZKd=NXAL z9Q%IScoU+Vg5wSNoTbbQ^I2x(OeJj0|KihUO~^J)n?Bn@m=>OIilw>0HO0`4Z~*b! z@M)7F;G@9+TVYAT5_GhH@3uI)8q&AL1?@-}%wF)qqWt{A#c1CFwry_)3coJ<>n^t0 z7ZuylV1yyf;mVxkL4zf)e7T_8z|tI{JocA9aY9bk48l&sOU-Kh0@~M{sBV93wF!kR ziwl?JVQ4%2)SRk(Y+PPoACX>;dKRQ^*VE@=&UPKmhl=f5S_*r%Yc-Wag!hfG8U-bo zMVvsfy#OOB;nwyrMHSk`Sr1I@74X_IPkCTawG>#3^MtwwpnS(uRRvExzLmnFyaJ0g zf6-DKTC-CIt5}v4iWb8BQU`slwgG9zpky5o=Aj_YZgGC0Eze?Io-fpLK6We4>vts6 z(N97kqs2d2k~WxE@XxnAUt+c96=T>AH1yx9U_cqQ<51QTo0dNGambRw{!(cAOSCO3 zu`eksE3nw?#d(Wfz_{~pr6rSgf?}tUz6>LG4xxXC6+08@0chT-r%%D@ouQhl5s&K? z=h^b?f6ZhYJlv@ZYku-^RdI34mfM$EUa&32^exV`SF$AZ7?khU(gV<4Nj z2t_4!VQ1Ze8@uDwt42OfwA^MXC@h#f{%JHGfsj2pinhOulZR#z<_48}43u-ezUP#j zu5~UsoXzN3IDSM=8{yUwBYqvpjv8qjq#TXGuiBYM(`320-|?jhdygr7wb*#6WTU9W zii$~8-WHW8Q7IA?;gk^aj;QPtmDPAO@Cyg%ai#34sO$jau{4?k3yzJZ?a*>85;y2c z9P{BOj-~J?j+LM}Zp3w+fMWp^9*?9F*oRE-1cY z-LFLD@1o)@Dn7#mp97-OBu1r*%2PtG$V^eG7Zss9ghU8Yu*J1Rc1+}DBA2(i%aVkC zkk>{21ah%I$fMs=g1OZle@D!2O~Z9`v_{IfQG&0`dAK#oOSLkGNnd2rrBQLC7_-G? om1kzgO)G~V&+WlqJ2mewq>auW-``EK5t}}!r)|!lj +XMSmainPUT XMSmoveSTRUC <> +XMSwordGET XMSmoveSTRUC <2,,,,,,OFFSET XMSword> +XMSwordPUT XMSmoveSTRUC <2,,,OFFSET XMSword> + +XMSfunctAdr DW 0, 0 + + +; Don't try to call this from your programs + +XMS_setup PROC NEAR + + PUSH DS + PUSH ES + PUSH BX + + MOV AX,CS ; Set Data segment to the code +segment. + MOV DS,AX ; + MOV [XMSwordGET.DestOffsetX],AX ; Set up the move data +structures. + MOV [XMSwordPUT.SrcOffsetX],AX ; + + MOV AX,4300H ; See if a XMS Driver Exists. + INT 2FH ; + CMP AL,80H ; + MOV AX,0 ; + JNE XMS_setup01 ; Return 0 if not. + + MOV AX,4310H ; If so, set the driver's function + INT 2FH ; address. + MOV [XMSfunctAdr],BX ; + MOV [XMSfunctAdr+2],ES ; + + MOV AX,1 ; Return 1. + + XMS_setup01: + POP BX + POP ES + POP DS + + RET + +XMS_setup ENDP + + +SUBTTL LSHL - Shift an unsigned long left +PAGE+ + + ;**************************************************************************** + ;* + ;* Shift an unsigned long integer left n number of bits. + ;* + ;**************************************************************************** + + ; + ; Stack frame definition for void LSHL( unsigned long *SHLnumber, unsigned n +); + ; + +LSHLparms STRUC + + DW 0, 0 + DW 0 +SHLadr DD ? +SHLn DW ? + +LSHLparms ENDS + +procname LSHL + + PUSH BP + MOV BP,SP + + PUSH BX + PUSH CX + PUSH DX + + PUSH DS + LDS BX,SHLadr[BP] + MOV CX,SHLn[BP] + + MOV AX,[BX] ; Get the long integer. + MOV DX,[BX+2] ; + + LSHL_01: + SHL AX,1 ; Do the long shift. + RCL DX,1 ; + LOOP LSHL_01 ; + + MOV [BX],AX ; Replace the addressed number. + MOV [BX+2],DX ; + + POP DS + POP DX + POP CX + POP BX + + POP BP + RET ; Exit + +endproc LSHL + + +SUBTTL Extended Memory - Stack template for EXTget, EXTput +PAGE+ + +EXTgpparms STRUC + + DW 0, 0 + DW 0 +extgpBase DW ? +extgpblk DW ? +extgpblkAdr DW ? +extgpBytes DW ? +extgpmemAdr DW ? + DW ? + +EXTgpparms ENDS + + + +SUBTTL Extended Memory - XMS - Return total XMS memory. +PAGE+ + + ; Use this function to detect wether or not XMS driver installed + ; + ; Stack frame definition for unsigned XMS_available( void ); + ; + ; The total XMS memory available (in 16k blocks) is returned. + ; +procname XMS_available + + PUSH BX + PUSH CX + PUSH DX + + CALL XMS_setup ; Ensure XMS memory is set. + TEST AX,AX ; + JZ XMS_available01 ; Return zero if not. + + MOV AH,08H ; Set the size function code. + CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size. + TEST AX,AX ; + JZ XMS_available01 ; + + MOV AX,DX ; Set available Kbytes. + SUB AX,64 ; Subtract out the HMA (HIMEM.SYS +bug). + JNC XMS_available01 ; + XOR AX,AX ; Set zero if underflow. + + XMS_available01: + MOV CL,4 ; Divide Kbytes by 16 for blocks. + SHR AX,CL ; + + POP DX + POP CX + POP BX + + RET ; Exit + +endproc XMS_available + +SUBTTL Extended Memory - XMS - Return largest block XMS mem. +PAGE+ + + ; + ; Stack frame definition for unsigned XMSblk_available( void ); + ; + ; The size of the largest block of XMS memory available, + ; (in 16Kbyte blocks) is returned. + ; +procname XMSblk_available + + PUSH BX + PUSH CX + PUSH DX + + CALL XMS_setup ; Ensure XMS memory is set. + TEST AX,AX ; + JZ XMSblk_available01 ; Return zero if not. + + MOV AH,08H ; Set the size function code. + CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size. + TEST AX,AX ; + JZ XMSblk_available01 ; + + SUB DX,64 ; Subtract out the HMA (HIMEM.SYS +bug). + JNC XMSblk_available0X ; + XOR DX,DX ; Set zero if underflow. + + XMSblk_available0X: + CMP AX,DX ; + JBE XMSblk_available01 ; + MOV AX,DX ; Set available Kbytes. + + XMSblk_available01: + MOV CL,4 ; Divide Kbytes by 16 for blocks. + SHR AX,CL ; + + POP DX + POP CX + POP BX + + RET ; Exit + +endproc XMSblk_available + +SUBTTL Extended Memory - XMS De-allocate a memory block. +PAGE+ + + ; + ; Stack frame definition for int XMS_dealloc( int Hdl ); + ; + ; Zero is returned if the operation fails, non-zero if success. + ; + ; its really important to do this, only other way to recover + ; XMS blocks is to re-boot + +XMSdealparms STRUC + + DW 0, 0 + DW 0 +xmsdealHdl DW ? + +XMSdealparms ENDS + + +procname XMS_dealloc + + PUSH BP + MOV BP,SP + + PUSH BX + PUSH DX + +; CALL XMS_setup ; Ensure XMS memory is set. +; TEST AX,AX ; +; JZ XMS_dealloc01 ; Return zero if not. + + MOV DX,xmsdealHdl[BP] ; Get the handle to de-allocate. + MOV AH,0AH ; + + CALL DWORD PTR CS:[XMSfunctAdr] ; De-allocate it. + + XMS_dealloc01: + POP DX + POP BX + + POP BP + RET ; Exit + +endproc XMS_dealloc + +SUBTTL Extended Memory - XMS Allocate a memory block. +PAGE+ + + ; + ; Stack frame definition for int XMS_alloc( unsigned rsrvd, *size ); + ; + ; rsrved and size are in 16K byte blocks. + ; rsrved is mem set aside for EMS, generaly zero + ; + ; Zero is returned if the operation fails. + ; Block (XMS) handle is returned if success. + ; + ; size - is reduced by the amount of XMS memory actually allocated. + ; + +XMSalparms STRUC + + DW 0, 0 + DW 0 +xmsalrsrvd DW ? +xmsalsize DD ? + +XMSalparms ENDS + +procname XMS_alloc + + PUSH BP + MOV BP,SP + + PUSH BX + PUSH CX + PUSH DX + PUSH DI + PUSH ES + PUSH DS + + MOV AX,CS ; Set the data segment to the code + MOV DS,AX ; segment. + + MOV CX,4 ; + ADD xmsalrsrvd[BP],CX ; Subtract out the HMA (HIMEM.SYS +bug). + SHL xmsalrsrvd[BP],CL ; Convert reserved blocks to K-bytes. + + LES DI,xmsalsize[BP] ; Load size address. + XOR AX,AX ; + MOV BX,ES:[DI] ; Get the requested size in blocks. + + TEST BX,0F000H ; Check for more than 64 Megabytes. + JZ XMS_alloc01 ; + MOV BX,00FFFH ; + + XMS_alloc01: + MOV CL,4 ; + SHL BX,CL ; Convert to K-Bytes. + MOV CX,BX ; In CX. + JZ XMS_alloc05 ; Return zero if no size requested. + +; CALL XMS_setup ; Ensure XMS memory is set. +; TEST AX,AX ; +; JZ XMS_alloc05 ; Return zero if not. + + XOR BX,BX ; + MOV AH,08H ; Set to Query Free XMS Memory. + CALL DWORD PTR [XMSfunctAdr] ; + + SUB DX,xmsalrsrvd[BP] ; Subtract out reserved blocks. + JB XMS_alloc03 ; Ensure no borrow. + CMP AX,DX ; + JBE XMS_alloc02 ; + MOV AX,DX ; + + XMS_alloc02: + MOV DX,AX ; + CMP AX,68 ; Ensure enough memory to allocate. + + XMS_alloc03: + MOV AX,0 ; + JB XMS_alloc05 ; Exit if not. + + CMP BL,80H ; Check for errors. + JE XMS_alloc05 ; + CMP BL,81H ; + JE XMS_alloc05 ; + + CMP CX,DX ; Check actual against requested size. + JBE XMS_alloc04 ; + MOV CX,DX ; Set if actual < requested. + + XMS_alloc04: + MOV DX,CX ; Set requested size. + MOV AH,09H ; + CALL DWORD PTR [XMSfunctAdr] ; Allocate it. + DEC AX ; Check for errors. + MOV AX,0 ; + JNZ XMS_alloc05 ; + + + MOV AX,CX ; Convert allocated size in KBytes + MOV CL,4 ; to allocated blocks. + SHR AX,CL ; + + SUB ES:[DI],AX ; Subtract the blocks allocated. + MOV AX,DX ; Set to return the handle. + + XMS_alloc05: + POP DS + POP ES + POP DI + POP DX + POP CX + POP BX + + POP BP + RET ; Exit + +endproc XMS_alloc + +SUBTTL Extended Memory - XMS get, put Stack Frame definition +PAGE+ + + +XMSgpparms STRUC + + DW 0, 0 + DW 0 +xmsgpHdl DW ? +xmsgpblk DW ? +xmsgpblkAdr DW ? +xmsgpBytes DW ? +xmsgpmemAdr DD ? + +XMSgpparms ENDS + +SUBTTL Extended Memory - XMStoMem +PAGE+ + + + ; + ; Stack frame definition for int XMStoMem( unsigned Handle, + ; unsigned blk, + ; unsigned blkAdr, + ; unsigned Bytes, + ; char *memAdr + ; ); + ; + ; XMSmemError is returned if the operation fails, Zero if success. + ; + +procname XMStoMem + + PUSH BP + MOV BP,SP + + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + + MOV AX,CS ; Set Data Segment to Code Segment. + MOV DS,AX ; + + MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer. + LES BX,xmsgpmemAdr[BP] ; Get the memory address. + MOV DX,xmsgpHdl[BP] ; Get the XMS handle. + MOV [XMSmainGET.SrcHandle],DX ; Set it in the move structures. + MOV [XMSwordGET.SrcHandle],DX ; + + XOR DX,DX ; + MOV DI,xmsgpblk[BP] ; Get the block number. + SHR DI,1 ; Form the 32 bit XMS address in + RCR DX,1 ; DI:DX. + SHR DI,1 ; + RCR DX,1 ; + ADD DX,xmsgpblkAdr[BP] ; + + TEST CX,1 ; Check for an odd number of bytes + JZ XMStoMem02 ; to transfer. + + DEC CX ; Decrement to an even number of +bytes. + + TEST DX,1 ; Check for an odd XMS address. + JZ XMStoMem01 ; + + ; XMS address is odd. + ; ------------------- + DEC DX ; + MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address. + MOV [XMSwordGET.SrcOffsetX],DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordGET ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ XMStoMem03 ; Error out if error. + + MOV AX,[XMSword] ; Get the moved word. + + MOV ES:[BX],AH ; Move the odd byte to memory. + + INC BX ; Reset the memory address. + ADD DX,2 ; And the XMS address. + + JMP XMStoMem02 ; Move the block. + + + XMStoMem01: + ; XMS address is even. + ; -------------------- + ADD DX,CX ; + MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address. + SUB DX,CX ; + MOV [XMSwordGET.SrcOffsetX],DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordGET ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ XMStoMem03 ; Error out if error. + + MOV AX,[XMSword] ; Get the moved word. + + XCHG DI,CX ; + MOV ES:[BX+DI],AL ; Move the odd byte to memory. + XCHG DI,CX ; + + XMStoMem02: + JCXZ XMStoMem04 ; Avoid a zero byte move. + + MOV XMSmainGET.Length,CX ; Set length for the move. + + MOV XMSmainGET.DestOffset,BX ; Set Memory address. + MOV XMSmainGET.DestOffsetX,ES ; + + MOV XMSmainGET.SrcOffset,DX ; Set XMS address. + MOV XMSmainGET.SrcOffsetX,DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSmainGET ; Set address of the move structure. + + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + DEC AX ; Check for errors. + JZ XMStoMem05 + + XMStoMem03: + MOV AX,XMSmemError ; Set error code if error. + JMP XMStoMem05 ; + + XMStoMem04: + XOR AX,AX ; + + XMStoMem05: + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + + POP BP + RET ; Exit + +endproc XMStoMem + +SUBTTL Extended Memory - MemToXMS +PAGE+ + + + ; + ; Stack frame definition for int MemToXMS( unsigned Handle, + ; unsigned blk, + ; unsigned blkAdr, + ; unsigned Bytes, + ; char *memAdr + ; ); + ; + ; XMSmemError is returned if the operation fails, Zero if success. + ; + +procname MemToXMS + + PUSH BP + MOV BP,SP + + PUSH BX + PUSH CX + PUSH DX + PUSH SI + PUSH DI + PUSH ES + PUSH DS + + MOV AX,CS ; + MOV DS,AX ; + + MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer. + LES BX,xmsgpmemAdr[BP] ; Get the memory address. + MOV DX,xmsgpHdl[BP] ; Get the XMS handle. + MOV [XMSmainPUT.DestHandle],DX ; Set it in the move structures. + MOV [XMSwordPUT.DestHandle],DX ; + MOV [XMSwordGET.SrcHandle],DX ; + + XOR DX,DX ; + MOV DI,xmsgpblk[BP] ; Get the block number. + SHR DI,1 ; Form the 32 bit XMS address in + RCR DX,1 ; DI:DX. + SHR DI,1 ; + RCR DX,1 ; + ADD DX,xmsgpblkAdr[BP] ; + + TEST CX,1 ; Check for an odd number of bytes + JZ MemToXMS02 ; to transfer. + + DEC CX ; Decrement to an even number of +bytes. + + TEST DX,1 ; Check for an odd XMS address. + JZ MemToXMS01 ; + + ; XMS address is odd. + ; ------------------- + DEC DX ; + MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address. + MOV [XMSwordGET.SrcOffsetX],DI ; + MOV [XMSwordPUT.DestOffset],DX ; + MOV [XMSwordPUT.DestOffsetX],DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordGET ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ MemToXMS03 ; Error out if error. + + MOV AH,ES:[BX] ; Get the odd memory byte. + + MOV [XMSwordByte+1],AH ; Put it in the moved word. + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordPUT ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ MemToXMS03 ; Error out if error. + + INC BX ; Reset the memory address. + ADD DX,2 ; And the XMS address. + + JMP MemToXMS02 ; Move the block. + + MemToXMS01: + ; XMS address is even. + ; -------------------- + ADD DX,CX ; + MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address. + MOV [XMSwordPUT.DestOffset],DX ; + SUB DX,CX ; + MOV [XMSwordGET.SrcOffsetX],DI ; + MOV [XMSwordPUT.DestOffsetX],DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordGET ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ MemToXMS03 ; Error out if error. + + XCHG DI,CX ; + MOV AL,ES:[BX+DI] ; Get the odd memory byte. + XCHG DI,CX ; + + MOV [XMSwordByte],AL ; Set the moved word. + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSwordPUT ; Set address of the move structure. + + PUSH BX ; + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + POP BX ; + DEC AX ; Check for errors. + JNZ MemToXMS03 ; Error out if error. + + MemToXMS02: + JCXZ MemToXMS04 ; Avoid a zero byte move. + + MOV XMSmainPUT.Length,CX ; Set length for the move. + + MOV XMSmainPUT.SrcOffset,BX ; Set Memory address. + MOV XMSmainPUT.SrcOffsetX,ES ; + + MOV XMSmainPUT.DestOffset,DX ; Set XMS address. + MOV XMSmainPUT.DestOffsetX,DI ; + + MOV AH,0BH ; Set the XMS move, function code. + MOV SI,OFFSET XMSmainPUT ; Set address of the move structure. + + CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler. + DEC AX ; Check for errors. + JZ MemToXMS05 + + MemToXMS03: + MOV AX,XMSmemError ; Set error code if error. + JMP MemToXMS05 ; + + MemToXMS04: + XOR AX,AX ; + + MemToXMS05: + POP DS + POP ES + POP DI + POP SI + POP DX + POP CX + POP BX + + POP BP + RET ; Exit + +endproc MemToXMS + + +SUBTTL Last Page +PAGE+ + +pwrlolvl_TEXT ENDS + + END + diff --git a/src/lib/xmem/xmem.h b/src/lib/xmem/xmem.h new file mode 100644 index 00000000..15df92c0 --- /dev/null +++ b/src/lib/xmem/xmem.h @@ -0,0 +1,79 @@ +#if !defined(_XMEM_H) +#define _XMEM_H + +typedef struct xms_node + { + long start, size, off; + short used; + struct xms_node *next; + } +xms_node_t; + +typedef struct + { + int handle; + unsigned long total; + unsigned long avail; + unsigned long next_off; + xms_node_t *next; + } +xms_head_t; + +#define XMSBLOCK 16384u +#define XMSBLOCKSHIFT 14 + +extern void LSHL( unsigned long far *SHLnumber, unsigned short n ); + +extern unsigned short XMS_available( void ); + +extern unsigned short XMSblk_available( void ); + +extern short XMS_alloc(unsigned short rsrvd, + unsigned short far *size + ); + +extern short XMS_dealloc(unsigned short Hdl ); + +extern short XMStoMem(unsigned short Handle, // XMS handle returned by +//XMS_alloc() + unsigned short blk, // which 16k block to copy to + unsigned short blkAdr, // offset within 16k block + unsigned short Bytes, // bytes to copy + void far *memAdr + ); + +extern short MemToXMS(unsigned short Handle, + unsigned short blk, + unsigned short blkAdr, + unsigned short Bytes, + void far *memAdr + ); + +// call these for ease +short alloc_xms(unsigned short far *size); // size in 16k blocks +// NOTE size is changed to the amount block size was altered by! +// normaly this is zero + +short xms_to_mem(unsigned short handle, void far *p, unsigned long off, +unsigned short n); +short mem_to_xms(unsigned short handle, void far *p, unsigned long off, +unsigned short n); +void deinit_xms(void); +short init_xms(unsigned short min_blocks); +void qfree_xms(xms_node_t *node); +xms_node_t *qalloc_xms(unsigned long size); +xms_node_t *xms_open(char *file); +short xms_read(void far *buffer, unsigned short n, xms_node_t *node); +short xms_write(void far *buffer, unsigned short n, xms_node_t *node); +long xms_tell(xms_node_t *node); +short xms_seek(xms_node_t *node, long off, short whence); +void xms_close(xms_node_t *node); + + +extern xms_head_t xms_head; + + + +#endif + +/* ---------------------------------- end of file --------------------- */ diff --git a/src/lib/xmem/xmem.txt b/src/lib/xmem/xmem.txt new file mode 100644 index 00000000..306374c2 --- /dev/null +++ b/src/lib/xmem/xmem.txt @@ -0,0 +1,33 @@ +Newsgroups: rec.games.programmer +From: alexad3@icebox.iceonline.com (Alexander J. Russell) +Subject: xms for x2ftp.oulu.fi +Date: Mon, 20 Mar 1995 08:16:21 GMT + +Can some kind soul please pass this on to x2ftp.oulu.fi for me. +I can't ftp from my currrent connection. + + +This file contains 3 files: +xmem.h : c include file +xmem.asm : low level basic XMS acess +xmemc.c : super easy C access via functions like fopen, fread, fwrite + xopen, xread, xwrite, xseek etc... + + +FOR DOS REAL mode programs, requires HIMEM.SYS to be loaded in +config.sys. + +... + +This should be enough code to do what ever you want with XMS. +I like to use the file style access to remind myself it isn't +as fast as say memcpy(). + +Cheers. + + + + +The AnArChIsT - Anarchy! NOT Chaos! aka Alec Russell +alexad3@icebox.iceonline.com + diff --git a/src/lib/xmem/xmemc.c b/src/lib/xmem/xmemc.c new file mode 100644 index 00000000..0ab1de3d --- /dev/null +++ b/src/lib/xmem/xmemc.c @@ -0,0 +1,316 @@ +/* + Written by Alexander J. Russell 1994 + + Placed in the public Domain by Alec Russell, March 1995 + + Slightly higher level xms calls than xmem.asm + +*/ + +#include +#include +#include +#include + +#include "src\lib\xmem\xmem.h" + +xms_head_t xms_head={0}; // set handle to zero + + +/* ---------------------- alloc_xms() ----------------- February 19,1994 */ +short alloc_xms(unsigned short far *size) // size in 16k blocks +{ + return(XMS_alloc(0, size)); +} + + + +/* ---------------------- xms_to_mem() ---------------- February 19,1994 */ +short xms_to_mem(unsigned short handle, void far *p, unsigned long off, +unsigned short n) +{ + unsigned short block, boff; + + block=off >> XMSBLOCKSHIFT; + boff=off - (block << XMSBLOCKSHIFT); + + return(XMStoMem(handle, block, boff, n, p)); +} + + +/* ---------------------- mem_to_xms() ---------------- February 19,1994 */ +short mem_to_xms(unsigned short handle, void far *p, unsigned long off, +unsigned short n) +{ + unsigned short block, boff; + + block=off >> XMSBLOCKSHIFT; + boff=off - (block << XMSBLOCKSHIFT); + + return(MemToXMS(handle, block, boff, n, p)); +} + + +/* ---------------------- qalloc_xms() -------------------- March 8,1994 */ +xms_node_t *qalloc_xms(unsigned long size) +{ + xms_node_t *node=NULL; + xms_node_t *t1; + + if ( size <= xms_head.avail ) + { + // look for existing node + t1=xms_head.next; + while ( t1 ) + { + if ( t1->used == 0 && t1->size >= size ) + { + t1->off=0; + t1->used=1; + node=t1; + break; + } + else + t1=t1->next; + } + + if ( node == NULL ) // didn't find existing node + { + node=malloc(sizeof(xms_node_t)); + if ( node ) + { + node->off=0; + node->used=1; + node->size=size; + node->next=NULL; + node->start=xms_head.next_off; + xms_head.avail-=size; + xms_head.next_off+=size; + if ( xms_head.next == NULL ) + { + xms_head.next=node; + } + else + { + t1=xms_head.next; + while ( t1->next ) + t1=t1->next; + t1->next=node; + } + } + else + printf("out of near mem in qalloc_xms"); + } + } + else + printf("out of xms mem in qalloc size %lu avail %lu", size, +xms_head.avail); + + return(node); +} + + +/* ---------------------- qfree_xms() --------------------- March 8,1994 */ +void qfree_xms(xms_node_t *node) +{ + xms_node_t *t1; + + if ( xms_head.next ) + { + t1=xms_head.next; + while ( t1 != node && t1 ) + t1=t1->next; + + if ( t1 ) + { + t1->used=0; + } + else + printf("ERROR didn't find node qfree"); + } + else + { + printf("ATTEMPTED to qfree empty list"); + } +} + + + +/* ---------------------- xms_open() ---------------------- March 8,1994 */ +xms_node_t *xms_open(char *file) +{ + int i; + xms_node_t *node=NULL; + FILE *fp; + char *buffer; + unsigned long off; + + fp=fopen(file, "rb"); + if ( fp ) + { + node=qalloc_xms(filelength(fileno(fp))); + if ( node ) + { + buffer=malloc(4096); + if ( buffer ) + { + off=0l; + while ( (i=fread(buffer, 1, 4096, fp)) ) + { + mem_to_xms(xms_head.handle, (char far *)buffer, +off+node->start, i); + off+=i; + } + + free(buffer); + } + else + printf("out of mem in xms_open 1"); + } + + fclose(fp); + } + else + printf("ERROR opening %s in xms_open", file); + + return(node); +} + + +/* ---------------------- xms_read() ---------------------- March 8,1994 */ +short xms_read(void far *buffer, unsigned short n, xms_node_t *node) +{ + + if ( node->off >= node->size ) + return 0; + + if ( n+node->off > node->size ) + n=node->size - node->off; + + xms_to_mem(xms_head.handle, buffer, node->start+node->off, n); + node->off+=n; + + return(n); +} + + +/* ---------------------- xms_write() ---------------------- March 8,1994 */ +short xms_write(void far *buffer, unsigned short n, xms_node_t *node) +{ + + if ( node->off >= node->size ) + return 0; + + if ( n+node->off > node->size ) + n=node->size - node->off; + + mem_to_xms(xms_head.handle, buffer, node->start+node->off, n); + node->off+=n; + + return(n); +} + + +/* ---------------------- xms_tell() ---------------------- March 8,1994 */ +long xms_tell(xms_node_t *node) +{ + return node->off; +} + + + +/* ---------------------- xms_seek() ---------------------- March 8,1994 */ +short xms_seek(xms_node_t *node, long off, short whence) +{ + short err=0; + + switch ( whence ) + { + case SEEK_SET: + if ( off < 0l || off > node->size ) + err=1; + else + node->off=off; + break; + + case SEEK_END: + if ( off > 0l || (node->size + off) < 0l ) + err=1; + else + node->off=node->size + off; + break; + + case SEEK_CUR: + if ( node->off + off < 0l || node->off + off > node->size ) + err=1; + else + node->off+=off; + break; + } + + return(err); +} + + +/* ---------------------- xms_close() --------------------- March 8,1994 */ +void xms_close(xms_node_t *node) +{ + qfree_xms(node); +} + + + + +/* ---------------------- init_xms() ---------------------- March 8,1994 */ +short init_xms(unsigned short min_blocks) +{ + unsigned short blocks; + + blocks=XMSblk_available(); + if ( blocks >= min_blocks ) + { + memset(&xms_head, 0, sizeof(xms_head_t)); + if ( (xms_head.handle=alloc_xms(&blocks)) ) + { + printf("blocks minus by = %u", blocks); + min_blocks-=blocks; + xms_head.avail=xms_head.total=(unsigned long)min_blocks*XMSBLOCK; + blocks=min_blocks; + } + else + blocks=0; + } + else + blocks=0; + + return(blocks); +} + + +/* ---------------------- deinit_xms() -------------------- March 8,1994 */ +void deinit_xms(void) +{ + xms_node_t *t1, *t2; + + if ( xms_head.handle ) + { + XMS_dealloc(xms_head.handle); + if ( xms_head.next ) + { + t1=xms_head.next; + t2=t1->next; + while ( t1 ) + { + free(t1); + t1=t2; + t2=t1->next; + } + } + + memset(&xms_head, 0, sizeof(xms_head_t)); + } +} + + + +/* --------------------------- end of file ------------------------- */ diff --git a/src/scroll.c b/src/scroll.c index 41e1c557..1a326fca 100644 --- a/src/scroll.c +++ b/src/scroll.c @@ -499,7 +499,7 @@ allocMap(int w, int h) { result.height=h; if(initxms()>0) result.data = malloc(sizeof(byte) * w * h); - else (void huge*)result.data = xmsmalloc(sizeof(byte) * w * h); + else result.data = xmsmalloc(sizeof(byte) * w * h); return result; } @@ -513,17 +513,17 @@ initMap(map_t *map) { int tile = 1; if(initxms()>0) map->tiles = malloc(sizeof(tiles_t)); - else (void huge*)map->tiles = xmsmalloc(sizeof(tiles_t)); + else map->tiles = xmsmalloc(sizeof(tiles_t)); /* create the tile set */ if(initxms()>0) map->tiles->data = malloc(sizeof(bitmap_t)); - else (void huge*)map->tiles->data = xmsmalloc(sizeof(bitmap_t)); + else map->tiles->data = xmsmalloc(sizeof(bitmap_t)); map->tiles->data->width = (TILEWH*2); map->tiles->data->height= TILEWH; if(initxms()>0) map->tiles->data->data = malloc((TILEWH*2)*TILEWH); - else (void huge*)map->tiles->data->data = xmsmalloc((TILEWH*2)*TILEWH); + else map->tiles->data->data = xmsmalloc((TILEWH*2)*TILEWH); map->tiles->tileHeight = TILEWH; map->tiles->tileWidth =TILEWH; map->tiles->rows = 1; -- 2.39.2