Statistics
| Branch: | Revision:

root / hw / parallel.c @ 5fafdf24

History | View | Annotate | Download (15.8 kB)

1 6508fe59 bellard
/*
2 6508fe59 bellard
 * QEMU Parallel PORT emulation
3 5fafdf24 ths
 *
4 e57a8c0e bellard
 * Copyright (c) 2003-2005 Fabrice Bellard
5 5867c88a ths
 * Copyright (c) 2007 Marko Kohtala
6 5fafdf24 ths
 *
7 6508fe59 bellard
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 6508fe59 bellard
 * of this software and associated documentation files (the "Software"), to deal
9 6508fe59 bellard
 * in the Software without restriction, including without limitation the rights
10 6508fe59 bellard
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 6508fe59 bellard
 * copies of the Software, and to permit persons to whom the Software is
12 6508fe59 bellard
 * furnished to do so, subject to the following conditions:
13 6508fe59 bellard
 *
14 6508fe59 bellard
 * The above copyright notice and this permission notice shall be included in
15 6508fe59 bellard
 * all copies or substantial portions of the Software.
16 6508fe59 bellard
 *
17 6508fe59 bellard
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 6508fe59 bellard
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 6508fe59 bellard
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 6508fe59 bellard
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 6508fe59 bellard
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 6508fe59 bellard
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 6508fe59 bellard
 * THE SOFTWARE.
24 6508fe59 bellard
 */
25 6508fe59 bellard
#include "vl.h"
26 6508fe59 bellard
27 6508fe59 bellard
//#define DEBUG_PARALLEL
28 6508fe59 bellard
29 5867c88a ths
#ifdef DEBUG_PARALLEL
30 5867c88a ths
#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
31 5867c88a ths
#else
32 5867c88a ths
#define pdebug(fmt, arg...) ((void)0)
33 5867c88a ths
#endif
34 5867c88a ths
35 5867c88a ths
#define PARA_REG_DATA 0
36 5867c88a ths
#define PARA_REG_STS 1
37 5867c88a ths
#define PARA_REG_CTR 2
38 5867c88a ths
#define PARA_REG_EPP_ADDR 3
39 5867c88a ths
#define PARA_REG_EPP_DATA 4
40 5867c88a ths
41 6508fe59 bellard
/*
42 6508fe59 bellard
 * These are the definitions for the Printer Status Register
43 6508fe59 bellard
 */
44 6508fe59 bellard
#define PARA_STS_BUSY        0x80        /* Busy complement */
45 6508fe59 bellard
#define PARA_STS_ACK        0x40        /* Acknowledge */
46 6508fe59 bellard
#define PARA_STS_PAPER        0x20        /* Out of paper */
47 6508fe59 bellard
#define PARA_STS_ONLINE        0x10        /* Online */
48 6508fe59 bellard
#define PARA_STS_ERROR        0x08        /* Error complement */
49 5867c88a ths
#define PARA_STS_TMOUT        0x01        /* EPP timeout */
50 6508fe59 bellard
51 6508fe59 bellard
/*
52 6508fe59 bellard
 * These are the definitions for the Printer Control Register
53 6508fe59 bellard
 */
