blob: 4e9d2a9c1071a5802401c2572b9edf614576c3b3 [file] [log] [blame] [raw]
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001/* vax630_sysdev.c: MicroVAX II system-specific logic
2
3 Copyright (c) 2009-2012, Matt Burke
4 This module incorporates code from SimH, Copyright (c) 1998-2008, Robert M Supnik
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
23 Except as contained in this notice, the name(s) of the author(s) shall not be
24 used in advertising or otherwise to promote the sale, use or other dealings
25 in this Software without prior written authorization from the author(s).
26
27 This module contains the MicroVAX II system-specific registers and devices.
28
29 rom bootstrap ROM (no registers)
30 nvr non-volatile ROM (no registers)
31 sysd system devices
32
33 08-Nov-2012 MB First version
34*/
35
36#include "vax_defs.h"
37#include <time.h>
38
39#ifdef DONT_USE_INTERNAL_ROM
40#if defined(VAX_620)
41#define BOOT_CODE_FILENAME "ka620.bin"
42#else
43#define BOOT_CODE_FILENAME "ka320.bin"
44#endif
45#else /* !DONT_USE_INTERNAL_ROM */
46#if defined(VAX_620)
47#include "vax_ka620_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
48#else
49#include "vax_ka630_bin.h" /* Defines BOOT_CODE_FILENAME and BOOT_CODE_ARRAY, etc */
50#endif
51#endif /* DONT_USE_INTERNAL_ROM */
52
53
54#define UNIT_V_NODELAY (UNIT_V_UF + 0) /* ROM access equal to RAM access */
55#define UNIT_NODELAY (1u << UNIT_V_NODELAY)
56
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -080057t_stat vax630_boot (int32 flag, char *ptr);
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -070058int32 sys_model = 0; /* MicroVAX or VAXstation */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -080059
60/* Special boot command, overrides regular boot */
61
62CTAB vax630_cmd[] = {
63 { "BOOT", &vax630_boot, RU_BOOT,
Mark Pizzolatoeaae1942014-02-01 07:04:44 -080064 "bo{ot} boot simulator\n", NULL, &run_cmd_message },
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -080065 { NULL }
66 };
67
68/* KA630 boot/diagnostic register */
69
70#define BDR_DISP 0x0000000F /* LED display */
71#define BDR_V_BDC 8 /* boot/diag code */
72#define BDR_M_BDC 0x3
73#define BDR_BDC (BDR_M_BDC << BDR_V_BDC)
74#define BDR_V_CPUC 11 /* cpu code */
75#define BDR_M_CPUC 0x3
76#define BDR_CPUC (BDR_M_CPUC << BDR_V_CPUC)
77#define BDR_BRKENB 0x00004000 /* break enable */
78#define BDR_POK 0x00008000 /* power ok */
79#define BDR_RD (BDR_DISP | BDR_BDC | BDR_CPUC | BDR_BRKENB | BDR_POK)
80#define BDR_WR (BDR_DISP)
81
82/* BDR boot/diagnostic codes */
83
84#define BDC_NORM 0x0 /* normal startup */
85#define BDC_LNGI 0x1 /* language inquiry */
86#define BDC_TSTL 0x2 /* test loop */
87#define BDC_SKPM 0x3 /* skip mem test */
88
89/* BDR CPU codes */
90
91#define CPUC_ARB 0x0 /* arbiter */
92#define CPUC_AUX1 0x1 /* auxiliary 1 */
93#define CPUC_AUX2 0x2 /* auxiliary 2 */
94#define CPUC_AUX3 0x3 /* auxiliary 3 */
95
96/* KA630 Memory system error register */
97
98#define MSER_PE 0x00000001 /* Parity Enable */
99#define MSER_WWP 0x00000002 /* Write Wrong Parity */
100#define MSER_LEB 0x00000008 /* Lost Error Bit */
101#define MSER_DQPE 0x00000010 /* DMA Q22 Parity Err */
102#define MSER_CQPE 0x00000020 /* CPU Q22 Parity Err */
103#define MSER_CLPE 0x00000040 /* CPU Mem Parity Err */
104#define MSER_NXM 0x00000080 /* CPU NXM */
105#define MSER_MCD0 0x00000100 /* Mem Code 0 */
106#define MSER_MCD1 0x00000200 /* Mem Code 1 */
107#define MSER_MBZ 0xFFFFFC04
108#define MSER_RD (MSER_PE | MSER_WWP | MSER_LEB | \
Mark Pizzolato651780c2013-06-03 06:29:01 -0700109 MSER_DQPE | MSER_CQPE | MSER_CLPE | \
110 MSER_NXM | MSER_MCD0 | MSER_MCD1)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800111#define MSER_WR (MSER_PE | MSER_WWP)
112#define MSER_RS (MSER_LEB | MSER_DQPE | MSER_CQPE | MSER_CLPE | MSER_NXM)
113
114/* KA630 CPU error address reg */
115
116#define CEAR_LMADD 0x00007FFF /* local mem addr */
117#define CEAR_RD (CEAR_LMADD)
118
119/* KA630 DMA error address reg */
120
121#define DEAR_LMADD 0x00007FFF /* local mem addr */
122#define DEAR_RD (DEAR_LMADD)
123
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800124extern UNIT clk_unit;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800125extern int32 tmr_poll;
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -0700126extern DEVICE vc_dev, lk_dev, vs_dev;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800127
128uint32 *rom = NULL; /* boot ROM */
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700129uint8 *nvr = NULL; /* non-volatile mem */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800130int32 conisp, conpc, conpsl; /* console reg */
131int32 ka_bdr = BDR_BRKENB; /* KA630 boot diag */
132int32 ka_mser = 0; /* KA630 mem sys err */
133int32 ka_cear = 0; /* KA630 cpu err */
134int32 ka_dear = 0; /* KA630 dma err */
135static uint32 rom_delay = 0;
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800136t_bool ka_diag_full = FALSE;
137t_bool ka_hltenab = TRUE; /* Halt Enable / Autoboot flag */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800138
139t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
140t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
141t_stat rom_reset (DEVICE *dptr);
142t_stat rom_set_diag (UNIT *uptr, int32 val, char *cptr, void *desc);
143t_stat rom_show_diag (FILE *st, UNIT *uptr, int32 val, void *desc);
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800144t_stat rom_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
145const char *rom_description (DEVICE *dptr);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800146t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw);
147t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw);
148t_stat nvr_reset (DEVICE *dptr);
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800149t_stat nvr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800150t_stat nvr_attach (UNIT *uptr, char *cptr);
151t_stat nvr_detach (UNIT *uptr);
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800152const char *nvr_description (DEVICE *dptr);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800153t_stat sysd_reset (DEVICE *dptr);
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800154t_stat sysd_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
155const char *sysd_description (DEVICE *dptr);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800156
157int32 rom_rd (int32 pa);
158int32 nvr_rd (int32 pa);
159void nvr_wr (int32 pa, int32 val, int32 lnt);
160int32 ka_rd (int32 pa);
161void ka_wr (int32 pa, int32 val, int32 lnt);
162t_stat sysd_powerup (void);
163int32 con_halt (int32 code, int32 cc);
164
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800165extern int32 qbmap_rd (int32 pa);
166extern void qbmap_wr (int32 pa, int32 val, int32 lnt);
167extern int32 qbmem_rd (int32 pa);
168extern void qbmem_wr (int32 pa, int32 val, int32 lnt);
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -0700169extern int32 vc_mem_rd (int32 pa);
170extern void vc_mem_wr (int32 pa, int32 val, int32 lnt);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800171extern int32 wtc_rd (int32 pa);
172extern void wtc_wr (int32 pa, int32 val, int32 lnt);
173extern void wtc_set_valid (void);
174extern void wtc_set_invalid (void);
175extern int32 iccs_rd (void);
176extern int32 todr_rd (void);
177extern int32 rxcs_rd (void);
178extern int32 rxdb_rd (void);
179extern int32 txcs_rd (void);
180extern void iccs_wr (int32 dat);
181extern void todr_wr (int32 dat);
182extern void rxcs_wr (int32 dat);
183extern void txcs_wr (int32 dat);
184extern void txdb_wr (int32 dat);
185extern void ioreset_wr (int32 dat);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800186
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700187/* debugging bitmaps */
188#define DBG_REG 0x0001 /* trace read/write registers */
189
190DEBTAB nvr_debug[] = {
191 {"REG", DBG_REG},
192 {0}
193};
194
195
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800196/* ROM data structures
197
198 rom_dev ROM device descriptor
199 rom_unit ROM units
200 rom_reg ROM register list
201*/
202
203UNIT rom_unit = { UDATA (NULL, UNIT_FIX+UNIT_BINK, ROMSIZE) };
204
205REG rom_reg[] = {
206 { NULL }
207 };
208
209MTAB rom_mod[] = {
Mark Pizzolato28b90552013-02-02 16:29:38 -0800210 { UNIT_NODELAY, UNIT_NODELAY, "fast access", "NODELAY", NULL, NULL, NULL, "Disable calibrated ROM access speed" },
211 { UNIT_NODELAY, 0, "1usec calibrated access", "DELAY", NULL, NULL, NULL, "Enable calibrated ROM access speed" },
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800212 { 0 }
213 };
214
215DEVICE rom_dev = {
216 "ROM", &rom_unit, rom_reg, rom_mod,
217 1, 16, ROMAWIDTH, 4, 16, 32,
218 &rom_ex, &rom_dep, &rom_reset,
219 NULL, NULL, NULL,
Mark Pizzolato28b90552013-02-02 16:29:38 -0800220 NULL, 0, 0, NULL, NULL, NULL, &rom_help, NULL, NULL,
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800221 &rom_description
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800222 };
223
224/* NVR data structures
225
226 nvr_dev NVR device descriptor
227 nvr_unit NVR units
228 nvr_reg NVR register list
229*/
230
231UNIT nvr_unit =
232 { UDATA (NULL, UNIT_FIX+UNIT_BINK, NVRSIZE) };
233
234REG nvr_reg[] = {
235 { NULL }
236 };
237
238DEVICE nvr_dev = {
239 "NVR", &nvr_unit, nvr_reg, NULL,
240 1, 16, NVRAWIDTH, 4, 16, 32,
241 &nvr_ex, &nvr_dep, &nvr_reset,
242 NULL, &nvr_attach, &nvr_detach,
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700243 NULL, DEV_DEBUG, 0, nvr_debug, NULL, NULL, &nvr_help, NULL, NULL,
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800244 &nvr_description
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800245 };
246
247/* SYSD data structures
248
249 sysd_dev SYSD device descriptor
250 sysd_unit SYSD units
251 sysd_reg SYSD register list
252*/
253
254UNIT sysd_unit = { UDATA (NULL, 0, 0) };
255
256REG sysd_reg[] = {
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800257 { HRDATAD (CONISP, conisp, 32, "console ISP") },
258 { HRDATAD (CONPC, conpc, 32, "console PD") },
259 { HRDATAD (CONPSL, conpsl, 32, "console PSL") },
260 { HRDATAD (BDR, ka_bdr, 16, "KA630 boot diag") },
261 { HRDATAD (MSER, ka_mser, 8, "KA630 mem sys err") },
262 { HRDATAD (CEAR, ka_cear, 8, "KA630 cpu err") },
263 { HRDATAD (DEAR, ka_dear, 8, "KA630 dma err") },
264 { HRDATAD (DEAR, ka_dear, 8, "KA630 dma err") },
265 { FLDATAD (DIAG, ka_diag_full, 0, "KA630 Full Boot diagnostics") },
266 { FLDATAD (HLTENAB, ka_hltenab, 0, "KA630 Autoboot/Halt Enable") },
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800267 { NULL }
268 };
269
270DEVICE sysd_dev = {
271 "SYSD", &sysd_unit, sysd_reg, NULL,
272 1, 16, 16, 1, 16, 8,
273 NULL, NULL, &sysd_reset,
274 NULL, NULL, NULL,
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800275 NULL, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL,
276 &sysd_description
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800277 };
278
279/* ROM: read only memory - stored in a buffered file
280 Register space access routines see ROM twice
281
282 ROM access has been 'regulated' to about 1Mhz to avoid issues
283 with testing the interval timers in self-test. Specifically,
284 the VAX boot ROM (ka630.bin) contains code which presumes that
285 the VAX runs at a particular slower speed when code is running
286 from ROM (which is not cached). These assumptions are built
287 into instruction based timing loops. As the host platform gets
288 much faster than the original VAX, the assumptions embedded in
289 these code loops are no longer valid.
290
291 Code has been added to the ROM implementation to limit CPU speed
292 to about 500K instructions per second. This heads off any future
293 issues with the embedded timing loops.
294*/
295
296int32 rom_swapb(int32 val)
297{
298return ((val << 24) & 0xff000000) | (( val << 8) & 0xff0000) |
299 ((val >> 8) & 0xff00) | ((val >> 24) & 0xff);
300}
301
Mark Pizzolato89ca7bd2014-08-02 15:43:39 -0700302volatile int32 rom_loopval = 0;
303
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800304int32 rom_read_delay (int32 val)
305{
306uint32 i, l = rom_delay;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800307
308if (rom_unit.flags & UNIT_NODELAY)
309 return val;
310
311/* Calibrate the loop delay factor when first used.
312 Do this 4 times to and use the largest value computed. */
313
314if (rom_delay == 0) {
315 uint32 ts, te, c = 10000, samples = 0;
316 while (1) {
317 c = c * 2;
318 te = sim_os_msec();
319 while (te == (ts = sim_os_msec ())); /* align on ms tick */
320
321/* This is merely a busy wait with some "work" that won't get optimized
322 away by a good compiler. loopval always is zero. To avoid smart compilers,
323 the loopval variable is referenced in the function arguments so that the
324 function expression is not loop invariant. It also must be referenced
325 by subsequent code or to avoid the whole computation being eliminated. */
326
327 for (i = 0; i < c; i++)
Mark Pizzolato89ca7bd2014-08-02 15:43:39 -0700328 rom_loopval |= (rom_loopval + ts) ^ rom_swapb (rom_swapb (rom_loopval + ts));
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800329 te = sim_os_msec ();
330 if ((te - ts) < 50) /* sample big enough? */
331 continue;
Mark Pizzolato89ca7bd2014-08-02 15:43:39 -0700332 if (rom_delay < (rom_loopval + (c / (te - ts) / 1000) + 1))
333 rom_delay = rom_loopval + (c / (te - ts) / 1000) + 1;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800334 if (++samples >= 4)
335 break;
336 c = c / 2;
337 }
338 if (rom_delay < 5)
339 rom_delay = 5;
340 }
341
342for (i = 0; i < l; i++)
Mark Pizzolato89ca7bd2014-08-02 15:43:39 -0700343 rom_loopval |= (rom_loopval + val) ^ rom_swapb (rom_swapb (rom_loopval + val));
344return val + rom_loopval;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800345}
346
347int32 rom_rd (int32 pa)
348{
349int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
350
351return rom_read_delay (rom[rg]);
352}
353
354void rom_wr_B (int32 pa, int32 val)
355{
356int32 rg = ((pa - ROMBASE) & ROMAMASK) >> 2;
357int32 sc = (pa & 3) << 3;
358
359rom[rg] = ((val & 0xFF) << sc) | (rom[rg] & ~(0xFF << sc));
360return;
361}
362
363/* ROM examine */
364
365t_stat rom_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
366{
367uint32 addr = (uint32) exta;
368
369if ((vptr == NULL) || (addr & 03))
370 return SCPE_ARG;
371if (addr >= ROMSIZE)
372 return SCPE_NXM;
373*vptr = rom[addr >> 2];
374return SCPE_OK;
375}
376
377/* ROM deposit */
378
379t_stat rom_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
380{
381uint32 addr = (uint32) exta;
382
383if (addr & 03)
384 return SCPE_ARG;
385if (addr >= ROMSIZE)
386 return SCPE_NXM;
387rom[addr >> 2] = (uint32) val;
388return SCPE_OK;
389}
390
391/* ROM reset */
392
393t_stat rom_reset (DEVICE *dptr)
394{
395if (rom == NULL)
396 rom = (uint32 *) calloc (ROMSIZE >> 2, sizeof (uint32));
397if (rom == NULL)
398 return SCPE_MEM;
399return SCPE_OK;
400}
401
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800402t_stat rom_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
Mark Pizzolato28b90552013-02-02 16:29:38 -0800403{
404fprintf (st, "Read-only memory (ROM)\n\n");
405fprintf (st, "The boot ROM consists of a single unit, simulating the 64KB boot ROM. It has\n");
406fprintf (st, "no registers. The boot ROM is loaded with a binary byte stream using the \n");
407fprintf (st, "LOAD -r command:\n\n");
Mark Pizzolato651780c2013-06-03 06:29:01 -0700408fprintf (st, " LOAD -r KA630.BIN load ROM image KA630.BIN\n\n");
Mark Pizzolato864b5812013-02-05 13:59:59 -0800409fprintf (st, "When the simulator starts running (via the BOOT command), if the ROM has\n");
410fprintf (st, "not yet been loaded, an attempt will be made to automatically load the\n");
411fprintf (st, "ROM image from the file ka655x.bin in the current working directory.\n");
412fprintf (st, "If that load attempt fails, then a copy of the missing ROM file is\n");
413fprintf (st, "written to the current directory and the load attempt is retried.\n\n");
414fprintf (st, "ROM accesses a use a calibrated delay that slows ROM-based execution to\n");
415fprintf (st, "about 500K instructions per second. This delay is required to make the\n");
416fprintf (st, "power-up self-test routines run correctly on very fast hosts.\n");
417fprint_set_help (st, dptr);
418fprintf (st, "By default the memory power-up self-tests are skipped as they take a long\n");
419fprintf (st, "time to complete. The self-test sequence can be controlled with the\n");
420fprintf (st, "following commands:\n\n");
421fprintf (st, " SET CPU DIAG=MIN Run minimal diagnostics (skip memory test)\n");
422fprintf (st, " SET CPU DIAG=FULL Run full diagnostics\n\n");
Mark Pizzolato28b90552013-02-02 16:29:38 -0800423return SCPE_OK;
424}
425
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800426const char *rom_description (DEVICE *dptr)
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800427{
428return "read-only memory";
429}
430
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800431/* NVR: non-volatile RAM - stored in a buffered file */
432
433int32 nvr_rd (int32 pa)
434{
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700435int32 rg = (pa - NVRBASE) >> 1;
436int32 result;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800437
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700438if (rg < 14) /* watch chip */
439 result = wtc_rd (pa);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800440else
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700441 if (rg & 1)
442 result = ((int32)nvr[rg]) << 16;
443 else
444 result = nvr[rg] | (((int32)nvr[rg+1]) << 16);
445
446sim_debug (DBG_REG, &nvr_dev, "nvr_rd(pa=0x%X) returns: 0x%X\n", pa, result);
447
448return result;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800449}
450
451void nvr_wr (int32 pa, int32 val, int32 lnt)
452{
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700453int32 rg = (pa - NVRBASE) >> 1;
454uint32 orig_nvr = nvr[rg] | (nvr[rg+1] << 8);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800455
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700456if (rg < 14) /* watch chip */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800457 wtc_wr (pa, val, lnt);
458else {
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700459 int32 v = val;
460 int32 r = rg;
461 int32 l = lnt;
462
463 while (l > 0) {
464 nvr[r] = (uint8)v;
465 ++r;
466 l -= 2;
467 v = (v >> 16);
468 }
469
470 sim_debug (DBG_REG, &nvr_dev, "nvr_wr(pa=0x%X,val=0x%04X,lnt=%d) nvr[%02X] was %04X now %04X\n", pa, val, lnt, rg, orig_nvr, nvr[rg] | (nvr[rg+1] << 8));
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800471 }
472}
473
474/* NVR examine */
475
476t_stat nvr_ex (t_value *vptr, t_addr exta, UNIT *uptr, int32 sw)
477{
478uint32 addr = (uint32) exta;
479
480if ((vptr == NULL) || (addr & 03))
481 return SCPE_ARG;
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700482if (addr >= NVRBASE+NVRASIZE)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800483 return SCPE_NXM;
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700484*vptr = nvr[addr >> 1] | (nvr[(addr >> 1) + 1] << 8);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800485return SCPE_OK;
486}
487
488/* NVR deposit */
489
490t_stat nvr_dep (t_value val, t_addr exta, UNIT *uptr, int32 sw)
491{
492uint32 addr = (uint32) exta;
493
494if (addr & 03)
495 return SCPE_ARG;
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700496if (addr >= NVRBASE+NVRASIZE)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800497 return SCPE_NXM;
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700498nvr[addr >> 1] = (uint8) val;
499nvr[(addr >> 1) + 1] = (uint8) (val >> 8);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800500return SCPE_OK;
501}
502
503/* NVR reset */
504
505t_stat nvr_reset (DEVICE *dptr)
506{
507if (nvr == NULL) {
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700508 nvr = (uint8 *) calloc (NVRSIZE, sizeof (*nvr));
509 nvr_unit.filebuf = (void *)nvr;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800510 }
511if (nvr == NULL)
512 return SCPE_MEM;
513return SCPE_OK;
514}
515
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800516t_stat nvr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
Mark Pizzolato28b90552013-02-02 16:29:38 -0800517{
518fprintf (st, "Non-volatile Memory (NVR)\n\n");
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700519fprintf (st, "The NVR simulates %d bytes of battery-backed up memory.\n", NVRSIZE);
Mark Pizzolato28b90552013-02-02 16:29:38 -0800520fprintf (st, "When the simulator starts, NVR is cleared to 0, and the battery-low indicator\n");
521fprintf (st, "is set. Alternately, NVR can be attached to a file. This allows the NVR\n");
522fprintf (st, "state to be preserved across simulator runs. Successfully attaching an NVR\n");
523fprintf (st, "image clears the battery-low indicator.\n\n");
524return SCPE_OK;
525}
526
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800527/* NVR attach */
528
Mark Pizzolato1a48d852013-08-21 14:31:31 -0700529/* Valid NVRAM contents are required for the Boot ROM to respect the
530 watch chip's CSRD VRT bit. This empty NVRAM image avoids inconsistent
531 ROM behavior the first time the NVR device is attached (to an empty
532 file). Attaching a already existing file will overwrite this initial
533 contents with whatever the NVRAM file contains. */
534uint8 nvr_empty_valid[NVRSIZE] = {
535 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
536 0x00, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE,
537 0xFF, 0x00, 0x00, 0xFE, 0xFF, 0x00, 0x48, 0x45, 0x41, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
539 };
540
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800541t_stat nvr_attach (UNIT *uptr, char *cptr)
542{
543t_stat r;
544
Mark Pizzolato1a48d852013-08-21 14:31:31 -0700545memcpy (nvr, nvr_empty_valid, NVRSIZE);
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800546uptr->flags = uptr->flags | (UNIT_ATTABLE | UNIT_BUFABLE);
547r = attach_unit (uptr, cptr);
548if (r != SCPE_OK)
549 uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
550else {
551 uptr->hwmark = (uint32) uptr->capac;
552 wtc_set_valid ();
553 }
554return r;
555}
556
557/* NVR detach */
558
559t_stat nvr_detach (UNIT *uptr)
560{
561t_stat r;
562
563r = detach_unit (uptr);
564if ((uptr->flags & UNIT_ATT) == 0) {
565 uptr->flags = uptr->flags & ~(UNIT_ATTABLE | UNIT_BUFABLE);
566 wtc_set_invalid ();
567 }
568return r;
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800569}
570
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -0800571const char *nvr_description (DEVICE *dptr)
Mark Pizzolatocbe11142013-01-25 12:04:25 -0800572{
573return "non-volatile memory";
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800574}
575
576/* Read KA630 specific IPR's */
577
578int32 ReadIPR (int32 rg)
579{
580int32 val;
581
582switch (rg) {
583
584 case MT_ICCS: /* ICCS */
585 val = iccs_rd ();
586 break;
587
588 case MT_RXCS: /* RXCS */
589 val = rxcs_rd ();
590 break;
591
592 case MT_RXDB: /* RXDB */
593 val = rxdb_rd ();
594 break;
595
596 case MT_TXCS: /* TXCS */
597 val = txcs_rd ();
598 break;
599
600 case MT_TXDB: /* TXDB */
601 val = 0;
602 break;
603
604 case MT_CONISP: /* console ISP */
605 val = conisp;
606 break;
607
608 case MT_CONPC: /* console PC */
609 val = conpc;
610 break;
611
612 case MT_CONPSL: /* console PSL */
613 val = conpsl;
614 break;
615
616 case MT_SID: /* SID */
617#if defined(VAX_620)
618 val = VAX620_SID;
619#else
620 val = VAX630_SID;
621#endif
622 break;
623
624 case MT_NICR: /* NICR */
625 case MT_ICR: /* ICR */
626 case MT_TODR: /* TODR */
627 case MT_CSRS: /* CSRS */
628 case MT_CSRD: /* CSRD */
629 case MT_CSTS: /* CSTS */
630 case MT_CSTD: /* CSTD */
631 case MT_TBDR: /* TBDR */
632 case MT_CADR: /* CADR */
633 case MT_MCESR: /* MCESR */
634 case MT_CAER: /* CAER */
635 case MT_SBIFS: /* SBIFS */
636 case MT_SBIS: /* SBIS */
637 case MT_SBISC: /* SBISC */
638 case MT_SBIMT: /* SBIMT */
639 case MT_SBIER: /* SBIER */
640 case MT_SBITA: /* SBITA */
641 case MT_SBIQC: /* SBIQC */
642 case MT_TBDATA: /* TBDATA */
643 case MT_MBRK: /* MBRK */
644 case MT_PME: /* PME */
645 val = 0;
646 break;
647
648 default:
649 RSVD_OPND_FAULT;
650 }
651
652return val;
653}
654
655/* Write KA630 specific IPR's */
656
657void WriteIPR (int32 rg, int32 val)
658{
659switch (rg) {
660
661 case MT_ICCS: /* ICCS */
662 iccs_wr (val);
663 break;
664
665 case MT_RXCS: /* RXCS */
666 rxcs_wr (val);
667 break;
668
669 case MT_RXDB: /* RXDB */
670 break;
671
672 case MT_TXCS: /* TXCS */
673 txcs_wr (val);
674 break;
675
676 case MT_TXDB: /* TXDB */
677 txdb_wr (val);
678 break;
679
680 case MT_IORESET: /* IORESET */
681 ioreset_wr (val);
682 break;
683
684 case MT_SID:
685 case MT_CONISP:
686 case MT_CONPC:
687 case MT_CONPSL: /* halt reg */
688 RSVD_OPND_FAULT;
689
690 case MT_NICR: /* NICR */
691 case MT_ICR: /* ICR */
692 case MT_TODR: /* TODR */
693 case MT_CSRS: /* CSRS */
694 case MT_CSRD: /* CSRD */
695 case MT_CSTS: /* CSTS */
696 case MT_CSTD: /* CSTD */
697 case MT_TBDR: /* TBDR */
698 case MT_CADR: /* CADR */
699 case MT_MCESR: /* MCESR */
700 case MT_CAER: /* CAER */
701 case MT_SBIFS: /* SBIFS */
702 case MT_SBIS: /* SBIS */
703 case MT_SBISC: /* SBISC */
704 case MT_SBIMT: /* SBIMT */
705 case MT_SBIER: /* SBIER */
706 case MT_SBITA: /* SBITA */
707 case MT_SBIQC: /* SBIQC */
708 case MT_TBDATA: /* TBDATA */
709 case MT_MBRK: /* MBRK */
710 case MT_PME: /* PME */
711 break;
712
713 default:
714 RSVD_OPND_FAULT;
715 }
716
717return;
718}
719
720/* Read/write I/O register space
721
722 These routines are the 'catch all' for address space map. Any
723 address that doesn't explicitly belong to memory, I/O, or ROM
724 is given to these routines for processing.
725*/
726
727struct reglink { /* register linkage */
728 uint32 low; /* low addr */
729 uint32 high; /* high addr */
Mark Pizzolato3346f4a2012-12-19 12:45:03 -0800730 int32 (*read)(int32 pa); /* read routine */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800731 void (*write)(int32 pa, int32 val, int32 lnt); /* write routine */
732 };
733
734struct reglink regtable[] = {
735 { QBMAPBASE, QBMAPBASE+QBMAPSIZE, &qbmap_rd, &qbmap_wr },
736 { ROMBASE, ROMBASE+ROMSIZE+ROMSIZE, &rom_rd, NULL },
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700737 { NVRBASE, NVRBASE+NVRASIZE, &nvr_rd, &nvr_wr },
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800738 { KABASE, KABASE+KASIZE, &ka_rd, &ka_wr },
Mark Pizzolato0b89e632014-09-20 18:50:39 -0700739#if !defined(VAX_620)
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -0700740 { QVMBASE, QVMBASE+QVMSIZE, &vc_mem_rd, &vc_mem_wr },
Mark Pizzolato0b89e632014-09-20 18:50:39 -0700741#endif
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800742 { QBMBASE, QBMBASE+QBMSIZE, &qbmem_rd, &qbmem_wr },
743 { 0, 0, NULL, NULL }
744 };
745
746/* ReadReg - read register space
747
748 Inputs:
749 pa = physical address
750 lnt = length (BWLQ) - ignored
751 Output:
752 longword of data
753*/
754
755int32 ReadReg (uint32 pa, int32 lnt)
756{
757struct reglink *p;
758
759for (p = &regtable[0]; p->low != 0; p++) {
760 if ((pa >= p->low) && (pa < p->high) && p->read)
761 return p->read (pa);
762 }
763
764MACH_CHECK (MCHK_READ);
765}
766
Mark Pizzolatobf58edf2013-12-22 04:10:01 -0800767/* ReadRegU - read register space, unaligned
768
769 Inputs:
770 pa = physical address
771 lnt = length in bytes (1, 2, or 3)
772 Output:
773 returned data, not shifted
774*/
775
776int32 ReadRegU (uint32 pa, int32 lnt)
777{
778return ReadReg (pa & ~03, L_LONG);
779}
780
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800781/* WriteReg - write register space
782
783 Inputs:
784 pa = physical address
785 val = data to write, right justified in 32b longword
786 lnt = length (BWLQ)
787 Outputs:
788 none
789*/
790
791void WriteReg (uint32 pa, int32 val, int32 lnt)
792{
793struct reglink *p;
794
795for (p = &regtable[0]; p->low != 0; p++) {
796 if ((pa >= p->low) && (pa < p->high) && p->write) {
797 p->write (pa, val, lnt);
798 return;
799 }
800 }
801
802MACH_CHECK (MCHK_WRITE);
803}
804
Mark Pizzolatobf58edf2013-12-22 04:10:01 -0800805/* WriteRegU - write register space, unaligned
806
807 Inputs:
808 pa = physical address
809 val = data to write, right justified in 32b longword
810 lnt = length (1, 2, or 3)
811 Outputs:
812 none
813*/
814
815void WriteRegU (uint32 pa, int32 val, int32 lnt)
816{
817int32 sc = (pa & 03) << 3;
818int32 dat = ReadReg (pa & ~03, L_LONG);
819
820dat = (dat & ~(insert[lnt] << sc)) | ((val & insert[lnt]) << sc);
821WriteReg (pa & ~03, dat, L_LONG);
822return;
823}
824
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800825/* KA630 registers */
826
827int32 ka_rd (int32 pa)
828{
829int32 rg = (pa - KABASE) >> 2;
830
831switch (rg) {
832
833 case 0: /* BDR */
834 return ka_bdr & BDR_RD;
835
836 case 1: /* MSER */
837 return ka_mser & MSER_RD;
838
839 case 2: /* CEAR */
840 return ka_cear & CEAR_RD;
841
842 case 3: /* DEAR */
843 return ka_dear & DEAR_RD;
844 }
845
846return 0;
847}
848
849void ka_wr (int32 pa, int32 val, int32 lnt)
850{
851int32 rg = (pa - KABASE) >> 2;
852
853switch (rg) {
854
855 case 0: /* BDR */
856 ka_bdr = (ka_bdr & ~BDR_WR) | (val & BDR_WR);
857 break;
858
859 case 1: /* MSER */
860 ka_mser = (ka_mser & ~MSER_WR) | (val & MSER_WR);
861 ka_mser = ka_mser & ~(val & MSER_RS);
862 break;
863
864 case 2: /* CEAR */
865 case 3: /* DEAR */
866 break;
867 }
868return;
869}
870
871int32 sysd_hlt_enb (void)
872{
873return ka_bdr & BDR_BRKENB;
874}
875
876/* Machine check */
877
878int32 machine_check (int32 p1, int32 opc, int32 cc, int32 delta)
879{
880int32 st, p2, acc;
881
882if (in_ie) {
883 in_ie = 0;
884 return con_halt(CON_DBLMCK, cc); /* double machine check */
885 }
886if (p1 & 0x80) /* mref? set v/p */
887 p1 = p1 + mchk_ref;
888p2 = mchk_va + 4; /* save vap */
889st = 0;
Mark Pizzolato478ff3d2015-03-30 10:37:41 -0700890cc = intexc (SCB_MCHK, cc, 0, IE_EXC); /* take normal exception */
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800891if (p1 & 0x80) { /* mref? */
Mark Pizzolato651780c2013-06-03 06:29:01 -0700892 if (!(ka_mser & MSER_CQPE) && !(ka_mser & MSER_CLPE))
893 ka_mser |= MSER_NXM;
Mark Pizzolato478ff3d2015-03-30 10:37:41 -0700894 }
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800895acc = ACC_MASK (KERN); /* in kernel mode */
896in_ie = 1;
897SP = SP - 16; /* push 4 words */
898Write (SP, 12, L_LONG, WA); /* # bytes */
899Write (SP + 4, p1, L_LONG, WA); /* mcheck type */
900Write (SP + 8, p2, L_LONG, WA); /* address */
901Write (SP + 12, st, L_LONG, WA); /* state */
902in_ie = 0;
903return cc;
904}
905
906/* Console entry */
907
908int32 con_halt (int32 code, int32 cc)
909{
910int32 temp;
911
912conisp = IS; /* save ISP */
913conpc = PC; /* save PC */
914conpsl = ((PSL | cc) & 0xFFFF00FF) | code; /* PSL, param */
915temp = (PSL >> PSL_V_CUR) & 0x7; /* get is'cur */
916if (temp > 4) /* invalid? */
917 conpsl = conpsl | CON_BADPSL;
918else STK[temp] = SP; /* save stack */
919if (mapen) /* mapping on? */
920 conpsl = conpsl | CON_MAPON;
921mapen = 0; /* turn off map */
922SP = IS; /* set SP from IS */
923PSL = PSL_IS | PSL_IPL1F; /* PSL = 41F0000 */
924JUMP (ROMBASE); /* PC = 20040000 */
925return 0; /* new cc = 0 */
926}
927
928
929/* Special boot command - linked into SCP by initial reset
930
931 Syntax: BOOT {CPU}
932
933*/
934
935t_stat vax630_boot (int32 flag, char *ptr)
936{
937char gbuf[CBUFSIZE];
938
939get_glyph (ptr, gbuf, 0); /* get glyph */
940if (gbuf[0] && strcmp (gbuf, "CPU"))
941 return SCPE_ARG; /* Only can specify CPU device */
942return run_cmd (flag, "CPU");
943}
944
945
946/* Bootstrap */
947
948t_stat cpu_boot (int32 unitno, DEVICE *dptr)
949{
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800950t_stat r;
951
952PC = ROMBASE;
953PSL = PSL_IS | PSL_IPL1F;
954conisp = 0;
955conpc = 0;
956conpsl = PSL_IS | PSL_IPL1F | CON_PWRUP;
957if (rom == NULL)
958 return SCPE_IERR;
959if (*rom == 0) { /* no boot? */
960 r = cpu_load_bootcode (BOOT_CODE_FILENAME, BOOT_CODE_ARRAY, BOOT_CODE_SIZE, TRUE, 0);
961 if (r != SCPE_OK)
962 return r;
963 }
964return SCPE_OK;
965}
966
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800967t_stat sysd_set_diag (UNIT *uptr, int32 val, char *cptr, void *desc)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800968{
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800969if (cptr != NULL) ka_diag_full = strcmp(cptr, "MIN");
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800970return SCPE_OK;
971}
972
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800973t_stat sysd_show_diag (FILE *st, UNIT *uptr, int32 val, void *desc)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800974{
Mark Pizzolatoc7299422013-01-26 17:07:27 -0800975fprintf(st, "DIAG=%s", (ka_diag_full ? "full" :"min"));
976return SCPE_OK;
977}
978
979t_stat sysd_set_halt (UNIT *uptr, int32 val, char *cptr, void *desc)
980{
981ka_hltenab = val;
982return SCPE_OK;
983}
984
985t_stat sysd_show_halt (FILE *st, UNIT *uptr, int32 val, void *desc)
986{
987fprintf(st, "%s", ka_hltenab ? "NOAUTOBOOT" : "AUTOBOOT");
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -0800988return SCPE_OK;
989}
990
Mark Pizzolatod3135b72013-08-21 13:59:22 -0700991t_stat sysd_show_leds (FILE *st, UNIT *uptr, int32 val, void *desc)
992{
993fprintf (st, "leds=(%s,%s,%s,%s)", ka_bdr&8 ? "ON" : "OFF",
994 ka_bdr&4 ? "ON" : "OFF",
995 ka_bdr&2 ? "ON" : "OFF",
996 ka_bdr&1 ? "ON" : "OFF");
997return SCPE_OK;
998}
999
1000
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001001/* SYSD reset */
1002
1003t_stat sysd_reset (DEVICE *dptr)
1004{
1005if (sim_switches & SWMASK ('P')) sysd_powerup (); /* powerup? */
1006ka_bdr = (BDR_POK | \
Mark Pizzolatoc7299422013-01-26 17:07:27 -08001007 ((ka_diag_full ? BDC_NORM : BDC_SKPM) << BDR_V_BDC) | \
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001008 (CPUC_ARB << BDR_V_CPUC) | \
Mark Pizzolatoc7299422013-01-26 17:07:27 -08001009 (ka_hltenab ? BDR_BRKENB : 0) | \
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001010 0xF);
1011ka_mser = 0;
1012ka_cear = 0;
1013ka_dear = 0;
1014
1015sim_vm_cmd = vax630_cmd;
1016
1017return SCPE_OK;
1018}
1019
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -08001020const char *sysd_description (DEVICE *dptr)
Mark Pizzolatocbe11142013-01-25 12:04:25 -08001021{
1022return "system devices";
1023}
1024
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001025/* SYSD powerup */
1026
1027t_stat sysd_powerup (void)
1028{
Mark Pizzolatoc7299422013-01-26 17:07:27 -08001029ka_diag_full = 0;
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001030return SCPE_OK;
1031}
1032
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001033t_stat cpu_set_model (UNIT *uptr, int32 val, char *cptr, void *desc)
1034{
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001035char gbuf[CBUFSIZE];
1036
1037if ((cptr == NULL) || (!*cptr))
1038 return SCPE_ARG;
1039cptr = get_glyph (cptr, gbuf, 0);
1040if (MATCH_CMD(gbuf, "MICROVAX") == 0) {
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001041 sys_model = 0;
Mark Pizzolato688416a2016-01-21 07:37:06 -08001042#if defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001043 vc_dev.flags = vc_dev.flags | DEV_DIS; /* disable QVSS */
1044 lk_dev.flags = lk_dev.flags | DEV_DIS; /* disable keyboard */
1045 vs_dev.flags = vs_dev.flags | DEV_DIS; /* disable mouse */
Mark Pizzolato688416a2016-01-21 07:37:06 -08001046#endif
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001047 strcpy (sim_name, "MicroVAX II (KA630)");
1048 reset_all (0); /* reset everything */
1049 }
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001050else if (MATCH_CMD(gbuf, "VAXSTATION") == 0) {
Mark Pizzolato688416a2016-01-21 07:37:06 -08001051#if defined(USE_SIM_VIDEO) && defined(HAVE_LIBSDL)
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001052 sys_model = 1;
1053 vc_dev.flags = vc_dev.flags & ~DEV_DIS; /* enable QVSS */
1054 lk_dev.flags = lk_dev.flags & ~DEV_DIS; /* enable keyboard */
1055 vs_dev.flags = vs_dev.flags & ~DEV_DIS; /* enable mouse */
1056 strcpy (sim_name, "VAXStation II (KA630)");
1057 reset_all (0); /* reset everything */
Mark Pizzolato688416a2016-01-21 07:37:06 -08001058#else
1059 return sim_messagef(SCPE_ARG, "Simulator built without Graphic Device Support");
1060#endif
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001061 }
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001062else
Mark Pizzolatoa7a8f3d2013-06-13 07:00:32 -07001063 return SCPE_ARG;
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001064return SCPE_OK;
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001065}
1066
Mark Pizzolato923d5412013-01-15 10:18:49 -08001067t_stat cpu_print_model (FILE *st)
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001068{
1069#if defined(VAX_620)
Mark Pizzolato923d5412013-01-15 10:18:49 -08001070fprintf (st, "rtVAX 1000");
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001071#else
Mark Pizzolatob3a9a0d2013-06-12 17:10:23 -07001072fprintf (st, (sys_model ? "VAXstation II" : "MicroVAX II"));
Mark Pizzolatob01fa8f2012-11-09 12:18:15 -08001073#endif
1074return SCPE_OK;
1075}
Mark Pizzolato923d5412013-01-15 10:18:49 -08001076
Mark Pizzolatoef9d1ad2015-02-13 06:18:24 -08001077t_stat cpu_model_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
Mark Pizzolato923d5412013-01-15 10:18:49 -08001078{
1079fprintf (st, "Initial memory size is 16MB.\n\n");
Mark Pizzolato51badc22013-03-19 01:52:31 -07001080fprintf (st, "The CPU supports the BOOT command and is the only VAX device to do so. Note\n");
1081fprintf (st, "that the behavior of the bootstrap depends on the capabilities of the console\n");
1082fprintf (st, "terminal emulator. If the terminal window supports full VT100 emulation\n");
1083fprintf (st, "(including Multilanguage Character Set support), the bootstrap will ask the\n");
1084fprintf (st, "user to specify the language; otherwise, it will default to English.\n\n");
Mark Pizzolato923d5412013-01-15 10:18:49 -08001085fprintf (st, "The simulator is booted with the BOOT command:\n\n");
1086fprintf (st, " sim> BOOT\n\n");
1087return SCPE_OK;
1088}
Mark Pizzolato96dbeae2013-04-08 12:18:09 -07001089
1090t_stat cpu_show_memory (FILE* st, UNIT* uptr, int32 val, void* desc)
1091{
1092uint32 memsize = (uint32)(MEMSIZE>>20);
1093uint32 baseaddr = 0;
1094struct {
1095 uint32 capacity;
1096 char *option;
1097 } boards[] = {
1098 { 16, "MS630-CA"},
1099 { 4, "MS630-BB"},
1100 { 2, "MS630-BA"},
1101 { 1, "MS630-AA"},
1102 { 0, NULL}};
1103int32 i;
1104
1105while (memsize > 1) {
1106 for (i=0; boards[i].capacity > memsize; ++i)
1107 ;
1108 if (memsize == 2)
1109 i = 3;
1110 fprintf(st, "Memory (@0x%08x): %3d Mbytes (%s)\n", baseaddr, boards[i].capacity, boards[i].option);
1111 memsize -= boards[i].capacity;
1112 baseaddr += boards[i].capacity<<20;
1113 }
1114if (memsize)
1115 fprintf(st, "Memory (0x%08x): 1 Mbytes (On-Board)\n", baseaddr);
1116return SCPE_OK;
1117}