PDP11: Added help to KE, KG, RF, TA, TC and TM devices. Fixed DECtape documentation.

This commit is contained in:
Mark Pizzolato 2013-09-09 05:36:17 -07:00
parent 786cda7c1b
commit 01b3179d93
9 changed files with 527 additions and 151 deletions

View file

@ -70,6 +70,8 @@ t_stat ke_rd (int32 *data, int32 PA, int32 access);
t_stat ke_wr (int32 data, int32 PA, int32 access);
t_stat ke_reset (DEVICE *dptr);
uint32 ke_set_SR (void);
t_stat ke_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *ke_description (DEVICE *dptr);
#define IOLN_KE 020
@ -80,16 +82,16 @@ UNIT ke_unit = {
};
REG ke_reg[] = {
{ ORDATA (AC, ke_AC, 16) },
{ ORDATA (MQ, ke_MQ, 16) },
{ ORDATA (SC, ke_SC, 6) },
{ ORDATA (SR, ke_SR, 8) },
{ ORDATAD (AC, ke_AC, 16, "accumulator") },
{ ORDATAD (MQ, ke_MQ, 16, "multiplier-quotient") },
{ ORDATAD (SC, ke_SC, 6, "shift count") },
{ ORDATAD (SR, ke_SR, 8, "status register") },
{ NULL }
};
MTAB ke_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL,
NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 010, "ADDRESS", NULL,
NULL, &show_addr, NULL, "Bus address" },
{ 0 }
};
@ -98,7 +100,9 @@ DEVICE ke_dev = {
1, 10, 31, 1, 8, 8,
NULL, NULL, &ke_reset,
NULL, NULL, NULL,
&ke_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS
&ke_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS, 0,
NULL, NULL, NULL, &ke_help, NULL, NULL,
&ke_description
};
/* KE read - reads are always 16b, to even addresses */
@ -348,3 +352,32 @@ ke_AC = 0;
ke_MQ = 0;
return auto_config(0, 0);
}
t_stat ke_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"KE11A Extended Arithmetic Option (KE)\n"
"\n"
" The KE11A extended arithmetic option (KE) provides multiply, divide,\n"
" normalization, and multi-bit shift capability on Unibus PDP-11s that\n"
" lack the EIS instruction set.\n"
"\n"
" The KE11-A performs five arithmetic operations.\n"
" a. Multiplication\n"
" b. Division\n"
" c. Three different shift operations on data operands of up to 32 bits.\n"
"\n"
" In practice, it was only sold with the PDP-11/20.\n"
" The KE is disabled by default.\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
return SCPE_OK;
}
char *ke_description (DEVICE *dptr)
{
return "KE11-A extended arithmetic element";
}

View file

