/[gxemul]/trunk/src/devices/dev_ps2_stuff.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_ps2_stuff.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 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_ps2_stuff.c,v 1.24 2005/10/26 14:37:04 debug Exp $   *  $Id: dev_ps2_stuff.c,v 1.33 2007/06/15 19:57:33 debug Exp $
29   *     *  
30   *  Playstation 2 misc. stuff:   *  COMMENT: PlayStation 2 misc stuff (timer, DMA, interrupts, ...)
31   *   *
32   *      offset 0x0000   timer control   *      offset 0x0000   timer control
33   *      offset 0x8000   DMA controller   *      offset 0x8000   DMA controller
34   *      offset 0xf000   Interrupt register   *      offset 0xf000   Interrupt register
35     *
36     *  The 16 normal PS2 interrupts interrupt at MIPS interrupt 2.
37     *  The 16 DMA interrupts are connected to MIPS interrupt 3.
38     *
39     *  SBUS interrupts go via PS2 interrupt 1.
40   */   */
41    
42  #include <stdio.h>  #include <stdio.h>
# Line 39  Line 44 
44  #include <string.h>  #include <string.h>
45    
46  #include "cpu.h"  #include "cpu.h"
47  #include "devices.h"  #include "device.h"
48  #include "machine.h"  #include "machine.h"
49  #include "memory.h"  #include "memory.h"
50  #include "misc.h"  #include "misc.h"
# Line 52  Line 57 
57  /*  NOTE/TODO: This should be the same as in ps2_gs:  */  /*  NOTE/TODO: This should be the same as in ps2_gs:  */
58  #define DEV_PS2_GIF_FAKE_BASE           0x50000000  #define DEV_PS2_GIF_FAKE_BASE           0x50000000
59    
60    #define N_PS2_DMA_CHANNELS              10
61    #define N_PS2_TIMERS                    4
62    
63  /*  struct ps2_data {
64   *  dev_ps2_stuff_tick():          uint32_t        timer_count[N_PS2_TIMERS];
65   */          uint32_t        timer_comp[N_PS2_TIMERS];
66  void dev_ps2_stuff_tick(struct cpu *cpu, void *extra)          uint32_t        timer_mode[N_PS2_TIMERS];
67            uint32_t        timer_hold[N_PS2_TIMERS];
68                                    /*  NOTE: only 0 and 1 are valid  */
69            struct interrupt timer_irq[N_PS2_TIMERS];
70    
71            uint64_t        dmac_reg[DMAC_REGSIZE / 0x10];
72            struct interrupt dmac_irq;              /*  MIPS irq 3  */
73            struct interrupt dma_channel2_irq;      /*  irq path of channel 2  */
74    
75            uint64_t        other_memory_base[N_PS2_DMA_CHANNELS];
76    
77            uint32_t        intr;
78            uint32_t        imask;
79            uint32_t        sbus_smflg;
80            struct interrupt intr_irq;              /*  MIPS irq 2  */
81            struct interrupt sbus_irq;              /*  PS2 irq 1  */
82    };
83    
84    #define DEV_PS2_LENGTH          0x10000
85    
86    
87    void ps2_intr_interrupt_assert(struct interrupt *interrupt)
88    {
89            struct ps2_data *d = interrupt->extra;
90            d->intr |= (1 << interrupt->line);
91            if (d->intr & d->imask)
92                    INTERRUPT_ASSERT(d->intr_irq);
93    }
94    void ps2_intr_interrupt_deassert(struct interrupt *interrupt)
95    {
96            struct ps2_data *d = interrupt->extra;
97            d->intr &= ~(1 << interrupt->line);
98            if (!(d->intr & d->imask))
99                    INTERRUPT_DEASSERT(d->intr_irq);
100    }
101    void ps2_dmac_interrupt_assert(struct interrupt *interrupt)
102    {
103            struct ps2_data *d = interrupt->extra;
104            d->dmac_reg[0x601] |= (1 << interrupt->line);
105            /*  TODO: DMA interrupt mask?  */
106            if (d->dmac_reg[0x601] & 0xffff)
107                    INTERRUPT_ASSERT(d->dmac_irq);
108    }
109    void ps2_dmac_interrupt_deassert(struct interrupt *interrupt)
110    {
111            struct ps2_data *d = interrupt->extra;
112            d->dmac_reg[0x601] &= ~(1 << interrupt->line);
113            /*  TODO: DMA interrupt mask?  */
114            if (!(d->dmac_reg[0x601] & 0xffff))
115                    INTERRUPT_DEASSERT(d->dmac_irq);
116    }
117    void ps2_sbus_interrupt_assert(struct interrupt *interrupt)
118    {
119            /*  Note: sbus irq 0 = mask 0x100, sbus irq 1 = mask 0x400  */
120            struct ps2_data *d = interrupt->extra;
121            d->sbus_smflg |= (1 << (8 + interrupt->line * 2));
122            /*  TODO: SBUS interrupt mask?  */
123            if (d->sbus_smflg != 0)
124                    INTERRUPT_ASSERT(d->sbus_irq);
125    }
126    void ps2_sbus_interrupt_deassert(struct interrupt *interrupt)
127    {
128            /*  Note: sbus irq 0 = mask 0x100, sbus irq 1 = mask 0x400  */
129            struct ps2_data *d = interrupt->extra;
130            d->sbus_smflg &= ~(1 << (8 + interrupt->line * 2));
131            /*  TODO: SBUS interrupt mask?  */
132            if (d->sbus_smflg == 0)
133                    INTERRUPT_DEASSERT(d->sbus_irq);
134    }
135    
136    
137    DEVICE_TICK(ps2)
138  {  {
139          struct ps2_data *d = extra;          struct ps2_data *d = extra;
140          int i;          int i;
# Line 75  void dev_ps2_stuff_tick(struct cpu *cpu, Line 153  void dev_ps2_stuff_tick(struct cpu *cpu,
153                          if (d->timer_mode[i] & T_MODE_ZRET)                          if (d->timer_mode[i] & T_MODE_ZRET)
154                                  d->timer_count[i] = 0;                                  d->timer_count[i] = 0;
155    
156                          /*  irq 9 is timer0, etc.  */                          INTERRUPT_ASSERT(d->timer_irq[i]);
                         cpu_interrupt(cpu, 8 + 9 + i);  
157    
158                          /*  timer 1..3 are "single-shot"? TODO  */                          /*  timer 1..3 are "single-shot"? TODO  */
159                          if (i > 0)                          if (i > 0) {
160                                  d->timer_mode[i] &= ~(T_MODE_CMPE | T_MODE_OVFF);                                  d->timer_mode[i] &=
161                                        ~(T_MODE_CMPE | T_MODE_OVFF);
162                            }
163                  }                  }
164          }          }
165  }  }
166    
167    
168  /*  DEVICE_ACCESS(ps2)
  *  dev_ps2_stuff_access():  
  */  
 int dev_ps2_stuff_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