54 5867c88a ths
#define PARA_CTR_DIR        0x20        /* Direction (1=read, 0=write) */
55 6508fe59 bellard
#define PARA_CTR_INTEN        0x10        /* IRQ Enable */
56 6508fe59 bellard
#define PARA_CTR_SELECT        0x08        /* Select In complement */
57 6508fe59 bellard
#define PARA_CTR_INIT        0x04        /* Initialize Printer complement */
58 6508fe59 bellard
#define PARA_CTR_AUTOLF        0x02        /* Auto linefeed complement */
59 6508fe59 bellard
#define PARA_CTR_STROBE        0x01        /* Strobe complement */
60 6508fe59 bellard
61 5867c88a ths
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
62 5867c88a ths
63 6508fe59 bellard
struct ParallelState {
64 5867c88a ths
    uint8_t dataw;
65 5867c88a ths
    uint8_t datar;
66 5867c88a ths
    uint8_t status;
67 6508fe59 bellard
    uint8_t control;
68 d537cf6c pbrook
    qemu_irq irq;
69 6508fe59 bellard
    int irq_pending;
70 6508fe59 bellard
    CharDriverState *chr;
71 e57a8c0e bellard
    int hw_driver;
72 5867c88a ths
    int epp_timeout;
73 5867c88a ths
    uint32_t last_read_offset; /* For debugging */
74 d60532ca ths
    /* Memory-mapped interface */
75 d60532ca ths
    target_phys_addr_t base;
76 d60532ca ths
    int it_shift;
77 6508fe59 bellard
};
78 6508fe59 bellard
79 6508fe59 bellard
static void parallel_update_irq(ParallelState *s)
80 6508fe59 bellard
{
81 6508fe59 bellard
    if (s->irq_pending)
82 d537cf6c pbrook
        qemu_irq_raise(s->irq);
83 6508fe59 bellard
    else
84 d537cf6c pbrook
        qemu_irq_lower(s->irq);
85 6508fe59 bellard
}
86 6508fe59 bellard
87 5867c88a ths
static void
88 5867c88a ths
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
89 6508fe59 bellard
{
90 6508fe59 bellard
    ParallelState *s = opaque;
91 5fafdf24 ths
   
92 5867c88a ths
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
93 5867c88a ths
94 5867c88a ths
    addr &= 7;
95 5867c88a ths
    switch(addr) {
96 5867c88a ths
    case PARA_REG_DATA:
97 0fa7f157 ths
        s->dataw = val;
98 0fa7f157 ths
        parallel_update_irq(s);
99 5867c88a ths
        break;
100 5867c88a ths
    case PARA_REG_CTR:
101 0fa7f157 ths
        if ((val & PARA_CTR_INIT) == 0 ) {
102 0fa7f157 ths
            s->status = PARA_STS_BUSY;
103 0fa7f157 ths
            s->status |= PARA_STS_ACK;
104 0fa7f157 ths
            s->status |= PARA_STS_ONLINE;
105 0fa7f157 ths
            s->status |= PARA_STS_ERROR;
106 0fa7f157 ths
        }
107 0fa7f157 ths
        else if (val & PARA_CTR_SELECT) {
108 0fa7f157 ths
            if (val & PARA_CTR_STROBE) {
109 0fa7f157 ths
                s->status &= ~PARA_STS_BUSY;
110 0fa7f157 ths
                if ((s->control & PARA_CTR_STROBE) == 0)
111 0fa7f157 ths
                    qemu_chr_write(s->chr, &s->dataw, 1);
112 0fa7f157 ths
            } else {
113 0fa7f157 ths
                if (s->control & PARA_CTR_INTEN) {
114 0fa7f157 ths
                    s->irq_pending = 1;
115 0fa7f157 ths
                }
116 0fa7f157 ths
            }
117 0fa7f157 ths
        }
118 0fa7f157 ths
        parallel_update_irq(s);
119 0fa7f157 ths
        s->control = val;
120 5867c88a ths
        break;
121 5867c88a ths
    }
122 5867c88a ths
}
123 5867c88a ths
124 5867c88a ths
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
125 5867c88a ths
{
126 5867c88a ths
    ParallelState *s = opaque;
127 5867c88a ths
    uint8_t parm = val;
128 5867c88a ths
129 5867c88a ths
    /* Sometimes programs do several writes for timing purposes on old
130 5867c88a ths
       HW. Take care not to waste time on writes that do nothing. */
131 5867c88a ths
132 5867c88a ths
    s->last_read_offset = ~0U;
133 5867c88a ths
134 6508fe59 bellard
    addr &= 7;
135 6508fe59 bellard
    switch(addr) {
136 5867c88a ths
    case PARA_REG_DATA:
137 5867c88a ths
        if (s->dataw == val)
138 0fa7f157 ths
            return;
139 0fa7f157 ths
        pdebug("wd%02x\n", val);
140 0fa7f157 ths
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
141 0fa7f157 ths
        s->dataw = val;
142 6508fe59 bellard
        break;
143 5867c88a ths
    case PARA_REG_STS:
144 0fa7f157 ths
        pdebug("ws%02x\n", val);
145 0fa7f157 ths
        if (val & PARA_STS_TMOUT)
146 0fa7f157 ths
            s->epp_timeout = 0;
147 0fa7f157 ths
        break;
148 5867c88a ths
    case PARA_REG_CTR:
149 5867c88a ths
        val |= 0xc0;
150 5867c88a ths
        if (s->control == val)
151 0fa7f157 ths
            return;
152 0fa7f157 ths
        pdebug("wc%02x\n", val);
153 0fa7f157 ths
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
154 0fa7f157 ths
        s->control = val;
155 6508fe59 bellard
        break;
156 5867c88a ths
    case PARA_REG_EPP_ADDR:
157 0fa7f157 ths
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
158 0fa7f157 ths
            /* Controls not correct for EPP address cycle, so do nothing */
159 0fa7f157 ths
            pdebug("wa%02x s\n", val);
160 0fa7f157 ths
        else {
161 0fa7f157 ths
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
162 0fa7f157 ths
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
163 0fa7f157 ths
                s->epp_timeout = 1;
164 0fa7f157 ths
                pdebug("wa%02x t\n", val);
165 0fa7f157 ths
            }
166 0fa7f157 ths
            else
167 0fa7f157 ths
                pdebug("wa%02x\n", val);
168 0fa7f157 ths
        }
169 0fa7f157 ths
        break;
170 5867c88a ths
    case PARA_REG_EPP_DATA:
171 0fa7f157 ths
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
172 0fa7f157 ths
            /* Controls not correct for EPP data cycle, so do nothing */
173 0fa7f157 ths
            pdebug("we%02x s\n", val);
174 0fa7f157 ths
        else {
175 0fa7f157 ths
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
176 0fa7f157 ths
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
177 0fa7f157 ths
                s->epp_timeout = 1;
178 0fa7f157 ths
                pdebug("we%02x t\n", val);
179 0fa7f157 ths
            }
180 0fa7f157 ths
            else
181 0fa7f157 ths
                pdebug("we%02x\n", val);
182 0fa7f157 ths
        }
