-
Notifications
You must be signed in to change notification settings - Fork 2
/
cpu8086.h
251 lines (223 loc) · 7.04 KB
/
cpu8086.h
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#if 0
File name: cpu8086.h
x86 Emulating Debugger (EDB)
Copyright (C) 1991-1993 Serge Pachkovsky
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
If you need to contact me, feel free to write to ps@oci.unizh.ch
or to Serge Pachkovsky, Erligatterweg 61, Zuerich CH 8038, Switzerland
#endif
/*
* Modifications history
*
* 03 Dec 91 - Added CPU_type variable and corresponding enum
*/
/*
#define FAST_INSTRUCTION_FETCH
*/
/*
* Implementation-dependent definitions & types
*/
typedef unsigned short WORD ; /* Should contain exactly 16 bits */
typedef signed short SWORD ; /* Should contain exactly 16 bits */
typedef unsigned long DWORD ; /* Should contain at least 32 bits */
typedef signed long SDWORD ; /* Should contain at least 32 bits */
typedef unsigned char BYTE ; /* Should contain exactly 8 bits */
typedef signed char SBYTE ; /* Should contain exactly 8 bits */
typedef unsigned long ADDR20 ; /* Should contain at least 20 bits */
/*
* LO_BYTE(x) gets address of least significant byte nibble of word at x
* HI_BYTE(x) gets address of most significant byte nibble of word at x
* Current definition is Ok on Intel processors and PDP-11
*/
BYTE *LO_BYTE(WORD*) ;
BYTE *HI_BYTE(WORD*) ;
WORD MK_WORD(BYTE,BYTE) ;
#define LO_BYTE(x) ((BYTE*)(x)+0)
#define HI_BYTE(x) ((BYTE*)(x)+1)
#define MK_WORD(lo,hi) (((WORD)(hi)<<8)|(lo))
/*
* CBW(x) performs sign extend conversion of BYTE to WORD
*/
WORD CBW(BYTE) ;
#define CBW(x) ((WORD)(SWORD)(SBYTE)x)
/*
* FASTCALL should be set to function type modifier which
* provides fastest call sequence (such as pascal in TC)
*/
#ifdef __TURBOC__
#if __TURBOC__ >= 0x0400
#define FASTCALL _fastcall
#else
#define FASTCALL pascal
#endif
#define LIBSYM _Cdecl
#else
#define FASTCALL
#define LIBSYM
#endif
/*
* FAR is the pointer type modifier which enables access to
* all system memory on target macine.
*/
#define FAR far
/*
* End of implementation-dependent definitions & types
*/
/*
* Bits in FLAGS register
*/
#define FL_OF 0x0800u /* Overflow */
#define FL_DF 0x0400u /* Direction */
#define FL_IF 0x0200u /* Interrupt */
#define FL_TF 0x0100u /* Debug trap */
#define FL_SF 0x0080u /* Sign */
#define FL_ZF 0x0040u /* Zero */
#define FL_AF 0x0010u /* Auxillary carry */
#define FL_PF 0x0004u /* Parity */
#define FL_CF 0x0001u /* Carry */
#define FL_RESET_86 0xF002u /* Bits always set */
#define FL_SET_86 0xFFD7u /* Bits always zero */
/* 286 extensions */
#define FL_IOPL 0x3000u /* IOPL */
#define FL_IOPL_SHIFT 12
#define FL_NT 0x4000u /* Nested task */
#define FL_RESET_286 0x0002u /* Bits always set */
#define FL_SET_286 0x0FD7u /* Bits always zero */
/*
* Bits in MSW register
*/
#define MSW_PE 0x0001u /* Protected mode */
#define MSW_MP 0x0002u /* Monitor math */
#define MSW_EM 0x0004u /* Emulate math */
#define MSW_TS 0x0008u /* Task switched */
#define MSW_RESET 0xFFF0u /* Bits always set */
#define MSW_SET 0xFFFFu /* Bits always zero */
/*
* 286 protected mode additional types
*/
typedef struct {
DWORD base ;
WORD selector ;
WORD limit ;
WORD flags ;
BYTE rights ;
} DESC ; /* Descriptor cache */
/*
* Bits in the descriptor cache flags word
*/
#define ADR_MASK 0x00FFFFFFul
#define DSC_VALID 0x0001u
#define DSC_READABLE 0x0002u
#define DSC_WRITEABLE 0x0004u
#define DSC_EXPANDDOWN 0x0008u
/*
* General-purpose 16-bit registers
*/
extern WORD ax, bx, cx, dx, si, di, bp, sp ;
/*
* 286 extension registers
*/
extern WORD msw ;
/*
* 286 special control registers
*/
extern DESC gdt, idt, ldt, tr ;
/*
* 286 segment registers (currently inactive)
*/
/*extern DESC cs, ds, ss, es ;*/
/*
* Definitions of 8-bit half-registers
*/
#define al (*LO_BYTE(&ax))
#define ah (*HI_BYTE(&ax))
#define bl (*LO_BYTE(&bx))
#define bh (*HI_BYTE(&bx))
#define cl (*LO_BYTE(&cx))
#define ch (*HI_BYTE(&cx))
#define dl (*LO_BYTE(&dx))
#define dh (*HI_BYTE(&dx))
/*
* Special & segment registers
*/
extern WORD ip, flags ;
extern WORD cs, ds, es, ss ;
/*
* Memory adressing.
* All CPU memory requests goes throu following functions.
* They should ALWAYS return to caller, instead of any
* breakpoints set on memory access.
*/
BYTE FASTCALL fetch_byte( WORD seg, WORD off ) ;
WORD FASTCALL fetch_word( WORD seg, WORD off ) ;
void FASTCALL store_word( WORD seg, WORD off, WORD x ) ;
void FASTCALL store_byte( WORD seg, WORD off, BYTE x ) ;
WORD FASTCALL word_IN( WORD ) ;
BYTE FASTCALL byte_IN( WORD ) ;
void FASTCALL word_OUT( WORD, WORD ) ;
void FASTCALL byte_OUT( WORD, BYTE ) ;
/*
* Interrupt handling.
* interrupt_check should return interrupt number or 0xFFFF if
* no interrupt request pending. It should NOT indicate maskable
* interrupts if bit FL_IF in flags reset to zero.
*/
WORD interrupt_check( void ) ;
/*
* Error handling.
* CPU_error will be called by decode_instruction any time then
* illegal instruction encoding is encountered or emulator
* internal error detected. Instruction exceptions (such as division
* by zero error) does NOT goes here.
* instruction_cs:instruction_ip will contain address of offending
* instruction. (cs:ip can point anythere)
* CPU_error should NOT return to it's caller.
*/
void FASTCALL CPU_error( char *message ) ;
extern WORD instruction_cs ;
extern WORD instruction_ip ;
/*
* Emulator entry point.
*/
void decode_instruction( void ) ;
/*
* Initialization entry point.
*/
int init_CPU_parameters( void ) ;
extern char halt_condition ;
extern char resume_flag ;
enum CPU_types { CPU_8086, CPU_186, CPU_286, CPU_COUNT } ;
extern char CPU_type ;
extern WORD FL_SET ;
extern WORD FL_RESET ;
/*
* Prefetch queue support
*/
#ifndef FAST_INSTRUCTION_FETCH
#define MAX_PREFETCH 40
#define MIN_PREFETCH 4
extern WORD prefetch_bytes ;
extern void (*restart_prefetch_fun)( void ) ;
extern void (*backspace_prefetch_fun)( void ) ;
void restart_prefetch( void ) ;
#define restart_prefetch() (*restart_prefetch_fun)()
#define backspace_prefetch() (*backspace_prefetch_fun)()
extern WORD prefetch_bytes ;
extern WORD prefetch_used ;
extern BYTE *prefetch_head ;
extern BYTE prefetch_queue[ MAX_PREFETCH + 1 ] ;
#define prefetch_top (prefetch_queue+MAX_PREFETCH)
#else
#define restart_prefetch()
#define backspace_prefetch()
#endif