/[gxemul]/upstream/0.3.8/src/devices/dev_ssc.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.8/src/devices/dev_ssc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 23 - (show annotations)
Mon Oct 8 16:19:43 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6752 byte(s)
0.3.8
1 /*
2 * Copyright (C) 2003-2006 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * $Id: dev_ssc.c,v 1.26 2006/01/01 13:17:17 debug Exp $
29 *
30 * Serial controller on DECsystem 5400 and 5800.
31 * Known as System Support Chip on VAX 3600 (KA650).
32 *
33 * Described around page 80 in the kn210tm1.pdf.
34 */
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "console.h"
41 #include "cpu.h"
42 #include "devices.h"
43 #include "machine.h"
44 #include "memory.h"
45 #include "misc.h"
46
47
48 #define RX_INT_ENABLE 0x40
49 #define RX_AVAIL 0x80
50 #define TX_INT_ENABLE 0x40
51 #define TX_READY 0x80
52
53
54 /*
55 * _TXRX is for debugging putchar/getchar. The other
56 * one is more general.
57 */
58 /* #define SSC_DEBUG_TXRX */
59 #define SSC_DEBUG
60
61 struct ssc_data {
62 int irq_nr;
63 int console_handle;
64 int use_fb;
65
66 int rx_ctl;
67 int tx_ctl;
68
69 uint32_t *csrp;
70 };
71
72
73 /*
74 * dev_ssc_tick():
75 */
76 void dev_ssc_tick(struct cpu *cpu, void *extra)
77 {
78 struct ssc_data *d = extra;
79
80 d->tx_ctl |= TX_READY; /* transmitter always ready */
81
82 d->rx_ctl &= ~RX_AVAIL;
83 if (console_charavail(d->console_handle))
84 d->rx_ctl |= RX_AVAIL;
85
86 /* rx interrupts enabled, and char avail? */
87 if (d->rx_ctl & RX_INT_ENABLE && d->rx_ctl & RX_AVAIL) {
88 /* TODO: This is for 5800 only! */
89
90 if (d->csrp != NULL) {
91 unsigned char txvector = 0xf8;
92 (*d->csrp) |= 0x10000000;
93 cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector,
94 1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL);
95 cpu_interrupt(cpu, 2);
96 }
97 }
98
99 /* tx interrupts enabled? */
100 if (d->tx_ctl & TX_INT_ENABLE) {
101 /* TODO: This is for 5800 only! */
102
103 if (d->csrp != NULL) {
104 unsigned char txvector = 0xfc;
105 (*d->csrp) |= 0x10000000;
106 cpu->memory_rw(cpu, cpu->mem, 0x40000050, &txvector,
107 1, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL);
108 cpu_interrupt(cpu, 2);
109 }
110 }
111 }
112
113
114 /*
115 * dev_ssc_access():
116 */
117 DEVICE_ACCESS(ssc)
118 {
119 uint64_t idata = 0, odata = 0;
120 struct ssc_data *d = extra;
121
122 if (writeflag == MEM_WRITE)
123 idata = memory_readmax64(cpu, data, len);
124
125 dev_ssc_tick(cpu, extra);
126
127 switch (relative_addr) {
128 case 0x0080: /* receive status */
129 if (writeflag==MEM_READ) {
130 odata = d->rx_ctl;
131 #ifdef SSC_DEBUG_TXRX
132 debug("[ ssc: read from 0x%08lx: 0x%02x ]\n",
133 (long)relative_addr, (int)odata);
134 #endif
135 } else {
136 d->rx_ctl = idata;
137
138 /* TODO: This only works for 5800 */
139 if (d->csrp != NULL) {
140 (*d->csrp) &= ~0x10000000;
141 cpu_interrupt_ack(cpu, 2);
142 }
143 #ifdef SSC_DEBUG_TXRX
144 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
145 (long)relative_addr, (int)idata);
146 #endif
147 }
148
149 break;
150 case 0x0084: /* receive data */
151 if (writeflag==MEM_READ) {
152 #ifdef SSC_DEBUG_TXRX
153 debug("[ ssc: read from 0x%08lx ]\n",
154 (long)relative_addr);
155 #endif
156 if (console_charavail(d->console_handle))
157 odata = console_readchar(d->console_handle);
158 } else {
159 #ifdef SSC_DEBUG_TXRX
160 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
161 (long)relative_addr, (int)idata);
162 #endif
163 }
164
165 break;
166 case 0x0088: /* transmit status */
167 if (writeflag==MEM_READ) {
168 odata = d->tx_ctl;
169 #ifdef SSC_DEBUG_TXRX
170 debug("[ ssc: read from 0x%08lx: 0x%04x ]\n",
171 (long)relative_addr, (int)odata);
172 #endif
173 } else {
174 d->tx_ctl = idata;
175
176 /* TODO: This only works for 5800 */
177 if (d->csrp != NULL) {
178 (*d->csrp) &= ~0x10000000;
179 cpu_interrupt_ack(cpu, 2);
180 }
181 #ifdef SSC_DEBUG_TXRX
182 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
183 (long)relative_addr, (int)idata);
184 #endif
185 }
186
187 break;
188 case 0x008c: /* transmit data */
189 if (writeflag==MEM_READ) {
190 debug("[ ssc: read from 0x%08lx ]\n",
191 (long)relative_addr);
192 } else {
193 /* debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
194 (long)relative_addr, (int)idata); */
195 console_putchar(d->console_handle, idata);
196 }
197
198 break;
199 case 0x0100:
200 if (writeflag==MEM_READ) {
201 odata = 128;
202 #ifdef SSC_DEBUG_TXRX
203 debug("[ ssc: read from 0x%08lx: 0x%08lx ]\n",
204 (long)relative_addr, (long)odata);
205 #endif
206 } else {
207 #ifdef SSC_DEBUG_TXRX
208 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
209 (long)relative_addr, idata);
210 #endif
211 }
212
213 break;
214 case 0x0108:
215 if (writeflag==MEM_READ) {
216 debug("[ ssc: read from 0x%08lx ]\n",
217 (long)relative_addr);
218 } else {
219 #ifdef SSC_DEBUG
220 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
221 (long)relative_addr, (int)idata);
222 #endif
223 }
224
225 break;
226 default:
227 if (writeflag==MEM_READ) {
228 debug("[ ssc: read from 0x%08lx ]\n",
229 (long)relative_addr);
230 } else {
231 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
232 (long)relative_addr, (int)idata);
233 }
234 }
235
236 dev_ssc_tick(cpu, extra);
237
238 if (writeflag == MEM_READ)
239 memory_writemax64(cpu, data, len, odata);
240
241 return 1;
242 }
243
244
245 /*
246 * dev_ssc_init():
247 */
248 void dev_ssc_init(struct machine *machine, struct memory *mem,
249 uint64_t baseaddr, int irq_nr, int use_fb, uint32_t *csrp)
250 {
251 struct ssc_data *d;
252
253 d = malloc(sizeof(struct ssc_data));
254 if (d == NULL) {
255 fprintf(stderr, "out of memory\n");
256 exit(1);
257 }
258 memset(d, 0, sizeof(struct ssc_data));
259 d->irq_nr = irq_nr;
260 d->use_fb = use_fb;
261 d->csrp = csrp;
262 d->console_handle = console_start_slave(machine, "SSC", 1);
263
264 memory_device_register(mem, "ssc", baseaddr, DEV_SSC_LENGTH,
265 dev_ssc_access, d, DM_DEFAULT, NULL);
266
267 machine_add_tickfunction(machine, dev_ssc_tick, d, 14);
268 }
269

  ViewVC Help
Powered by ViewVC 1.1.26