183 0fa7f157 ths
        break;
184 5867c88a ths
    }
185 5867c88a ths
}
186 5867c88a ths
187 5867c88a ths
static void
188 5867c88a ths
parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
189 5867c88a ths
{
190 5867c88a ths
    ParallelState *s = opaque;
191 5867c88a ths
    uint16_t eppdata = cpu_to_le16(val);
192 5867c88a ths
    int err;
193 5867c88a ths
    struct ParallelIOArg ioarg = {
194 0fa7f157 ths
        .buffer = &eppdata, .count = sizeof(eppdata)
195 5867c88a ths
    };
196 5867c88a ths
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
197 0fa7f157 ths
        /* Controls not correct for EPP data cycle, so do nothing */
198 0fa7f157 ths
        pdebug("we%04x s\n", val);
199 0fa7f157 ths
        return;
200 5867c88a ths
    }
201 5867c88a ths
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
202 5867c88a ths
    if (err) {
203 0fa7f157 ths
        s->epp_timeout = 1;
204 0fa7f157 ths
        pdebug("we%04x t\n", val);
205 5867c88a ths
    }
206 5867c88a ths
    else
207 0fa7f157 ths
        pdebug("we%04x\n", val);
208 5867c88a ths
}
209 5867c88a ths
210 5867c88a ths
static void
211 5867c88a ths
parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
212 5867c88a ths
{
213 5867c88a ths
    ParallelState *s = opaque;
214 5867c88a ths
    uint32_t eppdata = cpu_to_le32(val);
215 5867c88a ths
    int err;
216 5867c88a ths
    struct ParallelIOArg ioarg = {
217 0fa7f157 ths
        .buffer = &eppdata, .count = sizeof(eppdata)
218 5867c88a ths
    };
219 5867c88a ths
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
220 0fa7f157 ths
        /* Controls not correct for EPP data cycle, so do nothing */
221 0fa7f157 ths
        pdebug("we%08x s\n", val);
222 0fa7f157 ths
        return;
223 5867c88a ths
    }