@ -175,6 +175,8 @@ static t_stat kg_wr (int32, int32, int32);
static t_stat kg_reset (DEVICE *);
static void do_poly (int, t_bool);
static t_stat set_units (UNIT *, int32, char *, void *);
t_stat kg_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *kg_description (DEVICE *dptr);
/* 16-bit rotate right */
@ -216,45 +218,19 @@ static UNIT kg_unit[] = {
};
static const REG kg_reg[] = {
{ ORDATA (SR0, kg_unit[0].SR, 16) },
{ ORDATA (SR1, kg_unit[1].SR, 16) },
{ ORDATA (SR2, kg_unit[2].SR, 16) },
{ ORDATA (SR3, kg_unit[3].SR, 16) },
{ ORDATA (SR4, kg_unit[4].SR, 16) },
{ ORDATA (SR5, kg_unit[5].SR, 16) },
{ ORDATA (SR6, kg_unit[6].SR, 16) },
{ ORDATA (SR7, kg_unit[7].SR, 16) },
{ ORDATA (BCC0, kg_unit[0].BCC, 16) },
{ ORDATA (BCC1, kg_unit[1].BCC, 16) },
{ ORDATA (BCC2, kg_unit[2].BCC, 16) },
{ ORDATA (BCC3, kg_unit[3].BCC, 16) },
{ ORDATA (BCC4, kg_unit[4].BCC, 16) },
{ ORDATA (BCC5, kg_unit[5].BCC, 16) },
{ ORDATA (BCC6, kg_unit[6].BCC, 16) },
{ ORDATA (BCC7, kg_unit[7].BCC, 16) },
{ ORDATA (DR0, kg_unit[0].DR, 16) },
{ ORDATA (DR1, kg_unit[1].DR, 16) },
{ ORDATA (DR2, kg_unit[2].DR, 16) },
{ ORDATA (DR3, kg_unit[3].DR, 16) },
{ ORDATA (DR4, kg_unit[4].DR, 16) },
{ ORDATA (DR5, kg_unit[5].DR, 16) },
{ ORDATA (DR6, kg_unit[6].DR, 16) },
{ ORDATA (DR7, kg_unit[7].DR, 16) },
{ ORDATA (PULSCNT0, kg_unit[0].PULSCNT, 16) },
{ ORDATA (PULSCNT1, kg_unit[1].PULSCNT, 16) },
{ ORDATA (PULSCNT2, kg_unit[2].PULSCNT, 16) },
{ ORDATA (PULSCNT3, kg_unit[3].PULSCNT, 16) },
{ ORDATA (PULSCNT4, kg_unit[4].PULSCNT, 16) },
{ ORDATA (PULSCNT5, kg_unit[5].PULSCNT, 16) },
{ ORDATA (PULSCNT6, kg_unit[6].PULSCNT, 16) },
{ ORDATA (PULSCNT7, kg_unit[7].PULSCNT, 16) },
{ URDATAD (SR, kg_unit[0].SR, DEV_RDX, 16, 0, KG_UNITS, 0, "control and status register; R/W") },
{ URDATAD (BCC, kg_unit[0].BCC, DEV_RDX, 16, 0, KG_UNITS, 0, "result block check character; R/O") },
{ URDATAD (DR, kg_unit[0].DR, DEV_RDX, 16, 0, KG_UNITS, 0, "input data register; W/O") },
{ URDATAD (PULSCNT, kg_unit[0].PULSCNT, DEV_RDX, 16, 0, KG_UNITS, 0, "polynomial cycle stage") },
{ ORDATA (DEVADDR, kg_dib.ba, 32), REG_HRO },
{ NULL }
};
static const MTAB kg_mod[] = {
{ MTAB_XTD|MTAB_VDV, 0, "ADDRESS", NULL, NULL, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "UNITS=0..8", &set_units, NULL, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", NULL,
NULL, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV, 0, NULL, "UNITS=1..8",
&set_units, NULL, NULL, "Specify number of KG devices" },
{ 0 }
};
@ -283,7 +259,11 @@ DEVICE kg_dev = {
0, /* debug control */
(DEBTAB *) &kg_debug, /* debug flags */
NULL, /* memory size chage */
NULL /* logical name */
NULL, /* logical name */
&kg_help, /* help */
NULL, /* attach help */
NULL, /* help context */
&kg_description, /* description */
};
/* KG I/O address routines */
@ -407,7 +387,7 @@ static t_stat kg_reset (DEVICE *dptr)
kg_unit[i].BCC = 0;
kg_unit[i].PULSCNT = 0;
}
return auto_config(0, 0);
return auto_config(dptr->name, (dptr->flags & DEV_DIS) ? 0 : kg_dev.numunits);
}
static void cycleOneBit (int unit)
@ -468,6 +448,10 @@ static t_stat set_units (UNIT *u, int32 val, char *s, void *desc)
units = get_uint (s, 10, KG_UNITS, &stat);
if (stat != SCPE_OK)
return (stat);
if (units == 0)
return SCPE_ARG;
if (units == kg_dev.numunits)
return SCPE_OK;
for (i = 0; i < KG_UNITS; i++) {
if (i < units)
kg_unit[i].flags &= ~UNIT_DIS;
@ -475,5 +459,36 @@ static t_stat set_units (UNIT *u, int32 val, char *s, void *desc)
kg_unit[i].flags |= UNIT_DIS;
}
kg_dev.numunits = units;
kg_reset (&kg_dev);
return (SCPE_OK);
}
t_stat kg_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" KG11-A Communications Arithmetic Option (KG)\n"
"\n"
" The KG11-A is a programmed I/O, non-interrupting, dedicated arithmetic\n"
" processor for the Unibus. The device is used to compute the block check\n"
" character (BCC) over a block of data, typically in data communication\n"
" applications. The KG11 can compute three different Cyclic Redundancy\n"
" Check (CRC) polynomials (CRC-16, CRC-12, CRC-CCITT) and two Longitudinal\n"
" Redundancy Checks (LRC, Exclusive-OR; LRC-8, LRC-16). Up to eight units\n"
" may be contiguously present in a single machine and are all located at\n"
" fixed addresses. This simulation implements all functionality of the\n"
" device including the ability to single step computation of the BCC.\n"
" The KG is disabled by default.\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
return SCPE_OK;
}
char *kg_description (DEVICE *dptr)
{
return "KG11-A Communications Arithmetic Option";
}

View file

