1 /*
2  * Z80SIM  -  a Z80-CPU simulator
3  *
4  * Copyright (C) 1987-2021 by Udo Munk
5  *
6  * History:
7  * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
8  * 11-JAN-89 Release 1.1
9  * 08-FEB-89 Release 1.2
10  * 13-MAR-89 Release 1.3
11  * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
12  * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
13  * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
14  *			  and some optimisation
15  * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
16  * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
17  * 18-NOV-06 Release 1.9  modified to work with CP/M sources
18  * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
19  * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
20  * 25-DEC-06 Release 1.12 CPU speed option
21  * 19-FEB-07 Release 1.13 various improvements
22  * 06-OCT-07 Release 1.14 bug fixes and improvements
23  * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
24  * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
25  * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
26  * 24-JAN-14 Release 1.18 bug fixes and improvements
27  * 02-MAR-14 Release 1.19 source cleanup and improvements
28  * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
29  * 29-MAR-14 Release 1.21 many improvements
30  * 29-MAY-14 Release 1.22 improved networking and bugfixes
31  * 04-JUN-14 Release 1.23 added 8080 emulation
32  * 06-SEP-14 Release 1.24 bugfixes and improvements
33  * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
34  * 18-APR-15 Release 1.26 bugfixes and improvements
35  * 18-JAN-16 Release 1.27 bugfixes and improvements
36  * 05-MAY-16 Release 1.28 improved usability
37  * 20-NOV-16 Release 1.29 bugfixes and improvements
38  * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
39  * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
40  * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
41  * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
42  * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
43  * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
44  * 21-DEC-17 Release 1.36 bugfixes and improvements
45  * 06-JAN-21 Release 1.37 bugfixes and improvements
46  */
47 
48 /*
49  *	This module contains the global variables other than memory management
50  */
51 
52 #include <stddef.h>
53 #include "sim.h"
54 
55 #define MAXCHAN 5	/* max number of channels for I/O busy detect */
56 
57 /*
58  *	Type of CPU, either Z80 or 8080
59  */
60 int cpu = DEFAULT_CPU;
61 
62 /*
63  *	CPU Registers
64  */
65 BYTE A,B,C,D,E,H,L;		/* primary registers */
66 int  F;				/* normally 8-Bit, but int is faster */
67 WORD IX, IY;			/* Z80 index registers */
68 BYTE A_,B_,C_,D_,E_,H_,L_;	/* Z80 alternate registers */
69 int  F_;
70 WORD PC;			/* programm counter */
71 WORD SP;			/* stackpointer */
72 BYTE I;				/* Z80 interrupt register */
73 BYTE IFF;			/* interrupt flags */
74 long R;				/* Z80 refresh register */
75 				/* is normally a 8 bit register */
76 				/* the larger bits are used to measure the */
77 				/* clock frequency */
78 
79 #ifdef BUS_8080
80 BYTE cpu_bus;			/* CPU bus status, for frontpanels */
81 int m1_step;			/* flag for waiting at M1 in single step */
82 #endif
83 
84 BYTE io_port;			/* I/O port used */
85 BYTE io_data;			/* data on I/O port */
86 int busy_loop_cnt[MAXCHAN];	/* counters for I/O busy loop detection */
87 
88 BYTE cpu_state;			/* state of CPU emulation */
89 int cpu_error;			/* error status of CPU emulation */
90 int int_mode;			/* CPU interrupt mode (IM 0, IM 1, IM 2) */
91 int int_nmi;			/* non maskable interrupt request */
92 int int_int;			/* interrupt request */
93 int int_data = -1;		/* data from interrupting device on data bus */
94 int int_protection;		/* to delay interrupts after EI */
95 BYTE bus_request;		/* request address/data bus from CPU */
96 int tmax;			/* max t-states to execute in 10ms */
97 int cpu_needed;			/* don't adjust CPU freq if needed */
98 
99 /*
100  *	Variables for history memory
101  */
102 #ifdef HISIZE
103 struct history his[HISIZE];	/* memory to hold trace informations */
104 int h_next;			/* index into trace memory */
105 int h_flag;			/* flag for trace memory overrun */
106 #endif
107 
108 /*
109  *	Variables for breakpoint memory
110  */
111 #ifdef SBSIZE
112 struct softbreak soft[SBSIZE];	/* memory to hold breakpoint informations */
113 int sb_next;			/* index into breakpoint memory */
114 #endif
115 
116 /*
117  *	Variables for runtime measurement
118  */
119 long t_states;			/* number of counted T states */
120 int t_flag;			/* flag, 1 = on, 0 = off */
121 WORD t_start = 65535;		/* start address for measurement */
122 WORD t_end = 65535;		/* end address for measurement */
123 
124 /*
125  *	Variables for frontpanel emulation
126  */
127 #ifdef FRONTPANEL
128 unsigned long long fp_clock;	/* simulation clock */
129 float fp_fps = 30.0;		/* frame rate, default 30 usually works */
130 WORD fp_led_address;		/* lights for address bus */
131 BYTE fp_led_data;		/* lights for data bus */
132 WORD address_switch;		/* address and programmed input switches */
133 BYTE fp_led_output = 0xff;	/* IMSAI/Cromemco programmed output, inverted */
134 #endif
135 
136 /*
137  *	Flags to control operation of simulation
138  */
139 int s_flag;			/* flag for -s option */
140 int l_flag;			/* flag for -l option */
141 int m_flag = -1;		/* flag for -m option */
142 int x_flag;			/* flag for -x option */
143 int i_flag;			/* flag for -i option */
144 int f_flag;			/* flag for -f option */
145 int u_flag;			/* flag for -u option */
146 int r_flag;			/* flag for -r option */
147 
148 /*
149  *	Variables for configuration and disk images
150  */
151 char xfn[MAX_LFN];		/* buffer for filename (option -x) */
152 char *diskdir = NULL;		/* path for disk images (option -d) */
153 char diskd[MAX_LFN];		/* disk image directory in use */
154 char confdir[MAX_LFN];		/* path for configuration files */
155 
156 /*
157  *	Precompiled table to get parity as fast as possible
158  */
159 int parity[256] = {
160 		0 /* 00000000 */, 1 /* 00000001	*/, 1 /* 00000010 */,
161 		0 /* 00000011 */, 1 /* 00000100	*/, 0 /* 00000101 */,
162 		0 /* 00000110 */, 1 /* 00000111	*/, 1 /* 00001000 */,
163 		0 /* 00001001 */, 0 /* 00001010	*/, 1 /* 00001011 */,
164 		0 /* 00001100 */, 1 /* 00001101	*/, 1 /* 00001110 */,
165 		0 /* 00001111 */, 1 /* 00010000	*/, 0 /* 00010001 */,
166 		0 /* 00010010 */, 1 /* 00010011	*/, 0 /* 00010100 */,
167 		1 /* 00010101 */, 1 /* 00010110	*/, 0 /* 00010111 */,
168 		0 /* 00011000 */, 1 /* 00011001	*/, 1 /* 00011010 */,
169 		0 /* 00011011 */, 1 /* 00011100	*/, 0 /* 00011101 */,
170 		0 /* 00011110 */, 1 /* 00011111	*/, 1 /* 00100000 */,
171 		0 /* 00100001 */, 0 /* 00100010	*/, 1 /* 00100011 */,
172 		0 /* 00100100 */, 1 /* 00100101	*/, 1 /* 00100110 */,
173 		0 /* 00100111 */, 0 /* 00101000	*/, 1 /* 00101001 */,
174 		1 /* 00101010 */, 0 /* 00101011	*/, 1 /* 00101100 */,
175 		0 /* 00101101 */, 0 /* 00101110	*/, 1 /* 00101111 */,
176 		0 /* 00110000 */, 1 /* 00110001	*/, 1 /* 00110010 */,
177 		0 /* 00110011 */, 1 /* 00110100	*/, 0 /* 00110101 */,
178 		0 /* 00110110 */, 1 /* 00110111	*/, 1 /* 00111000 */,
179 		0 /* 00111001 */, 0 /* 00111010	*/, 1 /* 00111011 */,
180 		0 /* 00111100 */, 1 /* 00111101	*/, 1 /* 00111110 */,
181 		0 /* 00111111 */, 1 /* 01000000	*/, 0 /* 01000001 */,
182 		0 /* 01000010 */, 1 /* 01000011	*/, 0 /* 01000100 */,
183 		1 /* 01000101 */, 1 /* 01000110	*/, 0 /* 01000111 */,
184 		0 /* 01001000 */, 1 /* 01001001	*/, 1 /* 01001010 */,
185 		0 /* 01001011 */, 1 /* 01001100	*/, 0 /* 01001101 */,
186 		0 /* 01001110 */, 1 /* 01001111	*/, 0 /* 01010000 */,
187 		1 /* 01010001 */, 1 /* 01010010	*/, 0 /* 01010011 */,
188 		1 /* 01010100 */, 0 /* 01010101	*/, 0 /* 01010110 */,
189 		1 /* 01010111 */, 1 /* 01011000	*/, 0 /* 01011001 */,
190 		0 /* 01011010 */, 1 /* 01011011	*/, 0 /* 01011100 */,
191 		1 /* 01011101 */, 1 /* 01011110	*/, 0 /* 01011111 */,
192 		0 /* 01100000 */, 1 /* 01100001	*/, 1 /* 01100010 */,
193 		0 /* 01100011 */, 1 /* 01100100	*/, 0 /* 01100101 */,
194 		0 /* 01100110 */, 1 /* 01100111	*/, 1 /* 01101000 */,
195 		0 /* 01101001 */, 0 /* 01101010	*/, 1 /* 01101011 */,
196 		0 /* 01101100 */, 1 /* 01101101	*/, 1 /* 01101110 */,
197 		0 /* 01101111 */, 1 /* 01110000	*/, 0 /* 01110001 */,
198 		0 /* 01110010 */, 1 /* 01110011	*/, 0 /* 01110100 */,
199 		1 /* 01110101 */, 1 /* 01110110	*/, 0 /* 01110111 */,
200 		0 /* 01111000 */, 1 /* 01111001	*/, 1 /* 01111010 */,
201 		0 /* 01111011 */, 1 /* 01111100	*/, 0 /* 01111101 */,
202 		0 /* 01111110 */, 1 /* 01111111	*/,
203 		1 /* 10000000 */, 0 /* 10000001	*/, 0 /* 10000010 */,
204 		1 /* 10000011 */, 0 /* 10000100	*/, 1 /* 10000101 */,
205 		1 /* 10000110 */, 0 /* 10000111	*/, 0 /* 10001000 */,
206 		1 /* 10001001 */, 1 /* 10001010	*/, 0 /* 10001011 */,
207 		1 /* 10001100 */, 0 /* 10001101	*/, 0 /* 10001110 */,
208 		1 /* 10001111 */, 0 /* 10010000	*/, 1 /* 10010001 */,
209 		1 /* 10010010 */, 0 /* 10010011	*/, 1 /* 10010100 */,
210 		0 /* 10010101 */, 0 /* 10010110	*/, 1 /* 10010111 */,
211 		1 /* 10011000 */, 0 /* 10011001	*/, 0 /* 10011010 */,
212 		1 /* 10011011 */, 0 /* 10011100	*/, 1 /* 10011101 */,
213 		1 /* 10011110 */, 0 /* 10011111	*/, 0 /* 10100000 */,
214 		1 /* 10100001 */, 1 /* 10100010	*/, 0 /* 10100011 */,
215 		1 /* 10100100 */, 0 /* 10100101	*/, 0 /* 10100110 */,
216 		1 /* 10100111 */, 1 /* 10101000	*/, 0 /* 10101001 */,
217 		0 /* 10101010 */, 1 /* 10101011	*/, 0 /* 10101100 */,
218 		1 /* 10101101 */, 1 /* 10101110	*/, 0 /* 10101111 */,
219 		1 /* 10110000 */, 0 /* 10110001	*/, 0 /* 10110010 */,
220 		1 /* 10110011 */, 0 /* 10110100	*/, 1 /* 10110101 */,
221 		1 /* 10110110 */, 0 /* 10110111	*/, 0 /* 10111000 */,
222 		1 /* 10111001 */, 1 /* 10111010	*/, 0 /* 10111011 */,
223 		1 /* 10111100 */, 0 /* 10111101	*/, 0 /* 10111110 */,
224 		1 /* 10111111 */, 0 /* 11000000	*/, 1 /* 11000001 */,
225 		1 /* 11000010 */, 0 /* 11000011	*/, 1 /* 11000100 */,
226 		0 /* 11000101 */, 0 /* 11000110	*/, 1 /* 11000111 */,
227 		1 /* 11001000 */, 0 /* 11001001	*/, 0 /* 11001010 */,
228 		1 /* 11001011 */, 0 /* 11001100	*/, 1 /* 11001101 */,
229 		1 /* 11001110 */, 0 /* 11001111	*/, 1 /* 11010000 */,
230 		0 /* 11010001 */, 0 /* 11010010	*/, 1 /* 11010011 */,
231 		0 /* 11010100 */, 1 /* 11010101	*/, 1 /* 11010110 */,
232 		0 /* 11010111 */, 0 /* 11011000	*/, 1 /* 11011001 */,
233 		1 /* 11011010 */, 0 /* 11011011	*/, 1 /* 11011100 */,
234 		0 /* 11011101 */, 0 /* 11011110	*/, 1 /* 11011111 */,
235 		1 /* 11100000 */, 0 /* 11100001	*/, 0 /* 11100010 */,
236 		1 /* 11100011 */, 0 /* 11100100	*/, 1 /* 11100101 */,
237 		1 /* 11100110 */, 0 /* 11100111	*/, 0 /* 11101000 */,
238 		1 /* 11101001 */, 1 /* 11101010	*/, 0 /* 11101011 */,
239 		1 /* 11101100 */, 0 /* 11101101	*/, 0 /* 11101110 */,
240 		1 /* 11101111 */, 0 /* 11110000	*/, 1 /* 11110001 */,
241 		1 /* 11110010 */, 0 /* 11110011	*/, 1 /* 11110100 */,
242 		0 /* 11110101 */, 0 /* 11110110	*/, 1 /* 11110111 */,
243 		1 /* 11111000 */, 0 /* 11111001	*/, 0 /* 11111010 */,
244 		1 /* 11111011 */, 0 /* 11111100	*/, 1 /* 11111101 */,
245 		1 /* 11111110 */, 0 /* 11111111	*/
246 };
247