224 5867c88a ths
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
225 5867c88a ths
    if (err) {
226 0fa7f157 ths
        s->epp_timeout = 1;
227 0fa7f157 ths
        pdebug("we%08x t\n", val);
228 6508fe59 bellard
    }
229 5867c88a ths
    else
230 0fa7f157 ths
        pdebug("we%08x\n", val);
231 6508fe59 bellard
}
232 6508fe59 bellard
233 5867c88a ths
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
234 6508fe59 bellard
{
235 6508fe59 bellard
    ParallelState *s = opaque;
236 6508fe59 bellard
    uint32_t ret = 0xff;
237 6508fe59 bellard
238 6508fe59 bellard
    addr &= 7;
239 6508fe59 bellard
    switch(addr) {
240 5867c88a ths
    case PARA_REG_DATA:
241 0fa7f157 ths
        if (s->control & PARA_CTR_DIR)
242 0fa7f157 ths
            ret = s->datar;
243 0fa7f157 ths
        else
244 0fa7f157 ths
            ret = s->dataw;
245 6508fe59 bellard
        break;
246 5867c88a ths
    case PARA_REG_STS:
247 0fa7f157 ths
        ret = s->status;
248 0fa7f157 ths
        s->irq_pending = 0;
249 0fa7f157 ths
        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
250 0fa7f157 ths
            /* XXX Fixme: wait 5 microseconds */
251 0fa7f157 ths
            if (s->status & PARA_STS_ACK)
252 0fa7f157 ths
                s->status &= ~PARA_STS_ACK;
253 0fa7f157 ths
            else {
254 0fa7f157 ths
                /* XXX Fixme: wait 5 microseconds */
255 0fa7f157 ths
                s->status |= PARA_STS_ACK;
256 0fa7f157 ths
                s->status |= PARA_STS_BUSY;
257 0fa7f157 ths
            }
258 0fa7f157 ths
        }
259 0fa7f157 ths
        parallel_update_irq(s);
260 6508fe59 bellard
        break;
261 5867c88a ths
    case PARA_REG_CTR:
262 6508fe59 bellard
        ret = s->control;
263 6508fe59 bellard
        break;
264 6508fe59 bellard
    }
265 5867c88a ths
    pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
266 5867c88a ths
    return ret;
