//
// DPMI Interface class for PTC 2.0 C++ API
// Copyright (c) 1998 Jonathan Matthew (jmatthew@uq.net.au)
// The PTC 2.0 C++ API is (c) 1998 Glenn Fiedler (ptc@gaffer.org)
// This source code is licensed under the GNU LGPL
//

#ifndef __DPMI_H
#define __DPMI_H

#ifdef __WATCOMC__
#include <i86.h>
#endif

#ifdef __DJGPP__
#include <dpmi.h>
#endif

#include <mem.h>
#include <dos.h>
#include <string.h>

class DPMI
{
    public:

        // DPMI register structures
        #pragma pack(1)
        typedef struct dpmi_regs_l {
            unsigned long edi;
            unsigned long esi;
            unsigned long ebp;
            unsigned long rsvd;
            unsigned long ebx;
            unsigned long edx;
            unsigned long ecx;
            unsigned long eax;
            unsigned short flags;
            unsigned short es;
            unsigned short ds;
            unsigned short fs;
            unsigned short gs;
            unsigned short ip;
            unsigned short cs;
            unsigned short sp;
            unsigned short ss;
        } dpmi_regs_l;

        typedef struct dpmi_regs_w {
            unsigned short di, edih;
            unsigned short si, esih;
            unsigned short bp, ebph;
            unsigned long rsvd;
            unsigned short bx, ebxh;
            unsigned short dx, edxh;
            unsigned short cx, ecxh;
            unsigned short ax, eaxh;
            unsigned short flags;
            unsigned short es;
            unsigned short ds;
            unsigned short fs;
            unsigned short gs;
            unsigned short ip;
            unsigned short cs;
            unsigned short sp;
            unsigned short ss;
        } dpmi_regs_w;
     
        typedef struct dpmi_regs_b {
            unsigned char dil, dih, edil, edih;
            unsigned char sil, sih, esil, esih;
            unsigned char bpl, bph, epbl, ebph;
            unsigned long rsvd;
            unsigned char bl, bh, ebl, ebh;
            unsigned char dl, dh, edl, edh;
            unsigned char cl, ch, ecl, ech;
            unsigned char al, ah, eal, eah;
            unsigned short flags;
            unsigned short es;
            unsigned short ds;
            unsigned short fs;
            unsigned short gs;
            unsigned short ip;
            unsigned short cs;
            unsigned short sp;
            unsigned short ss;
        } dpmi_regs_b;

        typedef union dpmi_regs {
            dpmi_regs_b b;
            dpmi_regs_w w;
            dpmi_regs_l l;
        } dpmi_regs;

        typedef struct dpmi_ptr {
            unsigned int seg;
            unsigned int sel;
            void *ptr;
        } dpmi_ptr;
        #pragma pack()

        // setup
        DPMI();
        ~DPMI();

        int dos_alloc(int bytes, dpmi_ptr *dp);
        int dos_free(dpmi_ptr *dp);
        int dos_int(int intnum, dpmi_regs *dr, dpmi_regs *drout);
        int map_linear_mem(int addr, int size, int *ptr);
        int unmap_linear_mem(int ptr);
        int lock_mem(int ptr, int size);
        int unlock_mem(int ptr, int size);

    private:
        // watcom register structures
        union REGS regs;
        struct SREGS sregs;
        void clearregs();
};;

#endif
