summaryrefslogtreecommitdiffstats
path: root/private/nw/vwipxspx/dll/vwvdm.h
blob: 2fd23ba2252130d36d6dcad83c3b833171d3e939 (plain) (blame)
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
143
144
145
146
147
148
149
150
151
/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    vwvdm.h

Abstract:

    Contains macros, manifests, includes for dealing with VDM

Author:

    Richard L Firth (rfirth) 25-Oct-1993

Revision History:

    25-Oct-1993 rfirth
        Created

--*/

#ifndef _VWVDM_H_
#define _VWVDM_H_

//
// unaligned pointers - non-Intel platforms must use UNALIGNED to access data
// in VDM which can (and most likely will) be aligned on odd-byte and word
// boundaries
//

#ifndef ULPBYTE
#define ULPBYTE BYTE UNALIGNED FAR*
#endif

#ifndef ULPWORD
#define ULPWORD WORD UNALIGNED FAR*
#endif

#ifndef ULPDWORD
#define ULPDWORD DWORD UNALIGNED FAR*
#endif

#ifndef ULPVOID
#define ULPVOID VOID UNALIGNED FAR*
#endif

//
// VDM macros
//

#define MSW_PE  0x0001  // Protect-mode Enable bit in x86 Machine Status Word

//
// POINTER_FROM_WORDS - returns 32-bit pointer to address in VDM memory described
// by seg:off. If seg:off = 0:0, returns NULL
//

#define POINTER_FROM_WORDS(seg, off, size) \
    _inlinePointerFromWords((WORD)(seg), (WORD)(off), (WORD)(size))

//
// _inlinePointerFromWords - the POINTER_FROM_WORDS macro is inefficient if the
// arguments are calls to eg. getES(), getBX() - the calls are made twice if
// the pointer turns out to be non-zero. Use an inline function to achieve the
// same results, but only call function arguments once
//

__inline LPVOID _inlinePointerFromWords(WORD seg, WORD off, WORD size) {
    return (seg | off)
        ? (LPVOID)GetVDMPointer((ULONG)(MAKELONG(off, seg)), size, (CHAR)((getMSW() & MSW_PE) ? TRUE : FALSE))
        : NULL;
}

//
// GET_POINTER - does the same thing as POINTER_FROM_WORDS, but we know beforehand
// which processor mode we are in
//

#define GET_POINTER(seg, off, size, mode) \
    _inlineGetPointer((WORD)(seg), (WORD)(off), (WORD)(size), (BOOL)(mode))

__inline LPVOID _inlineGetPointer(WORD seg, WORD off, WORD size, BOOL mode) {
    return (seg | off)
        ? (LPVOID)GetVDMPointer(MAKELONG(off, seg), size, (UCHAR)mode)
        : NULL;
}

//
// GET_FAR_POINTER - same as READ_FAR_POINTER with the same proviso as for
// GET_POINTER
//

#define GET_FAR_POINTER(addr, mode) ((LPBYTE)(GET_POINTER(GET_SELECTOR(addr), GET_OFFSET(addr), sizeof(LPBYTE), mode)))

//
// GET_SELECTOR - retrieves the selector word from the intel 32-bit far pointer
// (DWORD) pointed at by <pointer> (remember: stored as offset, segment)
//

#define GET_SELECTOR(pointer)   READ_WORD((LPWORD)(pointer)+1)

//
// GET_SEGMENT - same as GET_SELECTOR
//

#define GET_SEGMENT(pointer)    GET_SELECTOR(pointer)

//
// GET_OFFSET - retrieves the offset word from an intel 32-bit far pointer
// (DWORD) pointed at by <pointer> (remember: stored as offset, segment)
//

#define GET_OFFSET(pointer)     READ_WORD((LPWORD)(pointer))

//
// READ_FAR_POINTER - read the pair of words in VDM memory, currently pointed at
// by a 32-bit flat pointer and convert them to a 32-bit flat pointer
//

#define READ_FAR_POINTER(addr)  ((LPBYTE)(POINTER_FROM_WORDS(GET_SELECTOR(addr), GET_OFFSET(addr), sizeof(LPBYTE))))

//
// READ_WORD - read a single 16-bit little-endian word from VDM memory. On non
// Intel platforms, use unaligned pointer to access data
//

#define READ_WORD(addr)         (*((ULPWORD)(addr)))

//
// READ_DWORD - read a 4-byte little-endian double word from VDM memory. On non
// Intel platforms, use unaligned pointer to access data
//

#define READ_DWORD(addr)        (*((ULPDWORD)(addr)))

//
// ARRAY_ELEMENTS - gives the number of elements of a particular type in an
// array
//

#define ARRAY_ELEMENTS(a)   (sizeof(a)/sizeof((a)[0]))

//
// LAST_ELEMENT - returns the index of the last element in array
//

#define LAST_ELEMENT(a)     (ARRAY_ELEMENTS(a)-1)

#endif // _VWVDM_H_