home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Boot_Images / 2.11_on_rl02 / pdpsim.tz / pdpsim / pdp8_lp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-29  |  3.4 KB  |  133 lines

  1. /* pdp8_lp.c: PDP-8 line printer simulator
  2.  
  3.    Copyright (c) 1993, 1994, Robert M Supnik, Digital Equipment Corporation
  4.    Commercial use prohibited
  5.  
  6.    lpt        line printer
  7. */
  8.  
  9. #include "pdp8_defs.h"
  10.  
  11. extern int int_req, dev_done, dev_enable, stop_inst;
  12. int lpt_err = 0;                    /* error flag */
  13. int lpt_stopioe = 0;                    /* stop on error */
  14. int lpt_svc (UNIT *uptr);
  15. int lpt_reset (DEVICE *dptr);
  16. int lpt_attach (UNIT *uptr, char *cptr);
  17. int lpt_detach (UNIT *uptr);
  18. extern int sim_activate (UNIT *uptr, int interval);
  19. extern int sim_cancel (UNIT *uptr);
  20. extern int attach_unit (UNIT *uptr, char *cptr);
  21. extern int detach_unit (UNIT *uptr);
  22.  
  23. /* LPT data structures
  24.  
  25.    lpt_dev    LPT device descriptor
  26.    lpt_unit    LPT unit descriptor
  27.    lpt_reg    LPT register list
  28. */
  29.  
  30. UNIT lpt_unit = {
  31.     UDATA (&lpt_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
  32.  
  33. REG lpt_reg[] = {
  34.     { ORDATA (BUF, lpt_unit.buf, 8) },
  35.     { FLDATA (ERR, lpt_err, 0) },
  36.     { FLDATA (DONE, dev_done, INT_V_LPT) },
  37.     { FLDATA (ENABLE, dev_enable, INT_V_LPT) },
  38.     { FLDATA (INT, int_req, INT_V_LPT) },
  39.     { DRDATA (POS, lpt_unit.pos, 32), PV_LEFT },
  40.     { DRDATA (TIME, lpt_unit.wait, 24), PV_LEFT },
  41.     { FLDATA (STOP_IOE, lpt_stopioe, 0) },
  42.     { NULL }  };
  43.  
  44. DEVICE lpt_dev = {
  45.     "LPT", &lpt_unit, lpt_reg, NULL,
  46.     1, 10, 32, 1, 8, 8,
  47.     NULL, NULL, &lpt_reset,
  48.     NULL, &lpt_attach, &lpt_detach };
  49.  
  50. /* IOT routine */
  51.  
  52. int lpt (int pulse, int AC)
  53. {
  54. switch (pulse) {                    /* decode IR<9:11> */
  55. case 1:                            /* PSKF */
  56.     return (dev_done & INT_LPT)? IOT_SKP + AC: AC;
  57. case 2:                            /* PCLF */
  58.     dev_done = dev_done & ~INT_LPT;            /* clear flag */
  59.     int_req = int_req & ~INT_LPT;            /* clear int req */
  60.     return AC;
  61. case 3:                            /* PSKE */
  62.     return (lpt_err)? IOT_SKP + AC: AC;
  63. case 6:                            /* PCLF!PSTB */
  64.     dev_done = dev_done & ~INT_LPT;            /* clear flag */
  65.     int_req = int_req & ~INT_LPT;            /* clear int req */
  66. case 4:                            /* PSTB */
  67.     lpt_unit.buf = AC & 0177;            /* load buffer */
  68.     if ((lpt_unit.buf == 015) || (lpt_unit.buf == 014) ||
  69.         (lpt_unit.buf == 012)) {
  70.         sim_activate (&lpt_unit, lpt_unit.wait);
  71.         return AC;  }
  72.     return (lpt_svc (&lpt_unit) << IOT_V_REASON) + AC;
  73. case 5:                            /* PSIE */
  74.     dev_enable = dev_enable | INT_LPT;        /* set enable */
  75.     int_req = INT_UPDATE;                /* update interrupts */
  76.     return AC;
  77. case 7:                            /* PCIE */
  78.     dev_enable = dev_enable & ~INT_LPT;        /* clear enable */
  79.     int_req = int_req & ~INT_LPT;            /* clear int req */
  80.     return AC;
  81. default:
  82.     return (stop_inst << IOT_V_REASON) + AC;  }    /* end switch */
  83. }
  84.  
  85. /* Unit service */
  86.  
  87. int lpt_svc (UNIT *uptr)
  88. {
  89. dev_done = dev_done | INT_LPT;                /* set done */
  90. int_req = INT_UPDATE;                    /* update interrupts */
  91. if ((lpt_unit.flags & UNIT_ATT) == 0) {
  92.     lpt_err = 1;
  93.     return IORETURN (lpt_stopioe, SCPE_UNATT);  }
  94. if (putc (lpt_unit.buf, lpt_unit.fileref) == EOF) {
  95.     perror ("LPT I/O error");
  96.     clearerr (lpt_unit.fileref);
  97.     return SCPE_IOERR;  }
  98. lpt_unit.pos = lpt_unit.pos + 1;
  99. return SCPE_OK;
  100. }
  101.  
  102. /* Reset routine */
  103.  
  104. int lpt_reset (DEVICE *dptr)
  105. {
  106. lpt_unit.buf = 0;
  107. dev_done = dev_done & ~INT_LPT;                /* clear done, int */
  108. int_req = int_req & ~INT_LPT;
  109. dev_enable = dev_enable | INT_LPT;            /* set enable */
  110. lpt_err = (lpt_unit.flags & UNIT_ATT) == 0;
  111. sim_cancel (&lpt_unit);                    /* deactivate unit */
  112. return SCPE_OK;
  113. }
  114.  
  115. /* Attach routine */
  116.  
  117. int lpt_attach (UNIT *uptr, char *cptr)
  118. {
  119. int reason;
  120.  
  121. reason = attach_unit (uptr, cptr);
  122. lpt_err = (lpt_unit.flags & UNIT_ATT) == 0;
  123. return reason;
  124. }
  125.  
  126. /* Detach routine */
  127.  
  128. int lpt_detach (UNIT *uptr)
  129. {
  130. lpt_err = 1;
  131. return detach_unit (uptr);
  132. }
  133.