/[qemu]/qemu/hw/parallel.c
ViewVC logotype

Diff of /qemu/hw/parallel.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.2 by bellard, Sun Jan 23 20:42:59 2005 UTC revision 1.3 by bellard, Thu Nov 10 23:58:52 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * QEMU Parallel PORT emulation   * QEMU Parallel PORT emulation
3   *   *
4   * Copyright (c) 2003-2004 Fabrice Bellard   * Copyright (c) 2003-2005 Fabrice Bellard
5   *   *
6   * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
7   * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
# Line 50  struct ParallelState { Line 50  struct ParallelState {
50      int irq;      int irq;
51      int irq_pending;      int irq_pending;
52      CharDriverState *chr;      CharDriverState *chr;
53        int hw_driver;
54  };  };
55    
56  static void parallel_update_irq(ParallelState *s)  static void parallel_update_irq(ParallelState *s)
# Line 70  static void parallel_ioport_write(void * Line 71  static void parallel_ioport_write(void *
71  #endif  #endif
72      switch(addr) {      switch(addr) {
73      case 0:      case 0:
74          s->data = val;          if (s->hw_driver) {
75          parallel_update_irq(s);              s->data = val;
76                qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_DATA, &s->data);
77            } else {
78                s->data = val;
79                parallel_update_irq(s);
80            }
81          break;          break;
82      case 2:      case 2:
83          if ((val & PARA_CTR_INIT) == 0 ) {          if (s->hw_driver) {
84              s->status = PARA_STS_BUSY;              s->control = val;
85              s->status |= PARA_STS_ACK;              qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_WRITE_CONTROL, &s->control);
86              s->status |= PARA_STS_ONLINE;          } else {
87              s->status |= PARA_STS_ERROR;              if ((val & PARA_CTR_INIT) == 0 ) {
88          }                  s->status = PARA_STS_BUSY;
89          else if (val & PARA_CTR_SELECT) {                  s->status |= PARA_STS_ACK;
90              if (val & PARA_CTR_STROBE) {                  s->status |= PARA_STS_ONLINE;
91                  s->status &= ~PARA_STS_BUSY;                  s->status |= PARA_STS_ERROR;
92                  if ((s->control & PARA_CTR_STROBE) == 0)              }
93                      qemu_chr_write(s->chr, &s->data, 1);              else if (val & PARA_CTR_SELECT) {
94              } else {                  if (val & PARA_CTR_STROBE) {
95                  if (s->control & PARA_CTR_INTEN) {                      s->status &= ~PARA_STS_BUSY;
96                      s->irq_pending = 1;                      if ((s->control & PARA_CTR_STROBE) == 0)
97                            qemu_chr_write(s->chr, &s->data, 1);
98                    } else {
99                        if (s->control & PARA_CTR_INTEN) {
100                            s->irq_pending = 1;
101                        }
102                  }                  }
103              }              }
104                parallel_update_irq(s);
105                s->control = val;
106          }          }
         parallel_update_irq(s);  
         s->control = val;  
107          break;          break;
108      }      }
109  }  }
# Line 105  static uint32_t parallel_ioport_read(voi Line 116  static uint32_t parallel_ioport_read(voi
116      addr &= 7;      addr &= 7;
117      switch(addr) {      switch(addr) {
118      case 0:      case 0:
119            if (s->hw_driver) {
120                qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_DATA, &s->data);
121            }
122          ret = s->data;          ret = s->data;
123          break;          break;
124      case 1:      case 1:
125          ret = s->status;          if (s->hw_driver) {
126          s->irq_pending = 0;              qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_STATUS, &s->status);
127          if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {              ret = s->status;
128              /* XXX Fixme: wait 5 microseconds */          } else {
129              if (s->status & PARA_STS_ACK)              ret = s->status;
130                  s->status &= ~PARA_STS_ACK;              s->irq_pending = 0;
131              else {              if ((s->status & PARA_STS_BUSY) == 0 && (s->control & PARA_CTR_STROBE) == 0) {
132              /* XXX Fixme: wait 5 microseconds */                  /* XXX Fixme: wait 5 microseconds */
133                  s->status |= PARA_STS_ACK;                  if (s->status & PARA_STS_ACK)
134                  s->status |= PARA_STS_BUSY;                      s->status &= ~PARA_STS_ACK;
135                    else {
136                        /* XXX Fixme: wait 5 microseconds */
137                        s->status |= PARA_STS_ACK;
138                        s->status |= PARA_STS_BUSY;
139                    }
140              }              }
141                parallel_update_irq(s);
142          }          }
         parallel_update_irq(s);  
143          break;          break;
144      case 2:      case 2:
145            if (s->hw_driver) {
146                qemu_chr_ioctl(s->chr, CHR_IOCTL_PP_READ_CONTROL, &s->control);
147            }
148          ret = s->control;          ret = s->control;
149          break;          break;
150      }      }
# Line 153  static void parallel_receive1(void *opaq Line 175  static void parallel_receive1(void *opaq
175      parallel_receive_byte(s, buf[0]);      parallel_receive_byte(s, buf[0]);
176  }  }
177    
 static void parallel_event(void *opaque, int event)  
 {  
 }  
   
178  /* If fd is zero, it means that the parallel device uses the console */  /* If fd is zero, it means that the parallel device uses the console */
179  ParallelState *parallel_init(int base, int irq, CharDriverState *chr)  ParallelState *parallel_init(int base, int irq, CharDriverState *chr)
180  {  {
181      ParallelState *s;      ParallelState *s;
182        uint8_t dummy;
183    
184      s = qemu_mallocz(sizeof(ParallelState));      s = qemu_mallocz(sizeof(ParallelState));
185      if (!s)      if (!s)
186          return NULL;          return NULL;
187        s->chr = chr;
188        s->hw_driver = 0;
189        if (qemu_chr_ioctl(chr, CHR_IOCTL_PP_READ_STATUS, &dummy) == 0)
190            s->hw_driver = 1;
191    
192      s->irq = irq;      s->irq = irq;
193      s->data = 0;      s->data = 0;
194      s->status = PARA_STS_BUSY;      s->status = PARA_STS_BUSY;
# Line 176  ParallelState *parallel_init(int base, i Line 200  ParallelState *parallel_init(int base, i
200    
201      register_ioport_write(base, 8, 1, parallel_ioport_write, s);      register_ioport_write(base, 8, 1, parallel_ioport_write, s);
202      register_ioport_read(base, 8, 1, parallel_ioport_read, s);      register_ioport_read(base, 8, 1, parallel_ioport_read, s);
     s->chr = chr;  
203      qemu_chr_add_read_handler(chr, parallel_can_receive1, parallel_receive1, s);      qemu_chr_add_read_handler(chr, parallel_can_receive1, parallel_receive1, s);
     qemu_chr_add_event_handler(chr, parallel_event);  
204      return s;      return s;
205  }  }

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26