forked from b-dmitry1/e86r
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ioports.cpp
159 lines (140 loc) · 2.84 KB
/
ioports.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include "stdafx.h"
#include "cpu.h"
#include "memdescr.h"
#include "interrupts.h"
#include "vga.h"
#include "disk.h"
#include "ioports.h"
#include "pic_pit.h"
#include "cmos.h"
#include "keybmouse.h"
unsigned char ports[1024];
unsigned char portread8(unsigned short port)
{
GP((cr[0] & 1) && (cpl > IOPL), 0);
// VGA goes first to speed up games
if ((port >= 0x3B0) && (port <= 0x3DF))
return vga_portread(port);
// IDE HDD
if (((port >= 0x1F0) && (port <= 0x1F7)) || ((port >= 0x3F0) && (port <= 0x3F7)))
return ide_read(port);
if (port >= 1024)
{
return 0;
}
switch (port)
{
case 0x20:
case 0x21:
case 0xA0:
case 0xA1:
return pic_read(port);
case 0x40:
case 0x41:
case 0x42:
case 0x43:
return pit_read(port);
case 0x61:
case 0x62:
case 0x63:
case 0x64:
case 0x3f8:
case 0x3fd:
case 0x3FA:
case 0x3FE:
return keybmouse_portread(port);
case 0x70:
case 0x71:
return cmos_read(port);
case 0x92:
// A20
return a20 ? 2 : 0;
case 0x201:
// Joystick
return 0xFF;
case 0x2f8:
return 0xFF;
}
return ports[port];
}
unsigned short portread16(unsigned short port)
{
GP((cr[0] & 1) && (cpl > IOPL), 0);
unsigned short res;
res = portread8(port);
res |= portread8(port + 1) << 8u;
return res;
}
unsigned int portread32(unsigned short port)
{
GP((cr[0] & 1) && (cpl > IOPL), 0);
unsigned short res;
res = portread8(port);
res |= portread8(port + 1) << 8u;
res |= portread8(port + 2) << 16u;
res |= portread8(port + 3) << 24u;
return res;
}
void portwrite8(unsigned short port, unsigned char v)
{
GPV((cr[0] & 1) && (cpl > IOPL), 0);
if ((port >= 0x3B0) && (port <= 0x3DF))
{
vga_portwrite(port, v);
return;
}
if (((port >= 0x1F0) && (port <= 0x1F7)) || ((port >= 0x3F0) && (port <= 0x3F7)))
{
ide_write(port, v);
return;
}
if (port >= 1024)
{
return;
}
ports[port] = v;
switch (port)
{
case 0x20:
case 0x21:
case 0xA0:
case 0xA1:
pic_write(port, v);
break;
case 0x40:
case 0x41:
case 0x42:
case 0x43:
pit_write(port, v);
break;
case 0x60:
case 0x3fc:
keybmouse_portwrite(port, v);
break;
case 0x70:
case 0x71:
cmos_write(port, v);
break;
case 0x92:
a20 = (v & 0x02) != 0;
// a20mask = a20 ? 0xFFFFFFFFu : 0xFFFFFu;
break;
case 0xBE:
vmode = v;
break;
}
}
void portwrite16(unsigned short port, unsigned short v)
{
GPV((cr[0] & 1) && (cpl > IOPL), 0);
portwrite8(port, (unsigned char)v);
portwrite8(port + 1, v >> 8u);
}
void portwrite32(unsigned short port, unsigned int v)
{
GPV((cr[0] & 1) && (cpl > IOPL), 0);
portwrite8(port, (unsigned char)v);
portwrite8(port + 1, v >> 8u);
portwrite8(port + 2, v >> 16u);
portwrite8(port + 3, v >> 24u);
}