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

  1. /* pdp11_stddev.c: PDP-11 standard I/O devices simulator
  2.  
  3.    Copyright (c) 1993, 1994, 1996,
  4.    Robert M Supnik, Digital Equipment Corporation
  5.    Commercial use prohibited
  6.  
  7.    ptr        paper tape reader
  8.    ptp        paper tape punch
  9.    tti        terminal input
  10.    tto        terminal output
  11.    clk        line frequency clock
  12. */
  13.  
  14. #include "pdp11_defs.h"
  15.  
  16. #define PTRCSR_IMP    (CSR_ERR+CSR_BUSY+CSR_DONE+CSR_IE) /* paper tape reader */
  17. #define PTRCSR_RW    (CSR_IE)
  18. #define PTPCSR_IMP    (CSR_ERR + CSR_DONE + CSR_IE)    /* paper tape punch */
  19. #define PTPCSR_RW    (CSR_IE)
  20. #define TTICSR_IMP    (CSR_DONE + CSR_IE)        /* terminal input */
  21. #define TTICSR_RW    (CSR_IE)
  22. #define TTOCSR_IMP    (CSR_DONE + CSR_IE)        /* terminal output */
  23. #define TTOCSR_RW    (CSR_IE)
  24. #define CLKCSR_IMP    (CSR_IE)            /* real-time clock */
  25. #define CLKCSR_RW    (CSR_IE)
  26.  
  27. extern int int_req;
  28. int ptr_csr = 0;                    /* control/status */
  29. int ptr_stopioe = 0;                    /* stop on error */
  30. int ptp_csr = 0;                    /* control/status */
  31. int ptp_stopioe = 0;                    /* stop on error */
  32. int tti_csr = 0;                    /* control/status */
  33. int tto_csr = 0;                    /* control/status */
  34. int clk_csr = 0;                    /* control/status */
  35. int ptr_svc (UNIT *uptr);
  36. int ptp_svc (UNIT *uptr);
  37. int tti_svc (UNIT *uptr);
  38. int tto_svc (UNIT *uptr);
  39. int clk_svc (UNIT *uptr);
  40. int ptr_reset (DEVICE *dptr);
  41. int ptp_reset (DEVICE *dptr);
  42. int tti_reset (DEVICE *dptr);
  43. int tto_reset (DEVICE *dptr);
  44. int clk_reset (DEVICE *dptr);
  45. int ptr_attach (UNIT *uptr, char *ptr);
  46. int ptr_detach (UNIT *uptr);
  47. int ptp_attach (UNIT *uptr, char *ptr);
  48. int ptp_detach (UNIT *uptr);
  49. extern int sim_activate (UNIT *uptr, int interval);
  50. extern int sim_cancel (UNIT *uptr);
  51. extern int attach_unit (UNIT *uptr, char *ptr);
  52. extern int detach_unit (UNIT *uptr);
  53. extern sim_poll_kbd (void);
  54. extern sim_type_tty (char out);
  55.  
  56. /* PTR data structures
  57.  
  58.    ptr_dev    PTR device descriptor
  59.    ptr_unit    PTR unit descriptor
  60.    ptr_reg    PTR register list
  61. */
  62.  
  63. UNIT ptr_unit = {
  64.     UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_IN_WAIT };
  65.  
  66. REG ptr_reg[] = {
  67.     { ORDATA (CSR, ptr_csr, 16) },
  68.     { ORDATA (BUF, ptr_unit.buf, 8) },
  69.     { FLDATA (INT, int_req, INT_V_PTR) },
  70.     { FLDATA (ERR, ptr_csr, CSR_V_ERR) },
  71.     { FLDATA (BUSY, ptr_csr, CSR_V_BUSY) },
  72.     { FLDATA (DONE, ptr_csr, CSR_V_DONE) },
  73.     { FLDATA (IE, ptr_csr, CSR_V_IE) },
  74.     { DRDATA (POS, ptr_unit.pos, 32), PV_LEFT },
  75.     { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
  76.     { FLDATA (STOP_IOE, ptr_stopioe, 0) },
  77.     { NULL }  };
  78.  
  79. DEVICE ptr_dev = {
  80.     "PTR", &ptr_unit, ptr_reg, NULL,
  81.     1, 10, 32, 1, 8, 8,
  82.     NULL, NULL, &ptr_reset,
  83.     NULL, &ptr_attach, &ptr_detach };
  84.  
  85. /* PTP data structures
  86.  
  87.    ptp_dev    PTP device descriptor
  88.    ptp_unit    PTP unit descriptor
  89.    ptp_reg    PTP register list
  90. */
  91.  
  92. UNIT ptp_unit = {
  93.     UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
  94.  
  95. REG ptp_reg[] = {
  96.     { ORDATA (BUF, ptp_unit.buf, 8) },
  97.     { ORDATA (CSR, ptp_csr, 16) },
  98.     { FLDATA (INT, int_req, INT_V_PTP) },
  99.     { FLDATA (ERR, ptp_csr, CSR_V_ERR) },
  100.     { FLDATA (DONE, ptp_csr, CSR_V_DONE) },
  101.     { FLDATA (IE, ptp_csr, CSR_V_IE) },
  102.     { DRDATA (POS, ptp_unit.pos, 32), PV_LEFT },
  103.     { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
  104.     { FLDATA (STOP_IOE, ptp_stopioe, 0) },
  105.     { NULL }  };
  106.  
  107. DEVICE ptp_dev = {
  108.     "PTP", &ptp_unit, ptp_reg, NULL,
  109.     1, 10, 32, 1, 8, 8,
  110.     NULL, NULL, &ptp_reset,
  111.     NULL, &ptp_attach, &ptp_detach };
  112.  
  113. /* TTI data structures
  114.  
  115.    tti_dev    TTI device descriptor
  116.    tti_unit    TTI unit descriptor
  117.    tti_reg    TTI register list
  118. */
  119.  
  120. UNIT tti_unit = { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT };
  121.  
  122. REG tti_reg[] = {
  123.     { ORDATA (BUF, tti_unit.buf, 8) },
  124.     { ORDATA (CSR, tti_csr, 16) },
  125.     { FLDATA (INT, int_req, INT_V_TTI) },
  126.     { FLDATA (ERR, tti_csr, CSR_V_ERR) },
  127.     { FLDATA (DONE, tti_csr, CSR_V_DONE) },
  128.     { FLDATA (IE, tti_csr, CSR_V_IE) },
  129.     { DRDATA (POS, tti_unit.pos, 32), PV_LEFT },
  130.     { DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
  131.     { NULL }  };
  132.  
  133. DEVICE tti_dev = {
  134.     "TTI", &tti_unit, tti_reg, NULL,
  135.     1, 10, 32, 1, 8, 8,
  136.     NULL, NULL, &tti_reset,
  137.     NULL, NULL, NULL };
  138.  
  139. /* TTO data structures
  140.  
  141.    tto_dev    TTO device descriptor
  142.    tto_unit    TTO unit descriptor
  143.    tto_reg    TTO register list
  144. */
  145.  
  146. UNIT tto_unit = { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT };
  147.  
  148. REG tto_reg[] = {
  149.     { ORDATA (BUF, tto_unit.buf, 8) },
  150.     { ORDATA (CSR, tto_csr, 16) },
  151.     { FLDATA (INT, int_req, INT_V_TTO) },
  152.     { FLDATA (ERR, tto_csr, CSR_V_ERR) },
  153.     { FLDATA (DONE, tto_csr, CSR_V_DONE) },
  154.     { FLDATA (IE, tto_csr, CSR_V_IE) },
  155.     { DRDATA (POS, tto_unit.pos, 32), PV_LEFT },
  156.     { DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
  157.     { NULL }  };
  158.  
  159. DEVICE tto_dev = {
  160.     "TTO", &tto_unit, tto_reg, NULL,
  161.     1, 10, 32, 1, 8, 8,
  162.     NULL, NULL, &tto_reset,
  163.     NULL, NULL, NULL };
  164.  
  165. /* CLK data structures
  166.  
  167.    clk_dev    CLK device descriptor
  168.    clk_unit    CLK unit descriptor
  169.    clk_reg    CLK register list
  170. */
  171.  
  172. UNIT clk_unit = { UDATA (&clk_svc, 0, 0), 8000 };
  173.  
  174. REG clk_reg[] = {
  175.     { ORDATA (CSR, clk_csr, 16) },
  176.     { FLDATA (INT, int_req, INT_V_CLK) },
  177.     { FLDATA (DONE, clk_csr, CSR_V_DONE) },
  178.     { FLDATA (IE, clk_csr, CSR_V_IE) },
  179.     { DRDATA (TIME, clk_unit.wait, 24), REG_NZ + PV_LEFT },
  180.     { NULL }  };
  181.  
  182. DEVICE clk_dev = {
  183.     "CLK", &clk_unit, clk_reg, NULL,
  184.     1, 0, 0, 0, 0, 0,
  185.     NULL, NULL, &clk_reset,
  186.     NULL, NULL, NULL };
  187.  
  188. /* Standard I/O dispatch routine, I/O addresses 17777546-17777567
  189.  
  190.    17777546        clock CSR
  191.    17777550        ptr CSR
  192.    17777552        ptr buffer
  193.    17777554        ptp CSR
  194.    17777556        ptp buffer
  195.    17777560        tti CSR
  196.    17777562        tti buffer
  197.    17777564        tto CSR
  198.    17777566        tto buffer
  199.  
  200.    Note: Word access routines filter out odd addresses.  Thus,
  201.    an odd address implies an (odd) byte access.
  202. */
  203.  
  204. int std_rd (int *data, int PA, int access)
  205. {
  206. switch ((PA >> 1) & 017) {                /* decode PA<4:1> */
  207. case 03:                        /* clk csr */
  208.     *data = clk_csr & CLKCSR_IMP;
  209.     return SCPE_OK;
  210. case 04:                        /* ptr csr */
  211.     *data = ptr_csr & PTRCSR_IMP;
  212.     return SCPE_OK;
  213. case 05:                        /* ptr buf */
  214.     ptr_csr = ptr_csr & ~CSR_DONE;
  215.     int_req = int_req & ~INT_PTR;
  216.     *data = ptr_unit.buf & 0377;
  217.     return SCPE_OK;
  218. case 06:                        /* ptp csr */
  219.     *data = ptp_csr & PTPCSR_IMP;
  220.     return SCPE_OK;
  221. case 07:                        /* ptp buf */
  222.     *data = ptp_unit.buf;
  223.     return SCPE_OK;
  224. case 010:                        /* tti csr */
  225.     *data = tti_csr & TTICSR_IMP;
  226.     return SCPE_OK;
  227. case 011:                        /* tti buf */
  228.     tti_csr = tti_csr & ~CSR_DONE;
  229.     int_req = int_req & ~INT_TTI;
  230.     *data = tti_unit.buf & 0377;
  231.     return SCPE_OK;
  232. case 012:                        /* tto csr */
  233.     *data = tto_csr & TTOCSR_IMP;
  234.     return SCPE_OK;
  235. case 013:                        /* tto buf */
  236.     *data = tto_unit.buf;
  237.     return SCPE_OK;  }                /* end switch PA */
  238. return SCPE_NXM;                    /* can't get here */
  239. }                            /* end std_rd */
  240.  
  241. int std_wr (int data, int PA, int access)
  242. {
  243. switch ((PA >> 1) & 017) {                /* decode PA<4:1> */
  244. case 03:                        /* clk csr */
  245.     if (PA & 1) return SCPE_OK;
  246.     if ((data & CSR_IE) == 0) int_req = int_req & ~INT_CLK;
  247.     clk_csr = (clk_csr & ~CLKCSR_RW) | (data & CLKCSR_RW);
  248.     sim_activate (&clk_unit, clk_unit.wait);
  249.     return SCPE_OK;
  250. case 04:                        /* ptr csr */
  251.     if (PA & 1) return SCPE_OK;
  252.     if ((data & CSR_IE) == 0) int_req = int_req & ~INT_PTR;
  253.     else if ((ptr_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
  254.         int_req = int_req | INT_PTR;
  255.     if (data & CSR_GO) {
  256.         ptr_csr = (ptr_csr & ~CSR_DONE) | CSR_BUSY;
  257.         int_req = int_req & ~INT_PTR;
  258.         sim_activate (&ptr_unit, ptr_unit.wait);  }
  259.     ptr_csr = (ptr_csr & ~PTRCSR_RW) | (data & PTRCSR_RW);
  260.     return SCPE_OK;
  261. case 05:                        /* ptr buf */
  262.     return SCPE_OK;
  263. case 06:                        /* ptp csr */
  264.     if (PA & 1) return SCPE_OK;
  265.     if ((data & CSR_IE) == 0) int_req = int_req & ~INT_PTP;
  266.     else if ((ptp_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
  267.         int_req = int_req | INT_PTP;
  268.     ptp_csr = (ptp_csr & ~PTPCSR_RW) | (data & PTPCSR_RW);
  269.     return SCPE_OK;
  270. case 07:                        /* ptp buf */
  271.     if ((PA & 1) == 0) ptp_unit.buf = data & 0377;
  272.     ptp_csr = ptp_csr & ~CSR_DONE;
  273.     int_req = int_req & ~INT_PTP;
  274.     sim_activate (&ptp_unit, ptp_unit.wait);
  275.     return SCPE_OK;
  276. case 010:                        /* tti csr */
  277.     if (PA & 1) return SCPE_OK;
  278.     if ((data & CSR_IE) == 0) int_req = int_req & ~INT_TTI;
  279.     else if ((tti_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
  280.         int_req = int_req | INT_TTI;
  281.     tti_csr = (tti_csr & ~TTICSR_RW) | (data & TTICSR_RW);
  282.     return SCPE_OK;
  283. case 011:                        /* tti buf */
  284.     return SCPE_OK;
  285. case 012:                        /* tto csr */
  286.     if (PA & 1) return SCPE_OK;
  287.     if ((data & CSR_IE) == 0) int_req = int_req & ~INT_TTO;
  288.     else if ((tto_csr & (CSR_DONE + CSR_IE)) == CSR_DONE)
  289.         int_req = int_req | INT_TTO;
  290.     tto_csr = (tto_csr & ~TTOCSR_RW) | (data & TTOCSR_RW);
  291.     return SCPE_OK;
  292. case 013:                        /* tto buf */
  293.     if ((PA & 1) == 0) tto_unit.buf = data & 0377;
  294.     tto_csr = tto_csr & ~CSR_DONE;
  295.     int_req = int_req & ~INT_TTO;
  296.     sim_activate (&tto_unit, tto_unit.wait);
  297.     return SCPE_OK;  }                /* end switch PA */
  298. return SCPE_NXM;                    /* can't get here */
  299. }                            /* end std_wr */
  300.  
  301. /* Paper tape reader routines
  302.  
  303.    ptr_svc    process event (character ready)
  304.    ptr_reset    process reset
  305.    ptr_attach    process attach
  306.    ptr_detach    process detach
  307. */
  308.  
  309. int ptr_svc (UNIT *uptr)
  310. {
  311. int temp;
  312.  
  313. ptr_csr = (ptr_csr | CSR_ERR | CSR_DONE) & ~CSR_BUSY;
  314. if (ptr_csr & CSR_IE) int_req = int_req | INT_PTR;
  315. if ((ptr_unit.flags & UNIT_ATT) == 0)
  316.     return IORETURN (ptr_stopioe, SCPE_UNATT);
  317. if ((temp = getc (ptr_unit.fileref)) == EOF) {
  318.     if (feof (ptr_unit.fileref)) {
  319.         if (ptr_stopioe) printf ("PTR end of file\n");
  320.         else return SCPE_OK;  }
  321.     else perror ("PTR I/O error");
  322.     clearerr (ptr_unit.fileref);
  323.     return SCPE_IOERR;  }
  324. ptr_csr = ptr_csr & ~CSR_ERR;
  325. ptr_unit.buf = temp & 0377;
  326. ptr_unit.pos = ptr_unit.pos + 1;
  327. return SCPE_OK;
  328. }                            /* end ptr_svc */
  329.  
  330. int ptr_reset (DEVICE *dptr)
  331. {
  332. ptr_unit.buf = 0;
  333. ptr_csr = 0;
  334. if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
  335. int_req = int_req & ~INT_PTR;
  336. sim_cancel (&ptr_unit);
  337. return SCPE_OK;
  338. }                            /* end ptr_reset */
  339.  
  340. int ptr_attach (UNIT *uptr, char *cptr)
  341. {
  342. int reason;
  343.  
  344. ptr_csr = ptr_csr & ~CSR_ERR;
  345. reason = attach_unit (uptr, cptr);
  346. if ((ptr_unit.flags & UNIT_ATT) == 0) ptr_csr = ptr_csr | CSR_ERR;
  347. return reason;
  348. }
  349.  
  350. int ptr_detach (UNIT *uptr)
  351. {
  352. ptr_csr = ptr_csr | CSR_ERR;
  353. return detach_unit (uptr);
  354. }
  355.  
  356. /* Paper tape punch routines
  357.  
  358.    ptp_svc    process event (character punched)
  359.    ptp_reset    process reset
  360.    ptp_attach    process attach
  361.    ptp_detach    process detach
  362. */
  363.  
  364. int ptp_svc (UNIT *uptr)
  365. {
  366. ptp_csr = ptp_csr | CSR_ERR | CSR_DONE;
  367. if (ptp_csr & CSR_IE) int_req = int_req | INT_PTP;
  368. if ((ptp_unit.flags & UNIT_ATT) == 0)
  369.     return IORETURN (ptp_stopioe, SCPE_UNATT);
  370. if (putc (ptp_unit.buf, ptp_unit.fileref) == EOF) {
  371.     perror ("PTP I/O error");
  372.     clearerr (ptp_unit.fileref);
  373.     return SCPE_IOERR;  }
  374. ptp_csr = ptp_csr & ~CSR_ERR;
  375. ptp_unit.pos = ptp_unit.pos + 1;
  376. return SCPE_OK;
  377. }                            /* end ptp_svc */
  378.  
  379. int ptp_reset (DEVICE *dptr)
  380. {
  381. ptp_unit.buf = 0;
  382. ptp_csr = CSR_DONE;
  383. if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
  384. int_req = int_req & ~INT_PTP;
  385. sim_cancel (&ptp_unit);                    /* deactivate unit */
  386. return SCPE_OK;
  387. }                            /* end ptp_reset */
  388.  
  389. int ptp_attach (UNIT *uptr, char *cptr)
  390. {
  391. int reason;
  392.  
  393. ptp_csr = ptp_csr & ~CSR_ERR;
  394. reason = attach_unit (uptr, cptr);
  395. if ((ptp_unit.flags & UNIT_ATT) == 0) ptp_csr = ptp_csr | CSR_ERR;
  396. return reason;
  397. }
  398.  
  399. int ptp_detach (UNIT *uptr)
  400. {
  401. ptp_csr = ptp_csr | CSR_ERR;
  402. return detach_unit (uptr);
  403. }
  404.  
  405. /* Terminal input routines
  406.  
  407.    tti_svc    process event (character ready)
  408.    tti_reset    process reset
  409. */
  410.  
  411. int tti_svc (UNIT *uptr)
  412. {
  413. int temp;
  414.  
  415. sim_activate (&tti_unit, tti_unit.wait);        /* continue poll */
  416. if ((temp = sim_poll_kbd ()) < SCPE_KFLAG) return temp;    /* no char or error? */
  417. tti_unit.buf = temp & 0377;
  418. tti_unit.pos = tti_unit.pos + 1;
  419. tti_csr = tti_csr | CSR_DONE;
  420. if (tti_csr & CSR_IE) int_req = int_req | INT_TTI;
  421. return SCPE_OK;
  422. }                            /* end tti_svc */
  423.  
  424. int tti_reset (DEVICE *dptr)
  425. {
  426. tti_unit.buf = 0;
  427. tti_csr = 0;
  428. int_req = int_req & ~INT_TTI;
  429. sim_activate (&tti_unit, tti_unit.wait);        /* activate unit */
  430. return SCPE_OK;
  431. }                            /* end tti_reset */
  432.  
  433. /* Terminal output routines
  434.  
  435.    tto_svc    process event (character typed)
  436.    tto_reset    process reset
  437. */
  438.  
  439. int tto_svc (UNIT *uptr)
  440. {
  441. int temp;
  442.  
  443. tto_csr = tto_csr | CSR_DONE;
  444. if (tto_csr & CSR_IE) int_req = int_req | INT_TTO;
  445. if ((temp = sim_type_tty (tto_unit.buf & 0177)) != SCPE_OK) return temp;
  446. tto_unit.pos = tto_unit.pos + 1;
  447. return SCPE_OK;
  448. }                            /* end tto_svc */
  449.  
  450. int tto_reset (DEVICE *dptr)
  451. {
  452. tto_unit.buf = 0;
  453. tto_csr = CSR_DONE;
  454. int_req = int_req & ~INT_TTO;
  455. sim_cancel (&tto_unit);                    /* deactivate unit */
  456. return SCPE_OK;
  457. }                            /* end tto_reset */
  458.  
  459. /* Clock routines
  460.  
  461.    clk_svc    process event (clock tick)
  462.    clk_reset    process reset
  463. */
  464.  
  465. int clk_svc (UNIT *uptr)
  466. {
  467. if (clk_csr & CSR_IE) int_req = int_req | INT_CLK;
  468. sim_activate (&clk_unit, clk_unit.wait);        /* reactivate unit */
  469. return SCPE_OK;
  470. }                            /* end clk_svc */
  471.  
  472. int clk_reset (DEVICE *dptr)
  473. {
  474. clk_csr = 0;
  475. int_req = int_req & ~INT_CLK;
  476. sim_activate (&clk_unit, clk_unit.wait);        /* activate unit */
  477. return SCPE_OK;
  478. }                            /* end clk_reset */
  479.