/[gxemul]/trunk/src/devices/dev_z8530.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

Diff of /trunk/src/devices/dev_z8530.c

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

revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_z8530.c,v 1.5 2006/02/09 20:02:59 debug Exp $   *  $Id: dev_z8530.c,v 1.9 2006/10/07 02:05:21 debug Exp $
29   *     *  
30   *  Zilog "zs" serial controller (Z8530).   *  Zilog "zs" serial controller (Z8530).
31   *   *
32   *  Features:   *  Features:
33   *      o)  Two channels, 0 = "channel B", 1 = "channel A".   *      o)  Two channels, 0 = "channel B", 1 = "channel A".
34     *          Normally, only channel B is in use.
35   *   *
36   *  This is a work in progress... TODOs include:   *  This is a work in progress... TODOs include:
37   *      o)  Implement more of the register set.   *      o)  Implement more of the register set.
# Line 52  Line 53 
53  #include "z8530reg.h"  #include "z8530reg.h"
54    
55    
56  #define debug fatal  /*  #define debug fatal  */
57    
58  #define ZS_TICK_SHIFT           14  #define ZS_TICK_SHIFT           14
59  #define ZS_N_REGS               16  #define ZS_N_REGS               16
60    #define ZS_N_CHANNELS           2
61  #define DEV_Z8530_LENGTH        4  #define DEV_Z8530_LENGTH        4
62    
63  struct z8530_data {  struct z8530_data {
64          int             irq_nr;          int             irq_nr;
65          int             dma_irq_nr;          int             dma_irq_nr;
66          int             irq_asserted;          int             irq_asserted;
   
         int             in_use;  
67          int             addr_mult;          int             addr_mult;
68    
69          /*  2 of everything, because there are two channels.  */          int             console_handle[ZS_N_CHANNELS];
70          int             console_handle[2];          int             reg_select[ZS_N_CHANNELS];
71          int             reg_select[2];          uint8_t         rr[ZS_N_CHANNELS][ZS_N_REGS];
72          uint8_t         rr[2][ZS_N_REGS];          uint8_t         wr[ZS_N_CHANNELS][ZS_N_REGS];
         uint8_t         wr[2][ZS_N_REGS];  
73  };  };
74    
75    
76  /*  /*
77   *  check_incoming():   *  check_incoming():
78     *
79     *  Sets the RX interrupt flag for ports B and A, if something there is input
80     *  available on port 0 or 1, respectively.
81   */   */
82  static void check_incoming(struct cpu *cpu, struct z8530_data *d)  static void check_incoming(struct cpu *cpu, struct z8530_data *d)
83  {  {
# Line 90  static void check_incoming(struct cpu *c Line 92  static void check_incoming(struct cpu *c
92  }  }
93    
94    
95  /*  DEVICE_TICK(z8530)
  *  dev_z8530_tick():  
  */  
 void dev_z8530_tick(struct cpu *cpu, void *extra)  
96  {  {
97            /*  Generate transmit and receive interrupts at regular intervals.  */
98          struct z8530_data *d = (struct z8530_data *) extra;          struct z8530_data *d = (struct z8530_data *) extra;
99          int asserted = 0;          int asserted = 0;
100    
# Line 125  void dev_z8530_tick(struct cpu *cpu, voi Line 125  void dev_z8530_tick(struct cpu *cpu, voi
125  }  }
126    
127    
 /*  
  *  dev_z8530_access():  
  */  
