home *** CD-ROM | disk | FTP | other *** search
- // Using LIM EMS 4.0 in Borland 3.1.
- // Copyright 1993, Mark T. Pflaging
- // Implementation for a class for handling the LIM EMS version 4.0.
- // Portions borrowed from:
- // "LOTUS(R)/INTEL(R)/MICROSOFT(R)
- // EXPANDED MEMORY SPECIFICATION
- // Version 4.0
- // 300275-005
- // October, 1987"
- #include <dos.h>
- #include <iomanip.h>
- #include <mem.h>
-
- #include "emm.hpp"
-
- union REGS LIMEMS::input_regs, LIMEMS::output_regs;
- struct SREGS LIMEMS::segment_regs;
-
- int LIMEMS::emm_handle;
- int LIMEMS::pages_needed = 0;
- char * LIMEMS::page_frame = NULL;
-
- //------------------------------------------------------------//
- // Function which determines whether EMM device driver //
- // is installed. //
- //------------------------------------------------------------//
- Boolean LIMEMS::emm_installed()
- {
- char *EMM_device_name = "EMMXXXX0";
- char *int_67_device_name_ptr;
-
- //--------------------------------------------------------//
- // AH = DOS get interrupt vector function. //
- //--------------------------------------------------------//
- input_regs.h.ah = 0x35;
-
- //--------------------------------------------------------//
- // AL = EMM interrupt vector number. //
- //--------------------------------------------------------//
- input_regs.h.al = EMM_INT;
- intdosx (&input_regs, &output_regs, &segment_regs);
-
- //--------------------------------------------------------//
- // Upon return ES:0Ah points to location where //
- // device name should be. //
- //--------------------------------------------------------//
- int_67_device_name_ptr = (char *)MK_FP(segment_regs.es, 0x0A);
-
- //--------------------------------------------------------//
- // Compare memory with EMM device name. //
- //--------------------------------------------------------//
- if (memcmp (EMM_device_name, int_67_device_name_ptr,
- DEVICE_NAME_LENGTH) == 0)
- return (True);
- else
- return (False);
- }
-
- //--------------------------------------------------------//
- // Determine if EMM is installed. //
- //--------------------------------------------------------//
- void LIMEMS::Create() {
- // This class may be instantiated more than once,
- // but it can only be 'Init'ed once!
- static Boolean checked = False;
- if (!checked)
- if (!emm_installed()) {
- cout << "EMM not installed!" << endl;
- exit(1);
- }
- checked = True;
- }
-
- //------------------------------------------------------------//
- // Function which determines if there are enough unallocated //
- // expanded memory pages for the application. //
- //------------------------------------------------------------//
- Boolean LIMEMS::enough_unallocated_pages (int pages_needed)
- {
- input_regs.h.ah = GET_UNALLOC_PAGE_COUNT;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah != 0 || pages_needed > output_regs.x.bx)
- return (False);
- else
- return (True);
- }
-
- //------------------------------------------------------------//
- // Function which allocates expanded memory pages and passes //
- // back to the main EMM handle. //
- //------------------------------------------------------------//
- Boolean LIMEMS::allocate_expanded_memory_pages (int pages_needed)
- {
- input_regs.h.ah = ALLOCATE_PAGES;
- input_regs.x.bx = pages_needed;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah == 0) {
- emm_handle = output_regs.x.dx;
- return (True);
- }
- else
- return (False);
- }
-
- //------------------------------------------------------------//
- // Routine to map a logical page to a physical page. //
- //------------------------------------------------------------//
- Boolean LIMEMS::map_expanded_memory_pages (int physical_page, int logical_page)
- {
- input_regs.h.ah = MAP_PAGES;
- input_regs.h.al = physical_page;
- input_regs.x.bx = logical_page;
- input_regs.x.dx = emm_handle;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah == 0)
- return (True);
- else
- return (False);
- }
-
- //------------------------------------------------------------//
- // Routine which gets the page frame base address from EMM. //
- //------------------------------------------------------------//
- Boolean LIMEMS::get_page_frame_address ()
- {
- input_regs.h.ah = GET_PAGE_FRAME;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah != 0) /* check EMM status */
- return (False);
- else
- page_frame = (char *)MK_FP(output_regs.x.bx, 0);
- return (True);
- }
-
- //------------------------------------------------------------//
- // Routine to release all expanded memory pages allocated //
- // by an EMM handle. //
- //------------------------------------------------------------//
- Boolean LIMEMS::deallocate_expanded_memory_pages ()
- {
- input_regs.h.ah = DEALLOCATE_PAGES;
- input_regs.x.dx = emm_handle;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah == 0)
- return (True);
- else
- return (False);
- }
-
- Boolean LIMEMS::get_mappable_physical_pages()
- {
- input_regs.h.ah = GET_PHYSICAL_PAGES;
- input_regs.h.al = 0x01;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah != 0) /* check EMM status */
- return (False);
- else {
- int num_pages = output_regs.x.cx;
- mappable_phys_page * map = new mappable_phys_page[num_pages];
- input_regs.h.ah = GET_PHYSICAL_PAGES;
- input_regs.h.al = 0x00;
- segment_regs.es = FP_SEG(map);
- input_regs.x.di = FP_OFF(map);
- int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
- if (output_regs.h.ah != 0) /* check EMM status */
- return (False);
- for (int i = 0; i < num_pages; i ++) {
- cout << "phys_page_segment=0x" << hex << map[i].phys_page_segment << dec;
- cout << "\tphys_page_number=" << map[i].phys_page_number << endl;
- }
- return (True);
- }
- }
-
- Boolean LIMEMS::map_multiple_pages(log_to_phys_map * mapping, int num_maps)
- {
- input_regs.h.ah = MAP_MULTIPLE_PAGES;
- input_regs.h.al = 0x00;
- input_regs.x.dx = emm_handle;
- input_regs.x.cx = num_maps;
- segment_regs.ds = FP_SEG(mapping);
- input_regs.x.si = FP_OFF(mapping);
- int86x (EMM_INT, &input_regs, &output_regs, &segment_regs);
- if (output_regs.h.ah != 0) // check EMM status
- return (False);
- return (True);
- }
-
- //------------------------------------------------------------//
- // Function which allocates expanded memory pages and passes //
- // back to the main EMM handle. //
- //------------------------------------------------------------//
- Boolean LIMEMS::reallocate_expanded_memory_pages (int pages_needed)
- {
- input_regs.h.ah = REALLOCATE_PAGES;
- input_regs.x.dx = emm_handle;
- input_regs.x.bx = pages_needed;
- int86 (EMM_INT, &input_regs, &output_regs);
- if (output_regs.h.ah == 0)
- return (True);
- else
- return (False);
- }
-
-