vax610_sysdev.c - Generalized the boot parsing.

The supported boot options now are:
	B XQ			; Network boot
	B XQA			; equivalent
	B XQA0			; equivalent
	B RQ			; Boot RQ0
	B RQ0			; equivalent
	B DUA			; equivalent
	B DUA0			; equivalent
	B RQn			; Boot RQn
	B DUAn			; equivalent
	B DUn			; equivalent
	B 			; Boot using boot ROM device search

Also the R5 boot options can be specified either before or after the device name and with or without the R5:

For example:
	B /R5:1 XQ
	B /1 XQ
	B XQ /R5:1
	B XQ/1
are all equivalent
This commit is contained in:
Mark Pizzolato 2012-11-05 16:12:41 -08:00
parent 03bbd66cef
commit 732ef8307e

View file

@ -41,7 +41,8 @@
/* MicroVAX I boot device definitions */ /* MicroVAX I boot device definitions */
struct boot_dev { struct boot_dev {
char *name; char *devname;
char *devalias;
int32 code; int32 code;
}; };
@ -60,8 +61,9 @@ int32 conisp, conpc, conpsl; /* console reg */
char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */ char cpu_boot_cmd[CBUFSIZE] = { 0 }; /* boot command */
static struct boot_dev boot_tab[] = { static struct boot_dev boot_tab[] = {
{ "RQ", 0x00415544 }, /* DUAn */ { "RQ", "DUA", 0x00415544 }, /* DUAn */
{ "XQ", 0x00415158 }, /* XQAn */ { "RQ", "DU", 0x00415544 }, /* DUAn */
{ "XQ", "XQA", 0x00415158 }, /* XQAn */
{ NULL } { NULL }
}; };
@ -342,26 +344,26 @@ return run_cmd (flag, "CPU");
t_stat vax610_boot_parse (int32 flag, char *ptr) t_stat vax610_boot_parse (int32 flag, char *ptr)
{ {
char gbuf[CBUFSIZE]; char gbuf[CBUFSIZE], dbuf[CBUFSIZE], rbuf[CBUFSIZE];
char *slptr, *regptr; char *slptr, *regptr;
int32 i, r5v, unitno; int32 i, r5v, unitno;
DEVICE *dptr; DEVICE *dptr;
UNIT *uptr; UNIT *uptr;
DIB *dibp;
t_stat r; t_stat r;
if (ptr && (*ptr == '/')) { /* handle "BOOT /R5:n DEV" format */
ptr = get_glyph (ptr, rbuf, 0); /* get glyph */
regptr = rbuf;
ptr = get_glyph (ptr, gbuf, 0); /* get glyph */
}
else { /* handle "BOOT DEV /R5:n" format */
regptr = get_glyph (ptr, gbuf, 0); /* get glyph */ regptr = get_glyph (ptr, gbuf, 0); /* get glyph */
if ((slptr = strchr (gbuf, '/'))) { /* found slash? */ if ((slptr = strchr (gbuf, '/'))) { /* found slash? */
regptr = strchr (ptr, '/'); /* locate orig */ regptr = strchr (ptr, '/'); /* locate orig */
*slptr = 0; /* zero in string */ *slptr = 0; /* zero in string */
} }
dptr = find_unit (gbuf, &uptr); /* find device */ }
if ((dptr == NULL) || (uptr == NULL)) /* parse R5 parameter value */
return SCPE_ARG;
dibp = (DIB *) dptr->ctxt; /* get DIB */
if (dibp == NULL)
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
r5v = 0; r5v = 0;
if ((strncmp (regptr, "/R5:", 4) == 0) || if ((strncmp (regptr, "/R5:", 4) == 0) ||
(strncmp (regptr, "/R5=", 4) == 0) || (strncmp (regptr, "/R5=", 4) == 0) ||
@ -371,10 +373,33 @@ if ((strncmp (regptr, "/R5:", 4) == 0) ||
if (r != SCPE_OK) if (r != SCPE_OK)
return r; return r;
} }
else if (*regptr == '/') {
r5v = (int32) get_uint (regptr + 1, 16, LMASK, &r);
if (r != SCPE_OK)
return r;
}
else if (*regptr != 0) else if (*regptr != 0)
return SCPE_ARG; return SCPE_ARG;
for (i = 0; boot_tab[i].name != NULL; i++) { if (gbuf[0]) {
if (strcmp (dptr->name, boot_tab[i].name) == 0) { unitno = -1;
for (i = 0; boot_tab[i].devname != NULL; i++) {
if (memcmp (gbuf, boot_tab[i].devalias, strlen(boot_tab[i].devalias)) == 0) {
sprintf(dbuf, "%s%s", boot_tab[i].devname, gbuf + strlen(boot_tab[i].devalias));
dptr = find_unit (dbuf, &uptr);
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
}
if ((unitno == -1) &&
(memcmp (gbuf, boot_tab[i].devname, strlen(boot_tab[i].devname)) == 0)) {
sprintf(dbuf, "%s%s", boot_tab[i].devname, gbuf + strlen(boot_tab[i].devname));
dptr = find_unit (dbuf, &uptr);
if ((dptr == NULL) || (uptr == NULL))
return SCPE_ARG;
unitno = (int32) (uptr - dptr->units);
}
if (unitno == -1)
continue;
R[0] = boot_tab[i].code | (('0' + unitno) << 24); R[0] = boot_tab[i].code | (('0' + unitno) << 24);
R[1] = 0xC0; R[1] = 0xC0;
R[2] = 0; R[2] = 0;
@ -384,6 +409,15 @@ for (i = 0; boot_tab[i].name != NULL; i++) {
return SCPE_OK; return SCPE_OK;
} }
} }
else {
R[0] = 0;
R[1] = 0xC0;
R[2] = 0;
R[3] = 0;
R[4] = 0;
R[5] = r5v;
return SCPE_OK;
}
return SCPE_NOFNC; return SCPE_NOFNC;
} }