@ -134,6 +134,8 @@ t_stat rf_boot (int32 unitno, DEVICE *dptr);
t_stat rf_attach (UNIT *uptr, char *cptr);
t_stat rf_set_size (UNIT *uptr, int32 val, char *cptr, void *desc);
uint32 update_rfcs (uint32 newcs, uint32 newdae);
t_stat rf_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *rf_description (DEVICE *dptr);
/* RF11 data structures
@ -156,40 +158,40 @@ UNIT rf_unit = {
};
REG rf_reg[] = {
{ ORDATA (RFCS, rf_cs, 16) },
{ ORDATA (RFWC, rf_wc, 16) },
{ ORDATA (RFCMA, rf_cma, 16) },
{ ORDATA (RFDA, rf_da, 16) },
{ ORDATA (RFDAE, rf_dae, 16) },
{ ORDATA (RFDBR, rf_dbr, 16) },
{ ORDATA (RFMR, rf_maint, 16) },
{ ORDATA (RFWLK, rf_wlk, 32) },
{ FLDATA (INT, IREQ (RF), INT_V_RF) },
{ FLDATA (ERR, rf_cs, CSR_V_ERR) },
{ FLDATA (DONE, rf_cs, CSR_V_DONE) },
{ FLDATA (IE, rf_cs, CSR_V_IE) },
{ DRDATA (TIME, rf_time, 24), REG_NZ + PV_LEFT },
{ FLDATA (BURST, rf_burst, 0) },
{ FLDATA (STOP_IOE, rf_stopioe, 0) },
{ ORDATAD (RFCS, rf_cs, 16, "control/status") },
{ ORDATAD (RFWC, rf_wc, 16, "word count") },
{ ORDATAD (RFCMA, rf_cma, 16, "current memory address") },
{ ORDATAD (RFDA, rf_da, 16, "current disk address") },
{ ORDATAD (RFDAE, rf_dae, 16, "disk address extension") },
{ ORDATAD (RFDBR, rf_dbr, 16, "data buffer") },
{ ORDATAD (RFMR, rf_maint, 16, "maintenance register") },
{ ORDATAD (RFWLK, rf_wlk, 32, "write lock switches") },
{ FLDATAD (INT, IREQ (RF), INT_V_RF, "interrupt pending flag") },
{ FLDATAD (ERR, rf_cs, CSR_V_ERR, "device error flag") },
{ FLDATAD (DONE, rf_cs, CSR_V_DONE, "device done flag") },
{ FLDATAD (IE, rf_cs, CSR_V_IE, "interrupt enable flag") },
{ DRDATAD (TIME, rf_time, 24, "rotational delay, per word"), REG_NZ + PV_LEFT },
{ FLDATAD (BURST, rf_burst, 0, "burst flag") },
{ FLDATAD (STOP_IOE, rf_stopioe, 0, "stop on I/O error") },
{ ORDATA (DEVADDR, rf_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, rf_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB rf_mod[] = {
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size },
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size },
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size },
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size },
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size },
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size },
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size },
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size },
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL },
{ MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ UNIT_PLAT, (0 << UNIT_V_PLAT), NULL, "1P", &rf_set_size, NULL, NULL, "set drive to one platter (256K)" },
{ UNIT_PLAT, (1 << UNIT_V_PLAT), NULL, "2P", &rf_set_size, NULL, NULL, "set drive to two platters (512K)" },
{ UNIT_PLAT, (2 << UNIT_V_PLAT), NULL, "3P", &rf_set_size, NULL, NULL, "set drive to three platters (768K)" },
{ UNIT_PLAT, (3 << UNIT_V_PLAT), NULL, "4P", &rf_set_size, NULL, NULL, "set drive to four platters (1024K)" },
{ UNIT_PLAT, (4 << UNIT_V_PLAT), NULL, "5P", &rf_set_size, NULL, NULL, "set drive to five platters (1280K)" },
{ UNIT_PLAT, (5 << UNIT_V_PLAT), NULL, "6P", &rf_set_size, NULL, NULL, "set drive to six platters (1536K)" },
{ UNIT_PLAT, (6 << UNIT_V_PLAT), NULL, "7P", &rf_set_size, NULL, NULL, "set drive to seven platters (1792K)" },
{ UNIT_PLAT, (7 << UNIT_V_PLAT), NULL, "8P", &rf_set_size, NULL, NULL, "set drive to eight platters (2048K)" },
{ UNIT_AUTO, UNIT_AUTO, "autosize", "AUTOSIZE", NULL, NULL, NULL, "set drive to autosize platters" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ 0 }
};
@ -198,7 +200,9 @@ DEVICE rf_dev = {
1, 8, 21, 1, 8, 16,
NULL, NULL, &rf_reset,
&rf_boot, &rf_attach, NULL,
&rf_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG
&rf_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0,
NULL, NULL, NULL, &rf_help, NULL, NULL,
&rf_description
};
/* I/O dispatch routine, I/O addresses 17777460 - 17777476 */
@ -503,3 +507,67 @@ uptr->capac = UNIT_GETP (val) * RF_DKSIZE;
uptr->flags = uptr->flags & ~UNIT_AUTO;
return SCPE_OK;
}
t_stat rf_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *text2, *text3;
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"RF11/RS11 Fixed Head Disk Controller (RF)\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" The RFll-A is a fast, low-cost, random·access bulk-storage system. An\n"
" RFll-A provides 262,144 17-bit words (16 data bits and 1 parity bit)\n"
" of storage. Up to eight RSll disk platters can be controlled by one RFll\n"
" Controller for a total of 2,047,152 words of storage. An RFll-A includes\n"
" a Control Unit and the first Disk Drive.\n"
"\n"
" The RF11-A is unique in fixed head disks because each word is address-\n"
" able. Data transfers may be as small as one word or as large as 65,536\n"
" words. Individual words or groups of words may be read or rewritten\n"
" without any limits of fixed blocks or sectors, providing optimum use of\n"
" both disk storage and main memory in the PDP-11 system.\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" The RSll disk contains a nickel·cobalt·plated disk driven by a hysterisis\n"
" synchronous motor. Data is recorded on a single disk surface by 128\n"
" fixed read/write heads.\n"
" Operation\n"
" Fast track switching time permits spiral read or write. Data may be\n"
" written in blocks from 1 to 65,536 words. The RFll Control automatic-\n"
" ally continues on the next track, or on the next disk surface, when the\n"
" last address on a track or surface has been used.\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
text2 =
"\n"
" The default is one platter. The RF11 supports the BOOT command. The\n"
" RF11 is disabled at startup and is automatically disabled in a Qbus\n"
" system.\n";
fprintf (st, "%s", text2);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
text3 =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" The RF11 is a DMA device. If BURST = 0, word transfers are scheduled\n"
" individually; if BURST = 1, the entire transfer occurs in a single DMA\n"
" transfer.\n"
"\n"
" Error handling is as follows:\n"
"\n"
" error STOP_IOE processed as\n"
"\n"
" not attached 1 report error and stop\n"
" 0 non-existent disk\n"
"\n"
" RF11 data files are buffered in memory; therefore, end of file and OS\n"
" I/O errors cannot occur.\n";
fprintf (st, "%s", text2);
return SCPE_OK;
}
char *rf_description (DEVICE *dptr)
{
return "RF11-A Fixed Head Disk controller";
}