169  {  {
170          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
171          int regnr = 0;          int regnr = 0;
# Line 127  int dev_ps2_stuff_access(struct cpu *cpu Line 201  int dev_ps2_stuff_access(struct cpu *cpu
201                                  /*  :-)  TODO: remove this?  */                                  /*  :-)  TODO: remove this?  */
202                                  d->timer_count[timer_nr] ++;                                  d->timer_count[timer_nr] ++;
203                          }                          }
204                          debug("[ ps2_stuff: read timer %i count: 0x%llx ]\n",                          debug("[ ps2: read timer %i count: 0x%llx ]\n",
205                              timer_nr, (long long)odata);                              timer_nr, (long long)odata);
206                  } else {                  } else {
207                          d->timer_count[timer_nr] = idata;                          d->timer_count[timer_nr] = idata;
208                          debug("[ ps2_stuff: write timer %i count: 0x%llx ]\n",                          debug("[ ps2: write timer %i count: 0x%llx ]\n",
209                              timer_nr, (long long)idata);                              timer_nr, (long long)idata);
210                  }                  }
211                  break;                  break;
212          case 0x0010:    /*  timer mode  */          case 0x0010:    /*  timer mode  */
213                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
214                          odata = d->timer_mode[timer_nr];                          odata = d->timer_mode[timer_nr];
215                          debug("[ ps2_stuff: read timer %i mode: 0x%llx ]\n",                          debug("[ ps2: read timer %i mode: 0x%llx ]\n",
216                              timer_nr, (long long)odata);                              timer_nr, (long long)odata);
217                  } else {                  } else {
218                          d->timer_mode[timer_nr] = idata;                          d->timer_mode[timer_nr] = idata;
219                          debug("[ ps2_stuff: write timer %i mode: 0x%llx ]\n",                          debug("[ ps2: write timer %i mode: 0x%llx ]\n",
220                              timer_nr, (long long)idata);                              timer_nr, (long long)idata);
221                  }                  }
222                  break;                  break;
223          case 0x0020:    /*  timer comp  */          case 0x0020:    /*  timer comp  */
224                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
225                          odata = d->timer_comp[timer_nr];                          odata = d->timer_comp[timer_nr];
226                          debug("[ ps2_stuff: read timer %i comp: 0x%llx ]\n",                          debug("[ ps2: read timer %i comp: 0x%llx ]\n",
227                              timer_nr, (long long)odata);                              timer_nr, (long long)odata);
228                  } else {                  } else {
229                          d->timer_comp[timer_nr] = idata;                          d->timer_comp[timer_nr] = idata;
230                          debug("[ ps2_stuff: write timer %i comp: 0x%llx ]\n",                          debug("[ ps2: write timer %i comp: 0x%llx ]\n",
231                              timer_nr, (long long)idata);                              timer_nr, (long long)idata);
232                  }                  }
233                  break;                  break;
234          case 0x0030:    /*  timer hold  */          case 0x0030:    /*  timer hold  */
235                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
236                          odata = d->timer_hold[timer_nr];                          odata = d->timer_hold[timer_nr];
237                          debug("[ ps2_stuff: read timer %i hold: 0x%llx ]\n",                          debug("[ ps2: read timer %i hold: 0x%llx ]\n",
238                              timer_nr, (long long)odata);                              timer_nr, (long long)odata);
239                          if (timer_nr >= 2)                          if (timer_nr >= 2)
240                                  fatal("[ WARNING: ps2_stuff: read from non-"                                  fatal("[ WARNING: ps2: read from non-"
241                                      "existant timer %i hold register ]\n");                                      "existant timer %i hold register ]\n");
242                  } else {                  } else {
243                          d->timer_hold[timer_nr] = idata;                          d->timer_hold[timer_nr] = idata;
244                          debug("[ ps2_stuff: write timer %i hold: 0x%llx ]\n",                          debug("[ ps2: write timer %i hold: 0x%llx ]\n",
245                              timer_nr, (long long)idata);                              timer_nr, (long long)idata);
246                          if (timer_nr >= 2)                          if (timer_nr >= 2)
247                                  fatal("[ WARNING: ps2_stuff: write to "                                  fatal("[ WARNING: ps2: write to "
248                                      "non-existant timer %i hold register ]\n",                                      "non-existant timer %i hold register ]\n",
249                                      timer_nr);                                      timer_nr);
250                  }                  }
# Line 179  int dev_ps2_stuff_access(struct cpu *cpu Line 253  int dev_ps2_stuff_access(struct cpu *cpu
253          case 0x8000 + D2_CHCR_REG:          case 0x8000 + D2_CHCR_REG:
254                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
255                          odata = d->dmac_reg[regnr];                          odata = d->dmac_reg[regnr];
256                          /*  debug("[ ps2_stuff: dmac read from D2_CHCR "                          /*  debug("[ ps2: dmac read from D2_CHCR "
257                              "(0x%llx) ]\n", (long long)d->dmac_reg[regnr]);  */                              "(0x%llx) ]\n", (long long)d->dmac_reg[regnr]);  */
258                  } else {                  } else {
259                          /*  debug("[ ps2_stuff: dmac write to D2_CHCR, "                          /*  debug("[ ps2: dmac write to D2_CHCR, "
260                              "data 0x%016llx ]\n", (long long) idata);  */                              "data 0x%016llx ]\n", (long long) idata);  */
261                          if (idata & D_CHCR_STR) {                          if (idata & D_CHCR_STR) {
262                                  int length = d->dmac_reg[D2_QWC_REG/0x10] * 16;                                  int length = d->dmac_reg[D2_QWC_REG/0x10] * 16;
# Line 192  int dev_ps2_stuff_access(struct cpu *cpu Line 266  int dev_ps2_stuff_access(struct cpu *cpu
266                                      D2_TADR_REG/0x10];                                      D2_TADR_REG/0x10];
267                                  unsigned char *copy_buf;                                  unsigned char *copy_buf;
268    
269                                  debug("[ ps2_stuff: dmac [ch2] transfer addr="                                  debug("[ ps2: dmac [ch2] transfer addr="
270                                      "0x%016llx len=0x%lx ]\n", (long long)                                      "0x%016llx len=0x%lx ]\n", (long long)
271                                      d->dmac_reg[D2_MADR_REG/0x10],                                      d->dmac_reg[D2_MADR_REG/0x10],
272                                      (long)length);                                      (long)length);
273    
274                                  copy_buf = malloc(length);                                  CHECK_ALLOCATION(copy_buf = malloc(length));
275                                  if (copy_buf == NULL) {  
                                         fprintf(stderr, "out of memory in "  
                                             "dev_ps2_stuff_access()\n");  
                                         exit(1);  
                                 }  
