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

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

revision 20 by dpavlin, Mon Oct 8 16:19:23 2007 UTC revision 42 by dpavlin, Mon Oct 8 16:22:32 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2007  Anders Gavare.  All rights reserved.
3   *   *
4   *  Redistribution and use in source and binary forms, with or without   *  Redistribution and use in source and binary forms, with or without
5   *  modification, are permitted provided that the following conditions are met:   *  modification, are permitted provided that the following conditions are met:
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_dc7085.c,v 1.51 2005/11/13 00:14:08 debug Exp $   *  $Id: dev_dc7085.c,v 1.62 2007/06/15 18:44:19 debug Exp $
29   *     *  
30   *  DC7085 serial controller, used in some DECstation models.   *  COMMENT: DC7085 serial controller, used in some DECstation models
31   */   */
32    
33  #include <stdio.h>  #include <stdio.h>
# Line 46  Line 46 
46    
47  #define DC_TICK_SHIFT           14  #define DC_TICK_SHIFT           14
48    
49  #define MAX_QUEUE_LEN           4096  #define MAX_QUEUE_LEN           32768
50    
51  struct dc_data {  struct dc_data {
52          struct dc7085regs       regs;          struct dc7085regs       regs;
# Line 63  struct dc_data { Line 63  struct dc_data {
63    
64          int                     tx_scanner;          int                     tx_scanner;
65    
66          int                     irqnr;          struct interrupt        irq;
67          int                     use_fb;          int                     use_fb;
68    
69          struct lk201_data       lk201;          struct lk201_data       lk201;
# Line 78  void add_to_rx_queue(void *e, int ch, in Line 78  void add_to_rx_queue(void *e, int ch, in
78          struct dc_data *d = (struct dc_data *) e;          struct dc_data *d = (struct dc_data *) e;
79          int entries_in_use = d->cur_rx_queue_pos_write -          int entries_in_use = d->cur_rx_queue_pos_write -
80              d->cur_rx_queue_pos_read;              d->cur_rx_queue_pos_read;
81    
82          while (entries_in_use < 0)          while (entries_in_use < 0)
83                  entries_in_use += MAX_QUEUE_LEN;                  entries_in_use += MAX_QUEUE_LEN;
84    
# Line 96  void add_to_rx_queue(void *e, int ch, in Line 97  void add_to_rx_queue(void *e, int ch, in
97  }  }
98    
99    
100  /*  DEVICE_TICK(dc7085)
  *  dev_dc7085_tick():  
  *  
  *  This function is called "every now and then".  
  *  If a key is available from the keyboard, add it to the rx queue.  
  *  If other bits are set, an interrupt might need to be caused.  
  */  
 void dev_dc7085_tick(struct cpu *cpu, void *extra)  
101  {  {
102            /*
103             *  If a key is available from the keyboard, add it to the rx queue.
104             *  If other bits are set, an interrupt might need to be caused.
105             */
106          struct dc_data *d = extra;          struct dc_data *d = extra;
107          int avail;          int avail;
108    
# Line 133  void dev_dc7085_tick(struct cpu *cpu, vo Line 131  void dev_dc7085_tick(struct cpu *cpu, vo
131                          if (d->regs.dc_tcr & (1 << d->tx_scanner)) {                          if (d->regs.dc_tcr & (1 << d->tx_scanner)) {
132                                  d->regs.dc_csr |= CSR_TRDY;                                  d->regs.dc_csr |= CSR_TRDY;
133                                  if (d->regs.dc_csr & CSR_TIE)                                  if (d->regs.dc_csr & CSR_TIE)
134                                          cpu_interrupt(cpu, d->irqnr);                                          INTERRUPT_ASSERT(d->irq);
135    
136                                  d->regs.dc_csr &= ~CSR_TX_LINE_NUM;                                  d->regs.dc_csr &= ~CSR_TX_LINE_NUM;
137                                  d->regs.dc_csr |= (d->tx_scanner << 8);                                  d->regs.dc_csr |= (d->tx_scanner << 8);
# Line 149  void dev_dc7085_tick(struct cpu *cpu, vo Line 147  void dev_dc7085_tick(struct cpu *cpu, vo
147                          return;                          return;
148          }          }
149    
150          lk201_tick(&d->lk201);          lk201_tick(cpu->machine, &d->lk201);
151    
152          avail = d->cur_rx_queue_pos_write != d->cur_rx_queue_pos_read;          avail = d->cur_rx_queue_pos_write != d->cur_rx_queue_pos_read;
153    
# Line 157  void dev_dc7085_tick(struct cpu *cpu, vo Line 155  void dev_dc7085_tick(struct cpu *cpu, vo
155                  d->regs.dc_csr |= CSR_RDONE;                  d->regs.dc_csr |= CSR_RDONE;
156    
157          if ((d->regs.dc_csr & CSR_RDONE) && (d->regs.dc_csr & CSR_RIE))          if ((d->regs.dc_csr & CSR_RDONE) && (d->regs.dc_csr & CSR_RIE))
158                  cpu_interrupt(cpu, d->irqnr);                  INTERRUPT_ASSERT(d->irq);
159  }  }
160    
161    
162  /*  DEVICE_ACCESS(dc7085)
  *  dev_dc7085_access():  
  */  
 int dev_dc7085_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
