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

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

revision 6 by dpavlin, Mon Oct 8 16:18:11 2007 UTC revision 28 by dpavlin, Mon Oct 8 16:20:26 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_asc.c,v 1.71 2005/05/15 01:55:50 debug Exp $   *  $Id: dev_asc.c,v 1.81 2006/07/21 16:55:41 debug Exp $
29   *   *
30   *  'asc' SCSI controller for some DECstation/DECsystem models, and   *  'asc' SCSI controller for some DECstation/DECsystem models and PICA-61.
  *  for PICA-61.  
31   *   *
32   *  Supposed to support SCSI-1 and SCSI-2. I've not yet found any docs   *  Supposed to support SCSI-1 and SCSI-2. I've not yet found any docs
33   *  on NCR53C9X, so I'll try to implement this device from LSI53CF92A docs   *  on NCR53C9X, so I'll try to implement this device from LSI53CF92A docs
# Line 50  Line 49 
49   *  TODO:  This module needs a clean-up, and some testing to see that   *  TODO:  This module needs a clean-up, and some testing to see that
50   *         it works will all OSes that might use it (NetBSD, OpenBSD,   *         it works will all OSes that might use it (NetBSD, OpenBSD,
51   *         Ultrix, Linux, Mach, OSF/1, Sprite, ...)   *         Ultrix, Linux, Mach, OSF/1, Sprite, ...)
52     *
53     *         Running Linux/DECstation 2.4.26 with no scsi disks attached causes
54     *         a warning message to be printed by Linux. (Whether this is a bug,
55     *         is is the way it works on real hardware, I don't know.)
56   */   */
57    
58  #include <stdio.h>  #include <stdio.h>
# Line 71  Line 74 
74  /*  #define ASC_FULL_REGISTER_ACCESS_DEBUG  */  /*  #define ASC_FULL_REGISTER_ACCESS_DEBUG  */
75  /*  static int quiet_mode = 0;  */  /*  static int quiet_mode = 0;  */
76    
77    #define ASC_TICK_SHIFT          15
78    
79  extern int quiet_mode;  extern int quiet_mode;
80    
81    
# Line 90  extern int quiet_mode; Line 95  extern int quiet_mode;
95  /*  The controller's SCSI id:  */  /*  The controller's SCSI id:  */
96  #define ASC_SCSI_ID             7  #define ASC_SCSI_ID             7
97    
98    #define ASC_DMA_SIZE            (128*1024)
99    
100  struct asc_data {  struct asc_data {
101          int             mode;          int             mode;
102    
# Line 118  struct asc_data { Line 125  struct asc_data {
125    
126          /*  Built-in DMA memory (for DECstation 5000/200):  */          /*  Built-in DMA memory (for DECstation 5000/200):  */
127          uint32_t        dma_address_reg;          uint32_t        dma_address_reg;
128          unsigned char   dma_address_reg_memory[4096];          unsigned char   *dma_address_reg_memory;
129                                  /*  NOTE: full page, for bintrans  */          unsigned char   *dma;
         unsigned char   dma[128 * 1024];  
130    
131          void            *dma_controller_data;          void            *dma_controller_data;
132          size_t          (*dma_controller)(void *dma_controller_data,          size_t          (*dma_controller)(void *dma_controller_data,
# Line 146  static int dev_asc_select(struct cpu *cp Line 152  static int dev_asc_select(struct cpu *cp
152          int to_id, int dmaflag, int n_messagebytes);          int to_id, int dmaflag, int n_messagebytes);
153    
154    
155  /*  DEVICE_TICK(asc)
  *  dev_asc_tick():  
  *  
  *  This function is called "every now and then" from the CPU  
  *  main loop.  
  */  
 void dev_asc_tick(struct cpu *cpu, void *extra)  
156  {  {
157          struct asc_data *d = extra;          struct asc_data *d = extra;
158    
# Line 306  fatal("TODO..............\n"); Line 306  fatal("TODO..............\n");
306                                  fatal("no incoming DMA data?\n");                                  fatal("no incoming DMA data?\n");
307                                  res = 0;                                  res = 0;
308                          } else {                          } else {
309                                  int len = d->xferp->data_in_len;                                  size_t len = d->xferp->data_in_len;
310                                  int len2 = d->reg_wo[NCR_TCL] +                                  size_t len2 = d->reg_wo[NCR_TCL] +
311                                      d->reg_wo[NCR_TCM] * 256;                                      d->reg_wo[NCR_TCM] * 256;
312                                  if (len2 == 0)                                  if (len2 == 0)
313                                          len2 = 65536;                                          len2 = 65536;
# Line 319  fatal("TODO..............\n"); Line 319  fatal("TODO..............\n");
319    
320                                  /*  TODO: check len2 in a similar way?  */                                  /*  TODO: check len2 in a similar way?  */
321                                  if (len + (d->dma_address_reg &                                  if (len + (d->dma_address_reg &
322                                      ((sizeof(d->dma)-1))) > sizeof(d->dma))                                      (ASC_DMA_SIZE-1)) > ASC_DMA_SIZE)
323                                          len = sizeof(d->dma) -                                          len = ASC_DMA_SIZE -
324                                              (d->dma_address_reg &                                              (d->dma_address_reg &
325                                              ((sizeof(d->dma)-1)));                                              (ASC_DMA_SIZE-1));
326    
327                                  if (len2 > len) {                                  if (len2 > len) {
328                                          memset(d->dma + (d->dma_address_reg &                                          memset(d->dma + (d->dma_address_reg &
329                                              ((sizeof(d->dma)-1))), 0, len2);                                              (ASC_DMA_SIZE-1)), 0, len2);
330                                          len2 = len;                                          len2 = len;
331                                  }                                  }
332    
# Line 352  fatal("TODO..............\n"); Line 352  fatal("TODO..............\n");
352                                              len2, 1);                                              len2, 1);
353                                  else                                  else
354                                          memcpy(d->dma + (d->dma_address_reg &                                          memcpy(d->dma + (d->dma_address_reg &
355                                              ((sizeof(d->dma)-1))),                                              (ASC_DMA_SIZE-1)),
356                                              d->xferp->data_in, len2);                                              d->xferp->data_in, len2);
357    
358                                  if (d->xferp->data_in_len > len2) {                                  if (d->xferp->data_in_len > len2) {
# Line 439  fatal("TODO.......asdgasin\n"); Line 439  fatal("TODO.......asdgasin\n");
439                                  else                                  else
440                                          memcpy(d->xferp->data_out,                                          memcpy(d->xferp->data_out,
441                                              d->dma + (d->dma_address_reg &                                              d->dma + (d->dma_address_reg &
442                                              ((sizeof(d->dma)-1))), len2);                                              (ASC_DMA_SIZE-1)), len2);
443                                  d->xferp->data_out_offset = len2;                                  d->xferp->data_out_offset = len2;
444                          } else {                          } else {
445                                  /*  Continuing a multi-transfer:  */                                  /*  Continuing a multi-transfer:  */
# Line 453  fatal("TODO.......asdgasin\n"); Line 453  fatal("TODO.......asdgasin\n");
453                                          memcpy(d->xferp->data_out +                                          memcpy(d->xferp->data_out +
454                                              d->xferp->data_out_offset,                                              d->xferp->data_out_offset,
455                                              d->dma + (d->dma_address_reg &                                              d->dma + (d->dma_address_reg &
456                                              ((sizeof(d->dma)-1))), len2);                                              (ASC_DMA_SIZE-1)), len2);
457                                  d->xferp->data_out_offset += len2;                                  d->xferp->data_out_offset += len2;
458                          }                          }
459    
# Line 705  static int dev_asc_select(struct cpu *cp Line 705  static int dev_asc_select(struct cpu *cp
705    
706                  for (i=0; i<len; i++) {                  for (i=0; i<len; i++) {
707                          int ofs = d->dma_address_reg + i;                          int ofs = d->dma_address_reg + i;
708                          ch = d->dma[ofs & (sizeof(d->dma)-1)];                          ch = d->dma[ofs & (ASC_DMA_SIZE-1)];
709                          d->xferp->cmd[i] = ch;                          d->xferp->cmd[i] = ch;
710                          if (!quiet_mode)                          if (!quiet_mode)
711                                  debug("%02x ", ch);                                  debug("%02x ", ch);
# Line 745  static int dev_asc_select(struct cpu *cp Line 745  static int dev_asc_select(struct cpu *cp
745  }  }
746    
747    
748  /*  DEVICE_ACCESS(asc_address_reg)
  *  dev_asc_address_reg_access():  
  */  
 int dev_asc_address_reg_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
749  {  {
750          struct asc_data *d = extra;          struct asc_data *d = extra;
751    
# Line 767  int dev_asc_address_reg_access(struct cp Line 762  int dev_asc_address_reg_access(struct cp
762  }  }
763    
764    
765  /*  DEVICE_ACCESS(asc_dma)
  *  dev_asc_dma_access():  
  */  
 int dev_asc_dma_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
766  {  {
767          struct asc_data *d = extra;          struct asc_data *d = extra;
768    
# Line 810  int dev_asc_dma_access(struct cpu *cpu, Line 800  int dev_asc_dma_access(struct cpu *cpu,
800  }  }
801    
802    
803  /*  DEVICE_ACCESS(asc)
  *  dev_asc_access():  
  */  
 int dev_asc_access(struct cpu *cpu, struct memory *mem,  
         uint64_t relative_addr, unsigned char *data, size_t len,  
         int writeflag, void *extra)  
804  {  {
805          int regnr;          int regnr;
806          struct asc_data *d = extra;          struct asc_data *d = extra;
# Line 823  int dev_asc_access(struct cpu *cpu, stru Line 808  int dev_asc_access(struct cpu *cpu, stru
808          int n_messagebytes = 0;          int n_messagebytes = 0;
809          uint64_t idata = 0, odata = 0;          uint64_t idata = 0, odata = 0;
810    
811            if (writeflag == MEM_WRITE)
812          idata = memory_readmax64(cpu, data, len);                  idata = memory_readmax64(cpu, data, len);
813    
814  #if 0  #if 0
815          /*  Debug stuff useful when trying to make dev_asc compatible          /*  Debug stuff useful when trying to make dev_asc compatible
# Line 1261  void dev_asc_init(struct machine *machin Line 1246  void dev_asc_init(struct machine *machin
1246    
1247          d->reg_ro[NCR_CFG3] = NCRF9XCFG3_CDB;          d->reg_ro[NCR_CFG3] = NCRF9XCFG3_CDB;
1248    
1249            d->dma_address_reg_memory = malloc(machine->arch_pagesize);
1250            d->dma = malloc(ASC_DMA_SIZE);
1251            if (d->dma == NULL || d->dma_address_reg_memory == NULL) {
1252                    fprintf(stderr, "out of memory\n");
1253                    exit(1);
1254            }
1255            memset(d->dma_address_reg_memory, 0, machine->arch_pagesize);
1256            memset(d->dma, 0, ASC_DMA_SIZE);
1257    
1258          d->dma_controller      = dma_controller;          d->dma_controller      = dma_controller;
1259          d->dma_controller_data = dma_controller_data;          d->dma_controller_data = dma_controller_data;
1260    
1261          memory_device_register(mem, "asc", baseaddr,          memory_device_register(mem, "asc", baseaddr,
1262              mode == DEV_ASC_PICA?              mode == DEV_ASC_PICA? DEV_ASC_PICA_LENGTH : DEV_ASC_DEC_LENGTH,
1263                  DEV_ASC_PICA_LENGTH : DEV_ASC_DEC_LENGTH,              dev_asc_access, d, DM_DEFAULT, NULL);
             dev_asc_access, d, MEM_DEFAULT, NULL);  
1264    
1265          if (mode == DEV_ASC_DEC) {          if (mode == DEV_ASC_DEC) {
1266                  memory_device_register(mem, "asc_dma_address_reg",                  memory_device_register(mem, "asc_dma_address_reg",
1267                      baseaddr + 0x40000, 4096, dev_asc_address_reg_access, d,                      baseaddr + 0x40000, 4096, dev_asc_address_reg_access, d,
1268                      MEM_BINTRANS_OK | MEM_BINTRANS_WRITE_OK,                      DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK,
1269                      d->dma_address_reg_memory);                      (unsigned char *)&d->dma_address_reg_memory[0]);
1270                  memory_device_register(mem, "asc_dma", baseaddr + 0x80000,                  memory_device_register(mem, "asc_dma", baseaddr + 0x80000,
1271                      128*1024, dev_asc_dma_access, d,                      ASC_DMA_SIZE, dev_asc_dma_access, d,
1272                      MEM_BINTRANS_OK | MEM_BINTRANS_WRITE_OK, d->dma);                      DM_DYNTRANS_OK | DM_DYNTRANS_WRITE_OK, d->dma);
1273          }          }
1274    
1275          machine_add_tickfunction(machine, dev_asc_tick, d, 15);          machine_add_tickfunction(machine, dev_asc_tick, d, ASC_TICK_SHIFT, 0.0);
1276  }  }
1277    

Legend:
Removed from v.6  
changed lines
  Added in v.28

  ViewVC Help
Powered by ViewVC 1.1.26