-
Notifications
You must be signed in to change notification settings - Fork 1
/
handler.cpp
130 lines (105 loc) · 2.06 KB
/
handler.cpp
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
/** XMS Handler */
#include <dos.h>
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct _ReqHdr {
BYTE ReqLen;
BYTE Unit;
BYTE Command;
WORD Status;
BYTE Reserved[8];
BYTE Units;
DWORD Address;
DWORD pCmdLine;
} ReqHdr;
typedef struct _Handle {
BYTE Flags;
BYTE cLock;
DWORD Base; /** Linear address of block */
DWORD Length; /** Length in byte */
} XMSHandle;
typedef union _Offset {
struct {
WORD Offset;
WORD Segment;
} segoff;
unsigned long address;
} Offset;
typedef struct _MoveExtended {
DWORD bCount;
WORD SourceHandle;
Offset SourceOffset;
WORD DestHandle;
Offset DestOffset;
} MoveExtended;
/** global request */
ReqHdr far *pReqHdr = 0;
void interrupt (*old_2f)();
/** Strategy => Called by MS-DOS when even the driver is accessed.
ARGS: ES:BX = Address of Request Header
RETS: Nothing
REGS: Preserved
*/
extern "C" void Strategy()
{
asm {
mov word ptr cs:[pReqHdr], bx
mov word ptr cs:[pReqHdr+2], es
}
}
int InitDriver(); /** prototype of InitDriver */
/** Interrupt => Called by MS-ODS after strategy routine
ARGS: None
RETS: Return code in Request Header's Status Field
REGS: Preserved
*/
extern "C" void interrupt XMSInterrupt()
{
BYTE cmd = pReqHdr->Command;
WORD status = 0;
if (cmd == 0x00)
status = InitDriver();
status = status | 0x0100;
pReqHdr->Status = status;
}
extern int (far *xms_control)();
#ifdef __cplusplus
#define __CPPARGS ...
#else
#define __CPPARGS
#endif
void interrupt Int2F(__CPPARGS)
{
enable();
if (_AH == 0x43) { // we are interested in this handler...
if (_AL == 0x00) { // return 0x80
_AL = 0x80;
return;
}
if (_AL == 0x10) {
asm {
push cs
pop es
mov bx, offset xms_control
}
return;
}
}
disable();
asm {
jmp dword ptr cs:[old_2f]
}
}
/** Driver Initialization */
int InitDriver()
{
_AX = 0x4300;
geninterrupt(0x2f);
if (_AL == 0x80) {
}
old_2f = (void (interrupt *)())_dos_getvect(0x2f);
_dos_setvect(0x2f, Int2F);
end:
return 0;
}