1 /*
2  * Z80SIM  -  a Z80-CPU simulator
3  *
4  * Copyright (C) 1987-2021 by Udo Munk
5  *
6  * This modul of the simulator contains a simple terminal I/O
7  * simulation as an example.
8  *
9  * History:
10  * 28-SEP-87 Development on TARGON/35 with AT&T Unix System V.3
11  * 11-JAN-89 Release 1.1
12  * 08-FEB-89 Release 1.2
13  * 13-MAR-89 Release 1.3
14  * 09-FEB-90 Release 1.4  Ported to TARGON/31 M10/30
15  * 20-DEC-90 Release 1.5  Ported to COHERENT 3.0
16  * 10-JUN-92 Release 1.6  long casting problem solved with COHERENT 3.2
17  *			  and some optimisation
18  * 25-JUN-92 Release 1.7  comments in english and ported to COHERENT 4.0
19  * 02-OCT-06 Release 1.8  modified to compile on modern POSIX OS's
20  * 18-NOV-06 Release 1.9  modified to work with CP/M sources
21  * 08-DEC-06 Release 1.10 modified MMU for working with CP/NET
22  * 17-DEC-06 Release 1.11 TCP/IP sockets for CP/NET
23  * 25-DEC-06 Release 1.12 CPU speed option
24  * 19-FEB-07 Release 1.13 various improvements
25  * 06-OCT-07 Release 1.14 bug fixes and improvements
26  * 06-AUG-08 Release 1.15 many improvements and Windows support via Cygwin
27  * 25-AUG-08 Release 1.16 console status I/O loop detection and line discipline
28  * 20-OCT-08 Release 1.17 frontpanel integrated and Altair/IMSAI emulations
29  * 24-JAN-14 Release 1.18 bug fixes and improvements
30  * 02-MAR-14 Release 1.19 source cleanup and improvements
31  * 14-MAR-14 Release 1.20 added Tarbell SD FDC and printer port to Altair
32  * 29-MAR-14 Release 1.21 many improvements
33  * 29-MAY-14 Release 1.22 improved networking and bugfixes
34  * 04-JUN-14 Release 1.23 added 8080 emulation
35  * 06-SEP-14 Release 1.24 bugfixes and improvements
36  * 18-FEB-15 Release 1.25 bugfixes, improvements, added Cromemco Z-1
37  * 18-APR-15 Release 1.26 bugfixes and improvements
38  * 18-JAN-16 Release 1.27 bugfixes and improvements
39  * 05-MAY-16 Release 1.28 improved usability
40  * 20-NOV-16 Release 1.29 bugfixes and improvements
41  * 15-DEC-16 Release 1.30 improved memory management, machine cycle correct CPUs
42  * 28-DEC-16 Release 1.31 improved memory management, reimplemented MMUs
43  * 12-JAN-17 Release 1.32 improved configurations, front panel, added IMSAI VIO
44  * 07-FEB-17 Release 1.33 bugfixes, improvements, better front panels
45  * 16-MAR-17 Release 1.34 improvements, added ProcTec VDM-1
46  * 03-AUG-17 Release 1.35 added UNIX sockets, bugfixes, improvements
47  * 21-DEC-17 Release 1.36 bugfixes and improvements
48  * 06-JAN-21 Release 1.37 bugfixes and improvements
49  */
50 
51 /*
52  *	Sample I/O-handler
53  *
54  *	Port 1 input:	reads the next byte from stdin
55  *	Port 1 output:	writes the byte to stdout
56  *
57  *	All the other ports are connected to an I/O-trap handler,
58  *	I/O to this ports stops the simulation with an I/O error.
59  */
60 
61 #include <stdio.h>
62 #include "sim.h"
63 #include "simglb.h"
64 
65 /*
66  *	Forward declarations of the I/O functions
67  *	for all port addresses.
68  */
69 static BYTE io_trap_in(void);
70 static void io_trap_out(BYTE);
71 static BYTE p001_in(void);
72 static void p001_out(BYTE);
73 
74 /*
75  *	This array contains function pointers for every input
76  *	I/O port (0 - 255), to do the required I/O.
77  */
78 static BYTE (*port_in[256]) (void) = {
79 	 io_trap_in,		/* port 0 */
80 	 p001_in		/* port 1 */
81 };
82 
83 /*
84  *	This array contains function pointers for every output
85  *	I/O port (0 - 255), to do the required I/O.
86  */
87 static void (*port_out[256]) (BYTE) = {
88 	io_trap_out,		/* port 0 */
89 	p001_out		/* port 1 */
90 };
91 
92 /*
93  *	This function is to initiate the I/O devices.
94  *	It will be called from the CPU simulation before
95  *	any operation with the CPU is possible.
96  *
97  *	In this sample I/O simulation we initialise all
98  *	unused port with an error trap handler, so that
99  *	simulation stops at I/O on the unused ports.
100  *
101  *	See the I/O simulation of of the other systems
102  *	for more complex examples.
103  */
init_io(void)104 void init_io(void)
105 {
106 	register int i;
107 
108 	for (i = 2; i <= 255; i++) {
109 		port_in[i] = io_trap_in;
110 		port_out[i] = io_trap_out;
111 	}
112 }
113 
114 /*
115  *	This function is to stop the I/O devices. It is
116  *	called from the CPU simulation on exit.
117  *
118  *	Nothing to do here, see the I/O simulation
119  *	of CP/M for a more complex example.
120  */
exit_io(void)121 void exit_io(void)
122 {
123 }
124 
125 /*
126  *	This is the main handler for all IN op-codes,
127  *	called by the simulator. It calls the input
128  *	function for port addr.
129  */
io_in(BYTE addrl,BYTE addrh)130 BYTE io_in(BYTE addrl, BYTE addrh)
131 {
132 	addrh = addrh;	/* to avoid compiler warning */
133 	io_port = addrl;
134 	io_data = (*port_in[addrl]) ();
135 	return(io_data);
136 }
137 
138 /*
139  *	This is the main handler for all OUT op-codes,
140  *	called by the simulator. It calls the output
141  *	function for port addr.
142  */
io_out(BYTE addrl,BYTE addrh,BYTE data)143 void io_out(BYTE addrl, BYTE addrh, BYTE data)
144 {
145 	addrh = addrh;	/* to avoid compiler warning */
146 	io_port = addrl;
147 	io_data = data;
148 	(*port_out[addrl]) (data);
149 }
150 
151 /*
152  *	I/O input trap function
153  *	This function should be added into all unused
154  *	entries of the input port array. It stops the
155  *	emulation with an I/O error.
156  */
io_trap_in(void)157 static BYTE io_trap_in(void)
158 {
159 	if (i_flag) {
160 		cpu_error = IOTRAPIN;
161 		cpu_state = STOPPED;
162 	}
163 	return((BYTE) 0xff);
164 }
165 
166 /*
167  *	I/O trap function
168  *	This function should be added into all unused
169  *	entries of the output port array. It stops the
170  *	emulation with an I/O error.
171  */
io_trap_out(BYTE data)172 static void io_trap_out(BYTE data)
173 {
174 	data++; /* to avoid compiler warning */
175 
176 	if (i_flag) {
177 		cpu_error = IOTRAPOUT;
178 		cpu_state = STOPPED;
179 	}
180 }
181 
182 /*
183  *	I/O function port 1 read:
184  *	Read next byte from stdin.
185  */
p001_in(void)186 static BYTE p001_in(void)
187 {
188 	return((BYTE) getchar());
189 }
190 
191 /*
192  *	I/O function port 1 write:
193  *	Write byte to stdout and flush the output.
194  */
p001_out(BYTE data)195 static void p001_out(BYTE data)
196 {
197 	putchar((int) data);
198 	fflush(stdout);
199 }
200