276                                  cpu->memory_rw(cpu, cpu->mem, from_addr,                                  cpu->memory_rw(cpu, cpu->mem, from_addr,
277                                      copy_buf, length, MEM_READ,                                      copy_buf, length, MEM_READ,
278                                      CACHE_NONE | PHYSICAL);                                      CACHE_NONE | PHYSICAL);
# Line 217  int dev_ps2_stuff_access(struct cpu *cpu Line 287  int dev_ps2_stuff_access(struct cpu *cpu
287                                  idata &= ~D_CHCR_STR;                                  idata &= ~D_CHCR_STR;
288    
289                                  /*  interrupt DMA channel 2  */                                  /*  interrupt DMA channel 2  */
290                                  cpu_interrupt(cpu, 8 + 16 + 2);                                  INTERRUPT_ASSERT(d->dma_channel2_irq);
291                          } else                          } else
292                                  debug("[ ps2_stuff: dmac [ch2] stopping "                                  debug("[ ps2: dmac [ch2] stopping "
293                                      "transfer ]\n");                                      "transfer ]\n");
294                          d->dmac_reg[regnr] = idata;                          d->dmac_reg[regnr] = idata;
295                          return 1;                          return 1;
# Line 242  int dev_ps2_stuff_access(struct cpu *cpu Line 312  int dev_ps2_stuff_access(struct cpu *cpu
312                          d->dmac_reg[regnr] |= oldmask;                          d->dmac_reg[regnr] |= oldmask;
313                          if (((d->dmac_reg[regnr] & 0xffff) &                          if (((d->dmac_reg[regnr] & 0xffff) &
314                              ((d->dmac_reg[regnr]>>16) & 0xffff)) == 0) {                              ((d->dmac_reg[regnr]>>16) & 0xffff)) == 0) {
315                                  /*  irq 3 is the DMAC  */                                  INTERRUPT_DEASSERT(d->dmac_irq);
                                 cpu_interrupt_ack(cpu, 3);  
316                          }                          }
317                  } else {                  } else {
318                          /*  Hm... make it seem like the mask bits are (at                          /*  Hm... make it seem like the mask bits are (at
# Line 256  int dev_ps2_stuff_access(struct cpu *cpu Line 325  int dev_ps2_stuff_access(struct cpu *cpu
325          case 0xf000:    /*  interrupt register  */          case 0xf000:    /*  interrupt register  */
326                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
327                          odata = d->intr;                          odata = d->intr;
328                          debug("[ ps2_stuff: read from Interrupt Register:"                          debug("[ ps2: read from Interrupt Register:"
329                              " 0x%llx ]\n", (long long)odata);                              " 0x%llx ]\n", (long long)odata);
330    
331                          /*  TODO: This is _NOT_ correct behavior:  */                          /*  TODO: This is _NOT_ correct behavior:  */
332                          d->intr = 0;  //                      d->intr = 0;
333                          cpu_interrupt_ack(cpu, 2);  //                      INTERRUPT_DEASSERT(d->intr_irq);
334                  } else {                  } else {
335                          debug("[ ps2_stuff: write to Interrupt Register: "                          debug("[ ps2: write to Interrupt Register: "
336                              "0x%llx ]\n", (long long)idata);                              "0x%llx ]\n", (long long)idata);
337                          /*  Clear out bits that are set in idata:  */                          /*  Clear out bits that are set in idata:  */
338                          d->intr &= ~idata;                          d->intr &= ~idata;
339    
340                          if ((d->intr & d->imask) == 0)                          if ((d->intr & d->imask) == 0)
341                                  cpu_interrupt_ack(cpu, 2);                                  INTERRUPT_DEASSERT(d->intr_irq);
342                  }                  }
343                  break;                  break;
344    
345          case 0xf010:    /*  interrupt mask  */          case 0xf010:    /*  interrupt mask  */
346                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
347                          odata = d->imask;                          odata = d->imask;
348                          /*  debug("[ ps2_stuff: read from Interrupt Mask "                          /*  debug("[ ps2: read from Interrupt Mask "
349                              "Register: 0x%llx ]\n", (long long)odata);  */                              "Register: 0x%llx ]\n", (long long)odata);  */
350                  } else {                  } else {
351                          /*  debug("[ ps2_stuff: write to Interrupt Mask "                          /*  debug("[ ps2: write to Interrupt Mask "
352                              "Register: 0x%llx ]\n", (long long)idata);  */                              "Register: 0x%llx ]\n", (long long)idata);  */
353                          d->imask = idata;                          /*  Note: written value indicates which bits
354                                to _toggle_, not which bits to set!  */
355                            d->imask ^= idata;
356                  }                  }
357                  break;                  break;
358    
359          case 0xf230:    /*  sbus interrupt register?  */          case 0xf230:    /*  sbus interrupt register?  */
360                  if (writeflag == MEM_READ) {                  if (writeflag == MEM_READ) {
361                          odata = d->sbus_smflg;                          odata = d->sbus_smflg;
362                          debug("[ ps2_stuff: read from SBUS SMFLG:"                          debug("[ ps2: read from SBUS SMFLG:"
363                              " 0x%llx ]\n", (long long)odata);                              " 0x%llx ]\n", (long long)odata);
364                  } else {                  } else {
365                          /*  Clear bits on write:  */                          /*  Clear bits on write:  */
366                          debug("[ ps2_stuff: write to SBUS SMFLG:"                          debug("[ ps2: write to SBUS SMFLG:"
367                              " 0x%llx ]\n", (long long)idata);                              " 0x%llx ]\n", (long long)idata);
368                          d->sbus_smflg &= ~idata;                          d->sbus_smflg &= ~idata;
369                          /*  irq 1 is SBUS  */                          /*  irq 1 is SBUS  */
370                          if (d->sbus_smflg == 0)                          if (d->sbus_smflg == 0)
371                                  cpu_interrupt_ack(cpu, 8 + 1);                                  INTERRUPT_DEASSERT(d->sbus_irq);
372                  }                  }
373                  break;                  break;
374          default:          default:
375                  if (writeflag==MEM_READ) {                  if (writeflag==MEM_READ) {
376                          debug("[ ps2_stuff: read from addr 0x%x: 0x%llx ]\n",                          debug("[ ps2: read from addr 0x%x: 0x%llx ]\n",
377                              (int)relative_addr, (long long)odata);                              (int)relative_addr, (long long)odata);
378                  } else {                  } else {
379                          debug("[ ps2_stuff: write to addr 0x%x: 0x%llx ]\n",                          debug("[ ps2: write to addr 0x%x: 0x%llx ]\n",
380                              (int)relative_addr, (long long)idata);                              (int)relative_addr, (long long)idata);
381                  }                  }
382          }          }
# Line 317  int dev_ps2_stuff_access(struct cpu *cpu Line 388  int dev_ps2_stuff_access(struct cpu *cpu
388  }  }
389    
390    
391  /*  DEVINIT(ps2)
  *  dev_ps2_stuff_init():  
  */  
 struct ps2_data *dev_ps2_stuff_init(struct machine *machine,  
         struct memory *mem, uint64_t baseaddr)  