View file

@ -138,6 +138,8 @@ UNIT *ta_busy (void);
void ta_set_tr (void);
uint32 ta_updsta (UNIT *uptr);
uint32 ta_crc (uint8 *buf, uint32 cnt);
t_stat ta_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *ta_description (DEVICE *dptr);
/* TA data structures
@ -159,39 +161,41 @@ UNIT ta_unit[] = {
};
REG ta_reg[] = {
{ ORDATA (TACS, ta_cs, 16) },
{ ORDATA (TAIDB, ta_idb, 8) },
{ ORDATA (TAODB, ta_odb, 8) },
{ FLDATA (WRITE, ta_write, 0) },
{ FLDATA (INT, IREQ (TA), INT_V_TA) },
{ FLDATA (ERR, ta_cs, CSR_V_ERR) },
{ FLDATA (TR, ta_cs, CSR_V_DONE) },
{ FLDATA (IE, ta_cs, CSR_V_IE) },
{ DRDATA (BPTR, ta_bptr, 17) },
{ DRDATA (BLNT, ta_blnt, 17) },
{ DRDATA (STIME, ta_stime, 24), PV_LEFT + REG_NZ },
{ DRDATA (CTIME, ta_ctime, 24), PV_LEFT + REG_NZ },
{ FLDATA (STOP_IOE, ta_stopioe, 0) },
{ URDATA (UFNC, ta_unit[0].FNC, 8, 5, 0, TA_NUMDR, 0), REG_HRO },
{ URDATA (UST, ta_unit[0].UST, 8, 2, 0, TA_NUMDR, 0), REG_HRO },
{ URDATA (POS, ta_unit[0].pos, 10, T_ADDR_W, 0,
TA_NUMDR, PV_LEFT | REG_RO) },
{ ORDATAD (TACS, ta_cs, 16, "control/status register") },
{ ORDATAD (TAIDB, ta_idb, 8, "input data buffer") },
{ ORDATAD (TAODB, ta_odb, 8, "output data buffer") },
{ FLDATAD (WRITE, ta_write, 0, "TA60 write operation flag") },
{ FLDATAD (INT, IREQ (TA), INT_V_TA, "interrupt request") },
{ FLDATAD (ERR, ta_cs, CSR_V_ERR, "error flag") },
{ FLDATAD (TR, ta_cs, CSR_V_DONE, "transfer request flag") },
{ FLDATAD (IE, ta_cs, CSR_V_IE, "interrupt enable flag") },
{ DRDATAD (BPTR, ta_bptr, 17, "buffer pointer") },
{ DRDATAD (BLNT, ta_blnt, 17, "buffer length") },
{ DRDATAD (STIME, ta_stime, 24, "operation start time"), PV_LEFT + REG_NZ },
{ DRDATAD (CTIME, ta_ctime, 24, "character latency"), PV_LEFT + REG_NZ },
{ FLDATAD (STOP_IOE, ta_stopioe, 0, "stop on I/O errors flag") },
{ URDATA (UFNC, ta_unit[0].FNC, 8, 5, 0, TA_NUMDR, REG_HRO), },
{ URDATA (UST, ta_unit[0].UST, 8, 2, 0, TA_NUMDR, REG_HRO), },
{ URDATAD (POS, ta_unit[0].pos, 10, T_ADDR_W, 0,
TA_NUMDR, PV_LEFT | REG_RO, "position") },
{ ORDATA (DEVADDR, ta_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, ta_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB ta_mod[] = {
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", NULL },
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED",
NULL, NULL, NULL, "Write enable tape drive" },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED",
NULL, NULL, NULL, "Write lock tape drive" },
// { MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
// &sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", NULL,
NULL, &sim_tape_show_capac, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, IOLN_TA, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
NULL, &sim_tape_show_capac, NULL, "Display tape capacity" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 1, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ 0 }
};
@ -200,7 +204,9 @@ DEVICE ta_dev = {
TA_NUMDR, 10, 31, 1, 8, 8,
NULL, NULL, &ta_reset,
&ta_boot, &ta_attach, &ta_detach,
&ta_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_UBUS | DEV_TAPE
&ta_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_UBUS | DEV_TAPE, 0,
NULL, NULL, NULL, &ta_help, NULL, NULL,
&ta_description
};
/* I/O dispatch routines, I/O addresses 17777500 - 17777503
@ -664,3 +670,35 @@ M[BOOT_CSR >> 1] = ta_dib.ba & DMASK;
saved_PC = BOOT_ENTRY;
return SCPE_OK;
}
t_stat ta_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" TA11/TA60 Cassette Tape (CT)\n"
"\n"
" The TA11 is a programmed I/O controller supporting two cassette drives\n"
" (0 and 1). The TA11 can be used like a small magtape under RT11 and\n"
" RSX-11M, and with the CAPS-11 operating system. Cassettes are simulated\n"
" as magnetic tapes with a fixed capacity (93,000 characters). The tape\n"
" format is always SimH standard.\n"
" The TA11 is disabled by default.\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
fprintf (st, "\nError handling is as follows:\n\n");
fprintf (st, " error processed as\n");
fprintf (st, " not attached tape not ready\n\n");
fprintf (st, " end of file end of medium\n");
fprintf (st, " OS I/O error fatal tape error\n\n");
sim_tape_attach_help (st, dptr, uptr, flag, cptr);
return SCPE_OK;
}
char *ta_description (DEVICE *dptr)
{
return "TA11/TA60 Cassette Tape";
}

View file

@ -306,6 +306,8 @@ void dt_stopunit (UNIT *uptr);
int32 dt_comobv (int32 val);
int32 dt_csum (UNIT *uptr, int32 blk);
int32 dt_gethdr (UNIT *uptr, int32 blk, int32 relpos);
t_stat dt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *dt_description (DEVICE *dptr);
/* DT data structures
@ -345,42 +347,44 @@ UNIT dt_unit[] = {
#define DT_TIMER (DT_NUMDR)
REG dt_reg[] = {
{ ORDATA (TCST, tcst, 16) },
{ ORDATA (TCCM, tccm, 16) },
{ ORDATA (TCWC, tcwc, 16) },
{ ORDATA (TCBA, tcba, 16) },
{ ORDATA (TCDT, tcdt, 16) },
{ FLDATA (INT, IREQ (DTA), INT_V_DTA) },
{ FLDATA (ERR, tccm, CSR_V_ERR) },
{ FLDATA (DONE, tccm, CSR_V_DONE) },
{ FLDATA (IE, tccm, CSR_V_DONE) },
{ DRDATA (CTIME, dt_ctime, 31), REG_NZ },
{ DRDATA (LTIME, dt_ltime, 31), REG_NZ },
{ DRDATA (DCTIME, dt_dctime, 31), REG_NZ },
{ ORDATA (SUBSTATE, dt_substate, 1) },
{ ORDATAD (TCST, tcst, 16, "status register") },
{ ORDATAD (TCCM, tccm, 16, "command register") },
{ ORDATAD (TCWC, tcwc, 16, "word count register") },
{ ORDATAD (TCBA, tcba, 16, "bus address register") },
{ ORDATAD (TCDT, tcdt, 16, "data register") },
{ FLDATAD (INT, IREQ (DTA), INT_V_DTA, "interrupt pending flag") },
{ FLDATAD (ERR, tccm, CSR_V_ERR, "error flag") },
{ FLDATAD (DONE, tccm, CSR_V_DONE, "done flag") },
{ FLDATAD (IE, tccm, CSR_V_DONE, "interrupt enable flag") },
{ DRDATAD (CTIME, dt_ctime, 31, "time to complete transport stop"), REG_NZ },
{ DRDATAD (LTIME, dt_ltime, 31, "time between lines"), REG_NZ },
{ DRDATAD (DCTIME, dt_dctime, 31, "time to decelerate to a full stop"), REG_NZ },
{ ORDATAD (SUBSTATE, dt_substate, 1, "read/write command substate") },
{ DRDATA (LBLK, dt_logblk, 12), REG_HIDDEN },
{ URDATA (POS, dt_unit[0].pos, 10, T_ADDR_W, 0,
DT_NUMDR, PV_LEFT | REG_RO) },
{ URDATA (STATT, dt_unit[0].STATE, 8, 18, 0,
DT_NUMDR, REG_RO) },
{ URDATAD (POS, dt_unit[0].pos, 10, T_ADDR_W, 0,
DT_NUMDR, PV_LEFT | REG_RO, "position, in lines, units 0 to 7") },
{ URDATAD (STATT, dt_unit[0].STATE, 8, 18, 0,
DT_NUMDR, REG_RO, "unit state, units 0 to 7") },
{ URDATA (LASTT, dt_unit[0].LASTT, 10, 32, 0,
DT_NUMDR, REG_HRO) },
{ FLDATA (STOP_OFFR, dt_stopoffr, 0) },
{ FLDATAD (STOP_OFFR, dt_stopoffr, 0, "stop on off-reel error") },
{ ORDATA (DEVADDR, dt_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, dt_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB dt_mod[] = {
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL },
{ UNIT_8FMT + UNIT_11FMT, 0, "18b", NULL, NULL },
{ UNIT_8FMT + UNIT_11FMT, UNIT_8FMT, "12b", NULL, NULL },
{ UNIT_8FMT + UNIT_11FMT, UNIT_11FMT, "16b", NULL, NULL },
{ MTAB_XTD|MTAB_VDV, 004, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ UNIT_WLK, 0, "write enabled", "WRITEENABLED",
NULL, NULL, NULL, "Write enable tape drive" },
{ UNIT_WLK, UNIT_WLK, "write locked", "LOCKED",
NULL, NULL, NULL, "Write lock tape drive" },
{ UNIT_8FMT + UNIT_11FMT, 0, "18b", NULL },
{ UNIT_8FMT + UNIT_11FMT, UNIT_8FMT, "12b", NULL },
{ UNIT_8FMT + UNIT_11FMT, UNIT_11FMT, "16b", NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ 0 }
};
@ -397,7 +401,8 @@ DEVICE dt_dev = {
NULL, NULL, &dt_reset,
&dt_boot, &dt_attach, &dt_detach,
&dt_dib, DEV_DISABLE | DEV_DIS | DEV_UBUS | DEV_DEBUG, 0,
dt_deb, NULL, NULL
dt_deb, NULL, NULL, &dt_help, NULL, NULL,
&dt_description
};
/* IO dispatch routines, I/O addresses 17777340 - 17777350 */
@ -1344,3 +1349,156 @@ uptr->flags = (uptr->flags | UNIT_11FMT) & ~UNIT_8FMT; /* default fmt */
uptr->capac = DT_CAPAC; /* default size */
return detach_unit (uptr);
}
t_stat dt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *text2;
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"TC11/TU56 DECtape Controller (DT)\n"
"\n"
" The TCll is a DECtape system consists a Controller and up to 4 dual-unit\n"
" bidirectional magnetic-tape transports, and DECtape 3/4-inch magnetic\n"
" tape on 3.9-inch reels. Low cost, low maintenance and high reliability\n"
" are assured by:\n"
"\n"
" - Simply designed transport mechanisms which have no capstans and\n"
" no pinch rollers.\n"
" - Hydrodynamically lubricated tape guiding (the tape floats on air\n"
" over the tape guides while in motion)\n"
" - Redundant recording\n"
" - Manchester phase recording techniques (virtually eliminate drop outs)\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" Each transport has a read/write head for information recording and\n"
" playback on five channels of tape. The system stores information at\n"
" fixed positions on magnetic tape as in magnetic disk or drum storage\n"
" devices, rather than at unknown or variable positions as in conventional\n"
" magnetic tape systems. This feature allows replacement of blocks of\n"
" data on tape in a random fashion without disturbing other previously\n"
" recorded information. In particular, during the writing of information\n"
" on tape, the system reads format (mark) and timing information from the\n"
" tape and uses this information to determine the exact position at which\n"
" to record the information to be written. Similarly, in reading, the\n"
" same mark and timing information is used to locate data to be played\n"
" back from the tape.\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" The system utilizes a lO-track read/write head. The first five tracks\n"
" on the tape include a timing track, a mark track, and three data tracks.\n"
" The other five tracks are identical counterparts and are used for\n"
" redundant recording to increase system reliability. The redundant\n"
" recording of each character bit on non-adjacent tracks materially\n"
" reduces bit dropouts and minimizes the effect of skew. The use of\n"
" Manchester phase recording, rather than amplitude sensing techniques,\n"
" virtually eliminates dropouts.\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" The timing and mark channels control the timing of operations within\n"
" the Controller and establish the format of data contained on the \n"
" information channels. The timing and mark channels are recorded prior\n"
" to all normal data reading and writing on the information channels. The\n"
" timing of operations performed by the tape drive and some control\n"
" functions are determined by the information on the timing channel.\n"
" Therefore, wide variations in the speed of tape motion do not affect\n"
" system performance.\n"
"\n"
" The standard format tape is divided into 578 blocks. The structure of\n"
" each block is symmetric: block numbers and checksums are recorded at\n"
" both ends of a block and thus searching, reading, or writing can occur\n"
" in either direction. However, a block read in the opposite direction\n"
" than it was written will have the order of the data words reversed.\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" Information read from the mark channel is used during reading and\n"
" writing data to indicate the beginning and end of data blocks and to\n"
" determine the functions performed by the system in each control mode.\n"
" The data tracks ara located in the middle of the tape where the effect\n"
" of skew is minimum. The data in one bit position of each track is\n"
" referred to as a line or as a character. Since. six lines make up a\n"
" word, the tape can record, 18-bit data words. During normal data\n"
" writing, the Controller disassembles the 18-bit word and distributes\n"
" the bits so they are recorded as six 3·bit characters. Since PDP-11\n"
" words are l6·bits long, the Controller writes the extra two bits as 0's\n"
" and ignores them when reading. However, during special modes, the\n"
" extra two bits can be written and recovered.\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" A 260 foot reel of DECtape is divided into three major areas: end zones\n"
" (forward and reverse), extension zones (forward and reverse), and the\n"
" information zone. The two end zones (each approximately 10 feet) mark\n"
" the end of the physical tape and are used for winding the tape around\n"
" the heads and onto the take·up reel. These zones never contain data.\n"
" The forward and reverse extension areas mark the end of the information\n"
" region of the tape. Their length is sufficient to ensure that once the\n"
" end zone is entered and tape motion is reversed; there is adequate\n"
" distance for the transport to come up to proper tape speed before\n"
" entering the information area.\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" The information area, consists of blocks of data. The standard is a\n"
" nominal 578 blocks, each containing 256 data words (nominally). In \n"
" addition each block contains 10 control words.\n"
"\n"
" The blocks permit digital data to be partitioned into groups of words\n"
" which are interrelated while at the same time reducing the amount of\n"
" storage area that would be needed for addressing individual words. A\n"
" simple example of such a group of words is a program. A program can\n"
" be stored and retrieved from magnetic tape in a single block format\n"
" because it is not necessary to be able to retrieve only a single word\n"
" from the program. It is necessary; however, to be able to retrieve\n"
" different programs which may not be related in any way. Thus, each\n"
" program can be stored in a different block on the tape.\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" Since DECtape is a fixed address system, the programmer need not know\n"
" accurately where the tape has stopped. To locate a specific point on\n"
" tape he must only start the tape motion in the search mode. The address\n"
" of the block currently passing over the head is read into the DECtape\n"
" Control and loaded into an interface register. Simultaneously, a flag\n"
" is set and a program interrupt can occur. The program can then compare\n"
" the block number found with the desired block address and tape motion\n"
" continued or reversed accordingly.\n"
"\n"
" DECtape options include the ability to make units write enabled or write\n"
" locked.\n"
" The TC11 supports the BOOT command. The TC11 is automatically disabled\n"
" in a Qbus system.\n"
"\n"
" The TC11 supports supports PDP-8 format, PDP-11 format, and 18b format\n"
" DECtape images. ATTACH assumes the image is in PDP-11 format; the user\n"
" can force other choices with switches:\n"
"\n"
" -t PDP-8 format\n"
" -f 18b format\n"
" -a autoselect based on file size\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" The DECtape controller is a data-only simulator; the timing and mark\n"
" track, and block header and trailer, are not stored. Thus, the WRITE\n"
" TIMING AND MARK TRACK function is not supported; the READ ALL function\n"
" always returns the hardware standard block header and trailer; and the\n"
" WRITE ALL function dumps non-data words into the bit bucket.\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
text2 =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" It is critically important to maintain certain timing relationships\n"
" among the DECtape parameters, or the DECtape simulator will fail to\n"
" operate correctly.\n"
"\n"
" - LTIME must be at least 6\n"
" - DCTIME needs to be at least 100 times LTIME\n"
"\n"
" Acceleration time is set to 75% of deceleration time.\n";
fprintf (st, "%s", text2);
return SCPE_OK;
}
char *dt_description (DEVICE *dptr)
{
return "TC11/TU56 DECtape controller";
}

