BESM6: 29 Mb disks (EC-5061, clones of IBM 2314) are now functional.

The OS seems to support them only on device MD4, though.
Native formatting works.
This commit is contained in:
Leo Broukhis 2022-03-07 21:06:57 -08:00
parent 3dd0d03321
commit 6c56968f15

View file

@ -45,17 +45,33 @@
#define DISK_HALFZONE 000000001 /* выбор половины зоны */
/*
* "Хороший" статус чтения/записи.
* Вычислено по текстам ОС Дубна.
* Диспак доволен.
* Status register bits (most are unused: error conditions are not simulated)
*/
#define STATUS_GOOD 014000400
#define STATUS_SEEK 000000377 /* "Seek done" mask, per unit */
#define STATUS_READY 000000400 /* Selected unit is ready */
#define STATUS_SEEK_FAIL 000001000 /* Head location unknown, unit not ready */
#define STATUS_CHECKSUM 000002000 /* Bad checksum on read */
#define STATUS_FAILURE 000004000 /* Failure, OR of some upper bits */
#define STATUS_MAYDAY 000010000 /* Unspecified failure */
#define STATUS_NO_AMRK 000020000 /* Address marker not found after a revolution */
#define STATUS_WRONG_CYL 000040000 /* Wrong address marker */
#define STATUS_WRONG_ID 000100000 /* Bad track ID */
#define STATUS_BAD_ACSUM 000200000 /* Bad checksum of the address marker */
#define STATUS_UNFINISHED 000400000 /* IO not finished after a revolution */
#define STATUS_TRK_PARITY 001000000 /* Track parity in two-track IO */
#define STATUS_READONLY 002000000 /* The selected unit is read-only */
#define STATUS_POWERUP 004000000 /* The unit is powered up */
#define STATUS_ABSENT 010000000 /* The unit is not connected */
#define STATUS_BUF_ERR 020000000 /* Transfer buffer not ready */
/*
* Total size of a disk in blocks, including hidden blocks
* Total size of a "7.25 Mb" disk is 1000 (decimal) blocks;
* of a "29 Mb" disk - 4000 blocks, out of which 4 are so called
* pre-blocks. Logical blocks are mapped to physical by adding 4.
* Physical blocks 0 to 2 are accesible only by standalone programs,
* block 3 has the logical number "minus one".
*/
#define DISK_TOTBLK 01767
#define SYSTEM_VOLUME_ID 2053
/*
* Параметры обмена с внешним устройством.
*/
@ -81,75 +97,75 @@ t_stat disk_event (UNIT *u);
/*
* DISK data structures
*
* mg_dev DISK device descriptor
* mg_unit DISK unit descriptor
* mg_reg DISK register list
* md_dev DISK device descriptor
* md_unit DISK unit descriptor
* md_reg DISK register list
*/
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) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
{ UDATA (disk_event, UNIT_FIX+UNIT_ATTABLE+UNIT_ROABLE+UNIT_DISABLE, 0) },
};
REG disk_reg[] = {
@ -186,12 +202,36 @@ t_stat disk_setsyslog (UNIT *up, int32 v, CONST char *cp, void *dp) {
return SCPE_OK;
}
#define DISK_TYPE_MASK (1 << UNIT_V_UF)
#define DISK_TYPE_7_25M 0
#define DISK_TYPE_29M (1 << UNIT_V_UF)
#define IS_29MB(u) (((u)->flags & DISK_TYPE_MASK) == DISK_TYPE_29M)
t_stat disk_set_type (UNIT *up, int32 v, CONST char *cp, void *dp) {
int first_unit = (up->dptr - md_dev) * 8;
int unit;
for (unit = first_unit; unit < first_unit + 8; ++unit) {
if (md_unit[unit].flags & UNIT_ATT)
return sim_messagef(SCPE_ALATT, "Drive type cannot be set if any unit is attached");
}
for (unit = first_unit; unit < first_unit + 8; ++unit) {
md_unit[unit].flags &= ~DISK_TYPE_MASK;
md_unit[unit].flags |= v;
md_unit[unit].capac = 7250000 * (v ? 4 : 1);
}
return SCPE_OK;
}
MTAB disk_mod[] = {
{ MTAB_VDV, DISK_TYPE_7_25M, NULL, "EC-5052", &disk_set_type, NULL, NULL, "EC-5052 drive (7.25 Mb)"},
{ MTAB_VDV, DISK_TYPE_29M, NULL, "EC-5061", &disk_set_type, NULL, NULL, "EC-5061 drive (29 Mb)"},
{ MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, NULL,
"SYSLOG", &disk_setsyslog, NULL, NULL, "file name (always appending) or OFF" },
{ 0 }
};
t_stat disk_reset (DEVICE *dptr);
t_stat disk_attach (UNIT *uptr, CONST char *cptr);
t_stat disk_detach (UNIT *uptr);
@ -218,49 +258,49 @@ DEBTAB disk_deb[] = {
DEVICE md_dev[8] = {
{
"MD0", md_unit, disk_reg, disk_mod,
8, 8, 21, 1, 8, 50,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 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,
8, 8, 21, 50, 8, 50,
NULL, NULL, &disk_reset, NULL, &disk_attach, &disk_detach,
NULL, DEV_DISABLE | DEV_DEBUG, 0, disk_deb
},
@ -289,6 +329,7 @@ t_stat disk_reset (DEVICE *dptr)
c->mask_fail = 020 >> ctlr;
for (i = first_unit; i < first_unit + 8; ++i) {
md_unit[i].dptr = dptr;
md_unit[i].capac = 7250000 * (IS_29MB(&md_unit[i]) ? 4 : 1);
sim_cancel (&md_unit[i]);
}
return SCPE_OK;
@ -342,10 +383,12 @@ t_stat disk_attach (UNIT *u, CONST char *cptr)
control[1] |= 01370707LL << 24; /* Magic mark */
control[1] |= diskno << 12;
for (blkno = 0; blkno < DISK_TOTBLK; ++blkno) {
control[0] = SET_PARITY((t_value)(2*blkno) << 36, PARITY_NUMBER);
/* Unlike the O/S routine, does not format the (useless) reserve tracks */
for (blkno = 0; blkno < (IS_29MB(u) ? 4000 : 1000); ++blkno) {
uint val = IS_29MB(u) ? blkno : 2 * blkno;
control[0] = SET_PARITY((t_value)val << 36, PARITY_NUMBER);
sim_fwrite(control, sizeof(t_value), 4, u->fileref);
control[0] = SET_PARITY((t_value)(2*blkno+1) << 36, PARITY_NUMBER);
control[0] = SET_PARITY((t_value)(val+1) << 36, PARITY_NUMBER);
sim_fwrite(control, sizeof(t_value), 4, u->fileref);
for (word = 0; word < 02000; ++word) {
sim_fwrite(control+2, sizeof(t_value), 1, u->fileref);
@ -358,11 +401,6 @@ t_stat disk_attach (UNIT *u, CONST char *cptr)
break;
sim_switches |= SWMASK ('N');
}
{
struct stat buf;
fstat(fileno(u->fileref), &buf);
u->capac = buf.st_size / 8;
}
return SCPE_OK;
}
@ -435,9 +473,10 @@ void disk_write (UNIT *u)
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);
/* Logging system disk accesses */
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == SYSTEM_VOLUME_ID) {
fprintf(syslog, "W %04o @%05o\n", (c->zone-4)&07777, c->memory);
fflush(syslog);
}
@ -470,7 +509,8 @@ void disk_write_track (UNIT *u)
void disk_format (UNIT *u)
{
KMD *c = unit_to_ctlr (u);
t_value fmtbuf[5], *ptr;
t_value fmtbuf[5];
t_value *ptr;
int i;
int cnum = c - controller;
/* По сути, эмулятору ничего делать не надо. */
@ -488,16 +528,24 @@ void disk_format (UNIT *u)
/* При первой попытке разметки адресный маркер начинается в старшем 5-разрядном слоге,
* пропускаем первый слог. */
for (i=0; i<4; i++)
for (i=0; i<5; i++)
fmtbuf[i] = ((fmtbuf[i] & BITS48) << 5) |
((fmtbuf[i+1] >> 40) & BITS(5));
(i == 4 ? 0 : (fmtbuf[i+1] >> 40) & BITS(5));
log_data(fmtbuf, 5);
/* Печатаем идентификатор, адрес и контрольную сумму адреса. */
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)));
/* log_data (fmtbuf, 4); */
if (u->dptr->dctrl & DEB_TRC)
if (IS_29MB(u))
besm6_debug ("::: формат МД %02o зона %04o память %05o skip %02o и-а-кса %010o %010o",
c->dev, c->zone, c->memory, ptr - memory -c ->memory,
(int) (fmtbuf[0] >> 8 & BITS(30)),
(int) (fmtbuf[2] >> 14 & BITS(30)));
else
besm6_debug ("::: формат МД %02o полузона %04o.%d память %05o skip %02o и-а-кса %010o %010o",
c->dev, c->zone, c->track, c->memory, ptr - memory -c ->memory,
(int) (fmtbuf[0] >> 8 & BITS(30)),
(int) (fmtbuf[2] >> 14 & BITS(30)));
}
/*
@ -525,8 +573,9 @@ void disk_read (UNIT *u)
return;
}
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == 2053) {
fprintf(syslog, "R %04o\n", (c->zone-4)&07777);
/* Logging system disk accesses */
if (syslog && ((c->sysdata[1] >> 12) & 0xFFF) == SYSTEM_VOLUME_ID) {
fprintf(syslog, "R %04o @%05o\n", (c->zone-4)&07777, c->memory);
fflush(syslog);
}
@ -580,17 +629,26 @@ void disk_read_track (UNIT *u)
void disk_read_header (UNIT *u)
{
KMD *c = unit_to_ctlr (u);
t_value *sysdata = c->sysdata + 4*c->track;
t_value *sysdata = IS_29MB(u) ? c->sysdata : c->sysdata + 4*c->track;
int iaksa, i, cyl, head;
int reserve_start = IS_29MB(u) ? 07640 : 01750;
/* Адрес: номер цилиндра и головки. */
head = (c->zone << 1) + c->track;
cyl = head / 10;
head %= 10;
iaksa = (cyl << 20) | (head << 16);
if (IS_29MB(u)) {
head = c->zone;
cyl = head / 20;
head %= 20;
iaksa = (head << 3) + (cyl << 8);
iaksa <<= 12;
} else {
head = (c->zone << 1) + c->track;
cyl = head / 10;
head %= 10;
iaksa = (cyl << 20) | (head << 16);
}
/* Идентификатор дорожки замены. */
if (c->zone >= 01750)
if (c->zone >= reserve_start)
iaksa |= BBIT(30);
/* Контрольная сумма адреса с переносом вправо. */
@ -601,12 +659,17 @@ void disk_read_header (UNIT *u)
sysdata[1] = 03740LL;
sysdata[2] = 00400000000037777LL | (t_value) iaksa << 14;
sysdata[3] = BITS48;
if (u->dptr->dctrl & DEB_TRC)
log_data (sysdata, 4);
if (IS_29MB(u)) {
for (i=0; i<4; i++) {
memory[c->memory + i + 014] = SET_PARITY(sysdata[i] & 0777777777777777LL, PARITY_NUMBER);
}
}
/* Кодируем гребенку. */
for (i=0; i<4; i++)
sysdata[i] = SET_PARITY (collect (sysdata[i]), PARITY_NUMBER);
}
/*
@ -631,8 +694,8 @@ void disk_io (int ctlr, uint32 cmd)
c->memory = (cmd & (DISK_PAGE | DISK_HALFPAGE)) >> 2 | (cmd & DISK_BLOCK) >> 8;
}
if (md_dev[ctlr * 4].dctrl & DEB_RWR)
besm6_debug ("::: КМД %c: задание на %s %08o", ctlr + '3',
(c->op & DISK_READ) ? "чтение" : "запись", cmd);
besm6_debug ("::: КМД %c: задание на %s %016llo RAM @%05o", ctlr + '3',
(c->op & DISK_READ) ? "чтение" : "запись", cmd, c->memory);
disk_fail &= ~c->mask_fail;
/* Гасим главный регистр прерываний. */
@ -647,7 +710,15 @@ void disk_ctl (int ctlr, uint32 cmd)
KMD *c = &controller [ctlr];
UNIT *u = &md_unit [c->dev];
if ((md_dev[ctlr].dctrl & DEB_OPS || c->dev != -1 && u->dptr->dctrl & DEB_OPS) && cmd & BBIT(13)) {
besm6_debug ("::: КМД %c: bit 13 + %04o",
ctlr + '3', cmd & 07777);
}
if (cmd & BBIT(12)) {
if (c->dev == -1)
besm6_debug("Setting block address for unknown device");
/* Выдача в КМД адреса дорожки.
* Здесь же выполняем обмен с диском.
* Номер дисковода к этому моменту уже известен. */
@ -656,21 +727,24 @@ void disk_ctl (int ctlr, uint32 cmd)
disk_fail |= c->mask_fail;
return;
}
if (u->capac <= (2<<20)) {
if (IS_29MB(u)) {
c->zone = ((cmd & BITS(11)) << 1) | (c->zone & 1);
} else {
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);
if (u->dptr->dctrl & DEB_OPS) {
if (IS_29MB(u))
besm6_debug ("::: КМД %c: cmd %08o = выдача адреса дорожки %04o",
ctlr + '3', cmd, c->zone);
else
besm6_debug ("::: КМД %c: cmd %08o = выдача адреса дорожки %04o.%d",
ctlr + '3', cmd, c->zone, c->track);
}
disk_fail &= ~c->mask_fail;
if (c->op & DISK_READ) {
if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
if (IS_29MB(u) || c->op & DISK_PAGE_MODE)
disk_read (u);
else
disk_read_track (u);
@ -683,7 +757,7 @@ void disk_ctl (int ctlr, uint32 cmd)
}
if (c->format)
disk_format (u);
else if (u->capac >= 2<<20 || c->op & DISK_PAGE_MODE)
else if (IS_29MB(u) || c->op & DISK_PAGE_MODE)
disk_write (u);
else
disk_write_track (u);
@ -704,17 +778,25 @@ void disk_ctl (int ctlr, uint32 cmd)
else if (cmd & BBIT(3)) c->dev = 2;
else if (cmd & BBIT(2)) c->dev = 1;
else if (cmd & BBIT(1)) c->dev = 0;
else {
else if (cmd != BBIT(11)) {
/* Неверная маска выбора устройства. */
c->dev = -1;
besm6_debug("Bad unit selection command %o", cmd);
return;
} else {
c->dev = -1;
return;
}
c->dev += ctlr * 32 + c->group * 8;
u = &md_unit [c->dev];
if (IS_29MB(u)) {
c->zone = (c->zone & ~1) | (cmd & BBIT(10) ? 1 : 0);
}
u = &md_unit[c->dev];
if (u->dptr->dctrl & DEB_OPS)
besm6_debug ("::: КМД %c: выбор устройства %02o",
ctlr + '3', c->dev);
besm6_debug ("::: КМД %c: cmd = %08o, выбор устройства %02o",
ctlr + '3', cmd, c->dev);
if ((u->dptr->flags & DEV_DIS) || ! (u->flags & UNIT_ATT)) {
/* Device not attached. */
@ -733,12 +815,10 @@ void disk_ctl (int ctlr, uint32 cmd)
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');
GRP |= c->mask_grp;
} else if (cmd & BBIT(8)) {
besm6_debug ("::: КМД %c: cmd = %08o\n",
ctlr + '3', cmd);
} else {
/* Команда, выдаваемая в КМД. */
@ -802,10 +882,9 @@ void disk_ctl (int ctlr, uint32 cmd)
c->status = 0;
break;
case 011: /* опрос 1÷12 разрядов PC */
c->status = 0;
if (md_unit[c->dev].flags & UNIT_ATT)
c->status = STATUS_GOOD & BITS(12);
else
c->status = 0;
c->status = STATUS_READY;
#if 1
if (u->dptr->dctrl & DEB_STA)
besm6_debug ("::: КМД %c: опрос младших разрядов состояния - %04o",
@ -813,10 +892,14 @@ void disk_ctl (int ctlr, uint32 cmd)
#endif
break;
case 031: /* опрос 13÷24 разрядов РС */
if (md_unit[c->dev].flags & UNIT_ATT)
c->status = (STATUS_GOOD >> 12) & BITS(12);
else
c->status = 0;
c->status = 0;
if (md_unit[c->dev].flags & UNIT_DISABLE)
c->status |= STATUS_ABSENT;
else if (md_unit[c->dev].flags & UNIT_ATT)
c->status |= STATUS_POWERUP;
if (md_unit[c->dev].flags & UNIT_RO)
c->status |= STATUS_READONLY;
c->status >>= 12;
#if 1
if (u->dptr->dctrl & DEB_STA)
besm6_debug ("::: КМД %c: опрос старших разрядов состояния - %04o",