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

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

revision 12 by dpavlin, Mon Oct 8 16:18:38 2007 UTC revision 14 by dpavlin, Mon Oct 8 16:18:51 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *     *  
27   *   *
28   *  $Id: dev_sgi_ip32.c,v 1.29 2005/08/13 08:25:48 debug Exp $   *  $Id: dev_sgi_ip32.c,v 1.32 2005/08/19 09:43:35 debug Exp $
29   *     *  
30   *  SGI IP32 devices.   *  SGI IP32 devices.
31   *   *
# Line 1037  void dev_sgi_ust_init(struct memory *mem Line 1037  void dev_sgi_ust_init(struct memory *mem
1037   *  memory. Used by (at least) the SGI O2 PROM.   *  memory. Used by (at least) the SGI O2 PROM.
1038   *   *
1039   *  Actually, it seems to be used for graphics output as well. (?)   *  Actually, it seems to be used for graphics output as well. (?)
1040   *  TODO: Run the O2's prom and try to figure out what it really does.   *  The O2's PROM uses it to output graphics.
1041   */   */
1042  /*  #define debug fatal  */  /*  #define debug fatal  */
1043    /*  #define MTE_DEBUG  */
1044  #define ZERO_CHUNK_LEN          4096  #define ZERO_CHUNK_LEN          4096
1045    
1046  struct sgi_mte_data {  struct sgi_mte_data {
1047          uint64_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint64_t)];          uint32_t        reg[DEV_SGI_MTE_LENGTH / sizeof(uint32_t)];
1048  };  };
1049    
1050  /*  /*
# Line 1060  int dev_sgi_mte_access(struct cpu *cpu, Line 1061  int dev_sgi_mte_access(struct cpu *cpu,
1061          int regnr;          int regnr;
1062    
1063          idata = memory_readmax64(cpu, data, len);          idata = memory_readmax64(cpu, data, len);
1064          regnr = relative_addr / sizeof(uint64_t);          regnr = relative_addr / sizeof(uint32_t);
1065    
1066            /*
1067             *  Treat all registers as read/write, by default.  Sometimes these
1068             *  are accessed as 32-bit words, sometimes as 64-bit words.
1069             */
1070            if (len != 4) {
1071                    if (writeflag == MEM_WRITE) {
1072                            d->reg[regnr] = idata >> 32;
1073                            d->reg[regnr+1] = idata;
1074                    } else
1075                            odata = ((uint64_t)d->reg[regnr] << 32) +
1076                                d->reg[regnr+1];
1077            }
1078    
         /*  Treat all registers as read/write, by default.  */  
