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

  1. /* pdp18b_drm.c: drum/fixed head disk simulator
  2.  
  3.    Copyright (c) 1995, 1996, Robert M Supnik, Digital Equipment Corporation
  4.    Commercial use prohibited
  5.  
  6.    drm        (PDP-7) Type 24 serial drum
  7.         (PDP-9) RM09 serial drum
  8. */
  9.  
  10. #include "pdp18b_defs.h"
  11. #include <math.h>
  12.  
  13. /* Constants */
  14.  
  15. #define DRM_NUMWDS    256                /* words/sector */
  16. #define DRM_NUMSC    2                /* sectors/track */
  17. #define DRM_NUMTR    256                /* tracks/drum */
  18. #define DRM_NUMDK    1                /* drum/controller */
  19. #define DRM_NUMWDT    (DRM_NUMWDS * DRM_NUMSC)    /* words/track */
  20. #define DRM_SIZE    (DRM_NUMDK * DRM_NUMTR * DRM_NUMWDT) /* words/drum */
  21. #define DRM_SMASK    ((DRM_NUMTR * DRM_NUMSC) - 1)    /* sector mask */
  22.  
  23. /* Parameters in the unit descriptor */
  24.  
  25. #define FUNC        u4                /* function */
  26. #define DRM_READ    000                /* read */
  27. #define DRM_WRITE    040                /* write */
  28.  
  29. #define GET_POS(x)    ((int) fmod (sim_gtime() / ((double) (x)), \
  30.             ((double) DRM_NUMWDT)))
  31.  
  32. extern unsigned int M[];
  33. extern int int_req;
  34. extern UNIT cpu_unit;
  35. int drm_da = 0;                        /* track address */
  36. int drm_ma = 0;                        /* memory address */
  37. int drm_err = 0;                    /* error flag */
  38. int drm_wlk = 0;                    /* write lock */
  39. int drm_time = 10;                    /* inter-word time */
  40. int drm_stopioe = 1;                    /* stop on error */
  41. int drm_svc (UNIT *uptr);
  42. int drm_reset (DEVICE *dptr);
  43. int drm_boot (int unitno);
  44. extern int sim_activate (UNIT *uptr, int interval);
  45. extern int sim_cancel (UNIT *uptr);
  46. extern int sim_is_active (UNIT *uptr);
  47. extern double sim_gtime(void);
  48.  
  49. /* DRM data structures
  50.  
  51.    drm_dev    DRM device descriptor
  52.    drm_unit    DRM unit descriptor
  53.    drm_reg    DRM register list
  54. */
  55.  
  56. UNIT drm_unit =
  57.     { UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,
  58.     DRM_SIZE) };
  59.  
  60. REG drm_reg[] = {
  61.     { ORDATA (DA, drm_da, 9) },
  62.     { ORDATA (MA, drm_ma, 15) },
  63.     { FLDATA (INT, int_req, INT_V_DRM) },
  64.     { FLDATA (DONE, int_req, INT_V_DRM) },
  65.     { FLDATA (ERR, drm_err, 0) },
  66.     { ORDATA (WLK, drm_wlk, 32) },
  67.     { DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },
  68.     { FLDATA (STOP_IOE, drm_stopioe, 0) },
  69.     { NULL }  };
  70.  
  71. DEVICE drm_dev = {
  72.     "DRM", &drm_unit, drm_reg, NULL,
  73.     1, 8, 20, 1, 8, 18,
  74.     NULL, NULL, &drm_reset,
  75.     &drm_boot, NULL, NULL };
  76.  
  77. /* IOT routines */
  78.  
  79. int drm60 (int pulse, int AC)
  80. {
  81. if ((pulse & 027) == 06) {                /* DRLR, DRLW */
  82.     drm_ma = AC & ADDRMASK;                /* load mem addr */
  83.     drm_unit.FUNC = pulse & 040;  }            /* save function */
  84. return AC;
  85. }
  86.  
  87. int drm61 (int pulse, int AC)
  88. {
  89. int t;
  90.  
  91. if (pulse == 001) return (int_req & INT_DRM)? IOT_SKP + AC: AC; /* DRSF */
  92. if (pulse == 002) {                    /* DRCF */
  93.     int_req = int_req & ~INT_DRM;            /* clear done */
  94.     drm_err = 0;  }                    /* clear error */
  95. if (pulse == 006) {                    /* DRSS */
  96.     drm_da = AC & DRM_SMASK;            /* load sector # */
  97.     int_req = int_req & ~INT_DRM;            /* clear done */
  98.     drm_err = 0;                    /* clear error */
  99.     t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
  100.     if (t < 0) t = t + DRM_NUMWDT;            /* wrap around? */
  101.     sim_activate (&drm_unit, t * drm_time);  }    /* schedule op */
  102. return AC;
  103. }
  104.  
  105. int drm62 (int pulse, int AC)
  106. {
  107. int t;
  108.  
  109. if (pulse == 001) return (drm_err)? AC: IOT_SKP + AC;    /* DRSN */
  110. if (pulse == 004) {                    /* DRCS */
  111.     int_req = int_req & ~INT_DRM;            /* clear done */
  112.     drm_err = 0;                    /* clear error */
  113.     t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);
  114.     if (t < 0) t = t + DRM_NUMWDT;            /* wrap around? */
  115.     sim_activate (&drm_unit, t * drm_time);  }    /* schedule op */
  116. return AC;
  117. }
  118.  
  119. /* Unit service
  120.  
  121.    This code assumes the entire drum is buffered.
  122. */
  123.  
  124. int drm_svc (UNIT *uptr)
  125. {
  126. int i, da;
  127.  
  128. if ((uptr -> flags & UNIT_BUF) == 0) {            /* not buf? abort */
  129.     drm_err = 1;                    /* set error */
  130.     int_req = int_req | INT_DRM;            /* set done */
  131.     return IORETURN (drm_stopioe, SCPE_UNATT);  }
  132.  
  133. da = drm_da * DRM_NUMWDS;                /* compute dev addr */
  134. for (i = 0; i < DRM_NUMWDS; i++, da++) {        /* do transfer */
  135.     if (uptr -> FUNC == DRM_READ) {
  136.         if (MEM_ADDR_OK (drm_ma))        /* read, check nxm */
  137.             M[drm_ma] = *(((int *) uptr -> filebuf) + da);  }
  138.     else {    if ((drm_wlk >> (drm_da >> 4)) & 1) drm_err = 1;
  139.         else {    *(((int *) uptr -> filebuf) + da) = M[drm_ma];
  140.             if (da >= uptr -> hwmark)
  141.                 uptr -> hwmark = da + 1;  }  }
  142.     drm_ma = (drm_ma + 1) & ADDRMASK;  }        /* incr mem addr */
  143. drm_da = (drm_da + 1) & DRM_SMASK;            /* incr dev addr */
  144. int_req = int_req | INT_DRM;                /* set done */
  145. return SCPE_OK;
  146. }
  147.  
  148. /* Reset routine */
  149.  
  150. int drm_reset (DEVICE *dptr)
  151. {
  152. drm_ma = drm_ma = drm_err = 0;
  153. int_req = int_req & ~INT_DRM;
  154. sim_cancel (&drm_unit);
  155. return SCPE_OK;
  156. }
  157.  
  158. /* IORS routine */
  159.  
  160. int drm_iors (void)
  161. {
  162. return ((int_req & INT_DRM)? IOS_DRM: 0);
  163. }
  164.  
  165. /* Bootstrap routine */
  166.  
  167. #define BOOT_START 02000
  168. #define BOOT_LEN (sizeof (boot_rom) / sizeof (int))
  169.  
  170. static const int boot_rom[] = {
  171.     0750000,        /* CLA            ; dev, mem addr */
  172.     0706006,        /* DRLR            ; load ma */
  173.     0706106,        /* DRSS            ; load da, start */
  174.     0706101,        /* DRSF            ; wait for done */
  175.     0602003,        /* JMP .-1
  176.     0600000            /* JMP 0        ; enter boot */
  177. };
  178.  
  179. int drm_boot (int unitno)
  180. {
  181. int i;
  182. extern int saved_PC;
  183.  
  184. for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];
  185. saved_PC = BOOT_START;
  186. return SCPE_OK;
  187. }
  188.