1 ;-----------------------------------------------------------------------
2 ;Can't take credit for the ASM code here, found it on a local BBS.
3 ;The author has beem lost in the mists of time.
28 pwrlolvl_TEXT SEGMENT WORD PUBLIC 'CODE'
30 ASSUME CS:pwrlolvl_TEXT, DS:pwrlolvl_TEXT, ES:pwrlolvl_TEXT
32 SUBTTL (Local Procedure) XMS_setup - find a XMS driver.
36 XMSwordByte LABEL BYTE
52 XMSmainGET XMSmoveSTRUC <>
53 XMSmainPUT XMSmoveSTRUC <>
54 XMSwordGET XMSmoveSTRUC <2,,,,,,OFFSET XMSword>
55 XMSwordPUT XMSmoveSTRUC <2,,,OFFSET XMSword>
60 ; Don't try to call this from your programs
68 MOV AX,CS ; Set Data segment to the code
71 MOV [XMSwordGET.DestOffsetX],AX ; Set up the move data
73 MOV [XMSwordPUT.SrcOffsetX],AX ;
75 MOV AX,4300H ; See if a XMS Driver Exists.
79 JNE XMS_setup01 ; Return 0 if not.
81 MOV AX,4310H ; If so, set the driver's function
83 MOV [XMSfunctAdr],BX ;
84 MOV [XMSfunctAdr+2],ES ;
98 SUBTTL LSHL - Shift an unsigned long left
101 ;****************************************************************************
103 ;* Shift an unsigned long integer left n number of bits.
105 ;****************************************************************************
108 ; Stack frame definition for void LSHL( unsigned long *SHLnumber, unsigned n
134 MOV AX,[BX] ; Get the long integer.
138 SHL AX,1 ; Do the long shift.
142 MOV [BX],AX ; Replace the addressed number.
156 SUBTTL Extended Memory - Stack template for EXTget, EXTput
174 SUBTTL Extended Memory - XMS - Return total XMS memory.
177 ; Use this function to detect wether or not XMS driver installed
179 ; Stack frame definition for unsigned XMS_available( void );
181 ; The total XMS memory available (in 16k blocks) is returned.
183 procname XMS_available
189 CALL XMS_setup ; Ensure XMS memory is set.
191 JZ XMS_available01 ; Return zero if not.
193 MOV AH,08H ; Set the size function code.
194 CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size.
198 MOV AX,DX ; Set available Kbytes.
199 SUB AX,64 ; Subtract out the HMA (HIMEM.SYS
201 JNC XMS_available01 ;
202 XOR AX,AX ; Set zero if underflow.
205 MOV CL,4 ; Divide Kbytes by 16 for blocks.
214 endproc XMS_available
216 SUBTTL Extended Memory - XMS - Return largest block XMS mem.
220 ; Stack frame definition for unsigned XMSblk_available( void );
222 ; The size of the largest block of XMS memory available,
223 ; (in 16Kbyte blocks) is returned.
225 procname XMSblk_available
231 CALL XMS_setup ; Ensure XMS memory is set.
233 JZ XMSblk_available01 ; Return zero if not.
235 MOV AH,08H ; Set the size function code.
236 CALL DWORD PTR CS:[XMSfunctAdr] ; Get the size.
238 JZ XMSblk_available01 ;
240 SUB DX,64 ; Subtract out the HMA (HIMEM.SYS
242 JNC XMSblk_available0X ;
243 XOR DX,DX ; Set zero if underflow.
247 JBE XMSblk_available01 ;
248 MOV AX,DX ; Set available Kbytes.
251 MOV CL,4 ; Divide Kbytes by 16 for blocks.
260 endproc XMSblk_available
262 SUBTTL Extended Memory - XMS De-allocate a memory block.
266 ; Stack frame definition for int XMS_dealloc( int Hdl );
268 ; Zero is returned if the operation fails, non-zero if success.
270 ; its really important to do this, only other way to recover
271 ; XMS blocks is to re-boot
290 ; CALL XMS_setup ; Ensure XMS memory is set.
292 ; JZ XMS_dealloc01 ; Return zero if not.
294 MOV DX,xmsdealHdl[BP] ; Get the handle to de-allocate.
297 CALL DWORD PTR CS:[XMSfunctAdr] ; De-allocate it.
308 SUBTTL Extended Memory - XMS Allocate a memory block.
312 ; Stack frame definition for int XMS_alloc( unsigned rsrvd, *size );
314 ; rsrved and size are in 16K byte blocks.
315 ; rsrved is mem set aside for EMS, generaly zero
317 ; Zero is returned if the operation fails.
318 ; Block (XMS) handle is returned if success.
320 ; size - is reduced by the amount of XMS memory actually allocated.
344 MOV AX,CS ; Set the data segment to the code
348 ADD xmsalrsrvd[BP],CX ; Subtract out the HMA (HIMEM.SYS
350 SHL xmsalrsrvd[BP],CL ; Convert reserved blocks to K-bytes.
352 LES DI,xmsalsize[BP] ; Load size address.
354 MOV BX,ES:[DI] ; Get the requested size in blocks.
356 TEST BX,0F000H ; Check for more than 64 Megabytes.
362 SHL BX,CL ; Convert to K-Bytes.
364 JZ XMS_alloc05 ; Return zero if no size requested.
366 ; CALL XMS_setup ; Ensure XMS memory is set.
368 ; JZ XMS_alloc05 ; Return zero if not.
371 MOV AH,08H ; Set to Query Free XMS Memory.
372 CALL DWORD PTR [XMSfunctAdr] ;
374 SUB DX,xmsalrsrvd[BP] ; Subtract out reserved blocks.
375 JB XMS_alloc03 ; Ensure no borrow.
382 CMP AX,68 ; Ensure enough memory to allocate.
386 JB XMS_alloc05 ; Exit if not.
388 CMP BL,80H ; Check for errors.
393 CMP CX,DX ; Check actual against requested size.
395 MOV CX,DX ; Set if actual < requested.
398 MOV DX,CX ; Set requested size.
400 CALL DWORD PTR [XMSfunctAdr] ; Allocate it.
401 DEC AX ; Check for errors.
406 MOV AX,CX ; Convert allocated size in KBytes
407 MOV CL,4 ; to allocated blocks.
410 SUB ES:[DI],AX ; Subtract the blocks allocated.
411 MOV AX,DX ; Set to return the handle.
426 SUBTTL Extended Memory - XMS get, put Stack Frame definition
442 SUBTTL Extended Memory - XMStoMem
447 ; Stack frame definition for int XMStoMem( unsigned Handle,
454 ; XMSmemError is returned if the operation fails, Zero if success.
470 MOV AX,CS ; Set Data Segment to Code Segment.
473 MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer.
474 LES BX,xmsgpmemAdr[BP] ; Get the memory address.
475 MOV DX,xmsgpHdl[BP] ; Get the XMS handle.
476 MOV [XMSmainGET.SrcHandle],DX ; Set it in the move structures.
477 MOV [XMSwordGET.SrcHandle],DX ;
480 MOV DI,xmsgpblk[BP] ; Get the block number.
481 SHR DI,1 ; Form the 32 bit XMS address in
485 ADD DX,xmsgpblkAdr[BP] ;
487 TEST CX,1 ; Check for an odd number of bytes
488 JZ XMStoMem02 ; to transfer.
490 DEC CX ; Decrement to an even number of
493 TEST DX,1 ; Check for an odd XMS address.
496 ; XMS address is odd.
497 ; -------------------
499 MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
500 MOV [XMSwordGET.SrcOffsetX],DI ;
502 MOV AH,0BH ; Set the XMS move, function code.
503 MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
506 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
508 DEC AX ; Check for errors.
509 JNZ XMStoMem03 ; Error out if error.
511 MOV AX,[XMSword] ; Get the moved word.
513 MOV ES:[BX],AH ; Move the odd byte to memory.
515 INC BX ; Reset the memory address.
516 ADD DX,2 ; And the XMS address.
518 JMP XMStoMem02 ; Move the block.
522 ; XMS address is even.
523 ; --------------------
525 MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
527 MOV [XMSwordGET.SrcOffsetX],DI ;
529 MOV AH,0BH ; Set the XMS move, function code.
530 MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
533 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
535 DEC AX ; Check for errors.
536 JNZ XMStoMem03 ; Error out if error.
538 MOV AX,[XMSword] ; Get the moved word.
541 MOV ES:[BX+DI],AL ; Move the odd byte to memory.
545 JCXZ XMStoMem04 ; Avoid a zero byte move.
547 MOV XMSmainGET.Length,CX ; Set length for the move.
549 MOV XMSmainGET.DestOffset,BX ; Set Memory address.
550 MOV XMSmainGET.DestOffsetX,ES ;
552 MOV XMSmainGET.SrcOffset,DX ; Set XMS address.
553 MOV XMSmainGET.SrcOffsetX,DI ;
555 MOV AH,0BH ; Set the XMS move, function code.
556 MOV SI,OFFSET XMSmainGET ; Set address of the move structure.
558 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
559 DEC AX ; Check for errors.
563 MOV AX,XMSmemError ; Set error code if error.
583 SUBTTL Extended Memory - MemToXMS
588 ; Stack frame definition for int MemToXMS( unsigned Handle,
595 ; XMSmemError is returned if the operation fails, Zero if success.
614 MOV CX,xmsgpBytes[BP] ; Get the number of bytes to transfer.
615 LES BX,xmsgpmemAdr[BP] ; Get the memory address.
616 MOV DX,xmsgpHdl[BP] ; Get the XMS handle.
617 MOV [XMSmainPUT.DestHandle],DX ; Set it in the move structures.
618 MOV [XMSwordPUT.DestHandle],DX ;
619 MOV [XMSwordGET.SrcHandle],DX ;
622 MOV DI,xmsgpblk[BP] ; Get the block number.
623 SHR DI,1 ; Form the 32 bit XMS address in
627 ADD DX,xmsgpblkAdr[BP] ;
629 TEST CX,1 ; Check for an odd number of bytes
630 JZ MemToXMS02 ; to transfer.
632 DEC CX ; Decrement to an even number of
635 TEST DX,1 ; Check for an odd XMS address.
638 ; XMS address is odd.
639 ; -------------------
641 MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
642 MOV [XMSwordGET.SrcOffsetX],DI ;
643 MOV [XMSwordPUT.DestOffset],DX ;
644 MOV [XMSwordPUT.DestOffsetX],DI ;
646 MOV AH,0BH ; Set the XMS move, function code.
647 MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
650 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
652 DEC AX ; Check for errors.
653 JNZ MemToXMS03 ; Error out if error.
655 MOV AH,ES:[BX] ; Get the odd memory byte.
657 MOV [XMSwordByte+1],AH ; Put it in the moved word.
659 MOV AH,0BH ; Set the XMS move, function code.
660 MOV SI,OFFSET XMSwordPUT ; Set address of the move structure.
663 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
665 DEC AX ; Check for errors.
666 JNZ MemToXMS03 ; Error out if error.
668 INC BX ; Reset the memory address.
669 ADD DX,2 ; And the XMS address.
671 JMP MemToXMS02 ; Move the block.
674 ; XMS address is even.
675 ; --------------------
677 MOV [XMSwordGET.SrcOffset],DX ; Set the XMS address.
678 MOV [XMSwordPUT.DestOffset],DX ;
680 MOV [XMSwordGET.SrcOffsetX],DI ;
681 MOV [XMSwordPUT.DestOffsetX],DI ;
683 MOV AH,0BH ; Set the XMS move, function code.
684 MOV SI,OFFSET XMSwordGET ; Set address of the move structure.
687 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
689 DEC AX ; Check for errors.
690 JNZ MemToXMS03 ; Error out if error.
693 MOV AL,ES:[BX+DI] ; Get the odd memory byte.
696 MOV [XMSwordByte],AL ; Set the moved word.
698 MOV AH,0BH ; Set the XMS move, function code.
699 MOV SI,OFFSET XMSwordPUT ; Set address of the move structure.
702 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
704 DEC AX ; Check for errors.
705 JNZ MemToXMS03 ; Error out if error.
708 JCXZ MemToXMS04 ; Avoid a zero byte move.
710 MOV XMSmainPUT.Length,CX ; Set length for the move.
712 MOV XMSmainPUT.SrcOffset,BX ; Set Memory address.
713 MOV XMSmainPUT.SrcOffsetX,ES ;
715 MOV XMSmainPUT.DestOffset,DX ; Set XMS address.
716 MOV XMSmainPUT.DestOffsetX,DI ;
718 MOV AH,0BH ; Set the XMS move, function code.
719 MOV SI,OFFSET XMSmainPUT ; Set address of the move structure.
721 CALL DWORD PTR [XMSfunctAdr] ; Call the XMS handler.
722 DEC AX ; Check for errors.
726 MOV AX,XMSmemError ; Set error code if error.