1079          if (writeflag == MEM_WRITE)          if (writeflag == MEM_WRITE)
1080                  d->reg[regnr] = idata;                  d->reg[regnr] = idata;
1081          else          else
1082                  odata = d->reg[regnr];                  odata = d->reg[regnr];
1083    
1084    #ifdef MTE_DEBUG
1085            if (writeflag == MEM_WRITE && relative_addr >= 0x2000 &&
1086                relative_addr < 0x3000)
1087                    fatal("[ MTE: 0x%08x: 0x%016llx ]\n", (int)relative_addr,
1088                        (long long)idata);
1089    #endif
1090    
1091          /*          /*
1092           *  I've not found any docs about this 'mte' device at all, so this is           *  I've not found any docs about this 'mte' device at all, so this is
1093           *  just a guess. The mte seems to be used for copying and zeroing           *  just a guess. The mte seems to be used for copying and zeroing
1094           *  chunks of memory.           *  chunks of memory.
1095           *           *
1096           *  [ sgi_mte: unimplemented write to address 0x3030, data=0x00000000003da000 ]  <-- first address           *   write to 0x3030, data=0x00000000003da000 ]  <-- first address
1097           *  [ sgi_mte: unimplemented write to address 0x3038, data=0x00000000003f9fff ]  <-- last address           *   write to 0x3038, data=0x00000000003f9fff ]  <-- last address
1098           *  [ sgi_mte: unimplemented write to address 0x3018, data=0x0000000000000000 ]  <-- what to fill?           *   write to 0x3018, data=0x0000000000000000 ]  <-- what to fill?
1099           *  [ sgi_mte: unimplemented write to address 0x3008, data=0x00000000ffffffff ]  <-- ?           *   write to 0x3008, data=0x00000000ffffffff ]  <-- ?
1100           *  [ sgi_mte: unimplemented write to address 0x3800, data=0x0000000000000011 ]  <-- operation (0x11 = zerofill)           *   write to 0x3800, data=0x0000000000000011 ]  <-- operation
1101             *                                                   (0x11 = zerofill)
1102           *           *
1103           *  [ sgi_mte: unimplemented write to address 0x1700, data=0x80001ea080001ea1 ]  <-- also containing the address to fill (?)           *   write to 0x1700, data=0x80001ea080001ea1  <-- also containing the
1104           *  [ sgi_mte: unimplemented write to address 0x1708, data=0x80001ea280001ea3 ]           *   write to 0x1708, data=0x80001ea280001ea3      address to fill (?)
1105           *  [ sgi_mte: unimplemented write to address 0x1710, data=0x80001ea480001ea5 ]           *   write to 0x1710, data=0x80001ea480001ea5
1106           *  ...           *  ...
1107           *  [ sgi_mte: unimplemented write to address 0x1770, data=0x80001e9c80001e9d ]           *   write to 0x1770, data=0x80001e9c80001e9d
1108           *  [ sgi_mte: unimplemented write to address 0x1778, data=0x80001e9e80001e9f ]           *   write to 0x1778, data=0x80001e9e80001e9f
1109           */           */
1110          switch (relative_addr) {          switch (relative_addr) {
1111    
# Line 1115  int dev_sgi_mte_access(struct cpu *cpu, Line 1136  int dev_sgi_mte_access(struct cpu *cpu,
1136          case 0x1778:          case 0x1778:
1137                  break;                  break;
1138    
1139  #if 1          /*  Graphics stuff? No warning:  */
1140  case 0x2074:          case 0x2018:
1141  {          case 0x2060:
1142  /*  This seems to have to do with graphical output:          case 0x2070:
1143      0x000000000xxx0yyy  where x is usually 0..1279 and y is 0..1023?  */          case 0x2074:
1144  /*  Gaaah...  */          case 0x20c0:
1145          int x = (idata >> 16) & 0xfff;          case 0x20c4:
1146          int y = idata & 0xfff;          case 0x20d0:
1147          int addr;          case 0x21b0:
1148  unsigned char buf[3];          case 0x21b8:
1149          printf("x = %i, y = %i\n", x, y);                  break;
1150  buf[0] = buf[1] = buf[2] = random() | 0x80;  
1151  addr = (x/2 + (y/2)*640) * 3;          /*  Perform graphics operation:  */
1152  if (x < 640 && y < 480)          case 0x21f8:
1153  cpu->memory_rw(cpu, cpu->mem, 0x38000000 + addr,                  {
1154   buf, 3, MEM_WRITE, NO_EXCEPTIONS | PHYSICAL);                          uint32_t op = d->reg[0x2060 / sizeof(uint32_t)];
1155                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1156                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1157                                >> 16) & 0xfff;
1158                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1159                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1160                                >> 16) & 0xfff;
1161                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1162                            int y;
1163    
1164                            op >>= 24;
1165    
1166                            switch (op) {
1167                            case 1: /*  Unknown. Used after drawing bitmaps?  */
1168                                    break;
1169                            case 3: /*  Fill:  */
1170                                    if (x2 < x1) {
1171                                            int tmp = x1; x1 = x2; x2 = tmp;
1172                                    }
1173                                    if (y2 < y1) {
1174                                            int tmp = y1; y1 = y2; y2 = tmp;
1175                                    }
1176                                    for (y=y1; y<=y2; y++) {
1177                                            unsigned char buf[1280];
1178                                            int length = x2-x1+1;
1179                                            int addr = (x1 + y*1280);
1180                                            if (length < 1)
1181                                                    length = 1;
1182                                            memset(buf, color, length);
1183                                            if (x1 < 1280 && y < 1024)
1184                                                    cpu->memory_rw(cpu, cpu->mem,
1185                                                        0x38000000 + addr, buf,
1186                                                        length, MEM_WRITE,
1187                                                        NO_EXCEPTIONS | PHYSICAL);
1188                                    }
1189                                    break;
1190    
1191                            default:fatal("\n--- MTE OP %i color 0x%02x: %i,%i - "
1192                                        "%i,%i\n\n", op, color, x1,y1, x2,y2);
1193                            }
1194                    }
1195                    break;
1196    
1197            case 0x29f0:
1198                    /*  Pixel output:  */
1199                    {
1200                            uint32_t data = d->reg[0x20c4 / sizeof(uint32_t)];
1201                            uint32_t color = d->reg[0x20d0 / sizeof(uint32_t)]&255;
1202                            uint32_t x1 = (d->reg[0x2070 / sizeof(uint32_t)]
1203                                >> 16) & 0xfff;
1204                            uint32_t y1 = d->reg[0x2070 / sizeof(uint32_t)]& 0xfff;
1205                            uint32_t x2 = (d->reg[0x2074 / sizeof(uint32_t)]
1206                                >> 16) & 0xfff;
1207                            uint32_t y2 = d->reg[0x2074 / sizeof(uint32_t)]& 0xfff;
1208                            int x,y;
1209                            if (x2 < x1) {
1210                                    int tmp = x1; x1 = x2; x2 = tmp;
1211                            }
1212                            if (y2 < y1) {
1213                                    int tmp = y1; y1 = y2; y2 = tmp;
1214                            }
1215                            if (x2-x1 <= 15)
1216                                    data <<= 16;
1217                            x=x1; y=y1;
1218                            while (x <= x2 && y <= y2) {
1219                                    unsigned char buf = color;
1220                                    int addr = x + y*1280;
1221                                    int bit_set = data & 0x80000000UL;
1222                                    data <<= 1;
1223                                    if (x < 1280 && y < 1024 && bit_set)
1224                                            cpu->memory_rw(cpu, cpu->mem,
1225                                                0x38000000 + addr, &buf,1,MEM_WRITE,
1226                                                NO_EXCEPTIONS | PHYSICAL);
1227                                    x++;
1228                                    if (x > x2) {
1229                                            x = x1;
1230                                            y++;
1231                                    }
1232                            }
1233                    }
1234                    break;
1235    
 }  
 break;  
 #endif  
