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,
&reg_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,

View file

@ -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;

View file

@ -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;

View file

@ -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.