|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1982, 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)dmf.c 7.4 (Berkeley) 2/19/87 ! 7: */ ! 8: ! 9: /* ! 10: * DMF32 driver ! 11: * ! 12: * ! 13: * TODO: ! 14: * test with modem ! 15: * load as much as possible into silo ! 16: * use auto XON/XOFF ! 17: * test reset code ! 18: */ ! 19: #include "dmf.h" ! 20: #if NDMF > 0 ! 21: ! 22: #ifndef NDMF_LP ! 23: #define NDMF_LP NDMF ! 24: #endif NDMF_LP ! 25: #include "../machine/pte.h" ! 26: ! 27: #include "bk.h" ! 28: #include "uba.h" ! 29: #include "param.h" ! 30: #include "conf.h" ! 31: #include "dir.h" ! 32: #include "user.h" ! 33: #include "proc.h" ! 34: #include "ioctl.h" ! 35: #include "tty.h" ! 36: #include "map.h" ! 37: #include "buf.h" ! 38: #include "vm.h" ! 39: #include "bkmac.h" ! 40: #include "clist.h" ! 41: #include "file.h" ! 42: #include "uio.h" ! 43: #include "kernel.h" ! 44: #include "syslog.h" ! 45: ! 46: #include "dmx.h" ! 47: #include "ubareg.h" ! 48: #include "ubavar.h" ! 49: #include "dmxreg.h" ! 50: #include "dmfreg.h" ! 51: #include "dmreg.h" ! 52: ! 53: extern int dmx_timeout; /* silo timeout, in ms */ ! 54: extern char dmx_speeds[]; ! 55: int dmfstart(); ! 56: ! 57: /* ! 58: * The clist space is mapped by one terminal driver onto each UNIBUS. ! 59: * The identity of the board which allocated resources is recorded, ! 60: * so the process may be repeated after UNIBUS resets. ! 61: * The UBACVT macro converts a clist space address for unibus uban ! 62: * into an i/o space address for the DMA routine. ! 63: */ ! 64: int dmf_uballoc[NUBA]; /* which dmf (if any) allocated unibus map */ ! 65: int cbase[NUBA]; /* base address of clists in unibus map */ ! 66: ! 67: /* ! 68: * Autoconfiguration and variables for DMF32 ! 69: */ ! 70: int dmfprobe(), dmfattach(), dmfrint(), dmfxint(); ! 71: int dmflint(); ! 72: struct uba_device *dmfinfo[NDMF]; ! 73: u_short dmfstd[] = { 0 }; ! 74: struct uba_driver dmfdriver = ! 75: { dmfprobe, 0, dmfattach, 0, dmfstd, "dmf", dmfinfo }; ! 76: ! 77: struct tty dmf_tty[NDMF*8]; ! 78: struct dmx_softc dmf_softc[NDMF]; ! 79: #ifndef lint ! 80: int ndmf = NDMF*8; /* used by iostat */ ! 81: #endif ! 82: ! 83: /* ! 84: * Routine for configuration to set dmf interrupt. ! 85: */ ! 86: /*ARGSUSED*/ ! 87: dmfprobe(reg, ctlr) ! 88: caddr_t reg; ! 89: struct uba_device *ctlr; ! 90: { ! 91: register int br, cvec; /* these are ``value-result'' */ ! 92: register struct dmfdevice *dmfaddr = (struct dmfdevice *)reg; ! 93: register int i; ! 94: register unsigned int a; ! 95: static char *dmfdevs[]= ! 96: {"parallel","printer","synch","asynch"}; ! 97: unsigned int dmfoptions; ! 98: static int (*intrv[3])() = { (int (*)())0, (int (*)())0, (int (*)())0 }; ! 99: ! 100: #ifdef lint ! 101: br = 0; cvec = br; br = cvec; ! 102: dmfxint(0); dmfrint(0); ! 103: dmfsrint(); dmfsxint(); dmfdaint(); dmfdbint(); dmflint(0); ! 104: #endif ! 105: /* ! 106: * Pick the usual size DMF vector here (don't decrement it here). ! 107: * grab configuration; note that the DMF32 ! 108: * doesn't seem to put the right bits in this ! 109: * register until AFTER the interrupt vector is set. ! 110: */ ! 111: br = 0x15; ! 112: cvec = (uba_hd[numuba].uh_lastiv - 4*8); ! 113: dmfaddr->dmfccsr0 = (cvec >> 2); ! 114: dmfoptions = dmfaddr->dmfccsr0 & DMFC_CONFMASK; ! 115: ! 116: /* catch a couple of special cases: Able vmz/32n and vmz/lp */ ! 117: if (dmfoptions == DMFC_ASYNC) { ! 118: /* Async portion only */ ! 119: ! 120: cvec = (uba_hd[numuba].uh_lastiv -= 8); ! 121: dmfaddr->dmfccsr0 = (cvec - 2*8) >> 2; ! 122: intrv[0] = ctlr->ui_intr[4]; ! 123: intrv[1] = ctlr->ui_intr[5]; ! 124: ctlr->ui_intr = intrv; ! 125: } else if (dmfoptions == DMFC_LP) { ! 126: /* LP portion only */ ! 127: ! 128: cvec = (uba_hd[numuba].uh_lastiv -= 8); ! 129: ctlr->ui_intr = &ctlr->ui_intr[6]; ! 130: } else if (dmfoptions == (DMFC_LP|DMFC_ASYNC)) { ! 131: /* LP and Async portions only */ ! 132: ! 133: cvec = (uba_hd[numuba].uh_lastiv -= 2*8); ! 134: ctlr->ui_intr = &ctlr->ui_intr[4]; ! 135: } else { ! 136: /* All other configurations get everything */ ! 137: ! 138: cvec = (uba_hd[numuba].uh_lastiv -= 4*8); ! 139: } ! 140: a = (dmfoptions >> 12) & 0xf; ! 141: printf("dmf%d:", ctlr->ui_unit); ! 142: for (i = 0; a != 0; ++i, a >>= 1) { ! 143: if (a & 1) ! 144: printf(" %s",dmfdevs[i]); ! 145: } ! 146: printf(".\n"); ! 147: ! 148: if (dmfoptions & DMFC_LP) ! 149: dmfaddr->dmfl_ctrl = DMFL_RESET; ! 150: return (sizeof (struct dmfdevice)); ! 151: } ! 152: ! 153: /* ! 154: * Routine called to attach a dmf. ! 155: */ ! 156: dmfattach(ui) ! 157: register struct uba_device *ui; ! 158: { ! 159: register struct dmx_softc *sc; ! 160: ! 161: sc = &dmf_softc[ui->ui_unit]; ! 162: sc->dmx_type = 'f'; ! 163: sc->dmx_unit = ui->ui_unit; ! 164: sc->dmx_unit0 = 0; ! 165: sc->dmx_ubanum = ui->ui_ubanum; ! 166: sc->dmx_softCAR = ui->ui_flags & 0xff; ! 167: sc->dmx_tty = &dmf_tty[ui->ui_unit * 8]; ! 168: sc->dmx_octet = ! 169: (struct dmx_octet *)&((struct dmfdevice *)ui->ui_addr)->dmfa; ! 170: ! 171: cbase[ui->ui_ubanum] = -1; ! 172: dmf_uballoc[ui->ui_unit] = -1; ! 173: #if NDMF_LP > 0 ! 174: dmflattach(ui); ! 175: #endif NDMF_LP ! 176: } ! 177: ! 178: /* ! 179: * Open a DMF32 line, mapping the clist onto the uba if this ! 180: * is the first dmf on this uba. Turn on this dmf if this is ! 181: * the first use of it. ! 182: */ ! 183: /*ARGSUSED*/ ! 184: dmfopen(dev, flag) ! 185: dev_t dev; ! 186: { ! 187: register struct tty *tp; ! 188: register struct dmx_softc *sc; ! 189: int unit, dmf; ! 190: register struct dmfdevice *addr; ! 191: register struct uba_device *ui; ! 192: int s; ! 193: ! 194: unit = minor(dev); ! 195: if (unit & 0200) ! 196: return (dmflopen(dev,flag)); ! 197: dmf = unit >> 3; ! 198: if (unit >= NDMF*8 || (ui = dmfinfo[dmf])== 0 || ui->ui_alive == 0) ! 199: return (ENXIO); ! 200: ! 201: tp = &dmf_tty[unit]; ! 202: sc = &dmf_softc[dmf]; ! 203: addr = (struct dmfdevice *)ui->ui_addr; ! 204: tp->t_addr = (caddr_t)(&addr->dmfa); ! 205: tp->t_oproc = dmfstart; ! 206: tp->t_dev = dev; /* needed before dmxopen */ ! 207: ! 208: /* ! 209: * While setting up state for this uba, ! 210: * block uba resets which can clear the state. ! 211: */ ! 212: s = spl6(); ! 213: if (cbase[ui->ui_ubanum] == -1) { ! 214: dmf_uballoc[ui->ui_ubanum] = dmf; ! 215: cbase[ui->ui_ubanum] = UBAI_ADDR(uballoc(ui->ui_ubanum, ! 216: (caddr_t)cfree, nclist*sizeof(struct cblock), 0)); ! 217: } ! 218: splx(s); ! 219: ! 220: return (dmxopen(tp, sc)); ! 221: } ! 222: ! 223: /* ! 224: * Close a DMF32 line. ! 225: */ ! 226: /*ARGSUSED*/ ! 227: dmfclose(dev, flag) ! 228: dev_t dev; ! 229: int flag; ! 230: { ! 231: register unit; ! 232: ! 233: unit = minor(dev); ! 234: if (unit & 0200) { ! 235: dmflclose(dev, flag); ! 236: return; ! 237: } ! 238: dmxclose(&dmf_tty[unit]); ! 239: } ! 240: ! 241: dmfread(dev, uio) ! 242: dev_t dev; ! 243: struct uio *uio; ! 244: { ! 245: register struct tty *tp; ! 246: ! 247: if (minor(dev) & 0200) ! 248: return(ENXIO); ! 249: tp = &dmf_tty[minor(dev)]; ! 250: return ((*linesw[tp->t_line].l_read)(tp, uio)); ! 251: } ! 252: ! 253: dmfwrite(dev, uio) ! 254: dev_t dev; ! 255: struct uio *uio; ! 256: { ! 257: register struct tty *tp; ! 258: ! 259: if (minor(dev) & 0200) ! 260: return (dmflwrite(dev,uio)); ! 261: tp = &dmf_tty[minor(dev)]; ! 262: return ((*linesw[tp->t_line].l_write)(tp, uio)); ! 263: } ! 264: ! 265: /* ! 266: * DMF32 receiver interrupt. ! 267: */ ! 268: dmfrint(dmf) ! 269: int dmf; ! 270: { ! 271: struct uba_device *ui; ! 272: ! 273: ui = dmfinfo[dmf]; ! 274: if (ui == 0 || ui->ui_alive == 0) ! 275: return; ! 276: dmxrint(&dmf_softc[dmf]); ! 277: } ! 278: ! 279: /* ! 280: * Ioctl for DMF32. ! 281: */ ! 282: dmfioctl(dev, cmd, data, flag) ! 283: dev_t dev; ! 284: caddr_t data; ! 285: { ! 286: int unit = minor(dev); ! 287: ! 288: if (unit & 0200) ! 289: return (ENOTTY); ! 290: return (dmxioctl(&dmf_tty[unit], cmd, data, flag)); ! 291: } ! 292: ! 293: /* ! 294: * DMF32 transmitter interrupt. ! 295: * Restart the idle line. ! 296: */ ! 297: dmfxint(dmf) ! 298: int dmf; ! 299: { ! 300: ! 301: dmxxint(&dmf_softc[dmf]); ! 302: } ! 303: ! 304: /* ! 305: * Start (restart) transmission on the given line. ! 306: */ ! 307: dmfstart(tp) ! 308: struct tty *tp; ! 309: { ! 310: ! 311: dmxstart(tp, &dmf_softc[minor(tp->t_dev) >> 3]); ! 312: } ! 313: ! 314: /* ! 315: * Stop output on a line, e.g. for ^S/^Q or output flush. ! 316: */ ! 317: dmfstop(tp, flag) ! 318: struct tty *tp; ! 319: { ! 320: ! 321: dmxstop(tp, &dmf_softc[minor(tp->t_dev) >> 3], flag); ! 322: } ! 323: ! 324: /* ! 325: * Reset state of driver if UBA reset was necessary. ! 326: * Reset the csr, lpr, and lcr registers on open lines, and ! 327: * restart transmitters. ! 328: */ ! 329: dmfreset(uban) ! 330: int uban; ! 331: { ! 332: register int dmf; ! 333: register struct tty *tp; ! 334: register struct uba_device *ui; ! 335: register struct dmfdevice *addr; ! 336: int i; ! 337: ! 338: for (dmf = 0; dmf < NDMF; dmf++) { ! 339: ui = dmfinfo[dmf]; ! 340: if (ui == 0 || ui->ui_alive == 0 || ui->ui_ubanum != uban) ! 341: continue; ! 342: printf(" dmf%d", dmf); ! 343: if (dmf_uballoc[uban] == dmf) { ! 344: int info; ! 345: ! 346: info = uballoc(uban, (caddr_t)cfree, ! 347: nclist * sizeof(struct cblock), UBA_CANTWAIT); ! 348: if (info) ! 349: cbase[uban] = UBAI_ADDR(info); ! 350: else { ! 351: printf(" [can't get uba map]"); ! 352: cbase[uban] = -1; ! 353: } ! 354: } ! 355: addr = (struct dmfdevice *)ui->ui_addr; ! 356: addr->dmfa.csr = DMF_IE; ! 357: addr->dmfa.rsp = dmx_timeout; ! 358: tp = &dmf_tty[dmf * 8]; ! 359: for (i = 0; i < 8; i++, tp++) { ! 360: if (tp->t_state & (TS_ISOPEN|TS_WOPEN)) { ! 361: dmxparam(tp); ! 362: (void) dmxmctl(tp, DMF_ON, DMSET); ! 363: tp->t_state &= ~TS_BUSY; ! 364: dmfstart(tp); ! 365: } ! 366: } ! 367: #if NDMF_LP > 0 ! 368: dmflint(dmf); ! 369: #endif ! 370: } ! 371: } ! 372: ! 373: #if NDMF_LP > 0 ! 374: /* ! 375: * DMF32 line printer driver ! 376: * ! 377: * the line printer on dmfx is indicated by a minor device code of 128+x ! 378: * ! 379: * the flags field of the config file is interpreted like so: ! 380: * bits meaning ! 381: * ---- ------- ! 382: * 0-7 soft carrier bits for ttys part of dmf32 ! 383: * 8-15 number of cols/line on the line printer ! 384: * if 0, 132 will be used. ! 385: * 16-23 number of lines/page on the line printer ! 386: * if 0, 66 will be used. ! 387: * 24 if 1 DO NOT use the auto format mode of the ! 388: * line printer parallel port ! 389: */ ! 390: ! 391: struct dmfl_softc { ! 392: u_int dmfl_state; /* soft state bits */ ! 393: int dmfl_info; /* uba info */ ! 394: u_short dmfl_lines; /* lines per page (66 def.) */ ! 395: u_short dmfl_cols; /* cols per line (132 def.) */ ! 396: u_short dmfl_format; /* fflag for auto form feed */ ! 397: char dmfl_buf[DMFL_BUFSIZ]; ! 398: } dmfl_softc[NDMF]; ! 399: ! 400: /* ! 401: * convert device number into DMF line printer unit number ! 402: */ ! 403: #define DMFL_UNIT(d) (minor(d) & 0xf) /* up to 16 DMFs */ ! 404: ! 405: #define ASLP 1 /* waiting for interrupt from dmf */ ! 406: #define OPEN 2 /* line printer is open */ ! 407: #define ERROR 4 /* error while printing, driver ! 408: refuses to do anything till closed */ ! 409: #define MOREIO 8 /* more data for printer */ ! 410: ! 411: /* ! 412: * Attach printer portion of dmf. ! 413: */ ! 414: dmflattach(ui) ! 415: register struct uba_device *ui; ! 416: { ! 417: register int unit = ui->ui_unit; ! 418: register int cols = (ui->ui_flags>>8) & 0xff; ! 419: register int lines = (ui->ui_flags>>16) & 0xff; ! 420: register struct dmfl_softc *sc; ! 421: ! 422: sc = &dmfl_softc[unit]; ! 423: sc->dmfl_cols = cols == 0 ? DMFL_DEFCOLS : cols; ! 424: sc->dmfl_lines = lines == 0 ? DMFL_DEFLINES : lines; ! 425: if ((ui->ui_flags >> 24) & 0x1) ! 426: sc->dmfl_format = (2 << 8); ! 427: else ! 428: sc->dmfl_format = (2 << 8) | DMFL_FORMAT; ! 429: } ! 430: ! 431: /* ! 432: * dmflopen -- open the line printer port on a dmf32 ! 433: */ ! 434: /* ARGSUSED */ ! 435: dmflopen(dev, flag) ! 436: dev_t dev; ! 437: int flag; ! 438: { ! 439: register int dmf; ! 440: register struct dmfl_softc *sc; ! 441: register struct uba_device *ui; ! 442: register struct dmfdevice *addr; ! 443: ! 444: dmf = DMFL_UNIT(dev); ! 445: if (dmf >= NDMF || (ui = dmfinfo[dmf]) == 0 || ui->ui_alive == 0) ! 446: return (ENXIO); ! 447: sc = &dmfl_softc[dmf]; ! 448: if (sc->dmfl_state & OPEN) ! 449: return (EBUSY); ! 450: addr = (struct dmfdevice *)ui->ui_addr; ! 451: if (addr->dmfl_ctrl & DMFL_OFFLINE) { ! 452: #ifdef notdef ! 453: log(LOG_WARNING, "dmf%d: line printer offline/jammed\n", ! 454: dmf); ! 455: #endif ! 456: return (EIO); ! 457: } ! 458: if ((addr->dmfl_ctrl & DMFL_CONV)) { ! 459: log(LOG_WARNING, "dmf%d: line printer disconnected\n", dmf); ! 460: return (EIO); ! 461: } ! 462: ! 463: addr->dmfl_ctrl = 0; ! 464: sc->dmfl_state |= OPEN; ! 465: return (0); ! 466: } ! 467: ! 468: /* ARGSUSED */ ! 469: dmflclose(dev, flag) ! 470: dev_t dev; ! 471: int flag; ! 472: { ! 473: register int dmf = DMFL_UNIT(dev); ! 474: register struct dmfl_softc *sc = &dmfl_softc[dmf]; ! 475: register struct uba_device *ui = dmfinfo[dmf]; ! 476: ! 477: sc->dmfl_state = 0; ! 478: if (sc->dmfl_info != 0) ! 479: ubarelse((int)ui->ui_ubanum, &sc->dmfl_info); ! 480: ! 481: ((struct dmfdevice *)ui->ui_addr)->dmfl_ctrl = 0; ! 482: } ! 483: ! 484: dmflwrite(dev, uio) ! 485: dev_t dev; ! 486: struct uio *uio; ! 487: { ! 488: register int n; ! 489: register int error; ! 490: register struct dmfl_softc *sc; ! 491: ! 492: sc = &dmfl_softc[DMFL_UNIT(dev)]; ! 493: if (sc->dmfl_state & ERROR) ! 494: return (EIO); ! 495: while (n = (unsigned)uio->uio_resid) { ! 496: if (n > DMFL_BUFSIZ) { ! 497: n = DMFL_BUFSIZ; ! 498: sc->dmfl_state |= MOREIO; ! 499: } else ! 500: sc->dmfl_state &= ~MOREIO; ! 501: if (error = uiomove(sc->dmfl_buf, (int)n, UIO_WRITE, uio)) ! 502: return (error); ! 503: if (error = dmflout(dev, sc->dmfl_buf, n)) ! 504: return (error); ! 505: } ! 506: return (0); ! 507: } ! 508: ! 509: ! 510: /* ! 511: * dmflout -- start io operation to dmf line printer ! 512: * cp is addr of buf of n chars to be sent. ! 513: * ! 514: * -- dmf will be put in formatted output mode, this will ! 515: * be selectable from an ioctl if the ! 516: * need ever arises. ! 517: */ ! 518: dmflout(dev, cp, n) ! 519: dev_t dev; ! 520: char *cp; ! 521: int n; ! 522: { ! 523: register struct dmfl_softc *sc; ! 524: register int dmf; ! 525: register struct uba_device *ui; ! 526: register struct dmfdevice *d; ! 527: int s; ! 528: ! 529: dmf = DMFL_UNIT(dev); ! 530: sc = &dmfl_softc[dmf]; ! 531: if (sc->dmfl_state & ERROR) ! 532: return (EIO); ! 533: ui = dmfinfo[dmf]; ! 534: /* ! 535: * allocate unibus resources, will be released when io ! 536: * operation is done. ! 537: */ ! 538: if (sc->dmfl_info == 0) ! 539: sc->dmfl_info = uballoc(ui->ui_ubanum, cp, n, 0); ! 540: d = (struct dmfdevice *)ui->ui_addr; ! 541: d->dmfl_ctrl = sc->dmfl_format; /* indir reg 2 */ ! 542: /* indir reg auto increments on r/w */ ! 543: /* SO DON'T CHANGE THE ORDER OF THIS CODE */ ! 544: d->dmfl_indrct = 0; /* prefix chars & num */ ! 545: d->dmfl_indrct = 0; /* suffix chars & num */ ! 546: d->dmfl_indrct = sc->dmfl_info; /* dma lo 16 bits addr */ ! 547: d->dmfl_indrct = -n; /* number of chars */ ! 548: ! 549: d->dmfl_indrct = ((sc->dmfl_info>>16)&3) | DMFL_OPTIONS; ! 550: /* dma hi 2 bits addr */ ! 551: d->dmfl_indrct = sc->dmfl_lines /* lines per page */ ! 552: | (sc->dmfl_cols<<8); /* carriage width */ ! 553: sc->dmfl_state |= ASLP; ! 554: s = spltty(); ! 555: d->dmfl_ctrl |= DMFL_PEN | DMFL_IE; ! 556: while (sc->dmfl_state & ASLP) { ! 557: sleep(sc->dmfl_buf, PZERO + 8); ! 558: while (sc->dmfl_state & ERROR) { ! 559: timeout(dmflint, (caddr_t)dmf, 10 * hz); ! 560: sleep((caddr_t)&sc->dmfl_state, PZERO + 8); ! 561: } ! 562: } ! 563: splx(s); ! 564: return (0); ! 565: } ! 566: ! 567: /* ! 568: * dmflint -- handle an interrupt from the line printer part of the dmf32 ! 569: */ ! 570: dmflint(dmf) ! 571: int dmf; ! 572: { ! 573: register struct uba_device *ui; ! 574: register struct dmfl_softc *sc; ! 575: register struct dmfdevice *d; ! 576: short dmfl_stats; ! 577: ! 578: ui = dmfinfo[dmf]; ! 579: sc = &dmfl_softc[dmf]; ! 580: d = (struct dmfdevice *)ui->ui_addr; ! 581: ! 582: d->dmfl_ctrl &= ~DMFL_IE; ! 583: dmfl_stats = d->dmfl_ctrl; ! 584: if (sc->dmfl_state & ERROR) { ! 585: if ((dmfl_stats & DMFL_OFFLINE) == 0) ! 586: sc->dmfl_state &= ~ERROR; ! 587: wakeup((caddr_t)&sc->dmfl_state); ! 588: return; ! 589: } ! 590: if (dmfl_stats & DMFL_DMAERR) ! 591: log(LOG_WARNING, "dmf%d: NXM\n", dmf); ! 592: if (dmfl_stats & DMFL_OFFLINE) { ! 593: log(LOG_WARNING, "dmf%d: printer error\n", dmf); ! 594: sc->dmfl_state |= ERROR; ! 595: } ! 596: #ifdef notdef ! 597: if (dmfl_stats & DMFL_PDONE) { ! 598: printf("bytes= %d\n", d->dmfl_indrct); ! 599: printf("lines= %d\n", d->dmfl_indrct); ! 600: } ! 601: #endif ! 602: sc->dmfl_state &= ~ASLP; ! 603: wakeup((caddr_t)sc->dmfl_buf); ! 604: if (sc->dmfl_info && (sc->dmfl_state & MOREIO) == 0) ! 605: ubarelse(ui->ui_ubanum, &sc->dmfl_info); ! 606: } ! 607: #endif NDMF_LP ! 608: ! 609: /* stubs for interrupt routines for devices not yet supported */ ! 610: ! 611: dmfsrint() ! 612: { ! 613: printf("dmfsrint\n"); ! 614: } ! 615: ! 616: dmfsxint() ! 617: { ! 618: printf("dmfsxint\n"); ! 619: } ! 620: ! 621: dmfdaint() ! 622: { ! 623: printf("dmfdaint\n"); ! 624: } ! 625: ! 626: dmfdbint() ! 627: { ! 628: printf("dmfdbint\n"); ! 629: } ! 630: #endif NDMF
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.