BESM6: Reorganized the disk devices.
Split the disk units into groups to match the OS naming convention. Added unit group multiplexing (partially functional in the OS). Split debug messages into categories.
This commit is contained in:
parent
c3491a28a2
commit
f5fc4f0313
4 changed files with 325 additions and 153 deletions
|
@ -273,7 +273,8 @@ DEVICE *sim_devices[] = {
|
|||
&cpu_dev,
|
||||
®_dev,
|
||||
&drum_dev,
|
||||
&disk_dev,
|
||||
md_dev, md_dev + 1, md_dev + 2, md_dev + 3,
|
||||
md_dev + 4, md_dev + 5, md_dev + 6, md_dev + 7,
|
||||
mg_dev, mg_dev + 1, mg_dev + 2, mg_dev + 3,
|
||||
&mmu_dev,
|
||||
&clock_dev,
|
||||
|
|
|
@ -141,7 +141,8 @@ extern t_value ACC, RMR;
|
|||
extern uint32 BAZ[8], TABST, RZ;
|
||||
extern uint32 READY; /* read by ext 4031 */
|
||||
extern uint32 READY2; /* read by ext 4102 */
|
||||
extern DEVICE cpu_dev, drum_dev, mmu_dev, disk_dev;
|
||||
extern DEVICE cpu_dev, drum_dev, mmu_dev;
|
||||
extern DEVICE md_dev[8];
|
||||
extern DEVICE clock_dev;
|
||||
extern DEVICE printer_dev;
|
||||
extern DEVICE tty_dev;
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
*/
|
||||
#include "besm6_defs.h"
|
||||
#include <ctype.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*
|
||||
* Управляющее слово обмена с магнитным диском.
|
||||
|
@ -59,6 +61,7 @@
|
|||
*/
|
||||
typedef struct {
|
||||
int op; /* Условное слово обмена */
|
||||
int group; /* Unit group number */
|
||||
int dev; /* Номер устройства, 0..7 */
|
||||
int zone; /* Номер зоны на диске */
|
||||
int track; /* Выбор половины зоны на диске */
|
||||
|
@ -78,47 +81,114 @@ t_stat disk_event (UNIT *u);
|
|||
/*
|
||||
* DISK data structures
|
||||
*
|
||||
* disk_dev DISK device descriptor
|
||||
* disk_unit DISK unit descriptor
|
||||
* disk_reg DISK register list
|
||||
* mg_dev DISK device descriptor
|
||||
* mg_unit DISK unit descriptor
|
||||
* mg_reg DISK register list
|
||||
*/
|
||||
UNIT disk_unit [16] = {
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) },
|
||||
UNIT md_unit [64] = {
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
|
||||
};
|
||||
|
||||
REG disk_reg[] = {
|
||||
{ ORDATA ( "КУС_0", controller[0].op, 24) },
|
||||
{ ORDATA ( "УСТР_0", controller[0].dev, 3) },
|
||||
{ ORDATA ( "ЗОНА_0", controller[0].zone, 10) },
|
||||
{ ORDATA ( "ДОРОЖКА_0", controller[0].track, 2) },
|
||||
{ ORDATA ( "МОЗУ_0", controller[0].memory, 20) },
|
||||
{ ORDATA ( "РС_0", controller[0].status, 24) },
|
||||
{ ORDATA ( "КУС_1", controller[1].op, 24) },
|
||||
{ ORDATA ( "УСТР_1", controller[1].dev, 3) },
|
||||
{ ORDATA ( "ЗОНА_1", controller[1].zone, 10) },
|
||||
{ ORDATA ( "ДОРОЖКА_1", controller[1].track, 2) },
|
||||
{ ORDATA ( "МОЗУ_1", controller[1].memory, 20) },
|
||||
{ ORDATA ( "РС_1", controller[1].status, 24) },
|
||||
{ ORDATA ( "ОШ", disk_fail, 6) },
|
||||
{ ORDATA (КУС_0, controller[0].op, 24) },
|
||||
{ ORDATA (ЛИНЕЙКА_0, controller[0].group, 2) },
|
||||
{ ORDATA (УСТР_0, controller[0].dev, 3) },
|
||||
{ ORDATA (ЗОНА_0, controller[0].zone, 10) },
|
||||
{ ORDATA (ДОРОЖКА_0, controller[0].track, 2) },
|
||||
{ ORDATA (МОЗУ_0, controller[0].memory, 20) },
|
||||
{ ORDATA (РС_0, controller[0].status, 24) },
|
||||
{ 0 },
|
||||
{ ORDATA (КУС_1, controller[1].op, 24) },
|
||||
{ ORDATA (ЛИНЕЙКА_1, controller[1].group, 2) },
|
||||
{ ORDATA (УСТР_1, controller[1].dev, 3) },
|
||||
{ ORDATA (ЗОНА_1, controller[1].zone, 10) },
|
||||
{ ORDATA (ДОРОЖКА_1, controller[1].track, 2) },
|
||||
{ ORDATA (МОЗУ_1, controller[1].memory, 20) },
|
||||
{ ORDATA (РС_1, controller[1].status, 24) },
|
||||
{ ORDATA (ОШ, disk_fail, 6) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static FILE * syslog = NULL;
|
||||
t_stat disk_setsyslog (UNIT *up, int32 v, CONST char *cp, void *dp) {
|
||||
if (syslog) {
|
||||
fclose(syslog);
|
||||
syslog = NULL;
|
||||
}
|
||||
if (strcasecmp(cp, "OFF") == 0)
|
||||
return SCPE_OK;
|
||||
syslog = fopen(cp, "a");
|
||||
if (!syslog)
|
||||
return sim_messagef (SCPE_OPENERR, "Failed to open SYSLOG file %s: %s\n", cp, strerror(errno));
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
MTAB disk_mod[] = {
|
||||
{ MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, NULL,
|
||||
"SYSLOG", &disk_setsyslog, NULL, NULL, "file name (always appending) or OFF" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -126,11 +196,74 @@ t_stat disk_reset (DEVICE *dptr);
|
|||
t_stat disk_attach (UNIT *uptr, CONST char *cptr);
|
||||
t_stat disk_detach (UNIT *uptr);
|
||||
|
||||
DEVICE disk_dev = {
|
||||
"DISK", disk_unit, disk_reg, disk_mod,
|
||||
16, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG
|
||||
#define DEB_OPS 000001
|
||||
#define DEB_RRD 000002
|
||||
#define DEB_RWR 000004
|
||||
#define DEB_INT 000010
|
||||
#define DEB_TRC 000020
|
||||
#define DEB_DAT 000040
|
||||
#define DEB_STA 000100
|
||||
|
||||
DEBTAB disk_deb[] = {
|
||||
{ "OPS", DEB_OPS, "transactions" },
|
||||
{ "RRD", DEB_RRD, "register reads" },
|
||||
{ "RWR", DEB_RWR, "register writes" },
|
||||
{ "INTERRUPT", DEB_INT, "interrupts" },
|
||||
{ "TRACE", DEB_TRC, "trace" },
|
||||
{ "DATA", DEB_DAT, "transfer data" },
|
||||
{ "STATUS", DEB_STA, "status check" },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
DEVICE md_dev[8] = {
|
||||
{
|
||||
"MD0", md_unit, disk_reg, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD1", md_unit + 8, disk_reg, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD2", md_unit + 16, disk_reg, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD3", md_unit + 24, disk_reg, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD4", md_unit + 32, disk_reg + 8, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD5", md_unit + 40, disk_reg + 8, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD6", md_unit + 48, disk_reg + 8, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
{
|
||||
"MD7", md_unit + 56, disk_reg + 8, disk_mod,
|
||||
8, 8, 21, 1, 8, 50,
|
||||
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
|
||||
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -138,10 +271,7 @@ DEVICE disk_dev = {
|
|||
*/
|
||||
static KMD *unit_to_ctlr (UNIT *u)
|
||||
{
|
||||
if (u < &disk_unit[8])
|
||||
return &controller[0];
|
||||
else
|
||||
return &controller[1];
|
||||
return &controller[(u - md_unit) / 32];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -150,16 +280,17 @@ static KMD *unit_to_ctlr (UNIT *u)
|
|||
t_stat disk_reset (DEVICE *dptr)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (&controller, 0, sizeof (controller));
|
||||
controller[0].sysdata = &memory [030];
|
||||
controller[1].sysdata = &memory [040];
|
||||
controller[0].mask_grp = GRP_CHAN3_FREE;
|
||||
controller[1].mask_grp = GRP_CHAN4_FREE;
|
||||
controller[0].mask_fail = 020;
|
||||
controller[1].mask_fail = 010;
|
||||
for (i=0; i<16; ++i)
|
||||
sim_cancel (&disk_unit[i]);
|
||||
int ctlr = (dptr - md_dev) / 4;
|
||||
int first_unit = (dptr - md_dev) * 8;
|
||||
KMD *c = &controller[ctlr];
|
||||
memset (c, 0, sizeof (KMD));
|
||||
c->sysdata = &memory [030 + ctlr * 8];
|
||||
c->mask_grp = GRP_CHAN3_FREE >> ctlr;
|
||||
c->mask_fail = 020 >> ctlr;
|
||||
for (i = first_unit; i < first_unit + 8; ++i) {
|
||||
md_unit[i].dptr = dptr;
|
||||
sim_cancel (&md_unit[i]);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -174,26 +305,35 @@ t_stat disk_attach (UNIT *u, CONST char *cptr)
|
|||
if ((s == SCPE_OK) && (sim_switches & SWMASK ('N'))) {
|
||||
t_value control[4]; /* block (zone) number, key, userid, checksum */
|
||||
int diskno, blkno, word;
|
||||
char *filenamepart = NULL;
|
||||
const char *pos;
|
||||
/* Using the rightmost sequence of digits within the filename
|
||||
* as a volume number, e.g. "/var/tmp/besm6/2052.bin" -> 2052
|
||||
* provided in the command line as a volume number,
|
||||
* e.g. "/var/tmp/besm6/2052.bin" -> 2052
|
||||
*/
|
||||
pos = cptr + strlen(cptr);
|
||||
while (pos > cptr && !isdigit(*--pos));
|
||||
while (pos > cptr && isdigit(*pos)) --pos;
|
||||
filenamepart = sim_filepath_parts (u->filename, "n");
|
||||
pos = filenamepart + strlen(filenamepart);
|
||||
while (pos > filenamepart && !isdigit(*--pos));
|
||||
while (pos > filenamepart && isdigit(*pos)) --pos;
|
||||
if (!isdigit(*pos)) ++pos;
|
||||
diskno = atoi(pos);
|
||||
diskno = strtoul (pos, NULL, 10);
|
||||
free (filenamepart);
|
||||
if (diskno < 2048 || diskno > 4095) {
|
||||
if (diskno == 0)
|
||||
sim_printf ("%s: filename must contain volume number 2048..4095\n", sim_uname(u));
|
||||
s = sim_messagef (SCPE_ARG,
|
||||
"%s: filename must contain volume number 2048..4095\n",
|
||||
sim_uname(u));
|
||||
else
|
||||
sim_printf ("%s: disk volume %d from filename %s invalid (must be 2048..4095)\n",
|
||||
sim_uname (u), diskno, cptr);
|
||||
/* unlink (cptr); ??? */
|
||||
return SCPE_ARG;
|
||||
s = sim_messagef (SCPE_ARG,
|
||||
"%s: disk volume %d from filename %s invalid (must be 2048..4095)\n",
|
||||
sim_uname (u), diskno, cptr);
|
||||
filenamepart = strdup (u->filename);
|
||||
detach_unit (u);
|
||||
remove (filenamepart);
|
||||
free (filenamepart);
|
||||
return s; /* not formatting */
|
||||
}
|
||||
if (!sim_quiet && !(sim_switches & SWMASK ('Q')))
|
||||
sim_printf ("%s: formatting disk volume %d\n", sim_uname (u), diskno);
|
||||
sim_messagef (SCPE_OK, "%s: formatting disk volume %d\n", sim_uname (u), diskno);
|
||||
|
||||
control[1] = SET_PARITY(0, PARITY_NUMBER);
|
||||
control[2] = SET_PARITY(0, PARITY_NUMBER);
|
||||
|
@ -211,14 +351,18 @@ t_stat disk_attach (UNIT *u, CONST char *cptr)
|
|||
sim_fwrite(control+2, sizeof(t_value), 1, u->fileref);
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
if (s == SCPE_OK ||
|
||||
(saved_switches & SWMASK ('E')) ||
|
||||
(sim_switches & SWMASK('N')))
|
||||
return s;
|
||||
break;
|
||||
sim_switches |= SWMASK ('N');
|
||||
}
|
||||
{
|
||||
struct stat buf;
|
||||
fstat(fileno(u->fileref), &buf);
|
||||
u->capac = buf.st_size / 8;
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -283,14 +427,20 @@ static unsigned sum_with_right_carry (unsigned a, unsigned b)
|
|||
void disk_write (UNIT *u)
|
||||
{
|
||||
KMD *c = unit_to_ctlr (u);
|
||||
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: запись МД %o зона %04o память %05o-%05o",
|
||||
int cnum = c - controller;
|
||||
if (u->dptr->dctrl & DEB_DAT)
|
||||
besm6_debug ("::: запись МД %02o зона %04o память %05o-%05o",
|
||||
c->dev, c->zone, c->memory, c->memory + 1023);
|
||||
if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) == 0) {
|
||||
sim_fwrite (c->sysdata, 8, 8, u->fileref);
|
||||
sim_fwrite (&memory [c->memory], 8, 1024, u->fileref);
|
||||
}
|
||||
|
||||
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == 2053) {
|
||||
fprintf(syslog, "W %04o\n", (c->zone-4)&07777);
|
||||
fflush(syslog);
|
||||
}
|
||||
|
||||
if (ferror (u->fileref))
|
||||
longjmp (cpu_halt, SCPE_IOERR);
|
||||
}
|
||||
|
@ -298,9 +448,9 @@ void disk_write (UNIT *u)
|
|||
void disk_write_track (UNIT *u)
|
||||
{
|
||||
KMD *c = unit_to_ctlr (u);
|
||||
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: запись МД %o полузона %04o.%d память %05o-%05o",
|
||||
int cnum = c - controller;
|
||||
if (u->dptr->dctrl & DEB_DAT)
|
||||
besm6_debug ("::: запись МД %02o полузона %04o.%d память %05o-%05o",
|
||||
c->dev, c->zone, c->track, c->memory, c->memory + 511);
|
||||
if (fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8,
|
||||
SEEK_SET) == 0) {
|
||||
|
@ -322,9 +472,9 @@ void disk_format (UNIT *u)
|
|||
KMD *c = unit_to_ctlr (u);
|
||||
t_value fmtbuf[5], *ptr;
|
||||
int i;
|
||||
|
||||
int cnum = c - controller;
|
||||
/* По сути, эмулятору ничего делать не надо. */
|
||||
if (! disk_dev.dctrl)
|
||||
if (! (u->dptr->dctrl & DEB_DAT))
|
||||
return;
|
||||
|
||||
/* Находим начало записываемого заголовка. */
|
||||
|
@ -343,7 +493,7 @@ void disk_format (UNIT *u)
|
|||
((fmtbuf[i+1] >> 40) & BITS(5));
|
||||
|
||||
/* Печатаем идентификатор, адрес и контрольную сумму адреса. */
|
||||
besm6_debug ("::: формат МД %o полузона %04o.%d память %05o и-а-кса %010o %010o",
|
||||
besm6_debug ("::: формат МД %02o полузона %04o.%d память %05o и-а-кса %010o %010o",
|
||||
c->dev, c->zone, c->track, c->memory,
|
||||
(int) (fmtbuf[0] >> 8 & BITS(30)),
|
||||
(int) (fmtbuf[2] >> 14 & BITS(30)));
|
||||
|
@ -356,11 +506,11 @@ void disk_format (UNIT *u)
|
|||
void disk_read (UNIT *u)
|
||||
{
|
||||
KMD *c = unit_to_ctlr (u);
|
||||
|
||||
if (disk_dev.dctrl)
|
||||
int cnum = c - controller;
|
||||
if (u->dptr->dctrl & DEB_DAT)
|
||||
besm6_debug ((c->op & DISK_READ_SYSDATA) ?
|
||||
"::: чтение МД %o зона %04o служебные слова" :
|
||||
"::: чтение МД %o зона %04o память %05o-%05o",
|
||||
"::: чтение МД %02o зона %04o служебные слова" :
|
||||
"::: чтение МД %02o зона %04o память %05o-%05o",
|
||||
c->dev, c->zone, c->memory, c->memory + 1023);
|
||||
if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) != 0 ||
|
||||
sim_fread (c->sysdata, 8, 8, u->fileref) != 8) {
|
||||
|
@ -374,6 +524,12 @@ void disk_read (UNIT *u)
|
|||
disk_fail |= c->mask_fail;
|
||||
return;
|
||||
}
|
||||
|
||||
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == 2053) {
|
||||
fprintf(syslog, "R %04o\n", (c->zone-4)&07777);
|
||||
fflush(syslog);
|
||||
}
|
||||
|
||||
if (ferror (u->fileref))
|
||||
longjmp (cpu_halt, SCPE_IOERR);
|
||||
}
|
||||
|
@ -393,11 +549,11 @@ t_value collect (t_value val)
|
|||
void disk_read_track (UNIT *u)
|
||||
{
|
||||
KMD *c = unit_to_ctlr (u);
|
||||
|
||||
if (disk_dev.dctrl)
|
||||
int cnum = c - controller;
|
||||
if (u->dptr->dctrl & DEB_DAT)
|
||||
besm6_debug ((c->op & DISK_READ_SYSDATA) ?
|
||||
"::: чтение МД %o полузона %04o.%d служебные слова" :
|
||||
"::: чтение МД %o полузона %04o.%d память %05o-%05o",
|
||||
"::: чтение МД %02o полузона %04o.%d служебные слова" :
|
||||
"::: чтение МД %02o полузона %04o.%d память %05o-%05o",
|
||||
c->dev, c->zone, c->track, c->memory, c->memory + 511);
|
||||
if (fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, SEEK_SET) != 0 ||
|
||||
sim_fread (c->sysdata + 4*c->track, 8, 4, u->fileref) != 4) {
|
||||
|
@ -445,7 +601,7 @@ void disk_read_header (UNIT *u)
|
|||
sysdata[1] = 03740LL;
|
||||
sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14;
|
||||
sysdata[3] = BITS48;
|
||||
if (disk_dev.dctrl)
|
||||
if (u->dptr->dctrl & DEB_TRC)
|
||||
log_data (sysdata, 4);
|
||||
|
||||
/* Кодируем гребенку. */
|
||||
|
@ -460,7 +616,11 @@ void disk_read_header (UNIT *u)
|
|||
void disk_io (int ctlr, uint32 cmd)
|
||||
{
|
||||
KMD *c = &controller [ctlr];
|
||||
|
||||
int cnum = c - controller;
|
||||
uint32 rem = cmd & ~(DISK_PAGE_MODE | DISK_PAGE | DISK_BLOCK | DISK_READ | DISK_READ_SYSDATA);
|
||||
if (rem && md_dev[ctlr * 4].dctrl & DEB_RWR) {
|
||||
besm6_debug ("::: КМД %c: unknown bits in IO request %08o", ctlr + '3', rem);
|
||||
}
|
||||
c->op = cmd;
|
||||
c->format = 0;
|
||||
if (c->op & DISK_PAGE_MODE) {
|
||||
|
@ -470,11 +630,9 @@ void disk_io (int ctlr, uint32 cmd)
|
|||
/* Обмен половиной страницы (дорожкой) */
|
||||
c->memory = (cmd & (DISK_PAGE | DISK_HALFPAGE)) >> 2 | (cmd & DISK_BLOCK) >> 8;
|
||||
}
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
if (md_dev[ctlr * 4].dctrl & DEB_RWR)
|
||||
besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3',
|
||||
(c->op & DISK_READ) ? "чтение" : "запись", cmd);
|
||||
#endif
|
||||
disk_fail &= ~c->mask_fail;
|
||||
|
||||
/* Гасим главный регистр прерываний. */
|
||||
|
@ -487,27 +645,32 @@ void disk_io (int ctlr, uint32 cmd)
|
|||
void disk_ctl (int ctlr, uint32 cmd)
|
||||
{
|
||||
KMD *c = &controller [ctlr];
|
||||
UNIT *u = &disk_unit [c->dev];
|
||||
UNIT *u = &md_unit [c->dev];
|
||||
|
||||
if (cmd & BBIT(12)) {
|
||||
/* Выдача в КМД адреса дорожки.
|
||||
* Здесь же выполняем обмен с диском.
|
||||
* Номер дисковода к этому моменту уже известен. */
|
||||
if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) {
|
||||
if ((u->dptr->flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) {
|
||||
/* Device not attached. */
|
||||
disk_fail |= c->mask_fail;
|
||||
return;
|
||||
}
|
||||
c->zone = (cmd >> 1) & BITS(10);
|
||||
c->track = cmd & 1;
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
if (u->capac <= (2<<20)) {
|
||||
c->zone = (cmd >> 1) & BITS(10);
|
||||
c->track = cmd & 1;
|
||||
} else {
|
||||
c->zone = ((cmd & BITS(11)) << 1) | c->track;
|
||||
c->track = 0;
|
||||
}
|
||||
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: выдача адреса дорожки %04o.%d",
|
||||
ctlr + '3', c->zone, c->track);
|
||||
#endif
|
||||
|
||||
disk_fail &= ~c->mask_fail;
|
||||
if (c->op & DISK_READ) {
|
||||
if (c->op & DISK_PAGE_MODE)
|
||||
if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
|
||||
disk_read (u);
|
||||
else
|
||||
disk_read_track (u);
|
||||
|
@ -520,7 +683,7 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
}
|
||||
if (c->format)
|
||||
disk_format (u);
|
||||
else if (c->op & DISK_PAGE_MODE)
|
||||
else if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
|
||||
disk_write (u);
|
||||
else
|
||||
disk_write_track (u);
|
||||
|
@ -546,14 +709,14 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
c->dev = -1;
|
||||
return;
|
||||
}
|
||||
c->dev += ctlr << 3;
|
||||
u = &disk_unit[c->dev];
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: КМД %c: выбор устройства %d",
|
||||
c->dev += ctlr * 32 + c->group * 8;
|
||||
u = &md_unit[c->dev];
|
||||
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: выбор устройства %02o",
|
||||
ctlr + '3', c->dev);
|
||||
#endif
|
||||
if ((disk_dev.flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) {
|
||||
|
||||
if ((u->dptr->flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) {
|
||||
/* Device not attached. */
|
||||
disk_fail |= c->mask_fail;
|
||||
GRP &= ~c->mask_grp;
|
||||
|
@ -561,46 +724,52 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
GRP |= c->mask_grp;
|
||||
|
||||
} else if (cmd & BBIT(9)) {
|
||||
/* Проверка прерывания от КМД? */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: КМД %c: проверка готовности",
|
||||
/* Group selection, LSB of track #, interrupt */
|
||||
if ((cmd & 01774) == 01400) {
|
||||
int prev = c->group;
|
||||
c->group = cmd & 3;
|
||||
c->dev = (c->dev & ~030) | (c->group << 3);
|
||||
if (u->dptr->dctrl & DEB_OPS && c->group != prev)
|
||||
besm6_debug ("::: КМД %c: selected group %d",
|
||||
ctlr + '3', c->group);
|
||||
}
|
||||
c->track = cmd & BBIT(13) ? 1 : 0;
|
||||
if (u->dptr->dctrl & DEB_OPS && cmd & BBIT(13))
|
||||
besm6_debug ("::: КМД %c: set track# LSB",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
|
||||
GRP |= c->mask_grp;
|
||||
|
||||
} else {
|
||||
/* Команда, выдаваемая в КМД. */
|
||||
switch (cmd & 077) {
|
||||
case 000: /* диспак выдаёт эту команду один раз в начале загрузки */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: КМД %c: недокументированная команда 00",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: недокументированная команда %08o",
|
||||
ctlr + '3', cmd);
|
||||
break;
|
||||
case 001: /* сброс на 0 цилиндр */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: сброс на 0 цилиндр",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
break;
|
||||
case 002: /* подвод */
|
||||
if (disk_dev.dctrl)
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: подвод", ctlr + '3');
|
||||
break;
|
||||
case 003: /* чтение (НСМД-МОЗУ) */
|
||||
case 043: /* резервной дорожки */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: чтение", ctlr + '3');
|
||||
#endif
|
||||
break;
|
||||
case 004: /* запись (МОЗУ-НСМД) */
|
||||
case 044: /* резервной дорожки */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: запись", ctlr + '3');
|
||||
#endif
|
||||
break;
|
||||
|
@ -608,14 +777,14 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
c->format = 1;
|
||||
break;
|
||||
case 006: /* сравнение кодов (МОЗУ-НСМД) */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: сравнение кодов", ctlr + '3');
|
||||
#endif
|
||||
break;
|
||||
case 007: /* чтение заголовка */
|
||||
case 047: /* резервной дорожки */
|
||||
if (disk_dev.dctrl)
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: чтение %s заголовка", ctlr + '3',
|
||||
cmd & 040 ? "резервного" : "");
|
||||
disk_fail &= ~c->mask_fail;
|
||||
|
@ -625,38 +794,38 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
sim_activate (u, 20*USEC); /* Ускорим для отладки. */
|
||||
break;
|
||||
case 010: /* гашение PC */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: гашение регистра состояния",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
c->status = 0;
|
||||
break;
|
||||
case 011: /* опрос 1÷12 разрядов PC */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: КМД %c: опрос младших разрядов состояния",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
if (disk_unit[c->dev].flags & UNIT_ATT)
|
||||
if (md_unit[c->dev].flags & UNIT_ATT)
|
||||
c->status = STATUS_GOOD & BITS(12);
|
||||
else
|
||||
c->status = 0;
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_STA)
|
||||
besm6_debug ("::: КМД %c: опрос младших разрядов состояния - %04o",
|
||||
ctlr + '3', c->status);
|
||||
#endif
|
||||
break;
|
||||
case 031: /* опрос 13÷24 разрядов РС */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
besm6_debug ("::: КМД %c: опрос старших разрядов состояния",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
if (disk_unit[c->dev].flags & UNIT_ATT)
|
||||
if (md_unit[c->dev].flags & UNIT_ATT)
|
||||
c->status = (STATUS_GOOD >> 12) & BITS(12);
|
||||
else
|
||||
c->status = 0;
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_STA)
|
||||
besm6_debug ("::: КМД %c: опрос старших разрядов состояния - %04o",
|
||||
ctlr + '3', c->status);
|
||||
#endif
|
||||
break;
|
||||
case 050: /* освобождение НМД */
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
#if 1
|
||||
if (u->dptr->dctrl & DEB_OPS)
|
||||
besm6_debug ("::: КМД %c: освобождение накопителя",
|
||||
ctlr + '3');
|
||||
#endif
|
||||
|
@ -676,11 +845,12 @@ void disk_ctl (int ctlr, uint32 cmd)
|
|||
int disk_state (int ctlr)
|
||||
{
|
||||
KMD *c = &controller [ctlr];
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
if (md_dev[ctlr*4].dctrl & DEB_RRD ||
|
||||
md_dev[ctlr*4+1].dctrl & DEB_RRD ||
|
||||
md_dev[ctlr*4+2].dctrl & DEB_RRD ||
|
||||
md_dev[ctlr*4+3].dctrl & DEB_RRD)
|
||||
besm6_debug ("::: КМД %c: опрос состояния = %04o",
|
||||
ctlr + '3', c->status);
|
||||
#endif
|
||||
return c->status;
|
||||
}
|
||||
|
||||
|
@ -702,7 +872,7 @@ t_stat disk_event (UNIT *u)
|
|||
int disk_errors ()
|
||||
{
|
||||
#if 0
|
||||
if (disk_dev.dctrl)
|
||||
if (u->dptr->dctrl & DEB_RRD)
|
||||
besm6_debug ("::: КМД: опрос шкалы ошибок = %04o", disk_fail);
|
||||
#endif
|
||||
return disk_fail;
|
||||
|
|
|
@ -4,7 +4,7 @@ set cpu idle
|
|||
;set cpu debug
|
||||
;set mmu debug
|
||||
;set drum debug
|
||||
;set disk debug
|
||||
;set md0 debug
|
||||
|
||||
;
|
||||
; Initializing the magnetic drums.
|
||||
|
@ -15,16 +15,16 @@ attach -n drum1 drum2x.bin
|
|||
;
|
||||
; Initializing a scratch disk.
|
||||
;
|
||||
attach -n disk6 2052.bin
|
||||
attach -n md06 2052.bin
|
||||
|
||||
;
|
||||
; Attaching system disks.
|
||||
;
|
||||
attach -e disk7 sbor2053.bin
|
||||
attach -e disk5 krab2063.bin
|
||||
attach -e disk0 sbor2048.bin
|
||||
attach -e disk1 svs2048.bin
|
||||
attach -e disk2 alt2048.bin
|
||||
attach -e md07 sbor2053.bin
|
||||
attach -e md05 krab2063.bin
|
||||
attach -e md00 sbor2048.bin
|
||||
attach -e md01 svs2048.bin
|
||||
attach -e md02 alt2048.bin
|
||||
|
||||
;
|
||||
; Attaching an output file.
|
||||
|
|
Loading…
Add table
Reference in a new issue