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:
parent
3dd0d03321
commit
6c56968f15
1 changed files with 222 additions and 139 deletions
|
@ -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",
|
||||
|
|
Loading…
Add table
Reference in a new issue