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:
Leo Broukhis 2022-02-20 09:56:29 -08:00 committed by Leo Broukhis
parent c3491a28a2
commit f5fc4f0313
4 changed files with 325 additions and 153 deletions

View file

@ -273,7 +273,8 @@ DEVICE *sim_devices[] = {
&cpu_dev, &cpu_dev,
&reg_dev, &reg_dev,
&drum_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, mg_dev, mg_dev + 1, mg_dev + 2, mg_dev + 3,
&mmu_dev, &mmu_dev,
&clock_dev, &clock_dev,

View file

@ -141,7 +141,8 @@ extern t_value ACC, RMR;
extern uint32 BAZ[8], TABST, RZ; extern uint32 BAZ[8], TABST, RZ;
extern uint32 READY; /* read by ext 4031 */ extern uint32 READY; /* read by ext 4031 */
extern uint32 READY2; /* read by ext 4102 */ 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 clock_dev;
extern DEVICE printer_dev; extern DEVICE printer_dev;
extern DEVICE tty_dev; extern DEVICE tty_dev;

View file

@ -29,6 +29,8 @@
*/ */
#include "besm6_defs.h" #include "besm6_defs.h"
#include <ctype.h> #include <ctype.h>
#include <sys/types.h>
#include <sys/stat.h>
/* /*
* Управляющее слово обмена с магнитным диском. * Управляющее слово обмена с магнитным диском.
@ -59,6 +61,7 @@
*/ */
typedef struct { typedef struct {
int op; /* Условное слово обмена */ int op; /* Условное слово обмена */
int group; /* Unit group number */
int dev; /* Номер устройства, 0..7 */ int dev; /* Номер устройства, 0..7 */
int zone; /* Номер зоны на диске */ int zone; /* Номер зоны на диске */
int track; /* Выбор половины зоны на диске */ int track; /* Выбор половины зоны на диске */
@ -78,47 +81,114 @@ t_stat disk_event (UNIT *u);
/* /*
* DISK data structures * DISK data structures
* *
* disk_dev DISK device descriptor * mg_dev DISK device descriptor
* disk_unit DISK unit descriptor * mg_unit DISK unit descriptor
* disk_reg DISK register list * mg_reg DISK register list
*/ */
UNIT disk_unit [16] = { UNIT md_unit [64] = {
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE, DISK_SIZE) }, { 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[] = { REG disk_reg[] = {
{ ORDATA ( "КУС_0", controller[0].op, 24) }, { ORDATA (КУС_0, controller[0].op, 24) },
{ ORDATA ( "УСТР_0", controller[0].dev, 3) }, { ORDATA (ЛИНЕЙКА_0, controller[0].group, 2) },
{ ORDATA ( "ЗОНА_0", controller[0].zone, 10) }, { ORDATA (УСТР_0, controller[0].dev, 3) },
{ ORDATA ( "ДОРОЖКА_0", controller[0].track, 2) }, { ORDATA (ЗОНА_0, controller[0].zone, 10) },
{ ORDATA ( "МОЗУ_0", controller[0].memory, 20) }, { ORDATA (ДОРОЖКА_0, controller[0].track, 2) },
{ ORDATA ( "РС_0", controller[0].status, 24) }, { ORDATA (МОЗУ_0, controller[0].memory, 20) },
{ ORDATA ( "КУС_1", controller[1].op, 24) }, { ORDATA (РС_0, controller[0].status, 24) },
{ ORDATA ( "УСТР_1", controller[1].dev, 3) }, { 0 },
{ ORDATA ( "ЗОНА_1", controller[1].zone, 10) }, { ORDATA (КУС_1, controller[1].op, 24) },
{ ORDATA ( "ДОРОЖКА_1", controller[1].track, 2) }, { ORDATA (ЛИНЕЙКА_1, controller[1].group, 2) },
{ ORDATA ( "МОЗУ_1", controller[1].memory, 20) }, { ORDATA (УСТР_1, controller[1].dev, 3) },
{ ORDATA ( "РС_1", controller[1].status, 24) }, { ORDATA (ЗОНА_1, controller[1].zone, 10) },
{ ORDATA ( "ОШ", disk_fail, 6) }, { ORDATA (ДОРОЖКА_1, controller[1].track, 2) },
{ ORDATA (МОЗУ_1, controller[1].memory, 20) },
{ ORDATA (РС_1, controller[1].status, 24) },
{ ORDATA (ОШ, disk_fail, 6) },
{ 0 } { 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 disk_mod[] = {
{ MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, NULL,
"SYSLOG", &disk_setsyslog, NULL, NULL, "file name (always appending) or OFF" },
{ 0 } { 0 }
}; };
@ -126,11 +196,74 @@ t_stat disk_reset (DEVICE *dptr);
t_stat disk_attach (UNIT *uptr, CONST char *cptr); t_stat disk_attach (UNIT *uptr, CONST char *cptr);
t_stat disk_detach (UNIT *uptr); t_stat disk_detach (UNIT *uptr);
DEVICE disk_dev = { #define DEB_OPS 000001
"DISK", disk_unit, disk_reg, disk_mod, #define DEB_RRD 000002
16, 8, 21, 1, 8, 50, #define DEB_RWR 000004
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach, #define DEB_INT 000010
NULL, DEV_DISABLE | DEV_DEBUG #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) static KMD *unit_to_ctlr (UNIT *u)
{ {
if (u < &disk_unit[8]) return &controller[(u - md_unit) / 32];
return &controller[0];
else
return &controller[1];
} }
/* /*
@ -150,16 +280,17 @@ static KMD *unit_to_ctlr (UNIT *u)
t_stat disk_reset (DEVICE *dptr) t_stat disk_reset (DEVICE *dptr)
{ {
int i; int i;
int ctlr = (dptr - md_dev) / 4;
memset (&controller, 0, sizeof (controller)); int first_unit = (dptr - md_dev) * 8;
controller[0].sysdata = &memory [030]; KMD *c = &controller[ctlr];
controller[1].sysdata = &memory [040]; memset (c, 0, sizeof (KMD));
controller[0].mask_grp = GRP_CHAN3_FREE; c->sysdata = &memory [030 + ctlr * 8];
controller[1].mask_grp = GRP_CHAN4_FREE; c->mask_grp = GRP_CHAN3_FREE >> ctlr;
controller[0].mask_fail = 020; c->mask_fail = 020 >> ctlr;
controller[1].mask_fail = 010; for (i = first_unit; i < first_unit + 8; ++i) {
for (i=0; i<16; ++i) md_unit[i].dptr = dptr;
sim_cancel (&disk_unit[i]); sim_cancel (&md_unit[i]);
}
return SCPE_OK; return SCPE_OK;
} }
@ -174,26 +305,35 @@ t_stat disk_attach (UNIT *u, CONST char *cptr)
if ((s == SCPE_OK) && (sim_switches & SWMASK ('N'))) { if ((s == SCPE_OK) && (sim_switches & SWMASK ('N'))) {
t_value control[4]; /* block (zone) number, key, userid, checksum */ t_value control[4]; /* block (zone) number, key, userid, checksum */
int diskno, blkno, word; int diskno, blkno, word;
char *filenamepart = NULL;
const char *pos; const char *pos;
/* Using the rightmost sequence of digits within the filename /* 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); filenamepart = sim_filepath_parts (u->filename, "n");
while (pos > cptr && !isdigit(*--pos)); pos = filenamepart + strlen(filenamepart);
while (pos > cptr && isdigit(*pos)) --pos; while (pos > filenamepart && !isdigit(*--pos));
while (pos > filenamepart && isdigit(*pos)) --pos;
if (!isdigit(*pos)) ++pos; if (!isdigit(*pos)) ++pos;
diskno = atoi(pos); diskno = strtoul (pos, NULL, 10);
free (filenamepart);
if (diskno < 2048 || diskno > 4095) { if (diskno < 2048 || diskno > 4095) {
if (diskno == 0) 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 else
sim_printf ("%s: disk volume %d from filename %s invalid (must be 2048..4095)\n", s = sim_messagef (SCPE_ARG,
sim_uname (u), diskno, cptr); "%s: disk volume %d from filename %s invalid (must be 2048..4095)\n",
/* unlink (cptr); ??? */ sim_uname (u), diskno, cptr);
return SCPE_ARG; filenamepart = strdup (u->filename);
detach_unit (u);
remove (filenamepart);
free (filenamepart);
return s; /* not formatting */
} }
if (!sim_quiet && !(sim_switches & SWMASK ('Q'))) sim_messagef (SCPE_OK, "%s: formatting disk volume %d\n", sim_uname (u), diskno);
sim_printf ("%s: formatting disk volume %d\n", sim_uname (u), diskno);
control[1] = SET_PARITY(0, PARITY_NUMBER); control[1] = SET_PARITY(0, PARITY_NUMBER);
control[2] = 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); sim_fwrite(control+2, sizeof(t_value), 1, u->fileref);
} }
} }
return SCPE_OK;
} }
if (s == SCPE_OK || if (s == SCPE_OK ||
(saved_switches & SWMASK ('E')) || (saved_switches & SWMASK ('E')) ||
(sim_switches & SWMASK('N'))) (sim_switches & SWMASK('N')))
return s; break;
sim_switches |= SWMASK ('N'); sim_switches |= SWMASK ('N');
} }
{
struct stat buf;
fstat(fileno(u->fileref), &buf);
u->capac = buf.st_size / 8;
}
return SCPE_OK; return SCPE_OK;
} }
@ -283,14 +427,20 @@ static unsigned sum_with_right_carry (unsigned a, unsigned b)
void disk_write (UNIT *u) void disk_write (UNIT *u)
{ {
KMD *c = unit_to_ctlr (u); KMD *c = unit_to_ctlr (u);
int cnum = c - controller;
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_DAT)
besm6_debug ("::: запись МД %o зона %04o память %05o-%05o", besm6_debug ("::: запись МД %02o зона %04o память %05o-%05o",
c->dev, c->zone, c->memory, c->memory + 1023); c->dev, c->zone, c->memory, c->memory + 1023);
if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) == 0) { if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) == 0) {
sim_fwrite (c->sysdata, 8, 8, u->fileref); sim_fwrite (c->sysdata, 8, 8, u->fileref);
sim_fwrite (&memory [c->memory], 8, 1024, 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)) if (ferror (u->fileref))
longjmp (cpu_halt, SCPE_IOERR); longjmp (cpu_halt, SCPE_IOERR);
} }
@ -298,9 +448,9 @@ void disk_write (UNIT *u)
void disk_write_track (UNIT *u) void disk_write_track (UNIT *u)
{ {
KMD *c = unit_to_ctlr (u); KMD *c = unit_to_ctlr (u);
int cnum = c - controller;
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_DAT)
besm6_debug ("::: запись МД %o полузона %04o.%d память %05o-%05o", besm6_debug ("::: запись МД %02o полузона %04o.%d память %05o-%05o",
c->dev, c->zone, c->track, c->memory, c->memory + 511); c->dev, c->zone, c->track, c->memory, c->memory + 511);
if (fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8, if (fseek (u->fileref, (ZONE_SIZE*c->zone + 4*c->track) * 8,
SEEK_SET) == 0) { SEEK_SET) == 0) {
@ -322,9 +472,9 @@ void disk_format (UNIT *u)
KMD *c = unit_to_ctlr (u); KMD *c = unit_to_ctlr (u);
t_value fmtbuf[5], *ptr; t_value fmtbuf[5], *ptr;
int i; int i;
int cnum = c - controller;
/* По сути, эмулятору ничего делать не надо. */ /* По сути, эмулятору ничего делать не надо. */
if (! disk_dev.dctrl) if (! (u->dptr->dctrl & DEB_DAT))
return; return;
/* Находим начало записываемого заголовка. */ /* Находим начало записываемого заголовка. */
@ -343,7 +493,7 @@ void disk_format (UNIT *u)
((fmtbuf[i+1] >> 40) & BITS(5)); ((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, c->dev, c->zone, c->track, c->memory,
(int) (fmtbuf[0] >> 8 & BITS(30)), (int) (fmtbuf[0] >> 8 & BITS(30)),
(int) (fmtbuf[2] >> 14 & BITS(30))); (int) (fmtbuf[2] >> 14 & BITS(30)));
@ -356,11 +506,11 @@ void disk_format (UNIT *u)
void disk_read (UNIT *u) void disk_read (UNIT *u)
{ {
KMD *c = unit_to_ctlr (u); KMD *c = unit_to_ctlr (u);
int cnum = c - controller;
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_DAT)
besm6_debug ((c->op & DISK_READ_SYSDATA) ? besm6_debug ((c->op & DISK_READ_SYSDATA) ?
"::: чтение МД %o зона %04o служебные слова" : "::: чтение МД %02o зона %04o служебные слова" :
"::: чтение МД %o зона %04o память %05o-%05o", "::: чтение МД %02o зона %04o память %05o-%05o",
c->dev, c->zone, c->memory, c->memory + 1023); c->dev, c->zone, c->memory, c->memory + 1023);
if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) != 0 || if (fseek (u->fileref, ZONE_SIZE * c->zone * 8, SEEK_SET) != 0 ||
sim_fread (c->sysdata, 8, 8, u->fileref) != 8) { sim_fread (c->sysdata, 8, 8, u->fileref) != 8) {
@ -374,6 +524,12 @@ void disk_read (UNIT *u)
disk_fail |= c->mask_fail; disk_fail |= c->mask_fail;
return; return;
} }
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == 2053) {
fprintf(syslog, "R %04o\n", (c->zone-4)&07777);
fflush(syslog);
}
if (ferror (u->fileref)) if (ferror (u->fileref))
longjmp (cpu_halt, SCPE_IOERR); longjmp (cpu_halt, SCPE_IOERR);
} }
@ -393,11 +549,11 @@ t_value collect (t_value val)
void disk_read_track (UNIT *u) void disk_read_track (UNIT *u)
{ {
KMD *c = unit_to_ctlr (u); KMD *c = unit_to_ctlr (u);
int cnum = c - controller;
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_DAT)
besm6_debug ((c->op & DISK_READ_SYSDATA) ? besm6_debug ((c->op & DISK_READ_SYSDATA) ?
"::: чтение МД %o полузона %04o.%d служебные слова" : "::: чтение МД %02o полузона %04o.%d служебные слова" :
"::: чтение МД %o полузона %04o.%d память %05o-%05o", "::: чтение МД %02o полузона %04o.%d память %05o-%05o",
c->dev, c->zone, c->track, c->memory, c->memory + 511); 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 || 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) { 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[1] = 03740LL;
sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14; sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14;
sysdata[3] = BITS48; sysdata[3] = BITS48;
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_TRC)
log_data (sysdata, 4); log_data (sysdata, 4);
/* Кодируем гребенку. */ /* Кодируем гребенку. */
@ -460,7 +616,11 @@ void disk_read_header (UNIT *u)
void disk_io (int ctlr, uint32 cmd) void disk_io (int ctlr, uint32 cmd)
{ {
KMD *c = &controller [ctlr]; 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->op = cmd;
c->format = 0; c->format = 0;
if (c->op & DISK_PAGE_MODE) { 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; c->memory = (cmd & (DISK_PAGE | DISK_HALFPAGE)) >> 2 | (cmd & DISK_BLOCK) >> 8;
} }
#if 0 if (md_dev[ctlr * 4].dctrl & DEB_RWR)
if (disk_dev.dctrl)
besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3', besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3',
(c->op & DISK_READ) ? "чтение" : "запись", cmd); (c->op & DISK_READ) ? "чтение" : "запись", cmd);
#endif
disk_fail &= ~c->mask_fail; disk_fail &= ~c->mask_fail;
/* Гасим главный регистр прерываний. */ /* Гасим главный регистр прерываний. */
@ -487,27 +645,32 @@ void disk_io (int ctlr, uint32 cmd)
void disk_ctl (int ctlr, uint32 cmd) void disk_ctl (int ctlr, uint32 cmd)
{ {
KMD *c = &controller [ctlr]; KMD *c = &controller [ctlr];
UNIT *u = &disk_unit [c->dev]; UNIT *u = &md_unit [c->dev];
if (cmd & BBIT(12)) { 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. */ /* Device not attached. */
disk_fail |= c->mask_fail; disk_fail |= c->mask_fail;
return; return;
} }
c->zone = (cmd >> 1) & BITS(10); if (u->capac <= (2<<20)) {
c->track = cmd & 1; c->zone = (cmd >> 1) & BITS(10);
#if 0 c->track = cmd & 1;
if (disk_dev.dctrl) } else {
c->zone = ((cmd & BITS(11)) << 1) | c->track;
c->track = 0;
}
if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: выдача адреса дорожки %04o.%d", besm6_debug ("::: КМД %c: выдача адреса дорожки %04o.%d",
ctlr + '3', c->zone, c->track); ctlr + '3', c->zone, c->track);
#endif
disk_fail &= ~c->mask_fail; disk_fail &= ~c->mask_fail;
if (c->op & DISK_READ) { if (c->op & DISK_READ) {
if (c->op & DISK_PAGE_MODE) if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
disk_read (u); disk_read (u);
else else
disk_read_track (u); disk_read_track (u);
@ -520,7 +683,7 @@ void disk_ctl (int ctlr, uint32 cmd)
} }
if (c->format) if (c->format)
disk_format (u); disk_format (u);
else if (c->op & DISK_PAGE_MODE) else if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
disk_write (u); disk_write (u);
else else
disk_write_track (u); disk_write_track (u);
@ -546,14 +709,14 @@ void disk_ctl (int ctlr, uint32 cmd)
c->dev = -1; c->dev = -1;
return; return;
} }
c->dev += ctlr << 3; c->dev += ctlr * 32 + c->group * 8;
u = &disk_unit[c->dev]; u = &md_unit[c->dev];
#if 0
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: выбор устройства %d", besm6_debug ("::: КМД %c: выбор устройства %02o",
ctlr + '3', c->dev); 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. */ /* Device not attached. */
disk_fail |= c->mask_fail; disk_fail |= c->mask_fail;
GRP &= ~c->mask_grp; GRP &= ~c->mask_grp;
@ -561,46 +724,52 @@ void disk_ctl (int ctlr, uint32 cmd)
GRP |= c->mask_grp; GRP |= c->mask_grp;
} else if (cmd & BBIT(9)) { } else if (cmd & BBIT(9)) {
/* Проверка прерывания от КМД? */ /* Group selection, LSB of track #, interrupt */
#if 0 if ((cmd & 01774) == 01400) {
if (disk_dev.dctrl) int prev = c->group;
besm6_debug ("::: КМД %c: проверка готовности", 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'); ctlr + '3');
#endif
GRP |= c->mask_grp; GRP |= c->mask_grp;
} else { } else {
/* Команда, выдаваемая в КМД. */ /* Команда, выдаваемая в КМД. */
switch (cmd & 077) { switch (cmd & 077) {
case 000: /* диспак выдаёт эту команду один раз в начале загрузки */ case 000: /* диспак выдаёт эту команду один раз в начале загрузки */
#if 0 if (u->dptr->dctrl & DEB_OPS)
if (disk_dev.dctrl) besm6_debug ("::: КМД %c: недокументированная команда %08o",
besm6_debug ("::: КМД %c: недокументированная команда 00", ctlr + '3', cmd);
ctlr + '3');
#endif
break; break;
case 001: /* сброс на 0 цилиндр */ case 001: /* сброс на 0 цилиндр */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: сброс на 0 цилиндр", besm6_debug ("::: КМД %c: сброс на 0 цилиндр",
ctlr + '3'); ctlr + '3');
#endif #endif
break; break;
case 002: /* подвод */ case 002: /* подвод */
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: подвод", ctlr + '3'); besm6_debug ("::: КМД %c: подвод", ctlr + '3');
break; break;
case 003: /* чтение (НСМД-МОЗУ) */ case 003: /* чтение (НСМД-МОЗУ) */
case 043: /* резервной дорожки */ case 043: /* резервной дорожки */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: чтение", ctlr + '3'); besm6_debug ("::: КМД %c: чтение", ctlr + '3');
#endif #endif
break; break;
case 004: /* запись (МОЗУ-НСМД) */ case 004: /* запись (МОЗУ-НСМД) */
case 044: /* резервной дорожки */ case 044: /* резервной дорожки */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: запись", ctlr + '3'); besm6_debug ("::: КМД %c: запись", ctlr + '3');
#endif #endif
break; break;
@ -608,14 +777,14 @@ void disk_ctl (int ctlr, uint32 cmd)
c->format = 1; c->format = 1;
break; break;
case 006: /* сравнение кодов (МОЗУ-НСМД) */ case 006: /* сравнение кодов (МОЗУ-НСМД) */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: сравнение кодов", ctlr + '3'); besm6_debug ("::: КМД %c: сравнение кодов", ctlr + '3');
#endif #endif
break; break;
case 007: /* чтение заголовка */ case 007: /* чтение заголовка */
case 047: /* резервной дорожки */ case 047: /* резервной дорожки */
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: чтение %s заголовка", ctlr + '3', besm6_debug ("::: КМД %c: чтение %s заголовка", ctlr + '3',
cmd & 040 ? "резервного" : ""); cmd & 040 ? "резервного" : "");
disk_fail &= ~c->mask_fail; disk_fail &= ~c->mask_fail;
@ -625,38 +794,38 @@ void disk_ctl (int ctlr, uint32 cmd)
sim_activate (u, 20*USEC); /* Ускорим для отладки. */ sim_activate (u, 20*USEC); /* Ускорим для отладки. */
break; break;
case 010: /* гашение PC */ case 010: /* гашение PC */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: гашение регистра состояния", besm6_debug ("::: КМД %c: гашение регистра состояния",
ctlr + '3'); ctlr + '3');
#endif #endif
c->status = 0; c->status = 0;
break; break;
case 011: /* опрос 1÷12 разрядов PC */ case 011: /* опрос 1÷12 разрядов PC */
#if 0 if (md_unit[c->dev].flags & UNIT_ATT)
if (disk_dev.dctrl)
besm6_debug ("::: КМД %c: опрос младших разрядов состояния",
ctlr + '3');
#endif
if (disk_unit[c->dev].flags & UNIT_ATT)
c->status = STATUS_GOOD & BITS(12); c->status = STATUS_GOOD & BITS(12);
else else
c->status = 0; c->status = 0;
#if 1
if (u->dptr->dctrl & DEB_STA)
besm6_debug ("::: КМД %c: опрос младших разрядов состояния - %04o",
ctlr + '3', c->status);
#endif
break; break;
case 031: /* опрос 13÷24 разрядов РС */ case 031: /* опрос 13÷24 разрядов РС */
#if 0 if (md_unit[c->dev].flags & UNIT_ATT)
if (disk_dev.dctrl)
besm6_debug ("::: КМД %c: опрос старших разрядов состояния",
ctlr + '3');
#endif
if (disk_unit[c->dev].flags & UNIT_ATT)
c->status = (STATUS_GOOD >> 12) & BITS(12); c->status = (STATUS_GOOD >> 12) & BITS(12);
else else
c->status = 0; c->status = 0;
#if 1
if (u->dptr->dctrl & DEB_STA)
besm6_debug ("::: КМД %c: опрос старших разрядов состояния - %04o",
ctlr + '3', c->status);
#endif
break; break;
case 050: /* освобождение НМД */ case 050: /* освобождение НМД */
#if 0 #if 1
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: освобождение накопителя", besm6_debug ("::: КМД %c: освобождение накопителя",
ctlr + '3'); ctlr + '3');
#endif #endif
@ -676,11 +845,12 @@ void disk_ctl (int ctlr, uint32 cmd)
int disk_state (int ctlr) int disk_state (int ctlr)
{ {
KMD *c = &controller [ctlr]; KMD *c = &controller [ctlr];
#if 0 if (md_dev[ctlr*4].dctrl & DEB_RRD ||
if (disk_dev.dctrl) 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", besm6_debug ("::: КМД %c: опрос состояния = %04o",
ctlr + '3', c->status); ctlr + '3', c->status);
#endif
return c->status; return c->status;
} }
@ -702,7 +872,7 @@ t_stat disk_event (UNIT *u)
int disk_errors () int disk_errors ()
{ {
#if 0 #if 0
if (disk_dev.dctrl) if (u->dptr->dctrl & DEB_RRD)
besm6_debug ("::: КМД: опрос шкалы ошибок = %04o", disk_fail); besm6_debug ("::: КМД: опрос шкалы ошибок = %04o", disk_fail);
#endif #endif
return disk_fail; return disk_fail;

View file

@ -4,7 +4,7 @@ set cpu idle
;set cpu debug ;set cpu debug
;set mmu debug ;set mmu debug
;set drum debug ;set drum debug
;set disk debug ;set md0 debug
; ;
; Initializing the magnetic drums. ; Initializing the magnetic drums.
@ -15,16 +15,16 @@ attach -n drum1 drum2x.bin
; ;
; Initializing a scratch disk. ; Initializing a scratch disk.
; ;
attach -n disk6 2052.bin attach -n md06 2052.bin
; ;
; Attaching system disks. ; Attaching system disks.
; ;
attach -e disk7 sbor2053.bin attach -e md07 sbor2053.bin
attach -e disk5 krab2063.bin attach -e md05 krab2063.bin
attach -e disk0 sbor2048.bin attach -e md00 sbor2048.bin
attach -e disk1 svs2048.bin attach -e md01 svs2048.bin
attach -e disk2 alt2048.bin attach -e md02 alt2048.bin
; ;
; Attaching an output file. ; Attaching an output file.