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

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

revision 18 by dpavlin, Mon Oct 8 16:19:11 2007 UTC revision 22 by dpavlin, Mon Oct 8 16:19:37 2007 UTC
# Line 1  Line 1 
1  /*  /*
2   *  Copyright (C) 2003-2005  Anders Gavare.  All rights reserved.   *  Copyright (C) 2003-2006  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_ns16550.c,v 1.42 2005/10/26 14:37:04 debug Exp $   *  $Id: dev_ns16550.c,v 1.51 2006/02/18 13:42:39 debug Exp $
29   *     *  
30   *  NS16550 serial controller.   *  NS16550 serial controller.
31   *   *
# Line 62  struct ns_data { Line 62  struct ns_data {
62    
63          unsigned char   reg[DEV_NS16550_LENGTH];          unsigned char   reg[DEV_NS16550_LENGTH];
64          unsigned char   fcr;            /*  FIFO control register  */          unsigned char   fcr;            /*  FIFO control register  */
65            int             int_asserted;
66          int             dlab;           /*  Divisor Latch Access bit  */          int             dlab;           /*  Divisor Latch Access bit  */
67          int             divisor;          int             divisor;
68    
# Line 84  void dev_ns16550_tick(struct cpu *cpu, v Line 84  void dev_ns16550_tick(struct cpu *cpu, v
84          struct ns_data *d = extra;          struct ns_data *d = extra;
85    
86          d->reg[com_iir] &= ~IIR_RXRDY;          d->reg[com_iir] &= ~IIR_RXRDY;
87          if (d->in_use && console_charavail(d->console_handle))          if (console_charavail(d->console_handle))
88                  d->reg[com_iir] |= IIR_RXRDY;                  d->reg[com_iir] |= IIR_RXRDY;
89    
90          /*          /*
# Line 94  void dev_ns16550_tick(struct cpu *cpu, v Line 94  void dev_ns16550_tick(struct cpu *cpu, v
94          if (((d->reg[com_ier] & IER_ETXRDY) && (d->reg[com_iir] & IIR_TXRDY)) ||          if (((d->reg[com_ier] & IER_ETXRDY) && (d->reg[com_iir] & IIR_TXRDY)) ||
95              ((d->reg[com_ier] & IER_ERXRDY) && (d->reg[com_iir] & IIR_RXRDY))) {              ((d->reg[com_ier] & IER_ERXRDY) && (d->reg[com_iir] & IIR_RXRDY))) {
96                  d->reg[com_iir] &= ~IIR_NOPEND;                  d->reg[com_iir] &= ~IIR_NOPEND;
97                  if (d->reg[com_mcr] & MCR_IENABLE)                  if (d->reg[com_mcr] & MCR_IENABLE) {
98                          cpu_interrupt(cpu, d->irqnr);                          cpu_interrupt(cpu, d->irqnr);
99                            d->int_asserted = 1;
100                    }
101          } else {          } else {
102                  d->reg[com_iir] |= IIR_NOPEND;                  d->reg[com_iir] |= IIR_NOPEND;
103                  cpu_interrupt_ack(cpu, d->irqnr);                  if (d->int_asserted)
104                            cpu_interrupt_ack(cpu, d->irqnr);
105                    d->int_asserted = 0;
106          }          }
107  }  }
108    
# Line 106  void dev_ns16550_tick(struct cpu *cpu, v Line 110  void dev_ns16550_tick(struct cpu *cpu, v
110  /*  /*
111   *  dev_ns16550_access():   *  dev_ns16550_access():
112   */   */
113  int dev_ns16550_access(struct cpu *cpu, struct memory *mem,  DEVICE_ACCESS(ns16550)
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
114  {  {
115          uint64_t idata = 0, odata=0;          uint64_t idata = 0, odata=0;
116          int i;          size_t i;
117          struct ns_data *d = extra;          struct ns_data *d = extra;
118    
119          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
120                  idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
121    
122    #if 0
123          /*  The NS16550 should be accessed using byte read/writes:  */          /*  The NS16550 should be accessed using byte read/writes:  */
124          if (len != 1)          if (len != 1)
125                  fatal("[ ns16550 (%s): len=%i, idata=0x%16llx! ]\n",                  fatal("[ ns16550 (%s): len=%i, idata=0x%16llx! ]\n",
126                      d->name, len, (long long)idata);                      d->name, len, (long long)idata);
127    #endif
128    
129          /*          /*
130           *  Always ready to transmit:           *  Always ready to transmit:
# Line 133  int dev_ns16550_access(struct cpu *cpu, Line 137  int dev_ns16550_access(struct cpu *cpu,
137                  d->reg[com_iir] |= ((d->fcr << 5) & 0xc0);                  d->reg[com_iir] |= ((d->fcr << 5) & 0xc0);
138    
139          d->reg[com_lsr] &= ~LSR_RXRDY;          d->reg[com_lsr] &= ~LSR_RXRDY;
140          if (d->in_use && console_charavail(d->console_handle))          if (console_charavail(d->console_handle))
141                  d->reg[com_lsr] |= LSR_RXRDY;                  d->reg[com_lsr] |= LSR_RXRDY;
142    
143          relative_addr /= d->addrmult;          relative_addr /= d->addrmult;
# Line 166  int dev_ns16550_access(struct cpu *cpu, Line 170  int dev_ns16550_access(struct cpu *cpu,
170                                  console_putchar(d->console_handle, idata);                                  console_putchar(d->console_handle, idata);
171                          d->reg[com_iir] |= IIR_TXRDY;                          d->reg[com_iir] |= IIR_TXRDY;
172                  } else {                  } else {
173                          if (d->in_use)                          int x = console_readchar(d->console_handle);
174                                  odata = console_readchar(d->console_handle);                          odata = x < 0? 0 : x;
                         else  
                                 odata = 0;  
175                  }                  }
176                  dev_ns16550_tick(cpu, d);                  dev_ns16550_tick(cpu, d);
177                  break;                  break;
# Line 314  int dev_ns16550_access(struct cpu *cpu, Line 316  int dev_ns16550_access(struct cpu *cpu,
316  }  }
317    
318    
319  /*  DEVINIT(ns16550)
  *  devinit_ns16550():  
  */  
 int devinit_ns16550(struct devinit *devinit)  
320  {  {
321          struct ns_data *d = malloc(sizeof(struct ns_data));          struct ns_data *d = malloc(sizeof(struct ns_data));
322          size_t nlen;          size_t nlen;
# Line 339  int devinit_ns16550(struct devinit *devi Line 338  int devinit_ns16550(struct devinit *devi
338          d->stopbits     = "1";          d->stopbits     = "1";
339          d->name         = devinit->name2 != NULL? devinit->name2 : "";          d->name         = devinit->name2 != NULL? devinit->name2 : "";
340          d->console_handle =          d->console_handle =
341              console_start_slave(devinit->machine, devinit->name);              console_start_slave(devinit->machine, devinit->name2 != NULL?
342                devinit->name2 : devinit->name, d->in_use);
343    
344          nlen = strlen(devinit->name) + 10;          nlen = strlen(devinit->name) + 10;
345          if (devinit->name2 != NULL)          if (devinit->name2 != NULL)
# Line 356  int devinit_ns16550(struct devinit *devi Line 356  int devinit_ns16550(struct devinit *devi
356    
357          memory_device_register(devinit->machine->memory, name, devinit->addr,          memory_device_register(devinit->machine->memory, name, devinit->addr,
358              DEV_NS16550_LENGTH * d->addrmult, dev_ns16550_access, d,              DEV_NS16550_LENGTH * d->addrmult, dev_ns16550_access, d,
359              MEM_DEFAULT, NULL);              DM_DEFAULT, NULL);
360          machine_add_tickfunction(devinit->machine,          machine_add_tickfunction(devinit->machine,
361              dev_ns16550_tick, d, TICK_SHIFT);              dev_ns16550_tick, d, TICK_SHIFT);
362    

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

  ViewVC Help
Powered by ViewVC 1.1.26