Statistics
| Branch: | Revision:

root / hw / parallel.c @ 9c02f1a2

History | View | Annotate | Download (12.3 kB)

1
/*
2
 * QEMU Parallel PORT emulation
3
 * 
4
 * Copyright (c) 2003-2005 Fabrice Bellard
5
 * Copyright (c) 2007 Marko Kohtala
6
 * 
7
 * Permission is hereby granted, free of charge, to any person obtaining a copy
8
 * of this software and associated documentation files (the "Software"), to deal
9
 * in the Software without restriction, including without limitation the rights
10
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
 * copies of the Software, and to permit persons to whom the Software is
12
 * furnished to do so, subject to the following conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be included in
15
 * all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
 * THE SOFTWARE.
24
 */
25
#include "vl.h"
26

    
27
//#define DEBUG_PARALLEL
28

    
29
#ifdef DEBUG_PARALLEL
30
#define pdebug(fmt, arg...) printf("pp: " fmt, ##arg)
31
#else
32
#define pdebug(fmt, arg...) ((void)0)
33
#endif
34

    
35
#define PARA_REG_DATA 0
36
#define PARA_REG_STS 1
37
#define PARA_REG_CTR 2
38
#define PARA_REG_EPP_ADDR 3
39
#define PARA_REG_EPP_DATA 4
40

    
41
/*
42
 * These are the definitions for the Printer Status Register
43
 */
44
#define PARA_STS_BUSY        0x80        /* Busy complement */
45
#define PARA_STS_ACK        0x40        /* Acknowledge */
46
#define PARA_STS_PAPER        0x20        /* Out of paper */
47
#define PARA_STS_ONLINE        0x10        /* Online */
48
#define PARA_STS_ERROR        0x08        /* Error complement */
49
#define PARA_STS_TMOUT        0x01        /* EPP timeout */
50

    
51
/*
52
 * These are the definitions for the Printer Control Register
53
 */
54
#define PARA_CTR_DIR        0x20        /* Direction (1=read, 0=write) */
55
#define PARA_CTR_INTEN        0x10        /* IRQ Enable */
56
#define PARA_CTR_SELECT        0x08        /* Select In complement */
57
#define PARA_CTR_INIT        0x04        /* Initialize Printer complement */
58
#define PARA_CTR_AUTOLF        0x02        /* Auto linefeed complement */
59
#define PARA_CTR_STROBE        0x01        /* Strobe complement */
60

    
61
#define PARA_CTR_SIGNAL (PARA_CTR_SELECT|PARA_CTR_INIT|PARA_CTR_AUTOLF|PARA_CTR_STROBE)
62

    
63
struct ParallelState {
64
    uint8_t dataw;
65
    uint8_t datar;
66
    uint8_t status;
67
    uint8_t control;
68
    qemu_irq irq;
69
    int irq_pending;
70
    CharDriverState *chr;
71
    int hw_driver;
72
    int epp_timeout;
73
    uint32_t last_read_offset; /* For debugging */
74
};
75

    
76
static void parallel_update_irq(ParallelState *s)
77
{
78
    if (s->irq_pending)
79
        qemu_irq_raise(s->irq);
80
    else
81
        qemu_irq_lower(s->irq);
82
}
83

    
84
static void
85
parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)
86
{
87
    ParallelState *s = opaque;
88
    
89
    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);
90

    
91
    addr &= 7;
92
    switch(addr) {
93
    case PARA_REG_DATA:
94
        s->dataw = val;
95
        parallel_update_irq(s);
96
        break;
97
    case PARA_REG_CTR:
98
        if ((val & PARA_CTR_INIT) == 0 ) {
99
            s->status = PARA_STS_BUSY;
100
            s->status |= PARA_STS_ACK;
101
            s->status |= PARA_STS_ONLINE;
102
            s->status |= PARA_STS_ERROR;
103
        }
104
        else if (val & PARA_CTR_SELECT) {
105
            if (val & PARA_CTR_STROBE) {
106
                s->status &= ~PARA_STS_BUSY;
107
                if ((s->control & PARA_CTR_STROBE) == 0)
108
                    qemu_chr_write(s->chr, &s->dataw, 1);
109
            } else {
110
                if (s->control & PARA_CTR_INTEN) {
111
                    s->irq_pending = 1;
112
                }
113
            }
114
        }
115
        parallel_update_irq(s);
116
        s->control = val;
117
        break;
118
    }
