File: dosutil.c

package info (click to toggle)
libmikmod 3.3.13-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,188 kB
  • sloc: ansic: 36,299; sh: 5,013; makefile: 548; javascript: 1
file content (142 lines) | stat: -rw-r--r-- 4,388 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* DOS glue code for DJGPP / Watcom compatibility
 * Written by Cameron Cawley <ccawley2011@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "dosutil.h"

#if defined(__DJGPP__)

#include <sys/version.h>
#include <dpmi.h>
#include <sys/nearptr.h>

/* BUG WARNING:  there is an error in DJGPP libraries <= 2.01:
 * src/libc/dpmi/api/d0102.s loads the selector and allocsize
 * arguments in the wrong order.  DJGPP >= 2.02 have it fixed. */
#if (!defined(__DJGPP_MINOR__) || (__DJGPP_MINOR__+0) < 2)
#error __dpmi_resize_dos_memory() from DJGPP <= 2.01 is broken!
#endif

int dpmi_allocate_dos_memory(int paragraphs, int *ret_selector_or_max) {
	return __dpmi_allocate_dos_memory(paragraphs, ret_selector_or_max);
}

int dpmi_free_dos_memory(int selector) {
	return __dpmi_free_dos_memory(selector);
}

int dpmi_resize_dos_memory(int selector, int newpara, int *ret_max) {
	return __dpmi_resize_dos_memory(selector, newpara, ret_max);
}

int dpmi_lock_linear_region(unsigned long address, unsigned long size) {
	__dpmi_meminfo info;

	info.address = address;
	info.size = size;
	return __dpmi_lock_linear_region(&info);
}

int dpmi_unlock_linear_region(unsigned long address, unsigned long size) {
	__dpmi_meminfo info;

	info.address = address;
	info.size = size;
	return __dpmi_unlock_linear_region(&info);
}

int dpmi_lock_linear_region_base(void *address, unsigned long size) {
	return dpmi_lock_linear_region(__djgpp_base_address + (unsigned long)address, size);
}

int dpmi_unlock_linear_region_base(void *address, unsigned long size) {
	return dpmi_unlock_linear_region(__djgpp_base_address + (unsigned long)address, size);
}

#elif defined(__WATCOMC__)

#include <i86.h>

int dpmi_allocate_dos_memory(int paragraphs, int *ret_selector_or_max) {
	union REGS r;

	r.x.eax = 0x0100;              /* DPMI allocate DOS memory */
	r.x.ebx = paragraphs;          /* Number of paragraphs */
	int386 (0x31, &r, &r);
	if (r.w.cflag & 1)
		return (-1);

	*ret_selector_or_max = r.w.dx;
	return (r.w.ax);              /* Return segment address */
}

int dpmi_free_dos_memory(int selector) {
	union REGS r;

	r.x.eax = 0x101;              /* DPMI free DOS memory */
	r.x.edx = selector;           /* Selector to free */
	int386 (0x31, &r, &r);
	return (r.w.cflag & 1) ? -1 : 0;
}

int dpmi_resize_dos_memory(int selector, int newpara, int *ret_max) {
	union REGS r;

	r.x.eax = 0x0102;              /* DPMI resize DOS memory */
	r.x.ebx = newpara;          /* Number of paragraphs */
	r.x.edx = selector;            /* Selector to free */
	int386 (0x31, &r, &r);
	if (r.w.cflag & 1) {
		*ret_max = r.x.ebx;
		return (-1);
	}
	return 0;
}

int dpmi_lock_linear_region(unsigned long address, unsigned long size) {
	union REGS r;

	r.w.ax = 0x600;                /* DPMI Lock Linear Region */
	r.w.bx = (address >> 16);      /* Linear address in BX:CX */
	r.w.cx = (address & 0xFFFF);
	r.w.si = (size >> 16);         /* Length in SI:DI */
	r.w.di = (size & 0xFFFF);
	int386 (0x31, &r, &r);
	return (r.w.cflag & 1) ? -1 : 0;
}

int dpmi_unlock_linear_region(unsigned long address, unsigned long size) {
	union REGS r;

	r.w.ax = 0x601;                /* DPMI Unlock Linear Region */
	r.w.bx = (address >> 16);      /* Linear address in BX:CX */
	r.w.cx = (address & 0xFFFF);
	r.w.si = (size >> 16);         /* Length in SI:DI */
	r.w.di = (size & 0xFFFF);
	int386 (0x31, &r, &r);
	return (r.w.cflag & 1) ? -1 : 0;
}

int dpmi_lock_linear_region_base(void *address, unsigned long size) {
	return dpmi_lock_linear_region((unsigned long)address, size);
}

int dpmi_unlock_linear_region_base(void *address, unsigned long size) {
	return dpmi_unlock_linear_region((unsigned long)address, size);
}

#endif