128  DEVICE_ACCESS(z8530)  DEVICE_ACCESS(z8530)
129  {  {
130          struct z8530_data *d = extra;          struct z8530_data *d = extra;
# Line 143  DEVICE_ACCESS(z8530) Line 140  DEVICE_ACCESS(z8530)
140    
141          relative_addr /= d->addr_mult;          relative_addr /= d->addr_mult;
142    
143          port_nr = relative_addr / 2;          port_nr = (relative_addr / 2) % ZS_N_CHANNELS;
144          relative_addr &= 1;          relative_addr &= 1;
145    
146          if (relative_addr == 0) {          if (relative_addr == 0) {
147                  /*  Register access:  */                  /*  Register access:  */
148                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
149                          odata = d->rr[port_nr][d->reg_select[port_nr]];                          odata = d->rr[port_nr][d->reg_select[port_nr]];
150                          if (d->reg_select[port_nr] != 0)                          debug("[ z8530: read from port %i reg %2i: "
151                                  debug("[ z8530: read from port %i reg %2i: "                              "0x%02x ]\n", port_nr, d->reg_select[
152                                      "0x%02x ]\n", port_nr, d->reg_select[                              port_nr], (int)odata);
                                     port_nr], (int)odata);  
153                          d->reg_select[port_nr] = 0;                          d->reg_select[port_nr] = 0;
154                  } else {                  } else {
155                          if (d->reg_select[port_nr] == 0) {                          if (d->reg_select[port_nr] == 0) {
156                                  d->reg_select[port_nr] = idata & 15;                                  if (idata < 16)
157                                            d->reg_select[port_nr] = idata & 15;
158                                    else
159                                            d->reg_select[port_nr] = idata & 7;
160                                    switch (idata & 0xf8) {
161                                    case ZSWR0_CLR_INTR:    /*  Interrupt ack:  */
162                                            d->rr[1][3] = 0;
163                                            break;
164                                    }
165                          } else {                          } else {
166                                  d->wr[port_nr][d->reg_select[port_nr]] = idata;                                  d->wr[port_nr][d->reg_select[port_nr]] = idata;
167                                  switch (d->reg_select[port_nr]) {                                  switch (d->reg_select[port_nr]) {
                                 case 8: /*  Interrupt ack:  */  
                                         if (idata == ZSWR0_CLR_INTR)  
                                                 d->rr[1][3] = 0;  
                                         break;  
168                                  default:debug("[ z8530: write to  port %i reg "                                  default:debug("[ z8530: write to  port %i reg "
169                                              "%2i: 0x%02x ]\n", port_nr, d->                                              "%2i: 0x%02x ]\n", port_nr, d->
170                                              reg_select[port_nr], (int)idata);                                              reg_select[port_nr], (int)idata);
# Line 213  DEVINIT(z8530) Line 213  DEVINIT(z8530)
213          memset(d, 0, sizeof(struct z8530_data));          memset(d, 0, sizeof(struct z8530_data));
214          d->irq_nr     = devinit->irq_nr;          d->irq_nr     = devinit->irq_nr;
215          d->dma_irq_nr = devinit->dma_irq_nr;          d->dma_irq_nr = devinit->dma_irq_nr;
         d->in_use     = devinit->in_use;  
216          d->addr_mult  = devinit->addr_mult;          d->addr_mult  = devinit->addr_mult;
217    
218          snprintf(tmp, sizeof(tmp), "%s [ch-b]", devinit->name);          snprintf(tmp, sizeof(tmp), "%s [ch-b]", devinit->name);
219          d->console_handle[0] = console_start_slave(devinit->machine, tmp,          d->console_handle[0] = console_start_slave(devinit->machine, tmp,
220              d->in_use);              devinit->in_use);
221          snprintf(tmp, sizeof(tmp), "%s [ch-a]", devinit->name);          snprintf(tmp, sizeof(tmp), "%s [ch-a]", devinit->name);
222          d->console_handle[1] = console_start_slave(devinit->machine, tmp, 0);          d->console_handle[1] = console_start_slave(devinit->machine, tmp, 0);
223    
# Line 233  DEVINIT(z8530) Line 232  DEVINIT(z8530)
232              NULL);              NULL);
233    
234          machine_add_tickfunction(devinit->machine, dev_z8530_tick, d,          machine_add_tickfunction(devinit->machine, dev_z8530_tick, d,
235              ZS_TICK_SHIFT);              ZS_TICK_SHIFT, 0.0);
236    
237          devinit->return_ptr = (void *)(size_t) d->console_handle[0];          devinit->return_ptr = (void *)(size_t) d->console_handle[0];
238    

Legend:
Removed from v.22  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26