119
}
120

    
121
static void parallel_ioport_write_hw(void *opaque, uint32_t addr, uint32_t val)
122
{
123
    ParallelState *s = opaque;
124
    uint8_t parm = val;
125

    
126
    /* Sometimes programs do several writes for timing purposes on old
127
       HW. Take care not to waste time on writes that do nothing. */
128

    
129
    s->last_read_offset = ~0U;
130

    
131
    addr &= 7;
132
    switch(addr) {
133
    case PARA_REG_DATA:
134
        if (s->dataw == val)
135
            return;
136
        pdebug("wd%02x\n", val);
137
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &parm);
138
        s->dataw = val;
139
        break;
140
    case PARA_REG_STS:
141
        pdebug("ws%02x\n", val);
142
        if (val & PARA_STS_TMOUT)
143
            s->epp_timeout = 0;
144
        break;
145
    case PARA_REG_CTR:
146
        val |= 0xc0;
147
        if (s->control == val)
148
            return;
149
        pdebug("wc%02x\n", val);
150
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &parm);
151
        s->control = val;
152
        break;
153
    case PARA_REG_EPP_ADDR:
154
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
155
            /* Controls not correct for EPP address cycle, so do nothing */
156
            pdebug("wa%02x s\n", val);
157
        else {
158
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
159
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE_ADDR, &ioarg)) {
160
                s->epp_timeout = 1;
161
                pdebug("wa%02x t\n", val);
162
            }
163
            else
164
                pdebug("wa%02x\n", val);
165
        }
166
        break;
167
    case PARA_REG_EPP_DATA:
168
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT)
169
            /* Controls not correct for EPP data cycle, so do nothing */
170
            pdebug("we%02x s\n", val);
171
        else {
172
            struct ParallelIOArg ioarg = { .buffer = &parm, .count = 1 };
173
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg)) {
174
                s->epp_timeout = 1;
175
                pdebug("we%02x t\n", val);
176
            }
177
            else
178
                pdebug("we%02x\n", val);
179
        }
180
        break;
181
    }
182
}
183

    
184
static void
185
parallel_ioport_eppdata_write_hw2(void *opaque, uint32_t addr, uint32_t val)
186
{
187
    ParallelState *s = opaque;
188
    uint16_t eppdata = cpu_to_le16(val);
189
    int err;
190
    struct ParallelIOArg ioarg = {
191
        .buffer = &eppdata, .count = sizeof(eppdata)
192
    };
193
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
194
        /* Controls not correct for EPP data cycle, so do nothing */
195
        pdebug("we%04x s\n", val);
196
        return;
197
    }
198
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
199
    if (err) {
200
        s->epp_timeout = 1;
201
        pdebug("we%04x t\n", val);
202
    }
203
    else
204
        pdebug("we%04x\n", val);
205
}
206

    
207
static void
208
parallel_ioport_eppdata_write_hw4(void *opaque, uint32_t addr, uint32_t val)
209
{
210
    ParallelState *s = opaque;
211
    uint32_t eppdata = cpu_to_le32(val);
212
    int err;
213
    struct ParallelIOArg ioarg = {
214
        .buffer = &eppdata, .count = sizeof(eppdata)
215
    };
216
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != PARA_CTR_INIT) {
217
        /* Controls not correct for EPP data cycle, so do nothing */
218
        pdebug("we%08x s\n", val);
219
        return;
220
    }
221
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_WRITE, &ioarg);
222
    if (err) {
223
        s->epp_timeout = 1;
224
        pdebug("we%08x t\n", val);
225
    }
226
    else
227
        pdebug("we%08x\n", val);