163  {  {
         uint64_t idata = 0, odata = 0;  
         int i;  
164          struct dc_data *d = extra;          struct dc_data *d = extra;
165            uint64_t idata = 0, odata = 0;
166            size_t i;
167    
168          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
169                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
# Line 179  int dev_dc7085_access(struct cpu *cpu, s Line 172  int dev_dc7085_access(struct cpu *cpu, s
172          d->regs.dc_csr &= ~CSR_CLR;          d->regs.dc_csr &= ~CSR_CLR;
173    
174          switch (relative_addr) {          switch (relative_addr) {
175    
176          case 0x00:      /*  CSR:  Control and Status  */          case 0x00:      /*  CSR:  Control and Status  */
177                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
178                          debug("[ dc7085 write to CSR: 0x%04x ]\n", idata);                          debug("[ dc7085 write to CSR: 0x%04x ]\n", idata);
# Line 198  int dev_dc7085_access(struct cpu *cpu, s Line 192  int dev_dc7085_access(struct cpu *cpu, s
192                          odata = d->regs.dc_csr;                          odata = d->regs.dc_csr;
193                  }                  }
194                  break;                  break;
195    
196          case 0x08:      /*  LPR:  */          case 0x08:      /*  LPR:  */
197                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
198                          debug("[ dc7085 write to LPR: 0x%04x ]\n", idata);                          debug("[ dc7085 write to LPR: 0x%04x ]\n", idata);
# Line 228  int dev_dc7085_access(struct cpu *cpu, s Line 223  int dev_dc7085_access(struct cpu *cpu, s
223                              (lineno << RBUF_LINE_NUM_SHIFT) | ch;                              (lineno << RBUF_LINE_NUM_SHIFT) | ch;
224    
225                          d->regs.dc_csr &= ~CSR_RDONE;                          d->regs.dc_csr &= ~CSR_RDONE;
226                          cpu_interrupt_ack(cpu, d->irqnr);                          INTERRUPT_DEASSERT(d->irq);
227    
228                          d->just_transmitted_something = 4;                          d->just_transmitted_something = 4;
229                  }                  }
230                  break;                  break;
231    
232          case 0x10:      /*  TCR:  */          case 0x10:      /*  TCR:  */
233                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
234                          /*  fatal("[ dc7085 write to TCR: 0x%04x) ]\n",                          /*  fatal("[ dc7085 write to TCR: 0x%04x) ]\n",
235                              (int)idata);  */                              (int)idata);  */
236                          d->regs.dc_tcr = idata;                          d->regs.dc_tcr = idata;
237                          d->regs.dc_csr &= ~CSR_TRDY;                          d->regs.dc_csr &= ~CSR_TRDY;
238                          cpu_interrupt_ack(cpu, d->irqnr);                          INTERRUPT_DEASSERT(d->irq);
239                          goto do_return;                          goto do_return;
240                  } else {                  } else {
241                          /*  read:  */                          /*  read:  */
# Line 248  int dev_dc7085_access(struct cpu *cpu, s Line 244  int dev_dc7085_access(struct cpu *cpu, s
244                          odata = d->regs.dc_tcr;                          odata = d->regs.dc_tcr;
245                  }                  }
246                  break;                  break;
247    
248          case 0x18:      /*  Modem status (R), transmit data (W)  */          case 0x18:      /*  Modem status (R), transmit data (W)  */
249                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
250                          int line_no = (d->regs.dc_csr >>                          int line_no = (d->regs.dc_csr >>
# Line 257  int dev_dc7085_access(struct cpu *cpu, s Line 254  int dev_dc7085_access(struct cpu *cpu, s
254                          lk201_tx_data(&d->lk201, line_no, idata);                          lk201_tx_data(&d->lk201, line_no, idata);
255    
256                          d->regs.dc_csr &= ~CSR_TRDY;                          d->regs.dc_csr &= ~CSR_TRDY;
257                          cpu_interrupt_ack(cpu, d->irqnr);                          INTERRUPT_DEASSERT(d->irq);
258    
259                          d->just_transmitted_something = 4;                          d->just_transmitted_something = 4;
260                  } else {                  } else {
# Line 269  int dev_dc7085_access(struct cpu *cpu, s Line 266  int dev_dc7085_access(struct cpu *cpu, s
266                          odata = d->regs.dc_msr_tdr;                          odata = d->regs.dc_msr_tdr;
267                  }                  }
268                  break;                  break;
269    
270          default:          default:
271                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
272                          debug("[ dc7085 read from 0x%08lx ]\n",                          debug("[ dc7085 read from 0x%08lx ]\n",
# Line 300  do_return: Line 298  do_return:
298   *  DECstation keyboard, instead of a plain serial console.   *  DECstation keyboard, instead of a plain serial console.
299   */   */
300  int dev_dc7085_init(struct machine *machine, struct memory *mem,  int dev_dc7085_init(struct machine *machine, struct memory *mem,
301          uint64_t baseaddr, int irq_nr, int use_fb)          uint64_t baseaddr, char *irq_path, int use_fb)
302  {  {
303          struct dc_data *d;          struct dc_data *d;
304    
305          d = malloc(sizeof(struct dc_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct dc_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
306          memset(d, 0, sizeof(struct dc_data));          memset(d, 0, sizeof(struct dc_data));
307          d->irqnr  = irq_nr;  
308            INTERRUPT_CONNECT(irq_path, d->irq);
309          d->use_fb = use_fb;          d->use_fb = use_fb;
310    
311          d->regs.dc_csr = CSR_TRDY | CSR_MSE;          d->regs.dc_csr = CSR_TRDY | CSR_MSE;
312          d->regs.dc_tcr = 0x00;          d->regs.dc_tcr = 0x00;
313    
314          d->console_handle = console_start_slave(machine, "DC7085");          d->console_handle = console_start_slave(machine, "DC7085", 1);
315    
316          lk201_init(&d->lk201, use_fb, add_to_rx_queue, d->console_handle, d);          lk201_init(&d->lk201, use_fb, add_to_rx_queue, d->console_handle, d);
317    
318          memory_device_register(mem, "dc7085", baseaddr, DEV_DC7085_LENGTH,          memory_device_register(mem, "dc7085", baseaddr, DEV_DC7085_LENGTH,
319              dev_dc7085_access, d, DM_DEFAULT, NULL);              dev_dc7085_access, d, DM_DEFAULT, NULL);
320          machine_add_tickfunction(machine, dev_dc7085_tick, d, DC_TICK_SHIFT);          machine_add_tickfunction(machine, dev_dc7085_tick, d,
321                DC_TICK_SHIFT);
322    
323          return d->console_handle;          return d->console_handle;
324  }  }

Legend:
Removed from v.20  
changed lines
  Added in v.42

  ViewVC Help
Powered by ViewVC 1.1.26