267 5867c88a ths
}
268 5867c88a ths
269 5867c88a ths
static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
270 5867c88a ths
{
271 5867c88a ths
    ParallelState *s = opaque;
272 5867c88a ths
    uint8_t ret = 0xff;
273 5867c88a ths
    addr &= 7;
274 5867c88a ths
    switch(addr) {
275 5867c88a ths
    case PARA_REG_DATA:
276 0fa7f157 ths
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
277 0fa7f157 ths
        if (s->last_read_offset != addr || s->datar != ret)
278 0fa7f157 ths
            pdebug("rd%02x\n", ret);
279 5867c88a ths
        s->datar = ret;
280 5867c88a ths
        break;
281 5867c88a ths
    case PARA_REG_STS:
282 0fa7f157 ths
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
283 0fa7f157 ths
        ret &= ~PARA_STS_TMOUT;
284 0fa7f157 ths
        if (s->epp_timeout)
285 0fa7f157 ths
            ret |= PARA_STS_TMOUT;
286 0fa7f157 ths
        if (s->last_read_offset != addr || s->status != ret)
287 0fa7f157 ths
            pdebug("rs%02x\n", ret);
288 0fa7f157 ths
        s->status = ret;
289 5867c88a ths
        break;
290 5867c88a ths
    case PARA_REG_CTR:
291 5867c88a ths
        /* s->control has some bits fixed to 1. It is zero only when
292 0fa7f157 ths
           it has not been yet written to.  */
293 0fa7f157 ths
        if (s->control == 0) {
294 0fa7f157 ths
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
295 0fa7f157 ths
            if (s->last_read_offset != addr)
296 0fa7f157 ths
                pdebug("rc%02x\n", ret);
297 0fa7f157 ths
            s->control = ret;
298 0fa7f157 ths
        }
299 0fa7f157 ths
        else {
300 0fa7f157 ths
            ret = s->control;
301 0fa7f157 ths
            if (s->last_read_offset != addr)
302 0fa7f157 ths
                pdebug("rc%02x\n", ret);
303 0fa7f157 ths
        }
304 5867c88a ths
        break;
305 5867c88a ths
    case PARA_REG_EPP_ADDR:
306 0fa7f157 ths
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
307 0fa7f157 ths
            /* Controls not correct for EPP addr cycle, so do nothing */
308 0fa7f157 ths
            pdebug("ra%02x s\n", ret);
309 0fa7f157 ths
        else {
310 0fa7f157 ths
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
311 0fa7f157 ths
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
312 0fa7f157 ths
                s->epp_timeout = 1;
313 0fa7f157 ths
                pdebug("ra%02x t\n", ret);
314 0fa7f157 ths
            }
315 0fa7f157 ths
            else
316 0fa7f157 ths
                pdebug("ra%02x\n", ret);
317 0fa7f157 ths
        }
318 0fa7f157 ths
        break;
319 5867c88a ths
    case PARA_REG_EPP_DATA:
320 0fa7f157 ths
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
321 0fa7f157 ths
            /* Controls not correct for EPP data cycle, so do nothing */
322 0fa7f157 ths
            pdebug("re%02x s\n", ret);
323 0fa7f157 ths
        else {
324 0fa7f157 ths
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
325 0fa7f157 ths
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
326 0fa7f157 ths
                s->epp_timeout = 1;
327 0fa7f157 ths
                pdebug("re%02x t\n", ret);
328 0fa7f157 ths
            }
329 0fa7f157 ths
            else
330 0fa7f157 ths
                pdebug("re%02x\n", ret);
331 0fa7f157 ths
        }
332 0fa7f157 ths
        break;
333 5867c88a ths
    }
334 5867c88a ths
    s->last_read_offset = addr;
335 5867c88a ths
    return ret;
336 5867c88a ths
}
337 5867c88a ths
338 5867c88a ths
static uint32_t
339 5867c88a ths
parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
340 5867c88a ths
{
341 5867c88a ths
    ParallelState *s = opaque;
342 5867c88a ths
    uint32_t ret;
343 5867c88a ths
    uint16_t eppdata = ~0;
344 5867c88a ths
    int err;
345 5867c88a ths
    struct ParallelIOArg ioarg = {
346 0fa7f157 ths
        .buffer = &eppdata, .count = sizeof(eppdata)
347 5867c88a ths
    };
348 5867c88a ths
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
349 0fa7f157 ths
        /* Controls not correct for EPP data cycle, so do nothing */
350 0fa7f157 ths
        pdebug("re%04x s\n", eppdata);
351 0fa7f157 ths
        return eppdata;
352 5867c88a ths
    }
353 5867c88a ths
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
354 5867c88a ths
    ret = le16_to_cpu(eppdata);
355 5867c88a ths
356 5867c88a ths
    if (err) {
357 0fa7f157 ths
        s->epp_timeout = 1;
358 0fa7f157 ths
        pdebug("re%04x t\n", ret);
359 5867c88a ths
    }
360 5867c88a ths
    else
361 0fa7f157 ths
        pdebug("re%04x\n", ret);
362 5867c88a ths
    return ret;
363 5867c88a ths
}
364 5867c88a ths
365 5867c88a ths
static uint32_t
366 5867c88a ths
parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
367 5867c88a ths
{
368 5867c88a ths
    ParallelState *s = opaque;
369 5867c88a ths
    uint32_t ret;
370 5867c88a ths
    uint32_t eppdata = ~0U;
371 5867c88a ths
    int err;
372 5867c88a ths
    struct ParallelIOArg ioarg = {
373 0fa7f157 ths
        .buffer = &eppdata, .count = sizeof(eppdata)
374 5867c88a ths
    };
375 5867c88a ths
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
376 0fa7f157 ths
        /* Controls not correct for EPP data cycle, so do nothing */
377 0fa7f157 ths
        pdebug("re%08x s\n", eppdata);
378 0fa7f157 ths
        return eppdata;
379 5867c88a ths
    }