228
}
229

    
230
static uint32_t parallel_ioport_read_sw(void *opaque, uint32_t addr)
231
{
232
    ParallelState *s = opaque;
233
    uint32_t ret = 0xff;
234

    
235
    addr &= 7;
236
    switch(addr) {
237
    case PARA_REG_DATA:
238
        if (s->control & PARA_CTR_DIR)
239
            ret = s->datar;
240
        else
241
            ret = s->dataw;
242
        break;
243
    case PARA_REG_STS:
244
        ret = s->status;
245
        s->irq_pending = 0;
246
        if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
247
            /* XXX Fixme: wait 5 microseconds */
248
            if (s->status & PARA_STS_ACK)
249
                s->status &= ~PARA_STS_ACK;
250
            else {
251
                /* XXX Fixme: wait 5 microseconds */
252
                s->status |= PARA_STS_ACK;
253
                s->status |= PARA_STS_BUSY;
254
            }
255
        }
256
        parallel_update_irq(s);
257
        break;
258
    case PARA_REG_CTR:
259
        ret = s->control;
260
        break;
261
    }
262
    pdebug("read addr=0x%02x val=0x%02x\n", addr, ret);
263
    return ret;
264
}
265

    
266
static uint32_t parallel_ioport_read_hw(void *opaque, uint32_t addr)
267
{
268
    ParallelState *s = opaque;
269
    uint8_t ret = 0xff;
270
    addr &= 7;
271
    switch(addr) {
272
    case PARA_REG_DATA:
273
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &ret);
274
        if (s->last_read_offset != addr || s->datar != ret)
275
            pdebug("rd%02x\n", ret);
276
        s->datar = ret;
277
        break;
278
    case PARA_REG_STS:
279
        qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &ret);
280
        ret &= ~PARA_STS_TMOUT;
281
        if (s->epp_timeout)
282
            ret |= PARA_STS_TMOUT;
283
        if (s->last_read_offset != addr || s->status != ret)
284
            pdebug("rs%02x\n", ret);
285
        s->status = ret;
286
        break;
287
    case PARA_REG_CTR:
288
        /* s->control has some bits fixed to 1. It is zero only when
289
           it has not been yet written to.  */
290
        if (s->control == 0) {
291
            qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &ret);
292
            if (s->last_read_offset != addr)
293
                pdebug("rc%02x\n", ret);
294
            s->control = ret;
295
        }
296
        else {
297
            ret = s->control;
298
            if (s->last_read_offset != addr)
299
                pdebug("rc%02x\n", ret);
300
        }
301
        break;
302
    case PARA_REG_EPP_ADDR:
303
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
304
            /* Controls not correct for EPP addr cycle, so do nothing */
305
            pdebug("ra%02x s\n", ret);
306
        else {
307
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
308
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ_ADDR, &ioarg)) {
309
                s->epp_timeout = 1;
310
                pdebug("ra%02x t\n", ret);
311
            }
312
            else
313
                pdebug("ra%02x\n", ret);
314
        }
315
        break;
316
    case PARA_REG_EPP_DATA:
317
        if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT))
318
            /* Controls not correct for EPP data cycle, so do nothing */
319
            pdebug("re%02x s\n", ret);
320
        else {
321
            struct ParallelIOArg ioarg = { .buffer = &ret, .count = 1 };
322
            if (qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg)) {
323
                s->epp_timeout = 1;
324
                pdebug("re%02x t\n", ret);
325
            }
326
            else
327
                pdebug("re%02x\n", ret);
328
        }
329
        break;
330
    }
331
    s->last_read_offset = addr;
332
    return ret;
333
}
334

    
335
static uint32_t
336
parallel_ioport_eppdata_read_hw2(void *opaque, uint32_t addr)
337
{
338
    ParallelState *s = opaque;
339
    uint32_t ret;
340
    uint16_t eppdata = ~0;
341
    int err;
342
    struct ParallelIOArg ioarg = {
343
        .buffer = &eppdata, .count = sizeof(eppdata)
344
    };
345
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
346
        /* Controls not correct for EPP data cycle, so do nothing */
347
        pdebug("re%04x s\n", eppdata);
348
        return eppdata;
349
    }
