/[gxemul]/upstream/0.3.6.2/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.6.2/src/devices/dev_ssc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 19 - (show annotations)
Mon Oct 8 16:19:16 2007 UTC (16 years, 8 months ago) by dpavlin
File MIME type: text/plain
File size: 6874 byte(s)
0.3.6.2
1 /*
2 * Copyright (C) 2003-2005 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.23 2005/10/26 14:37:04 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 int dev_ssc_access(struct cpu *cpu, struct memory *mem,
118 uint64_t relative_addr, unsigned char *data, size_t len,
119 int writeflag, void *extra)
120 {
121 uint64_t idata = 0, odata = 0;
122 struct ssc_data *d = extra;
123
124 if (writeflag == MEM_WRITE)
125 idata = memory_readmax64(cpu, data, len);
126
127 dev_ssc_tick(cpu, extra);
128
129 switch (relative_addr) {
130 case 0x0080: /* receive status */
131 if (writeflag==MEM_READ) {
132 odata = d->rx_ctl;
133 #ifdef SSC_DEBUG_TXRX
134 debug("[ ssc: read from 0x%08lx: 0x%02x ]\n",
135 (long)relative_addr, (int)odata);
136 #endif
137 } else {
138 d->rx_ctl = idata;
139
140 /* TODO: This only works for 5800 */
141 if (d->csrp != NULL) {
142 (*d->csrp) &= ~0x10000000;
143 cpu_interrupt_ack(cpu, 2);
144 }
145 #ifdef SSC_DEBUG_TXRX
146 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
147 (long)relative_addr, (int)idata);
148 #endif
149 }
150
151 break;
152 case 0x0084: /* receive data */
153 if (writeflag==MEM_READ) {
154 #ifdef SSC_DEBUG_TXRX
155 debug("[ ssc: read from 0x%08lx ]\n",
156 (long)relative_addr);
157 #endif
158 if (console_charavail(d->console_handle))
159 odata = console_readchar(d->console_handle);
160 } else {
161 #ifdef SSC_DEBUG_TXRX
162 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
163 (long)relative_addr, (int)idata);
164 #endif
165 }
166
167 break;
168 case 0x0088: /* transmit status */
169 if (writeflag==MEM_READ) {
170 odata = d->tx_ctl;
171 #ifdef SSC_DEBUG_TXRX
172 debug("[ ssc: read from 0x%08lx: 0x%04x ]\n",
173 (long)relative_addr, (int)odata);
174 #endif
175 } else {
176 d->tx_ctl = idata;
177
178 /* TODO: This only works for 5800 */
179 if (d->csrp != NULL) {
180 (*d->csrp) &= ~0x10000000;
181 cpu_interrupt_ack(cpu, 2);
182 }
183 #ifdef SSC_DEBUG_TXRX
184 debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
185 (long)relative_addr, (int)idata);
186 #endif
187 }
188
189 break;
190 case 0x008c: /* transmit data */
191 if (writeflag==MEM_READ) {
192 debug("[ ssc: read from 0x%08lx ]\n",
193 (long)relative_addr);
194 } else {
195 /* debug("[ ssc: write to 0x%08lx: 0x%02x ]\n",
196 (long)relative_addr, (int)idata); */
197 console_putchar(d->console_handle, idata);
198 }
199
200 break;
201 case 0x0100:
202 if (writeflag==MEM_READ) {
203 odata = 128;
204 #ifdef SSC_DEBUG_TXRX
205 debug("[ ssc: read from 0x%08lx: 0x%08lx ]\n",
206 (long)relative_addr, (long)odata);
207 #endif
208 } else {
209 #ifdef SSC_DEBUG_TXRX
210 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
211 (long)relative_addr, idata);
212 #endif
213 }
214
215 break;
216 case 0x0108:
217 if (writeflag==MEM_READ) {
218 debug("[ ssc: read from 0x%08lx ]\n",
219 (long)relative_addr);
220 } else {
221 #ifdef SSC_DEBUG
222 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
223 (long)relative_addr, (int)idata);
224 #endif
225 }
226
227 break;
228 default:
229 if (writeflag==MEM_READ) {
230 debug("[ ssc: read from 0x%08lx ]\n",
231 (long)relative_addr);
232 } else {
233 debug("[ ssc: write to 0x%08lx: 0x%08x ]\n",
234 (long)relative_addr, (int)idata);
235 }
236 }
237
238 dev_ssc_tick(cpu, extra);
239
240 if (writeflag == MEM_READ)
241 memory_writemax64(cpu, data, len, odata);
242
243 return 1;
244 }
245
246
247 /*
248 * dev_ssc_init():
249 */
250 void dev_ssc_init(struct machine *machine, struct memory *mem,
251 uint64_t baseaddr, int irq_nr, int use_fb, uint32_t *csrp)
252 {
253 struct ssc_data *d;
254
255 d = malloc(sizeof(struct ssc_data));
256 if (d == NULL) {
257 fprintf(stderr, "out of memory\n");
258 exit(1);
259 }
260 memset(d, 0, sizeof(struct ssc_data));
261 d->irq_nr = irq_nr;
262 d->use_fb = use_fb;
263 d->csrp = csrp;
264 d->console_handle = console_start_slave(machine, "SSC");
265
266 memory_device_register(mem, "ssc", baseaddr, DEV_SSC_LENGTH,
267 dev_ssc_access, d, MEM_DEFAULT, NULL);
268
269 machine_add_tickfunction(machine, dev_ssc_tick, d, 14);
270 }
271

  ViewVC Help
Powered by ViewVC 1.1.26