diff --git a/BESM6/besm6_cpu.c b/BESM6/besm6_cpu.c index 96b8ffa5..9239c523 100644 --- a/BESM6/besm6_cpu.c +++ b/BESM6/besm6_cpu.c @@ -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, diff --git a/BESM6/besm6_defs.h b/BESM6/besm6_defs.h index feafa605..3d930995 100644 --- a/BESM6/besm6_defs.h +++ b/BESM6/besm6_defs.h @@ -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; diff --git a/BESM6/besm6_disk.c b/BESM6/besm6_disk.c index 91954488..cbb812d3 100644 --- a/BESM6/besm6_disk.c +++ b/BESM6/besm6_disk.c @@ -29,6 +29,8 @@ */ #include "besm6_defs.h" #include +#include +#include /* * Управляющее слово обмена с магнитным диском. @@ -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; diff --git a/BESM6/dispak.ini b/BESM6/dispak.ini index d9d41b39..955949f7 100644 --- a/BESM6/dispak.ini +++ b/BESM6/dispak.ini @@ -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.