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