350
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
351
    ret = le16_to_cpu(eppdata);
352

    
353
    if (err) {
354
        s->epp_timeout = 1;
355
        pdebug("re%04x t\n", ret);
356
    }
357
    else
358
        pdebug("re%04x\n", ret);
359
    return ret;
360
}
361

    
362
static uint32_t
363
parallel_ioport_eppdata_read_hw4(void *opaque, uint32_t addr)
364
{
365
    ParallelState *s = opaque;
366
    uint32_t ret;
367
    uint32_t eppdata = ~0U;
368
    int err;
369
    struct ParallelIOArg ioarg = {
370
        .buffer = &eppdata, .count = sizeof(eppdata)
371
    };
372
    if ((s->control & (PARA_CTR_DIR|PARA_CTR_SIGNAL)) != (PARA_CTR_DIR|PARA_CTR_INIT)) {
373
        /* Controls not correct for EPP data cycle, so do nothing */
374
        pdebug("re%08x s\n", eppdata);
375
        return eppdata;
376
    }
377
    err = qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_EPP_READ, &ioarg);
378
    ret = le32_to_cpu(eppdata);
379

    
380
    if (err) {
381
        s->epp_timeout = 1;
382
        pdebug("re%08x t\n", ret);
383
    }
384
    else
385
        pdebug("re%08x\n", ret);
386
    return ret;
387
}
388

    
389
static void parallel_ioport_ecp_write(void *opaque, uint32_t addr, uint32_t val)
390
{
391
    addr &= 7;
392
    pdebug("wecp%d=%02x\n", addr, val);
393
}
394

    
395
static uint32_t parallel_ioport_ecp_read(void *opaque, uint32_t addr)
396
{
397
    uint8_t ret = 0xff;
398
    addr &= 7;
399
    pdebug("recp%d:%02x\n", addr, ret);
400
    return ret;
401
}
402

    
403
/* If fd is zero, it means that the parallel device uses the console */
404
ParallelState *parallel_init(int base, qemu_irq irq, CharDriverState *chr)
405
{
406
    ParallelState *s;
407
    uint8_t dummy;
408

    
409
    s = qemu_mallocz(sizeof(ParallelState));
410
    if (!s)
411
        return NULL;
412
    s->datar = ~0;
413
    s->dataw = ~0;
414
    s->status = PARA_STS_BUSY;
415
    s->status |= PARA_STS_ACK;
416
    s->status |= PARA_STS_ONLINE;
417
    s->status |= PARA_STS_ERROR;
418
    s->control = PARA_CTR_SELECT;
419
    s->control |= PARA_CTR_INIT;
420
    s->irq = irq;
421
    s->irq_pending = 0;
422
    s->chr = chr;
423
    s->hw_driver = 0;
424
    s->epp_timeout = 0;
425
    s->last_read_offset = ~0U;
426

    
427
    if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0) {
428
        s->hw_driver = 1;
429
        s->status = dummy;
430
    }
431

    
432
    if (s->hw_driver) {
433
        register_ioport_write(base, 8, 1, parallel_ioport_write_hw, s);
434
        register_ioport_read(base, 8, 1, parallel_ioport_read_hw, s);
435
        register_ioport_write(base+4, 1, 2, parallel_ioport_eppdata_write_hw2, s);
436
        register_ioport_read(base+4, 1, 2, parallel_ioport_eppdata_read_hw2, s);
437
        register_ioport_write(base+4, 1, 4, parallel_ioport_eppdata_write_hw4, s);
438
        register_ioport_read(base+4, 1, 4, parallel_ioport_eppdata_read_hw4, s);
439
        register_ioport_write(base+0x400, 8, 1, parallel_ioport_ecp_write, s);
440
        register_ioport_read(base+0x400, 8, 1, parallel_ioport_ecp_read, s);
441
    }
442
    else {
443
        register_ioport_write(base, 8, 1, parallel_ioport_write_sw, s);
444
        register_ioport_read(base, 8, 1, parallel_ioport_read_sw, s);
445
    }
446
    return s;
447
}