View file

@ -178,6 +178,8 @@ int32 tm_updcsta (UNIT *uptr);
void tm_set_done (void);
t_stat tm_map_err (UNIT *uptr, t_stat st);
t_stat tm_vlock (UNIT *uptr, int32 val, char *cptr, void *desc);
t_stat tm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr);
char *tm_description (DEVICE *dptr);
/* MT data structures
@ -206,37 +208,39 @@ UNIT tm_unit[] = {
};
REG tm_reg[] = {
{ ORDATA (MTS, tm_sta, 16) },
{ ORDATA (MTC, tm_cmd, 16) },
{ ORDATA (MTBRC, tm_bc, 16) },
{ ORDATA (MTCMA, tm_ca, 16) },
{ ORDATA (MTD, tm_db, 8) },
{ ORDATA (MTRD, tm_rdl, 16) },
{ FLDATA (INT, IREQ (TM), INT_V_TM) },
{ FLDATA (ERR, tm_cmd, CSR_V_ERR) },
{ FLDATA (DONE, tm_cmd, CSR_V_DONE) },
{ FLDATA (IE, tm_cmd, CSR_V_IE) },
{ FLDATA (STOP_IOE, tm_stopioe, 0) },
{ DRDATA (TIME, tm_time, 24), PV_LEFT },
{ URDATA (UST, tm_unit[0].USTAT, 8, 16, 0, TM_NUMDR, 0) },
{ URDATA (POS, tm_unit[0].pos, 10, T_ADDR_W, 0,
TM_NUMDR, PV_LEFT | REG_RO) },
{ ORDATAD (MTS, tm_sta, 16, "status") },
{ ORDATAD (MTC, tm_cmd, 16, "command") },
{ ORDATAD (MTCMA, tm_ca, 16, "memory address") },
{ ORDATAD (MTBRC, tm_bc, 16, "byte/record count") },
{ ORDATAD (MTD, tm_db, 8, "data buffer") },
{ ORDATAD (MTRD, tm_rdl, 16, "read lines") },
{ FLDATAD (INT, IREQ (TM), INT_V_TM, "interrupt pending flag") },
{ FLDATAD (ERR, tm_cmd, CSR_V_ERR, "error flag") },
{ FLDATAD (DONE, tm_cmd, CSR_V_DONE, "device done flag") },
{ FLDATAD (IE, tm_cmd, CSR_V_IE, "interrupt enable flag") },
{ FLDATAD (STOP_IOE, tm_stopioe, 0, "stop on I/O error") },
{ DRDATAD (TIME, tm_time, 24, "delay"), PV_LEFT },
{ URDATAD (UST, tm_unit[0].USTAT, 8, 16, 0, TM_NUMDR, 0, "unit status, units 0 to 7") },
{ URDATAD (POS, tm_unit[0].pos, 10, T_ADDR_W, 0,
TM_NUMDR, PV_LEFT | REG_RO, "position, units 0 to 7") },
{ ORDATA (DEVADDR, tm_dib.ba, 32), REG_HRO },
{ ORDATA (DEVVEC, tm_dib.vec, 16), REG_HRO },
{ NULL }
};
MTAB tm_mod[] = {
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED", &tm_vlock },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED", &tm_vlock },
{ MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL },
{ MTAB_XTD|MTAB_VUN, 0, "CAPACITY", "CAPACITY",
&sim_tape_set_capac, &sim_tape_show_capac, NULL },
{ MTAB_XTD|MTAB_VDV, 020, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL },
{ MTAB_XTD|MTAB_VDV, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL },
{ MTUF_WLK, 0, "write enabled", "WRITEENABLED",
&tm_vlock, NULL, NULL, "Write enable tape drive" },
{ MTUF_WLK, MTUF_WLK, "write locked", "LOCKED",
&tm_vlock, NULL, NULL, "Write lock tape drive" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "FORMAT", "FORMAT",
&sim_tape_set_fmt, &sim_tape_show_fmt, NULL, "Set/Display tape format (SIMH, E11, TPC, P7B)" },
{ MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "CAPACITY", "CAPACITY",
&sim_tape_set_capac, &sim_tape_show_capac, NULL, "Set/Display capacity" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 010, "ADDRESS", "ADDRESS",
&set_addr, &show_addr, NULL, "Bus address" },
{ MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "VECTOR", "VECTOR",
&set_vec, &show_vec, NULL, "Interrupt vector" },
{ 0 }
};
@ -245,7 +249,9 @@ DEVICE tm_dev = {
TM_NUMDR, 10, T_ADDR_W, 1, 8, 8,
NULL, NULL, &tm_reset,
&tm_boot, &tm_attach, &tm_detach,
&tm_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG | DEV_TAPE
&tm_dib, DEV_DISABLE | DEV_UBUS | DEV_Q18 | DEV_DEBUG | DEV_TAPE, 0,
NULL, NULL, NULL, &tm_help, NULL, NULL,
&tm_description
};
/* I/O dispatch routines, I/O addresses 17772520 - 17772532
@ -729,3 +735,61 @@ M[BOOT_CSR >> 1] = (tm_dib.ba & DMASK) + 06;
saved_PC = BOOT_ENTRY;
return SCPE_OK;
}
t_stat tm_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
{
const char *text2;
const char *const text =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"TM11 Magnetic Tape Controller (TM)\n"
"\n"
" The TM11 is a high-performance, low-cost magnetic tape system ideally\n"
" suited for writing, reading, and storing large volumes of data and\n"
" programs in a serial manner. Because the system reads and writes in\n"
" industry-compatible format, information can be transferred between a\n"
" PDP11 and other computers.\n"
" The 10 1/2-inch tape reels contain up to 2400 feet of tape upon which\n"
" over 180 million bits of data can be stored on hight density 9-track\n"
" tape or over 140 million bits can be stored on high density 7-track tape.\n"
"\n"
" A Magtape System consists of up to 8 tape transports and a Control Unit.\n"
" Transports are capable of operation with seven or nine-track tape and a\n"
" system can contain any combination of 7-track and 9-track units.\n"
"\n"
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
" The TM11 supports the BOOT command. The bootstrap supports both\n"
" original and DEC standard boot formats. Originally, a tape bootstrap\n"
" read and executed the first record on tape. To allow for ANSI labels,\n"
" the DEC standard bootstrap skipped the first record and read and executed\n"
" the second. The DEC standard is the default; to bootstrap an original\n"
" format tape, use the command BOOT O MTn. The TM11 is automatically\n"
" disabled in a Qbus system with more than 256KB of memory.\n";
fprintf (st, "%s", text);
fprint_set_help (st, dptr);
fprint_show_help (st, dptr);
fprint_reg_help (st, dptr);
text2 =
/*567901234567890123456789012345678901234567890123456789012345678901234567890*/
"\n"
" It is critically important to maintain certain timing relationships\n"
" among the DECtape parameters, or the DECtape simulator will fail to\n"
" operate correctly.\n"
"\n"
" - LTIME must be at least 6\n"
" - DCTIME needs to be at least 100 times LTIME\n"
"\n"
" Acceleration time is set to 75% of deceleration time.\n";
fprintf (st, "%s", text2);
fprintf (st, "\nError handling is as follows:\n\n");
fprintf (st, " error processed as\n");
fprintf (st, " not attached tape not ready\n\n");
fprintf (st, " end of file bad tape\n");
fprintf (st, " OS I/O error fatal tape error\n\n");
sim_tape_attach_help (st, dptr, uptr, flag, cptr);
return SCPE_OK;
}
char *tm_description (DEVICE *dptr)
{
return "TM11 Magnet Tape controller";
}

Binary file not shown.

Binary file not shown.

Binary file not shown.