1236    
1237          /*  Operations:  */          /*  Operations:  */
1238          case 0x3800:          case 0x3800:
1239                  if (writeflag == MEM_WRITE) {                  if (writeflag == MEM_WRITE) {
1240                          switch (idata) {                          switch (idata) {
1241                          case 0x11:              /*  zerofill  */                          case 0x11:              /*  zerofill  */
1242                                  first_addr = d->reg[0x3030 / sizeof(uint64_t)];                                  first_addr = d->reg[0x3030 / sizeof(uint32_t)];
1243                                  last_addr  = d->reg[0x3038 / sizeof(uint64_t)];                                  last_addr  = d->reg[0x3038 / sizeof(uint32_t)];
1244                                  zerobuflen = last_addr - first_addr + 1;                                  zerobuflen = last_addr - first_addr + 1;
1245                                  debug("[ sgi_mte: zerofill: first = 0x%016llx, last = 0x%016llx, length = 0x%llx ]\n",                                  debug("[ sgi_mte: zerofill: first = 0x%016llx,"
1246                                      (long long)first_addr, (long long)last_addr, (long long)zerobuflen);                                      " last = 0x%016llx, length = 0x%llx ]\n",
1247                                        (long long)first_addr, (long long)
1248                                        last_addr, (long long)zerobuflen);
1249    
1250                                  /*  TODO:  is there a better way to implement this?  */                                  /*  TODO:  is there a better way to
1251                                               implement this?  */
1252                                  memset(zerobuf, 0, sizeof(zerobuf));                                  memset(zerobuf, 0, sizeof(zerobuf));
1253                                  fill_addr = first_addr;                                  fill_addr = first_addr;
1254                                  while (zerobuflen != 0) {                                  while (zerobuflen != 0) {
# Line 1164  break; Line 1265  break;
1265    
1266                                  break;                                  break;
1267                          default:                          default:
1268                                  fatal("[ sgi_mte: UNKNOWN operation 0x%x ]\n", idata);                                  fatal("[ sgi_mte: UNKNOWN operation "
1269                                        "0x%x ]\n", idata);
1270                          }                          }
1271                  }                  }
1272                  break;                  break;
1273          default:          default:
1274                  if (writeflag == MEM_WRITE)                  if (writeflag == MEM_WRITE)
1275                          debug("[ sgi_mte: unimplemented write to address 0x%llx, data=0x%016llx ]\n", (long long)relative_addr, (long long)idata);                          debug("[ sgi_mte: unimplemented write to "
1276                                "address 0x%llx, data=0x%016llx ]\n",
1277                                (long long)relative_addr, (long long)idata);
1278                  else                  else
1279                          debug("[ sgi_mte: unimplemented read from address 0x%llx ]\n", (long long)relative_addr);                          debug("[ sgi_mte: unimplemented read from address"
1280                                " 0x%llx ]\n", (long long)relative_addr);
1281          }          }
1282    
1283          if (writeflag == MEM_READ)          if (writeflag == MEM_READ)

Legend:
Removed from v.12  
changed lines
  Added in v.14

  ViewVC Help
Powered by ViewVC 1.1.26