392  {  {
393          struct ps2_data *d;          struct ps2_data *d;
394            int i;
395            struct interrupt template;
396            char n[300];
397    
398          d = malloc(sizeof(struct ps2_data));          CHECK_ALLOCATION(d = malloc(sizeof(struct ps2_data)));
         if (d == NULL) {  
                 fprintf(stderr, "out of memory\n");  
                 exit(1);  
         }  
399          memset(d, 0, sizeof(struct ps2_data));          memset(d, 0, sizeof(struct ps2_data));
400    
401          d->other_memory_base[DMA_CH_GIF] = DEV_PS2_GIF_FAKE_BASE;          d->other_memory_base[DMA_CH_GIF] = DEV_PS2_GIF_FAKE_BASE;
402    
403          memory_device_register(mem, "ps2_stuff", baseaddr,          /*  Connect to MIPS irq 2 (interrupt controller) and 3 (dmac):  */
404              DEV_PS2_STUFF_LENGTH, dev_ps2_stuff_access, d, MEM_DEFAULT, NULL);          snprintf(n, sizeof(n), "%s.2", devinit->interrupt_path);
405          machine_add_tickfunction(machine,          INTERRUPT_CONNECT(n, d->intr_irq);
406              dev_ps2_stuff_tick, d, TICK_STEPS_SHIFT);          snprintf(n, sizeof(n), "%s.3", devinit->interrupt_path);
407            INTERRUPT_CONNECT(n, d->dmac_irq);
408    
409            /*
410             *  Register interrupts:
411             *
412             *      16 normal IRQs  (emul[x].machine[x].cpu[x].ps2_intr.%i)
413             *      16 DMA IRQs     (emul[x].machine[x].cpu[x].ps2_dmac.%i)
414             *       2 sbus IRQs    (emul[x].machine[x].cpu[x].ps2_sbus.%i)
415             */
416            for (i=0; i<16; i++) {
417                    snprintf(n, sizeof(n), "%s.ps2_intr.%i",
418                        devinit->interrupt_path, i);
419                    memset(&template, 0, sizeof(template));
420                    template.line = i;
421                    template.name = n;
422                    template.extra = d;
423                    template.interrupt_assert = ps2_intr_interrupt_assert;
424                    template.interrupt_deassert = ps2_intr_interrupt_deassert;
425                    interrupt_handler_register(&template);
426            }
427            for (i=0; i<16; i++) {
428                    snprintf(n, sizeof(n), "%s.ps2_dmac.%i",
429                        devinit->interrupt_path, i);
430                    memset(&template, 0, sizeof(template));
431                    template.line = i;
432                    template.name = n;
433                    template.extra = d;
434                    template.interrupt_assert = ps2_dmac_interrupt_assert;
435                    template.interrupt_deassert = ps2_dmac_interrupt_deassert;
436                    interrupt_handler_register(&template);
437            }
438            for (i=0; i<2; i++) {
439                    snprintf(n, sizeof(n), "%s.ps2_sbus.%i",
440                        devinit->interrupt_path, i);
441                    memset(&template, 0, sizeof(template));
442                    template.line = i;
443                    template.name = n;
444                    template.extra = d;
445                    template.interrupt_assert = ps2_sbus_interrupt_assert;
446                    template.interrupt_deassert = ps2_sbus_interrupt_deassert;
447                    interrupt_handler_register(&template);
448            }
449    
450            /*  Connect to DMA channel 2 irq:  */
451            snprintf(n, sizeof(n), "%s.ps2_dmac.2", devinit->interrupt_path);
452            INTERRUPT_CONNECT(n, d->dma_channel2_irq);
453    
454            /*  Connect to SBUS interrupt, at ps2 interrupt 1:  */
455            snprintf(n, sizeof(n), "%s.ps2_intr.1", devinit->interrupt_path);
456            INTERRUPT_CONNECT(n, d->sbus_irq);
457    
458          return d;          /*  Connect to the timers' interrupts:  */
459            for (i=0; i<N_PS2_TIMERS; i++) {
460                    /*  PS2 irq 9 is timer0, etc.  */
461                    snprintf(n, sizeof(n), "%s.ps2_intr.%i",
462                        devinit->interrupt_path, 9 + i);
463                    INTERRUPT_CONNECT(n, d->timer_irq[i]);
464            }
465    
466            memory_device_register(devinit->machine->memory, "ps2", devinit->addr,
467                DEV_PS2_LENGTH, dev_ps2_access, d, DM_DEFAULT, NULL);
468            machine_add_tickfunction(devinit->machine,
469                dev_ps2_tick, d, TICK_STEPS_SHIFT);
470    
471            return 1;
472  }  }
473    

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

  ViewVC Help
Powered by ViewVC 1.1.26