First Commit of my working state
[simh.git] / PDP18B / pdp18b_drm.c
CommitLineData
196ba1fc
PH
1/* pdp18b_drm.c: drum/fixed head disk simulator\r
2\r
3 Copyright (c) 1993-2005, Robert M Supnik\r
4\r
5 Permission is hereby granted, free of charge, to any person obtaining a\r
6 copy of this software and associated documentation files (the "Software"),\r
7 to deal in the Software without restriction, including without limitation\r
8 the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
9 and/or sell copies of the Software, and to permit persons to whom the\r
10 Software is furnished to do so, subject to the following conditions:\r
11\r
12 The above copyright notice and this permission notice shall be included in\r
13 all copies or substantial portions of the Software.\r
14\r
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
18 ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21\r
22 Except as contained in this notice, the name of Robert M Supnik shall not be\r
23 used in advertising or otherwise to promote the sale, use or other dealings\r
24 in this Software without prior written authorization from Robert M Supnik.\r
25\r
26 drm (PDP-4,PDP-7) Type 24 serial drum\r
27\r
28 14-Jan-04 RMS Revised IO device call interface\r
29 26-Oct-03 RMS Cleaned up buffer copy code\r
30 05-Dec-02 RMS Updated from Type 24 documentation\r
31 22-Nov-02 RMS Added PDP-4 support\r
32 05-Feb-02 RMS Added DIB, device number support\r
33 03-Feb-02 RMS Fixed bug in reset routine (found by Robert Alan Byer)\r
34 06-Jan-02 RMS Revised enable/disable support\r
35 25-Nov-01 RMS Revised interrupt structure\r
36 10-Jun-01 RMS Cleaned up IOT decoding to reflect hardware\r
37 26-Apr-01 RMS Added device enable/disable support\r
38 14-Apr-99 RMS Changed t_addr to unsigned\r
39*/\r
40\r
41#include "pdp18b_defs.h"\r
42#include <math.h>\r
43\r
44/* Constants */\r
45\r
46#define DRM_NUMWDS 256 /* words/sector */\r
47#define DRM_NUMSC 2 /* sectors/track */\r
48#define DRM_NUMTR 256 /* tracks/drum */\r
49#define DRM_NUMDK 1 /* drum/controller */\r
50#define DRM_NUMWDT (DRM_NUMWDS * DRM_NUMSC) /* words/track */\r
51#define DRM_SIZE (DRM_NUMDK * DRM_NUMTR * DRM_NUMWDT) /* words/drum */\r
52#define DRM_SMASK ((DRM_NUMTR * DRM_NUMSC) - 1) /* sector mask */\r
53\r
54/* Parameters in the unit descriptor */\r
55\r
56#define FUNC u4 /* function */\r
57#define DRM_READ 000 /* read */\r
58#define DRM_WRITE 040 /* write */\r
59\r
60#define GET_POS(x) ((int) fmod (sim_gtime() / ((double) (x)), \\r
61 ((double) DRM_NUMWDT)))\r
62\r
63extern int32 M[];\r
64extern int32 int_hwre[API_HLVL+1];\r
65extern UNIT cpu_unit;\r
66\r
67int32 drm_da = 0; /* track address */\r
68int32 drm_ma = 0; /* memory address */\r
69int32 drm_err = 0; /* error flag */\r
70int32 drm_wlk = 0; /* write lock */\r
71int32 drm_time = 10; /* inter-word time */\r
72int32 drm_stopioe = 1; /* stop on error */\r
73\r
74DEVICE drm_dev;\r
75int32 drm60 (int32 dev, int32 pulse, int32 AC);\r
76int32 drm61 (int32 dev, int32 pulse, int32 AC);\r
77int32 drm62 (int32 dev, int32 pulse, int32 AC);\r
78int32 drm_iors (void);\r
79t_stat drm_svc (UNIT *uptr);\r
80t_stat drm_reset (DEVICE *dptr);\r
81t_stat drm_boot (int32 unitno, DEVICE *dptr);\r
82\r
83/* DRM data structures\r
84\r
85 drm_dev DRM device descriptor\r
86 drm_unit DRM unit descriptor\r
87 drm_reg DRM register list\r
88*/\r
89\r
90DIB drm_dib = { DEV_DRM, 3 ,&drm_iors, { &drm60, &drm61, &drm62 } };\r
91\r
92UNIT drm_unit = {\r
93 UDATA (&drm_svc, UNIT_FIX+UNIT_ATTABLE+UNIT_BUFABLE+UNIT_MUSTBUF,\r
94 DRM_SIZE)\r
95 };\r
96\r
97REG drm_reg[] = {\r
98 { ORDATA (DA, drm_da, 9) },\r
99 { ORDATA (MA, drm_ma, 16) },\r
100 { FLDATA (INT, int_hwre[API_DRM], INT_V_DRM) },\r
101 { FLDATA (DONE, int_hwre[API_DRM], INT_V_DRM) },\r
102 { FLDATA (ERR, drm_err, 0) },\r
103 { ORDATA (WLK, drm_wlk, 32) },\r
104 { DRDATA (TIME, drm_time, 24), REG_NZ + PV_LEFT },\r
105 { FLDATA (STOP_IOE, drm_stopioe, 0) },\r
106 { ORDATA (DEVNO, drm_dib.dev, 6), REG_HRO },\r
107 { NULL }\r
108 };\r
109\r
110MTAB drm_mod[] = {\r
111 { MTAB_XTD|MTAB_VDV, 0, "DEVNO", "DEVNO", &set_devno, &show_devno },\r
112 { 0 }\r
113 };\r
114\r
115DEVICE drm_dev = {\r
116 "DRM", &drm_unit, drm_reg, drm_mod,\r
117 1, 8, 20, 1, 8, 18,\r
118 NULL, NULL, &drm_reset,\r
119 &drm_boot, NULL, NULL,\r
120 &drm_dib, DEV_DISABLE\r
121 };\r
122\r
123/* IOT routines */\r
124\r
125int32 drm60 (int32 dev, int32 pulse, int32 AC)\r
126{\r
127if ((pulse & 027) == 06) { /* DRLR, DRLW */\r
128 drm_ma = AC & 0177777; /* load mem addr */\r
129 drm_unit.FUNC = pulse & DRM_WRITE; /* save function */\r
130 }\r
131return AC;\r
132}\r
133\r
134int32 drm61 (int32 dev, int32 pulse, int32 AC)\r
135{\r
136int32 t;\r
137\r
138if (pulse & 001) { /* DRSF */\r
139 if (TST_INT (DRM)) AC = AC | IOT_SKP;\r
140 }\r
141if (pulse & 002) { /* DRCF */\r
142 CLR_INT (DRM); /* clear done */\r
143 drm_err = 0; /* clear error */\r
144 }\r
145if (pulse & 004) { /* DRSS */\r
146 drm_da = AC & DRM_SMASK; /* load sector # */\r
147 t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);\r
148 if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */\r
149 sim_activate (&drm_unit, t * drm_time); /* schedule op */\r
150 }\r
151return AC;\r
152}\r
153\r
154int32 drm62 (int32 dev, int32 pulse, int32 AC)\r
155{\r
156int32 t;\r
157\r
158if (pulse & 001) { /* DRSN */\r
159 if (drm_err == 0) AC = AC | IOT_SKP;\r
160 }\r
161if (pulse & 004) { /* DRCS */\r
162 CLR_INT (DRM); /* clear done */\r
163 drm_err = 0; /* clear error */\r
164 t = ((drm_da % DRM_NUMSC) * DRM_NUMWDS) - GET_POS (drm_time);\r
165 if (t <= 0) t = t + DRM_NUMWDT; /* wrap around? */\r
166 sim_activate (&drm_unit, t * drm_time); /* schedule op */\r
167 }\r
168return AC;\r
169}\r
170\r
171/* Unit service\r
172\r
173 This code assumes the entire drum is buffered.\r
174*/\r
175\r
176t_stat drm_svc (UNIT *uptr)\r
177{\r
178int32 i;\r
179uint32 da;\r
180int32 *fbuf = uptr->filebuf;\r
181\r
182if ((uptr->flags & UNIT_BUF) == 0) { /* not buf? abort */\r
183 drm_err = 1; /* set error */\r
184 SET_INT (DRM); /* set done */\r
185 return IORETURN (drm_stopioe, SCPE_UNATT);\r
186 }\r
187\r
188da = drm_da * DRM_NUMWDS; /* compute dev addr */\r
189for (i = 0; i < DRM_NUMWDS; i++, da++) { /* do transfer */\r
190 if (uptr->FUNC == DRM_READ) { /* read? */\r
191 if (MEM_ADDR_OK (drm_ma)) /* if !nxm */\r
192 M[drm_ma] = fbuf[da]; /* read word */\r
193 }\r
194 else { /* write */\r
195 if ((drm_wlk >> (drm_da >> 4)) & 1) drm_err = 1;\r
196 else { /* not locked */\r
197 fbuf[da] = M[drm_ma]; /* write word */\r
198 if (da >= uptr->hwmark) uptr->hwmark = da + 1;\r
199 }\r
200 }\r
201 drm_ma = (drm_ma + 1) & 0177777; /* incr mem addr */\r
202 }\r
203drm_da = (drm_da + 1) & DRM_SMASK; /* incr dev addr */\r
204SET_INT (DRM); /* set done */\r
205return SCPE_OK;\r
206}\r
207\r
208/* Reset routine */\r
209\r
210t_stat drm_reset (DEVICE *dptr)\r
211{\r
212drm_da = drm_ma = drm_err = 0;\r
213CLR_INT (DRM); /* clear done */\r
214sim_cancel (&drm_unit);\r
215return SCPE_OK;\r
216}\r
217\r
218/* IORS routine */\r
219\r
220int32 drm_iors (void)\r
221{\r
222return (TST_INT (DRM)? IOS_DRM: 0);\r
223}\r
224\r
225/* Bootstrap routine */\r
226\r
227#define BOOT_START 02000\r
228#define BOOT_LEN (sizeof (boot_rom) / sizeof (int))\r
229\r
230static const int32 boot_rom[] = {\r
231 0750000, /* CLA ; dev, mem addr */\r
232 0706006, /* DRLR ; load ma */\r
233 0706106, /* DRSS ; load da, start */\r
234 0706101, /* DRSF ; wait for done */\r
235 0602003, /* JMP .-1 */\r
236 0600000 /* JMP 0 ; enter boot */\r
237 };\r
238\r
239t_stat drm_boot (int32 unitno, DEVICE *dptr)\r
240{\r
241int32 i;\r
242extern int32 PC;\r
243\r
244if (drm_dib.dev != DEV_DRM) return STOP_NONSTD; /* non-std addr? */\r
245for (i = 0; i < BOOT_LEN; i++) M[BOOT_START + i] = boot_rom[i];\r
246PC = BOOT_START;\r
247return SCPE_OK;\r
248}\r