380 5867c88a ths
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
381 5867c88a ths
    ret = le32_to_cpu(eppdata);
382 5867c88a ths
383 5867c88a ths
    if (err) {
384 0fa7f157 ths
        s->epp_timeout = 1;
385 0fa7f157 ths
        pdebug("re%08x t\n", ret);
386 5867c88a ths
    }
387 5867c88a ths
    else
388 0fa7f157 ths
        pdebug("re%08x\n", ret);
389 5867c88a ths
    return ret;
390 5867c88a ths
}
391 5867c88a ths
392 5867c88a ths
static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
393 5867c88a ths
{
394 5867c88a ths
    addr &= 7;
395 5867c88a ths
    pdebug("wecp%d=%02x\n", addr, val);
396 5867c88a ths
}
397 5867c88a ths
398 5867c88a ths
static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
399 5867c88a ths
{
400 5867c88a ths
    uint8_t ret = 0xff;
401 5867c88a ths
    addr &= 7;
402 5867c88a ths
    pdebug("recp%d:%02x\n", addr, ret);
403 6508fe59 bellard
    return ret;
404 6508fe59 bellard
}
405 6508fe59 bellard
406 d60532ca ths
static void parallel_reset(ParallelState *s, qemu_irq irq, CharDriverState *chr)
407 6508fe59 bellard
{
408 5867c88a ths
    s->datar = ~0;
409 5867c88a ths
    s->dataw = ~0;
410 6508fe59 bellard
    s->status = PARA_STS_BUSY;
411 6508fe59 bellard
    s->status |= PARA_STS_ACK;
412 6508fe59 bellard
    s->status |= PARA_STS_ONLINE;
413 6508fe59 bellard
    s->status |= PARA_STS_ERROR;
414 6508fe59 bellard
    s->control = PARA_CTR_SELECT;
415 6508fe59 bellard
    s->control |= PARA_CTR_INIT;
416 5867c88a ths
    s->irq = irq;
417 5867c88a ths
    s->irq_pending = 0;
418 5867c88a ths
    s->chr = chr;
419 5867c88a ths
    s->hw_driver = 0;
420 5867c88a ths
    s->epp_timeout = 0;
421 5867c88a ths
    s->last_read_offset = ~0U;
422 d60532ca ths
}
423 d60532ca ths
424 d60532ca ths
/* If fd is zero, it means that the parallel device uses the console */
425 d60532ca ths
ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
426 d60532ca ths
{
427 d60532ca ths
    ParallelState *s;
428 d60532ca ths
    uint8_t dummy;
429 d60532ca ths
430 d60532ca ths
    s = qemu_mallocz(sizeof(ParallelState));
431 d60532ca ths
    if (!s)
432 d60532ca ths
        return NULL;
433 d60532ca ths
    parallel_reset(s, irq, chr);
434 6508fe59 bellard
435 5867c88a ths
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
436 5867c88a ths
        s->hw_driver = 1;
437 0fa7f157 ths
        s->status = dummy;
438 5867c88a ths
    }
439 5867c88a ths
440 5867c88a ths
    if (s->hw_driver) {
441 0fa7f157 ths
        register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
442 0fa7f157 ths
        register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
443 0fa7f157 ths
        register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
444 0fa7f157 ths
        register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
445 0fa7f157 ths
        register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
446 0fa7f157 ths
        register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
447 0fa7f157 ths
        register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
448 0fa7f157 ths
        register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
449 5867c88a ths
    }
450 5867c88a ths
    else {
451 0fa7f157 ths
        register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
452 0fa7f157 ths
        register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
453 5867c88a ths
    }
454 6508fe59 bellard
    return s;
455 6508fe59 bellard
}
456 d60532ca ths
457 d60532ca ths
/* Memory mapped interface */
458 d60532ca ths
uint32_t parallel_mm_readb (void *opaque, target_phys_addr_t addr)
459 d60532ca ths
{
460 d60532ca ths
    ParallelState *s = opaque;
461 d60532ca ths
462 d60532ca ths
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFF;
463 d60532ca ths
}
464 d60532ca ths
465 d60532ca ths
void parallel_mm_writeb (void *opaque,
466 d60532ca ths
                       target_phys_addr_t addr, uint32_t value)
467 d60532ca ths
{
468 d60532ca ths
    ParallelState *s = opaque;
469 d60532ca ths
470 d60532ca ths
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFF);
471 d60532ca ths
}
472 d60532ca ths
473 d60532ca ths
uint32_t parallel_mm_readw (void *opaque, target_phys_addr_t addr)
474 d60532ca ths
{
475 d60532ca ths
    ParallelState *s = opaque;
476 d60532ca ths
477 d60532ca ths
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift) & 0xFFFF;
478 d60532ca ths
}
479 d60532ca ths
480 d60532ca ths
void parallel_mm_writew (void *opaque,
481 d60532ca ths
                       target_phys_addr_t addr, uint32_t value)
482 d60532ca ths
{
483 d60532ca ths
    ParallelState *s = opaque;
484 d60532ca ths
485 d60532ca ths
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value & 0xFFFF);
486 d60532ca ths
}
487 d60532ca ths
488 d60532ca ths
uint32_t parallel_mm_readl (void *opaque, target_phys_addr_t addr)
489 d60532ca ths
{
490 d60532ca ths
    ParallelState *s = opaque;
491 d60532ca ths
492 d60532ca ths
    return parallel_ioport_read_sw(s, (addr - s->base) >> s->it_shift);
493 d60532ca ths
}
494 d60532ca ths
495 d60532ca ths
void parallel_mm_writel (void *opaque,
496 d60532ca ths
                       target_phys_addr_t addr, uint32_t value)
497 d60532ca ths
{
498 d60532ca ths
    ParallelState *s = opaque;
499 d60532ca ths
500 d60532ca ths
    parallel_ioport_write_sw(s, (addr - s->base) >> s->it_shift, value);
501 d60532ca ths
}
502 d60532ca ths
503 d60532ca ths
static CPUReadMemoryFunc *parallel_mm_read_sw[] = {
504 d60532ca ths
    &parallel_mm_readb,
505 d60532ca ths
    &parallel_mm_readw,
506 d60532ca ths
    &parallel_mm_readl,
507 d60532ca ths
};
508 d60532ca ths
509 d60532ca ths
static CPUWriteMemoryFunc *parallel_mm_write_sw[] = {
510 d60532ca ths
    &parallel_mm_writeb,
511 d60532ca ths
    &parallel_mm_writew,
512 d60532ca ths
    &parallel_mm_writel,
513 d60532ca ths
};
514 d60532ca ths
515 d60532ca ths
/* If fd is zero, it means that the parallel device uses the console */
516 d60532ca ths
ParallelState *parallel_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq, CharDriverState *chr)
517 d60532ca ths
{
518 d60532ca ths
    ParallelState *s;
519 d60532ca ths
    int io_sw;
520 d60532ca ths
521 d60532ca ths
    s = qemu_mallocz(sizeof(ParallelState));
522 d60532ca ths
    if (!s)
523 d60532ca ths
        return NULL;
524 d60532ca ths
    parallel_reset(s, irq, chr);
525 d60532ca ths
    s->base = base;
526 d60532ca ths
    s->it_shift = it_shift;
527 d60532ca ths
528 d60532ca ths
    io_sw = cpu_register_io_memory(0, parallel_mm_read_sw, parallel_mm_write_sw, s);
529 d60532ca ths
    cpu_register_physical_memory(base, 8 << it_shift, io_sw);
530 d60532ca ths
    return s;
531 d60532ca ths
}