mirror of
https://github.com/simh/simh.git
synced 2026-03-22 17:07:51 +00:00
simh v3.12-2
This commit is contained in:
committed by
Mark Pizzolato
parent
b0568dc2cb
commit
14dccaa4e7
@@ -1,6 +1,6 @@
|
||||
/* id_fd.c: Interdata floppy disk simulator
|
||||
|
||||
Copyright (c) 2001-2013, Robert M Supnik
|
||||
Copyright (c) 2001-2021, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
fd M46-630 floppy disk
|
||||
|
||||
31-Jan-21 RMS Revised for new register macros
|
||||
03-Sep-13 RMS Added explicit void * cast
|
||||
19-Mar-12 RMS Fixed macro naming conflict (Mark Pizzolato)
|
||||
|
||||
@@ -169,7 +170,7 @@ REG fd_reg[] = {
|
||||
{ HRDATA (STA, fd_sta, 8) },
|
||||
{ HRDATA (BUF, fd_db, 8) },
|
||||
{ HRDATA (LRN, fd_lrn, 16) },
|
||||
{ BRDATA (ESTA, fd_es, 16, 8, ES_SIZE * FD_NUMDR) },
|
||||
{ CRDATA (ESTA, fd_es, 16, 8, ES_SIZE * FD_NUMDR) },
|
||||
{ BRDATA (DBUF, fdxb, 16, 8, FD_NUMBY) },
|
||||
{ HRDATA (DBPTR, fd_bptr, 8) },
|
||||
{ FLDATA (WDV, fd_wdv, 0) },
|
||||
|
||||
274
PDP11/pdp11_rq.c
274
PDP11/pdp11_rq.c
@@ -1,6 +1,6 @@
|
||||
/* pdp11_rq.c: MSCP disk controller simulator
|
||||
|
||||
Copyright (c) 2002-2018, Robert M Supnik
|
||||
Copyright (c) 2002-2022, Robert M Supnik
|
||||
Derived from work by Stephen F. Shirron
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
@@ -26,6 +26,8 @@
|
||||
|
||||
rq RQDX3 disk controller
|
||||
|
||||
06=Mar-22 RMS Added more disk types (Mark Pizzolato)
|
||||
31-Jan-21 RMS Revised for new register macros
|
||||
28-May-18 RMS Changed to avoid nested comment warnings (Mark Pizzolato)
|
||||
23-Oct-13 RMS Revised for new boot setup routine
|
||||
17-Mar-13 RMS Fixed bug in ABORT link walk loop (Dave Bryan)
|
||||
@@ -249,6 +251,7 @@ x RA73 70(+1) 21 2667+ 21 1 ? 3920490
|
||||
#define RQDF_RMV 01 /* removable */
|
||||
#define RQDF_RO 02 /* read only */
|
||||
#define RQDF_SDI 04 /* SDI drive */
|
||||
#define RQDF_DSSI 010 /* DSSI drive */
|
||||
|
||||
#define RX50_DTYPE 0
|
||||
#define RX50_SECT 10
|
||||
@@ -525,6 +528,160 @@ x RA73 70(+1) 21 2667+ 21 1 ? 3920490
|
||||
#define RD32_MED 0x25644020
|
||||
#define RD32_FLGS 0
|
||||
|
||||
/* Below here, imported from V4 */
|
||||
|
||||
#define RC25_DTYPE 17 /* */
|
||||
#define RC25_SECT 50 /* */
|
||||
#define RC25_SURF 8
|
||||
#define RC25_CYL 1260 /* */
|
||||
#define RC25_TPG RC25_SURF
|
||||
#define RC25_GPC 1
|
||||
#define RC25_XBN 0 /* */
|
||||
#define RC25_DBN 0 /* */
|
||||
#define RC25_LBN 50902 /* ? 50*8*1260 ? */
|
||||
#define RC25_RCTS 0 /* */
|
||||
#define RC25_RCTC 1
|
||||
#define RC25_RBN 0 /* */
|
||||
#define RC25_MOD 2
|
||||
#define RC25_MED 0x20643019
|
||||
#define RC25_FLGS RQDF_RMV
|
||||
|
||||
#define RCF25_DTYPE 18 /* */
|
||||
#define RCF25_SECT 50 /* */
|
||||
#define RCF25_SURF 8
|
||||
#define RCF25_CYL 1260 /* */
|
||||
#define RCF25_TPG RCF25_SURF
|
||||
#define RCF25_GPC 1
|
||||
#define RCF25_XBN 0 /* */
|
||||
#define RCF25_DBN 0 /* */
|
||||
#define RCF25_LBN 50902 /* ? 50*8*1260 ? */
|
||||
#define RCF25_RCTS 0 /* */
|
||||
#define RCF25_RCTC 1
|
||||
#define RCF25_RBN 0 /* */
|
||||
#define RCF25_MOD 3
|
||||
#define RCF25_MED 0x20643319
|
||||
#define RCF25_FLGS 0
|
||||
|
||||
#define RA80_DTYPE 19 /* SDI drive */
|
||||
#define RA80_SECT 31 /* +1 spare/track */
|
||||
#define RA80_SURF 14
|
||||
#define RA80_CYL 546 /* */
|
||||
#define RA80_TPG RA80_SURF
|
||||
#define RA80_GPC 1
|
||||
#define RA80_XBN 0 /* */
|
||||
#define RA80_DBN 0 /* */
|
||||
#define RA80_LBN 237212 /* 31*14*546 */
|
||||
#define RA80_RCTS 0 /* */
|
||||
#define RA80_RCTC 1
|
||||
#define RA80_RBN 0 /* */
|
||||
#define RA80_MOD 1
|
||||
#define RA80_MED 0x25641050
|
||||
#define RA80_FLGS RQDF_SDI
|
||||
|
||||
// [RLA] Most of these RA70 parameters came from doing a DUSTAT on a real
|
||||
// [RLA] RA70 drive. The remainder are just educated guesses...
|
||||
|
||||
#define RA70_DTYPE 20 /* SDI drive */
|
||||
#define RA70_SECT 33 /* +1 spare/track */
|
||||
#define RA70_SURF 11 /* tracks/cylinder */
|
||||
#define RA70_CYL 1507 /* 0-1506 user */
|
||||
#define RA70_TPG RA70_SURF
|
||||
#define RA70_GPC 1
|
||||
#define RA70_XBN 0 /* ??? */
|
||||
#define RA70_DBN 0 /* ??? */
|
||||
#define RA70_LBN 547041 /* 33*11*1507 */
|
||||
#define RA70_RCTS 198 /* Size of the RCT */
|
||||
#define RA70_RCTC 7 /* Number of RCT copies */
|
||||
#define RA70_RBN 16577 /* 1*11*1507 */
|
||||
#define RA70_MOD 18
|
||||
#define RA70_MED 0x25641046 /* RA70 MEDIA ID */
|
||||
#define RA70_FLGS RQDF_SDI
|
||||
|
||||
// [RLA] Likewise for the RA73 ...
|
||||
#define RA73_DTYPE 21 /* SDI drive */
|
||||
#define RA73_SECT 70 /* +1 spare/track */
|
||||
#define RA73_SURF 21 /* tracks/cylinder */
|
||||
#define RA73_CYL 2667 /* 0-2666 user */
|
||||
#define RA73_TPG RA73_SURF
|
||||
#define RA73_GPC 1
|
||||
#define RA73_XBN 0 /* ??? */
|
||||
#define RA73_DBN 0 /* ??? */
|
||||
#define RA73_LBN 3920490 /* 70*21*2667 */
|
||||
#define RA73_RCTS 198 /* Size of the RCT ??????*/
|
||||
#define RA73_RCTC 7 /* Number of RCT copies */
|
||||
#define RA73_RBN 56007 /* 1*21*2667 */
|
||||
#define RA73_MOD 47
|
||||
#define RA73_MED 0x25641049 /* RA73 MEDIA ID */
|
||||
#define RA73_FLGS RQDF_SDI
|
||||
|
||||
/* The RF drives don't have any useful error parameters. */
|
||||
/* These entries are derived from basic geometry and size */
|
||||
/* info in Ultrix 4.5 disktab entries. */
|
||||
|
||||
#define RF30_DTYPE 22 /* DSSI drive */
|
||||
#define RF30_SECT 37 /* +1 spare/track */
|
||||
#define RF30_SURF 6
|
||||
#define RF30_CYL 1320 /* 0-1914 user */
|
||||
#define RF30_TPG RF30_SURF
|
||||
#define RF30_GPC 1
|
||||
#define RF30_XBN 1456 /* cyl 1917-1918? */
|
||||
#define RF30_DBN 1456 /* cyl 1919-1920? */
|
||||
#define RF30_LBN 293040 /* 37*6*1320 */
|
||||
#define RF30_RCTS 1428 /* cyl 1915-1916? */
|
||||
#define RF30_RCTC 1
|
||||
#define RF30_RBN 26810 /* 1 *14*1915 */
|
||||
#define RF30_MOD 21
|
||||
#define RF30_MED 0x2264601E
|
||||
#define RF30_FLGS RQDF_DSSI
|
||||
|
||||
#define RF31_DTYPE 23 /* DSSI drive */
|
||||
#define RF31_SECT 50 /* +1 spare/track */
|
||||
#define RF31_SURF 8
|
||||
#define RF31_CYL 1861 /* 0-1860 user */
|
||||
#define RF31_TPG RF31_SURF
|
||||
#define RF31_GPC 1
|
||||
#define RF31_XBN 1456 /* cyl 1917-1918? */
|
||||
#define RF31_DBN 1456 /* cyl 1919-1920? */
|
||||
#define RF31_LBN 744400 /* 50*8*1861 */
|
||||
#define RF31_RCTS 1428 /* cyl 1915-1916? */
|
||||
#define RF31_RCTC 1
|
||||
#define RF31_RBN 26810 /* 1 *14*1915 */
|
||||
#define RF31_MOD 27
|
||||
#define RF31_MED 0x2264601F
|
||||
#define RF31_FLGS RQDF_DSSI
|
||||
|
||||
#define RF71_DTYPE 24 /* DSSI drive */
|
||||
#define RF71_SECT 37 /* +1 spare/track */
|
||||
#define RF71_SURF 16
|
||||
#define RF71_CYL 1320 /* 0-1914 user */
|
||||
#define RF71_TPG RF71_SURF
|
||||
#define RF71_GPC 1
|
||||
#define RF71_XBN 1456 /* cyl 1917-1918? */
|
||||
#define RF71_DBN 1456 /* cyl 1919-1920? */
|
||||
#define RF71_LBN 781440 /* 37*16*1320 */
|
||||
#define RF71_RCTS 1428 /* cyl 1915-1916? */
|
||||
#define RF71_RCTC 1
|
||||
#define RF71_RBN 26810 /* 1 *14*1915 */
|
||||
#define RF71_MOD 40
|
||||
#define RF71_MED 0x22646047
|
||||
#define RF71_FLGS RQDF_DSSI
|
||||
|
||||
#define RF72_DTYPE 25 /* DSSI drive */
|
||||
#define RF72_SECT 50 /* +1 spare/track */
|
||||
#define RF72_SURF 21
|
||||
#define RF72_CYL 1861 /* 0-1860 user */
|
||||
#define RF72_TPG RF72_SURF
|
||||
#define RF72_GPC 1
|
||||
#define RF72_XBN 1456 /* cyl 1917-1918? */
|
||||
#define RF72_DBN 1456 /* cyl 1919-1920? */
|
||||
#define RF72_LBN 1954050 /* 50*21*1861 */
|
||||
#define RF72_RCTS 1428 /* cyl 1915-1916? */
|
||||
#define RF72_RCTC 1
|
||||
#define RF72_RBN 26810 /* 1 *14*1915 */
|
||||
#define RF72_MOD 28
|
||||
#define RF72_MED 0x22646048
|
||||
#define RF72_FLGS RQDF_DSSI
|
||||
|
||||
struct drvtyp {
|
||||
int32 sect; /* sectors */
|
||||
int32 surf; /* surfaces */
|
||||
@@ -551,15 +708,87 @@ struct drvtyp {
|
||||
#define RQ_SIZE(d) (d##_LBN * RQ_NUMBY)
|
||||
|
||||
static struct drvtyp drv_tab[] = {
|
||||
{ RQ_DRV (RX50), "RX50" }, { RQ_DRV (RX33), "RX33" },
|
||||
{ RQ_DRV (RD51), "RD51" }, { RQ_DRV (RD31), "RD31" },
|
||||
{ RQ_DRV (RD52), "RD52" }, { RQ_DRV (RD53), "RD53" },
|
||||
{ RQ_DRV (RD54), "RD54" }, { RQ_DRV (RA82), "RA82" },
|
||||
{ RQ_DRV (RRD40), "RRD40" }, { RQ_DRV (RA72), "RA72" },
|
||||
{ RQ_DRV (RA90), "RA90" }, { RQ_DRV (RA92), "RA92" },
|
||||
{ RQ_DRV (RA8U), "RAUSER" }, { RQ_DRV (RA60), "RA60" },
|
||||
{ RQ_DRV (RA81), "RA81" }, { RQ_DRV (RA71), "RA71" },
|
||||
{ RQ_DRV (RX50), "RX50" },
|
||||
{ RQ_DRV (RX33), "RX33" },
|
||||
{ RQ_DRV (RD51), "RD51" },
|
||||
{ RQ_DRV (RD31), "RD31" },
|
||||
{ RQ_DRV (RD52), "RD52" },
|
||||
{ RQ_DRV (RD53), "RD53" },
|
||||
{ RQ_DRV (RD54), "RD54" },
|
||||
{ RQ_DRV (RA82), "RA82" },
|
||||
{ RQ_DRV (RRD40), "RRD40" },
|
||||
{ RQ_DRV (RA72), "RA72" },
|
||||
{ RQ_DRV (RA90), "RA90" },
|
||||
{ RQ_DRV (RA92), "RA82" },
|
||||
{ RQ_DRV (RA8U), "RAUSER" },
|
||||
{ RQ_DRV (RA60), "RA60" },
|
||||
{ RQ_DRV (RA81), "RA81" },
|
||||
{ RQ_DRV (RA71), "RA71" },
|
||||
{ RQ_DRV (RD32), "RD32" },
|
||||
{ RQ_DRV (RC25), "RC25" },
|
||||
{ RQ_DRV (RCF25), "RCF25" },
|
||||
{ RQ_DRV (RA80), "RA80" },
|
||||
{ RQ_DRV (RA70), "RA70" },
|
||||
{ RQ_DRV (RA73), "RA73" },
|
||||
{ RQ_DRV (RF30), "RF30" },
|
||||
{ RQ_DRV (RF31), "RF31" },
|
||||
{ RQ_DRV (RF71), "RF71" },
|
||||
{ RQ_DRV (RF72), "RF72" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Controller parameters */
|
||||
|
||||
#define DEFAULT_CTYPE 0
|
||||
|
||||
// AFAIK the UNIBUS KLESI and QBUS KLESI used the same controller type...
|
||||
|
||||
#define KLESI_CTYPE 1 // RC25 controller (UNIBUS and QBUS both)
|
||||
#define KLESI_UQPM 1
|
||||
#define KLESI_MODEL 1
|
||||
|
||||
#define RUX50_CTYPE 2 // UNIBUS RX50-only controller
|
||||
#define RUX50_UQPM 2
|
||||
#define RUX50_MODEL 2
|
||||
|
||||
#define UDA50_CTYPE 3 // UNIBUS SDI (RAxx) controller
|
||||
#define UDA50_UQPM 6
|
||||
#define UDA50_MODEL 6
|
||||
|
||||
#define RQDX3_CTYPE 4 // QBUS RX50/RDxx controller
|
||||
#define RQDX3_UQPM 19
|
||||
#define RQDX3_MODEL 19
|
||||
|
||||
#define KDA50_CTYPE 5 // QBUS SDI (RAxx) controller
|
||||
#define KDA50_UQPM 13
|
||||
#define KDA50_MODEL 13
|
||||
|
||||
#define KRQ50_CTYPE 6 // QBUS RRD40/50 CDROM controller
|
||||
#define KRQ50_UQPM 16
|
||||
#define KRQ50_MODEL 16
|
||||
|
||||
#define KRU50_CTYPE 7 // UNIBUS RRD40/50 CDROM controller
|
||||
#define KRU50_UQPM 26
|
||||
#define KRU50_MODEL 26
|
||||
|
||||
struct ctlrtyp {
|
||||
uint32 uqpm; /* port model */
|
||||
uint16 model; /* controller model */
|
||||
const char *name; /* name */
|
||||
};
|
||||
|
||||
#define RQ_CTLR(d) \
|
||||
d##_UQPM, d##_MODEL
|
||||
|
||||
static struct ctlrtyp ctlr_tab[] = {
|
||||
{ 0, 0, "DEFAULT" },
|
||||
{ RQ_CTLR (KLESI), "KLESI" },
|
||||
{ RQ_CTLR (RUX50), "RUX50" },
|
||||
{ RQ_CTLR (UDA50), "UDA50" },
|
||||
{ RQ_CTLR (RQDX3), "RQDX3" },
|
||||
{ RQ_CTLR (KDA50), "KDA50" },
|
||||
{ RQ_CTLR (KRQ50), "KRQ50" },
|
||||
{ RQ_CTLR (KRU50), "KRU50" },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@@ -592,6 +821,7 @@ typedef struct {
|
||||
uint32 credits; /* credits */
|
||||
uint32 hat; /* host timer */
|
||||
uint32 htmo; /* host timeout */
|
||||
// uint32 ctype; /* controller type */
|
||||
struct uq_ring cq; /* cmd ring */
|
||||
struct uq_ring rq; /* rsp ring */
|
||||
struct rqpkt pak[RQ_NPKTS]; /* packet queue */
|
||||
@@ -708,7 +938,7 @@ REG rq_reg[] = {
|
||||
{ DRDATA (I4TIME, rq_itime4, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (QTIME, rq_qtime, 24), PV_LEFT + REG_NZ },
|
||||
{ DRDATA (XTIME, rq_xtime, 24), PV_LEFT + REG_NZ },
|
||||
{ BRDATA (PKTS, rq_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) },
|
||||
{ XRDATA (PKTS, rq_ctx.pak, DEV_RDX, 16, 0, RQ_NPKTS * (RQ_PKT_SIZE_W + 1), sizeof (int16), sizeof (int16)) },
|
||||
{ URDATA (CPKT, rq_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rq_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rq_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
@@ -754,6 +984,8 @@ MTAB rq_mod[] = {
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA60_DTYPE, NULL, "RA60",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA80_DTYPE, NULL, "RA80",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA81_DTYPE, NULL, "RA81",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA82_DTYPE, NULL, "RA82",
|
||||
@@ -762,16 +994,32 @@ MTAB rq_mod[] = {
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RRD40_DTYPE, NULL, "CDROM",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA70_DTYPE, NULL, "RA70",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA71_DTYPE, NULL, "RA71",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA72_DTYPE, NULL, "RA72",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA73_DTYPE, NULL, "RA73",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA90_DTYPE, NULL, "RA90",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA92_DTYPE, NULL, "RA92",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA8U_DTYPE, NULL, "RAUSER",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RC25_DTYPE, NULL, "RC25",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RCF25_DTYPE, NULL, "RCF25",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RF30_DTYPE, NULL, "RF30",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RF31_DTYPE, NULL, "RF31",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA8U_DTYPE, NULL, "RAUSER",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, RA8U_DTYPE, NULL, "RA8U",
|
||||
&rq_set_type, NULL, NULL },
|
||||
{ MTAB_XTD | MTAB_VUN, 0, "TYPE", NULL,
|
||||
NULL, &rq_show_type, NULL },
|
||||
#if defined (VM_PDP11)
|
||||
@@ -847,7 +1095,7 @@ REG rqb_reg[] = {
|
||||
{ FLDATA (PRGI, rqb_ctx.prgi, 0), REG_HIDDEN },
|
||||
{ FLDATA (PIP, rqb_ctx.pip, 0), REG_HIDDEN },
|
||||
{ FLDATA (INT, rqb_ctx.irq, 0) },
|
||||
{ BRDATA (PKTS, rqb_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) },
|
||||
{ XRDATA (PKTS, rqb_ctx.pak, DEV_RDX, 16, 0, RQ_NPKTS * (RQ_PKT_SIZE_W + 1), sizeof (int16), sizeof (int16)) },
|
||||
{ URDATA (CPKT, rqb_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqb_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqb_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
@@ -916,7 +1164,7 @@ REG rqc_reg[] = {
|
||||
{ FLDATA (PRGI, rqc_ctx.prgi, 0), REG_HIDDEN },
|
||||
{ FLDATA (PIP, rqc_ctx.pip, 0), REG_HIDDEN },
|
||||
{ FLDATA (INT, rqc_ctx.irq, 0) },
|
||||
{ BRDATA (PKTS, rqc_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) },
|
||||
{ XRDATA (PKTS, rqc_ctx.pak, DEV_RDX, 16, 0, RQ_NPKTS * (RQ_PKT_SIZE_W + 1), sizeof (int16), sizeof (int16)) },
|
||||
{ URDATA (CPKT, rqc_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqc_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqc_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
@@ -985,7 +1233,7 @@ REG rqd_reg[] = {
|
||||
{ FLDATA (PRGI, rqd_ctx.prgi, 0), REG_HIDDEN },
|
||||
{ FLDATA (PIP, rqd_ctx.pip, 0), REG_HIDDEN },
|
||||
{ FLDATA (INT, rqd_ctx.irq, 0) },
|
||||
{ BRDATA (PKTS, rqd_ctx.pak, DEV_RDX, 16, RQ_NPKTS * (RQ_PKT_SIZE_W + 1)) },
|
||||
{ XRDATA (PKTS, rqd_ctx.pak, DEV_RDX, 16, 0, RQ_NPKTS * (RQ_PKT_SIZE_W + 1), sizeof (int16), sizeof (int16)) },
|
||||
{ URDATA (CPKT, rqd_unit[0].cpkt, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (PKTQ, rqd_unit[0].pktq, 10, 5, 0, RQ_NUMDR, 0) },
|
||||
{ URDATA (UFLG, rqd_unit[0].uf, DEV_RDX, 16, 0, RQ_NUMDR, 0) },
|
||||
|
||||
Binary file not shown.
BIN
doc/simh_doc.doc
BIN
doc/simh_doc.doc
Binary file not shown.
273
scp.c
273
scp.c
@@ -1,6 +1,6 @@
|
||||
/* scp.c: simulator control program
|
||||
|
||||
Copyright (c) 1993-2020, Robert M Supnik
|
||||
Copyright (c) 1993-2022, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,7 +23,17 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
06-Mar-22 RMS Removed UNIT_RAW support
|
||||
21-Oct-21 RMS Fixed bug in byte deposits if aincr > 1
|
||||
20=Sep-21 RMS Fixed bug in nested DO recognition (per Mark Pizzolato)
|
||||
15-Apr-21 RMS Changed RUN to store new PC value both before RESET
|
||||
(former behavior) and after (per Mark Pizzolato)
|
||||
18-Mar-21 JDB Revised "attach_unit" and "detach_unit" for pipe support
|
||||
Modified tests to allow UNIT_RO without UNIT_ROABLE
|
||||
16-Feb-21 JDB Rewrote get_rval, put_rval to support arrays of structures
|
||||
01-Feb-21 JDB Added casts for down-conversions
|
||||
25-Jan-21 JDB REG "size" field now determines access size
|
||||
REG "maxval" field now determines maximum allowed value
|
||||
30-Nov-20 RMS Fixed RUN problem if CPU reset clears PC (Mark Pizzolato)
|
||||
09-Nov-20 RMS Added hack for sim_card multiple attach (Mark Pizzolato)
|
||||
23-Oct-20 JDB Added tmxr_post_logs calls to flush and close log files
|
||||
@@ -230,8 +240,9 @@
|
||||
#include "sim_tmxr.h"
|
||||
#include <signal.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(HAVE_DLOPEN) /* Dynamic Readline support */
|
||||
#if defined(SIM_HAVE_DLOPEN) /* Dynamic Readline support */
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
@@ -258,8 +269,6 @@
|
||||
x = sim_interval
|
||||
|
||||
#define SZ_D(dp) (size_map[((dp)->dwidth + CHAR_BIT - 1) / CHAR_BIT])
|
||||
#define SZ_R(rp) \
|
||||
(size_map[((rp)->width + (rp)->offset + CHAR_BIT - 1) / CHAR_BIT])
|
||||
#if defined (USE_INT64)
|
||||
#define SZ_LOAD(sz,v,mb,j) \
|
||||
if (sz == sizeof (uint8)) v = *(((uint8 *) mb) + ((uint32) j)); \
|
||||
@@ -374,7 +383,8 @@ t_stat ex_reg (FILE *ofile, t_value val, int32 flag, REG *rptr, uint32 idx);
|
||||
t_stat dep_reg (int32 flag, char *cptr, REG *rptr, uint32 idx);
|
||||
t_stat exdep_addr_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr,
|
||||
t_addr low, t_addr high, DEVICE *dptr, UNIT *uptr);
|
||||
t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr, UNIT *uptr, int32 dfltinc);
|
||||
t_stat ex_addr (FILE *ofile, int32 flag, t_addr addr, DEVICE *dptr,
|
||||
UNIT *uptr, int32 dfltinc);
|
||||
t_stat dep_addr (int32 flag, char *cptr, t_addr addr, DEVICE *dptr,
|
||||
UNIT *uptr, int32 dfltinc);
|
||||
t_stat step_svc (UNIT *ptr);
|
||||
@@ -1020,7 +1030,7 @@ do {
|
||||
sim_switches = 0; /* init switches */
|
||||
isdo = FALSE;
|
||||
if (cmdp = find_cmd (gbuf)) { /* lookup command */
|
||||
isdo = (MATCH_CMD (gbuf, "DO") == 0);
|
||||
isdo = (strcmp (cmdp->name, "DO") == 0);
|
||||
if (isdo) { /* DO command? */
|
||||
if (flag >= DO_NEST_LVL) /* nest too deep? */
|
||||
stat = SCPE_NEST;
|
||||
@@ -1374,8 +1384,9 @@ if (cptr)
|
||||
if (uptr == NULL)
|
||||
return SCPE_NOFNC;
|
||||
if (((uptr->flags & UNIT_SEQ) == 0) || /* must be sequential, */
|
||||
((uptr->flags & UNIT_ROABLE) != 0) || /* not RO settable */
|
||||
((uptr->flags & UNIT_MUSTBUF) != 0)) /* not buffered */
|
||||
((uptr->flags & (UNIT_RO | UNIT_ROABLE)) != 0) || /* not RO settable */
|
||||
((uptr->flags & UNIT_MUSTBUF) != 0) || /* not buffered */
|
||||
((uptr->dynflags & UNIT_PIPE) != 0)) /* not a pipe */
|
||||
return SCPE_NOFNC;
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* must be attached */
|
||||
return SCPE_UNATT;
|
||||
@@ -2127,9 +2138,21 @@ return attach_unit (uptr, cptr); /* no, std routine */
|
||||
|
||||
/* Attach unit to file */
|
||||
|
||||
#if !defined (S_ISFIFO)
|
||||
#if !defined (S_IFMT) && defined (_S_IFMT)
|
||||
#define S_IFMT _S_IFMT
|
||||
#endif
|
||||
#if defined (_S_IFIFO)
|
||||
#define S_ISFIFO(m) (((m) & S_IFMT) == _S_IFIFO)
|
||||
#else
|
||||
#define S_ISFIFO(m) 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
t_stat attach_unit (UNIT *uptr, char *cptr)
|
||||
{
|
||||
DEVICE *dptr;
|
||||
struct stat info;
|
||||
|
||||
if (!(uptr->flags & UNIT_ATTABLE)) /* not attachable? */
|
||||
return SCPE_NOATT;
|
||||
@@ -2141,8 +2164,24 @@ uptr->filename = (char *) calloc (CBUFSIZE, sizeof (char)); /* alloc name buf */
|
||||
if (uptr->filename == NULL)
|
||||
return SCPE_MEM;
|
||||
strncpy (uptr->filename, cptr, CBUFSIZE); /* save name */
|
||||
if (sim_switches & SWMASK ('R')) { /* read only? */
|
||||
if ((uptr->flags & UNIT_ROABLE) == 0) /* allowed? */
|
||||
|
||||
if ((!stat (cptr, &info)) && S_ISFIFO (info.st_mode)) /* if file exists and is a pipe */
|
||||
if (uptr->flags & UNIT_SEQ) { /* then if the unit is sequential */
|
||||
if (uptr->flags & (UNIT_RO | UNIT_ROABLE)) /* if the unit is readable */
|
||||
uptr->fileref = sim_fopen (cptr, "rb"); /* then open the pipe for reading */
|
||||
else /* otherwise */
|
||||
uptr->fileref = sim_fopen (cptr, "wb"); /* open the pipe for writing */
|
||||
|
||||
if (uptr->fileref == NULL) /* if the file failed to open */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* then report the error */
|
||||
else /* otherwise */
|
||||
uptr->dynflags = uptr->dynflags | UNIT_PIPE; /* set the pipe flag */
|
||||
}
|
||||
else /* otherwise the unit is not sequential */
|
||||
return SCPE_NOFNC; /* so it cannot be attached to a pipe */
|
||||
|
||||
else if (sim_switches & SWMASK ('R')) { /* read only? */
|
||||
if ((uptr->flags & (UNIT_RO | UNIT_ROABLE)) == 0) /* allowed? */
|
||||
return attach_err (uptr, SCPE_NORO); /* no, error */
|
||||
uptr->fileref = sim_fopen (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
@@ -2152,18 +2191,18 @@ if (sim_switches & SWMASK ('R')) { /* read only? */
|
||||
sim_printf ("%s: unit is read only\n", sim_dname (dptr));
|
||||
}
|
||||
else if (sim_switches & SWMASK ('N')) { /* new file only? */
|
||||
uptr->fileref = sim_fopen (cptr, "wb+"); /* open new file */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
if (!sim_quiet)
|
||||
sim_printf ("%s: creating new file\n", sim_dname (dptr));
|
||||
uptr->fileref = sim_fopen (cptr, "wb+"); /* open new file */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
if (!sim_quiet)
|
||||
sim_printf ("%s: creating new file\n", sim_dname (dptr));
|
||||
}
|
||||
else { /* normal */
|
||||
uptr->fileref = sim_fopen (cptr, "rb+"); /* open r/w */
|
||||
if (uptr->fileref == NULL) { /* open fail? */
|
||||
if ((errno == EROFS) || (errno == EACCES)) { /* read only? */
|
||||
if ((uptr->flags & UNIT_ROABLE) == 0) /* allowed? */
|
||||
return attach_err (uptr, SCPE_NORO); /* no error */
|
||||
if ((uptr->flags & (UNIT_RO | UNIT_ROABLE)) == 0) /* allowed? */
|
||||
return attach_err (uptr, SCPE_NORO); /* no error */
|
||||
uptr->fileref = sim_fopen (cptr, "rb"); /* open rd only */
|
||||
if (uptr->fileref == NULL) /* open fail? */
|
||||
return attach_err (uptr, SCPE_OPENERR); /* yes, error */
|
||||
@@ -2316,6 +2355,7 @@ if ((uptr->flags & UNIT_BUF) && (uptr->filebuf)) { /* buffered? */
|
||||
}
|
||||
uptr->flags = uptr->flags & ~(UNIT_ATT | /* clear ATT */
|
||||
((uptr->flags & UNIT_ROABLE) ? UNIT_RO : 0)); /* clear RO if dynamic */
|
||||
uptr->dynflags = uptr->dynflags & ~UNIT_PIPE; /* clear the pipe flag */
|
||||
free (uptr->filename);
|
||||
uptr->filename = NULL;
|
||||
if (fclose (uptr->fileref) == EOF)
|
||||
@@ -2560,7 +2600,7 @@ void *mbuf;
|
||||
int32 j, blkcnt, limit, unitno, time, flg;
|
||||
uint32 us, depth;
|
||||
t_addr k, high, old_capac;
|
||||
t_value val, mask;
|
||||
t_value val, max;
|
||||
t_stat r;
|
||||
size_t sz;
|
||||
t_bool v35, v32;
|
||||
@@ -2732,10 +2772,13 @@ for ( ;; ) { /* device loop */
|
||||
if (depth != rptr->depth) /* [V2.10+] mismatch? */
|
||||
sim_printf ("Register depth mismatch: %s %s, file = %d, sim = %d\n",
|
||||
sim_dname (dptr), buf, depth, rptr->depth);
|
||||
mask = width_mask[rptr->width]; /* get mask */
|
||||
if (rptr->maxval > 0) /* if a maximum value is defined */
|
||||
max = rptr->maxval; /* then use it */
|
||||
else /* otherwise */
|
||||
max = width_mask[rptr->width]; /* the mask defines the maximum value */
|
||||
for (us = 0; us < depth; us++) { /* loop thru values */
|
||||
READ_I (val); /* read value */
|
||||
if (val > mask) /* value ok? */
|
||||
if (val > max) /* value ok? */
|
||||
sim_printf ("Invalid register value: %s %s\n", sim_dname (dptr), buf);
|
||||
else if (us < rptr->depth) /* in range? */
|
||||
put_rval (rptr, us, val);
|
||||
@@ -2777,14 +2820,17 @@ if ((flag == RU_RUN) || (flag == RU_GO)) { /* run or go */
|
||||
pcv = sim_vm_parse_addr (sim_dflt_dev, gbuf, &tptr);
|
||||
else pcv = strtotv (gbuf, &tptr, sim_PC->radix);/* parse PC */
|
||||
if ((tptr == gbuf) || (*tptr != 0) || /* error? */
|
||||
(pcv > width_mask[sim_PC->width]))
|
||||
(pcv > (sim_PC->maxval > 0
|
||||
? sim_PC->maxval
|
||||
: width_mask[sim_PC->width])))
|
||||
return SCPE_ARG;
|
||||
put_rval (sim_PC, 0, pcv); /* store new PC */
|
||||
}
|
||||
if ((flag == RU_RUN) && /* run? */
|
||||
((r = run_boot_prep ()) != SCPE_OK)) /* reset sim */
|
||||
return r;
|
||||
if (new_pcv) /* new PC value? */
|
||||
put_rval (sim_PC, 0, pcv);
|
||||
put_rval (sim_PC, 0, pcv); /* store again */
|
||||
}
|
||||
|
||||
else if (flag == RU_STEP) { /* step */
|
||||
@@ -2830,7 +2876,8 @@ else if (flag != RU_CONT) /* must be cont */
|
||||
for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* reposition all */
|
||||
for (j = 0; j < dptr->numunits; j++) { /* seq devices */
|
||||
uptr = dptr->units + j;
|
||||
if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ))
|
||||
if ((uptr->flags & (UNIT_ATT + UNIT_SEQ)) == (UNIT_ATT + UNIT_SEQ) &&
|
||||
(uptr->dynflags & UNIT_PIPE) == 0)
|
||||
sim_fseek (uptr->fileref, uptr->pos, SEEK_SET);
|
||||
}
|
||||
}
|
||||
@@ -2875,7 +2922,6 @@ for (i = 1; (dptr = sim_devices[i]) != NULL; i++) { /* flush attached files
|
||||
if ((uptr->flags & UNIT_ATT) && /* attached, */
|
||||
!(uptr->flags & UNIT_BUF) && /* not buffered, */
|
||||
(uptr->fileref) && /* real file, */
|
||||
!(uptr->flags & UNIT_RAW) && /* not raw, */
|
||||
!(uptr->flags & UNIT_RO)) /* not read only? */
|
||||
fflush (uptr->fileref);
|
||||
}
|
||||
@@ -3155,11 +3201,15 @@ t_stat exdep_addr_loop (FILE *ofile, SCHTAB *schptr, int32 flag, char *cptr,
|
||||
t_addr i, mask;
|
||||
t_stat reason, dfltinc;
|
||||
|
||||
|
||||
if (uptr->flags & UNIT_DIS) /* disabled? */
|
||||
return SCPE_UDIS;
|
||||
mask = (t_addr) width_mask[dptr->awidth];
|
||||
if ((low > mask) || (high > mask) || (low > high))
|
||||
return SCPE_ARG;
|
||||
dfltinc = parse_sym ("0", 0, uptr, sim_eval, sim_switches);
|
||||
if (dfltinc > 0) /* parse_sym doing nums? */
|
||||
dfltinc = 1 - dptr->aincr; /* no, use std dflt incr */
|
||||
for (i = low; i <= high; ) { /* all paths must incr!! */
|
||||
reason = get_aval (i, dptr, uptr); /* get data */
|
||||
if (reason != SCPE_OK) /* return if error */
|
||||
@@ -3229,43 +3279,50 @@ return SCPE_OK;
|
||||
idx = index
|
||||
Outputs:
|
||||
return = register value
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. The stride is the size of the element spacing for arrays, which is
|
||||
equivalent to the addressing increment for array subscripting. For
|
||||
scalar registers, the stride will be zero (as will the idx value), so the
|
||||
access pointer is same as the specified location pointer.
|
||||
|
||||
2. The size of the t_value type is determined by the USE_INT64 symbol and
|
||||
will be either a 32-bit or a 64-bit type. It represents the largest
|
||||
value that can be returned and so is the default if one of the smaller
|
||||
sizes is not indicated. If USE_INT64 is not defined, t_value will be
|
||||
identical to uint32. In this case, compilers are generally smart enough
|
||||
to eliminate the 32-bit size test and combine the two assignments into a
|
||||
single default assignment.
|
||||
*/
|
||||
|
||||
t_value get_rval (REG *rptr, uint32 idx)
|
||||
{
|
||||
size_t sz;
|
||||
t_value val;
|
||||
UNIT *uptr;
|
||||
void *ptr;
|
||||
|
||||
sz = SZ_R (rptr);
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) {
|
||||
idx = idx + rptr->qptr;
|
||||
if (idx >= rptr->depth) idx = idx - rptr->depth;
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { /* if the register is a circular queue */
|
||||
idx = idx + rptr->qptr; /* then adjust the index relative to the queue */
|
||||
if (idx >= rptr->depth) /* if the index is beyond the end of the array */
|
||||
idx = idx - rptr->depth; /* then wrap it around */
|
||||
}
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) {
|
||||
uptr = ((UNIT *) rptr->loc) + idx;
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
val = *((uint32 *) uptr);
|
||||
else val = *((t_uint64 *) uptr);
|
||||
#else
|
||||
val = *((uint32 *) uptr);
|
||||
#endif
|
||||
}
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint8)))
|
||||
val = *(((uint8 *) rptr->loc) + idx);
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint16)))
|
||||
val = *(((uint16 *) rptr->loc) + idx);
|
||||
#if defined (USE_INT64)
|
||||
else if (sz <= sizeof (uint32))
|
||||
val = *(((uint32 *) rptr->loc) + idx);
|
||||
else val = *(((t_uint64 *) rptr->loc) + idx);
|
||||
#else
|
||||
else val = *(((uint32 *) rptr->loc) + idx);
|
||||
#endif
|
||||
val = (val >> rptr->offset) & width_mask[rptr->width];
|
||||
|
||||
ptr = ((char *) rptr->loc) + (idx * rptr->stride); /* point at the starting byte of the item */
|
||||
|
||||
if (rptr->size == sizeof (uint8)) /* get the value */
|
||||
val = *((uint8 *) ptr); /* using a size */
|
||||
/* appropriate to */
|
||||
else if (rptr->size == sizeof (uint16)) /* the size of */
|
||||
val = *((uint16 *) ptr); /* the underlying type */
|
||||
|
||||
else if (rptr->size == sizeof (uint32))
|
||||
val = *((uint32 *) ptr);
|
||||
|
||||
else /* if the element size is non-standard */
|
||||
val = *((t_value *) ptr); /* then access using the largest size permitted */
|
||||
|
||||
val = (val >> rptr->offset) & width_mask[rptr->width]; /* shift and mask to obtain the final value */
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
@@ -3283,7 +3340,7 @@ return val;
|
||||
t_stat dep_reg (int32 flag, char *cptr, REG *rptr, uint32 idx)
|
||||
{
|
||||
t_stat r;
|
||||
t_value val, mask;
|
||||
t_value val, max;
|
||||
int32 rdx;
|
||||
char *tptr, gbuf[CBUFSIZE];
|
||||
|
||||
@@ -3300,17 +3357,20 @@ if (flag & EX_I) {
|
||||
if (*cptr == 0) /* success */
|
||||
return SCPE_OK;
|
||||
}
|
||||
mask = width_mask[rptr->width];
|
||||
if (rptr->maxval > 0) /* if a maximum value is defined */
|
||||
max = rptr->maxval; /* then use it */
|
||||
else /* otherwise */
|
||||
max = width_mask[rptr->width]; /* the mask defines the maximum value */
|
||||
GET_RADIX (rdx, rptr->radix);
|
||||
if ((rptr->flags & REG_VMAD) && sim_vm_parse_addr) { /* address form? */
|
||||
val = sim_vm_parse_addr (sim_dflt_dev, cptr, &tptr);
|
||||
if ((tptr == cptr) || (*tptr != 0) || (val > mask))
|
||||
if ((tptr == cptr) || (*tptr != 0) || (val > max))
|
||||
return SCPE_ARG;
|
||||
}
|
||||
else if (!(rptr->flags & REG_VMFLAGS) || /* dont use sym? */
|
||||
(parse_sym (cptr, (rptr->flags & REG_UFMASK) | rdx, NULL,
|
||||
&val, sim_switches | SIM_SW_REG) > SCPE_OK)) {
|
||||
val = get_uint (cptr, rdx, mask, &r);
|
||||
val = get_uint (cptr, rdx, max, &r);
|
||||
if (r != SCPE_OK)
|
||||
return SCPE_ARG;
|
||||
}
|
||||
@@ -3326,59 +3386,54 @@ return SCPE_OK;
|
||||
rptr = pointer to register descriptor
|
||||
idx = index
|
||||
val = new value
|
||||
mask = mask
|
||||
Outputs:
|
||||
none
|
||||
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. mask and val are of type t_value, so an explicit cast is not needed for
|
||||
that type of assignment.
|
||||
|
||||
2. See the notes for the get_rval routine for additional information
|
||||
regarding the stride calculation and the t_value default assignment,
|
||||
*/
|
||||
|
||||
void put_rval (REG *rptr, uint32 idx, t_value val)
|
||||
{
|
||||
size_t sz;
|
||||
t_value mask;
|
||||
UNIT *uptr;
|
||||
void *ptr;
|
||||
|
||||
#define PUT_RVAL(sz,rp,id,v,m) \
|
||||
*(((sz *) rp->loc) + id) = \
|
||||
(*(((sz *) rp->loc) + id) & \
|
||||
~((m) << (rp)->offset)) | ((v) << (rp)->offset)
|
||||
if (rptr == sim_PC) /* if the PC is changing */
|
||||
sim_brk_npc (0); /* then notify the breakpoint package */
|
||||
|
||||
if (rptr == sim_PC)
|
||||
sim_brk_npc (0);
|
||||
sz = SZ_R (rptr);
|
||||
mask = width_mask[rptr->width];
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) {
|
||||
idx = idx + rptr->qptr;
|
||||
if (idx >= rptr->depth)
|
||||
idx = idx - rptr->depth;
|
||||
mask = ~(width_mask [rptr->width] << rptr->offset); /* set up a mask to produce a hole in the element */
|
||||
val = val << rptr->offset; /* and position the new value to fit the hole */
|
||||
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_CIRC)) { /* if the register is a circular queue */
|
||||
idx = idx + rptr->qptr; /* then adjust the index relative to the queue */
|
||||
if (idx >= rptr->depth) /* if the index is beyond the end of the array */
|
||||
idx = idx - rptr->depth; /* then wrap it around */
|
||||
}
|
||||
if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) {
|
||||
uptr = ((UNIT *) rptr->loc) + idx;
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
*((uint32 *) uptr) = (*((uint32 *) uptr) &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
else *((t_uint64 *) uptr) = (*((t_uint64 *) uptr)
|
||||
& ~(mask << rptr->offset)) | (val << rptr->offset);
|
||||
#else
|
||||
*((uint32 *) uptr) = (*((uint32 *) uptr) &
|
||||
~(((uint32) mask) << rptr->offset)) |
|
||||
(((uint32) val) << rptr->offset);
|
||||
#endif
|
||||
}
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint8)))
|
||||
PUT_RVAL (uint8, rptr, idx, (uint32) val, (uint32) mask);
|
||||
else if (((rptr->depth > 1) || (rptr->flags & REG_FIT)) &&
|
||||
(sz == sizeof (uint16)))
|
||||
PUT_RVAL (uint16, rptr, idx, (uint32) val, (uint32) mask);
|
||||
#if defined (USE_INT64)
|
||||
else if (sz <= sizeof (uint32))
|
||||
PUT_RVAL (uint32, rptr, idx, (int32) val, (uint32) mask);
|
||||
else PUT_RVAL (t_uint64, rptr, idx, val, mask);
|
||||
#else
|
||||
else PUT_RVAL (uint32, rptr, idx, val, mask);
|
||||
#endif
|
||||
|
||||
ptr = ((char *) rptr->loc) + (idx * rptr->stride); /* point at the starting byte of the item */
|
||||
|
||||
if (rptr->size == sizeof (uint8)) /* store the value */
|
||||
*((uint8 *) ptr) = /* using a size */
|
||||
(uint8) (*((uint8 *) ptr) & mask | val); /* appropriate to */
|
||||
/* the size of */
|
||||
else if (rptr->size == sizeof (uint16)) /* the underlying type */
|
||||
*((uint16 *) ptr) =
|
||||
(uint16) (*((uint16 *) ptr) & mask | val);
|
||||
|
||||
else if (rptr->size == sizeof (uint32))
|
||||
*((uint32 *) ptr) =
|
||||
(uint32) (*((uint32 *) ptr) & mask | val);
|
||||
|
||||
else /* if the element size is non-standard */
|
||||
*((t_value *) ptr) = /* then access using the largest size permitted */
|
||||
*((t_value *) ptr) & mask | val;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3411,7 +3466,7 @@ if (!(flag & EX_E))
|
||||
GET_RADIX (rdx, dptr->dradix);
|
||||
if ((reason = fprint_sym (ofile, addr, sim_eval, uptr, sim_switches)) > 0) {
|
||||
fprint_val (ofile, sim_eval[0], rdx, dptr->dwidth, PV_RZRO);
|
||||
return dfltinc;
|
||||
reason = dfltinc;
|
||||
}
|
||||
if (flag & EX_I)
|
||||
fprintf (ofile, "\t");
|
||||
@@ -3452,8 +3507,8 @@ for (i = 0, j = addr; i < sim_emax; i++, j = j + dptr->aincr) {
|
||||
else {
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_UNATT;
|
||||
if (((uptr->flags & UNIT_RAW) != 0) ||
|
||||
(uptr->fileref == NULL))
|
||||
if ((uptr->fileref == NULL) ||
|
||||
((uptr->dynflags & UNIT_PIPE) != 0))
|
||||
return SCPE_NOFNC;
|
||||
if (((uptr->flags & UNIT_FIX) != 0) &&
|
||||
(j >= uptr->capac)) {
|
||||
@@ -3545,7 +3600,7 @@ for (i = 0, j = addr; i < count; i++, j = j + dptr->aincr) {
|
||||
else {
|
||||
if (!(uptr->flags & UNIT_ATT))
|
||||
return SCPE_UNATT;
|
||||
if (uptr->flags & UNIT_RAW)
|
||||
if (uptr->dynflags & UNIT_PIPE)
|
||||
return SCPE_NOFNC;
|
||||
if ((uptr->flags & UNIT_FIX) && (j >= uptr->capac))
|
||||
return SCPE_NXM;
|
||||
@@ -3641,7 +3696,7 @@ return read_line_p (NULL, cptr, size, stream);
|
||||
char *read_line_p (char *prompt, char *cptr, int32 size, FILE *stream)
|
||||
{
|
||||
char *tptr;
|
||||
#if defined(HAVE_DLOPEN)
|
||||
#if defined(SIM_HAVE_DLOPEN)
|
||||
static int initialized = 0;
|
||||
static char *(*p_readline)(const char *) = NULL;
|
||||
static void (*p_add_history)(const char *) = NULL;
|
||||
@@ -3705,7 +3760,7 @@ while (isspace (*cptr)) /* trim leading spc */
|
||||
if (*cptr == ';') /* ignore comment */
|
||||
*cptr = 0;
|
||||
|
||||
#if defined (HAVE_DLOPEN)
|
||||
#if defined (SIM_HAVE_DLOPEN)
|
||||
if (prompt && p_add_history && *cptr) /* Save non blank lines in history */
|
||||
p_add_history (cptr);
|
||||
#endif
|
||||
@@ -3730,7 +3785,7 @@ char *get_glyph_gen (char *iptr, char *optr, char mchar, t_bool uc)
|
||||
{
|
||||
while ((isspace (*iptr) == 0) && (*iptr != 0) && (*iptr != mchar)) {
|
||||
if (islower (*iptr) && uc)
|
||||
*optr = toupper (*iptr);
|
||||
*optr = (char) toupper (*iptr);
|
||||
else *optr = *iptr;
|
||||
iptr++; optr++;
|
||||
}
|
||||
@@ -4528,7 +4583,7 @@ do {
|
||||
d = d - 1;
|
||||
digit = (int32) (val % radix);
|
||||
val = val / radix;
|
||||
dbuf[d] = (digit <= 9)? '0' + digit: 'A' + (digit - 10);
|
||||
dbuf[d] = (char) ((digit <= 9)? '0' + digit: 'A' + (digit - 10));
|
||||
} while ((d > 0) && (val != 0));
|
||||
|
||||
if (format != PV_LEFT) {
|
||||
|
||||
235
sim_defs.h
235
sim_defs.h
@@ -1,6 +1,6 @@
|
||||
/* sim_defs.h: simulator definitions
|
||||
|
||||
Copyright (c) 1993-2020, Robert M Supnik
|
||||
Copyright (c) 1993-2022, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -23,6 +23,13 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
10-Mar-22 JDB Modified REG macros to fix "stringizing" problem
|
||||
12-Nov-21 JDB Added UNIT_EXTEND dynamic flag
|
||||
17-Mar-21 JDB Added UNIT_PIPE dynamic flag
|
||||
16-Feb-21 JDB Added "stride" to REG to support arrays of structures
|
||||
Modified REG macros to initialize strides
|
||||
21-Jan-21 JDB Added "size" and "maxval" fields to the REG structure
|
||||
Modified REG macros to initialize access sizes
|
||||
09-Nov-20 RMS More V4.X compatibility hooks (Mark Pizzolato)
|
||||
26-Oct-19 RMS Removed MTAB_VAL definition
|
||||
23-Jun-17 RMS Added #include sim_rev.h (Mark Pizzolato)
|
||||
@@ -137,7 +144,7 @@ typedef signed short int16;
|
||||
typedef signed int int32;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef unsigned int uint32;
|
||||
typedef int t_stat; /* status */
|
||||
typedef int t_bool; /* boolean */
|
||||
|
||||
@@ -417,11 +424,13 @@ struct sim_unit {
|
||||
#define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
|
||||
#define UNIT_RFLAGS (UNIT_UFMASK|UNIT_DIS) /* restored flags */
|
||||
|
||||
/* Unit dynamic flags (dynflags) (from 4.0)
|
||||
/* Unit dynamic flags (dynflags) (from 4.0)
|
||||
These flags are only set dynamically */
|
||||
|
||||
#define UNIT_ATTMULT 000001 /* allow multiple ATT cmd */
|
||||
#define UNIT_V_DF_TAPE 3 /* tape density reservation */
|
||||
#define UNIT_PIPE 000002 /* file is a pipe */
|
||||
#define UNIT_EXTEND 000004 /* extended SIMH tape format is enabled */
|
||||
#define UNIT_V_DF_TAPE 3 /* tape density reservation (bits 3-5) */
|
||||
#define UNIT_W_DF_TAPE 3
|
||||
|
||||
/* Register data structure */
|
||||
@@ -433,7 +442,10 @@ struct sim_reg {
|
||||
uint32 width; /* width */
|
||||
uint32 offset; /* starting bit */
|
||||
uint32 depth; /* save depth */
|
||||
size_t size; /* size of location in bytes */
|
||||
size_t stride; /* spacing of array elements in bytes */
|
||||
uint32 flags; /* flags */
|
||||
t_value maxval; /* maximum value */
|
||||
uint32 qptr; /* circ q ptr */
|
||||
};
|
||||
|
||||
@@ -443,11 +455,10 @@ struct sim_reg {
|
||||
#define REG_RO 00004 /* read only */
|
||||
#define REG_HIDDEN 00010 /* hidden */
|
||||
#define REG_NZ 00020 /* must be non-zero */
|
||||
#define REG_UNIT 00040 /* in unit struct */
|
||||
#define REG_CIRC 00100 /* circular array */
|
||||
#define REG_VMIO 00200 /* use VM data print/parse */
|
||||
#define REG_VMAD 00400 /* use VM addr print/parse */
|
||||
#define REG_FIT 01000 /* fit access to size */
|
||||
#define REG_FIT 00000 /* fit access to size (obsolete) */
|
||||
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
|
||||
|
||||
#define REG_V_UF 16 /* device specific */
|
||||
@@ -520,7 +531,7 @@ struct sim_schtab {
|
||||
struct sim_brktab {
|
||||
t_addr addr; /* address */
|
||||
int32 typ; /* mask of types */
|
||||
int32 cnt; /* proceed count */
|
||||
int32 cnt; /* proceed count */
|
||||
char *act; /* action string */
|
||||
};
|
||||
|
||||
@@ -540,31 +551,117 @@ struct sim_debtab {
|
||||
|
||||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,0,0,(fl),0,(cap),0,0
|
||||
|
||||
#if defined (__STDC__) || defined (_WIN32)
|
||||
#define ORDATA(nm,loc,wd) #nm, &(loc), 8, (wd), 0, 1
|
||||
#define DRDATA(nm,loc,wd) #nm, &(loc), 10, (wd), 0, 1
|
||||
#define HRDATA(nm,loc,wd) #nm, &(loc), 16, (wd), 0, 1
|
||||
#define FLDATA(nm,loc,pos) #nm, &(loc), 2, 1, (pos), 1
|
||||
#define GRDATA(nm,loc,rdx,wd,pos) #nm, &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep)
|
||||
#define VBRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep)
|
||||
#define SAVEDATA(nm,loc) \
|
||||
#nm, &(loc), 8, 8, 0, sizeof(loc), REG_HRO
|
||||
/* Register initialization macros.
|
||||
|
||||
The following macros should be used to initialize the elements of a
|
||||
simulator's register array. The macros provide simplified initialization,
|
||||
ensure that unspecified fields are set appropriately, and insulate the
|
||||
simulator writer from changes in the underlying REG structure.
|
||||
|
||||
The macros take varying numbers of parameters with the following meanings:
|
||||
|
||||
Param Meaning
|
||||
----- ------------------------------------------
|
||||
nm Register symbolic name
|
||||
loc Location of the associated variable
|
||||
aloc Location of the associated array
|
||||
floc Location of the associated structure field
|
||||
rdx Display and entry radix
|
||||
wd Field width in bits
|
||||
off Field offset in bits from LSB
|
||||
dep Number of array elements
|
||||
siz Element size in bytes
|
||||
str Array element spacing in bytes
|
||||
|
||||
The macros have the following uses:
|
||||
|
||||
Macro Use with
|
||||
-------- ---------------------------------------------------------------
|
||||
ORDATA Scalar with octal display/entry
|
||||
DRDATA Scalar with decimal display/entry
|
||||
HRDATA Scalar with hexadecimal display/entry
|
||||
FLDATA Scalar with single bit display/entry
|
||||
GRDATA Scalar with with specification of radix/width/offset parameters
|
||||
|
||||
BRDATA Singly-subscripted array
|
||||
CRDATA Doubly-subscripted array
|
||||
|
||||
SRDATA Singly-subscripted array of general structure fields
|
||||
URDATA Singly-subscripted array of UNIT structure fields
|
||||
|
||||
XRDATA Generic type with specification of all parameters
|
||||
SAVEDATA Generic type used only for persistence across SAVE/RESTORE
|
||||
|
||||
Normally, scalar and array locations specify the variable name; the names are
|
||||
converted internally to pointers as needed. However, the starting point of
|
||||
a partial array may be specified by passing a pointer to the desired element.
|
||||
For example:
|
||||
|
||||
BRDATA (SYM, array, ...)
|
||||
|
||||
...specifies a register starting with array element zero, while:
|
||||
|
||||
BRDATA (SYM, &array[3], ...)
|
||||
|
||||
...specifies a register starting with array element three.
|
||||
|
||||
For arrays of general structures, the names of the array and selected field
|
||||
are given:
|
||||
|
||||
SRDATA (SYM, array, field, ...)
|
||||
|
||||
This specifies a arrayed register whose elements are array[0].field,
|
||||
array[1].field, etc.
|
||||
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. The "RegCheck" macro is used to ensure that each of the user macros has
|
||||
the correct number of parameters. This improves maintenance reliability,
|
||||
as changes to the REG structure need to be reflected only in the
|
||||
"RegCheck" macro.
|
||||
|
||||
2. "Stringization" must occur at the first macro call level to support
|
||||
register names that are themselves macros. Otherwise, macro expansion
|
||||
will occur before stringization, resulting in the wrong register name.
|
||||
|
||||
3. Additional REG initialization values may be supplied after a macro
|
||||
invocation. If present, these begin with the "flags" field.
|
||||
|
||||
4. The URDATA macro is obsolescent and present for backward-compatibility.
|
||||
It is a special case of the generic SRDATA macro, which provides the same
|
||||
functionality. Note also that URDATA requires a "flags" parameter value,
|
||||
which is optional for all other macros.
|
||||
|
||||
5. The SAVEDATA macro is useful to indicate global variables whose values
|
||||
must persist across a SAVE and RESTORE. Such data is hidden from the
|
||||
register user interface.
|
||||
*/
|
||||
|
||||
#define RegCheck(nm,loc,rdx,wd,off,dep,siz,str) \
|
||||
nm, (loc), (rdx), (wd), (off), (dep), (siz), (str)
|
||||
|
||||
#define ORDATA(nm,loc,wd) RegCheck (#nm, &(loc), 8, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define DRDATA(nm,loc,wd) RegCheck (#nm, &(loc), 10, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define HRDATA(nm,loc,wd) RegCheck (#nm, &(loc), 16, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define FLDATA(nm,loc,off) RegCheck (#nm, &(loc), 2, 1, (off), 1, sizeof (loc), 0)
|
||||
#define GRDATA(nm,loc,rdx,wd,off) RegCheck (#nm, &(loc), (rdx), (wd), (off), 1, sizeof (loc), 0)
|
||||
|
||||
#define BRDATA(nm,aloc,rdx,wd,dep) RegCheck (#nm, (aloc), (rdx), (wd), 0, (dep), sizeof *(aloc), sizeof *(aloc))
|
||||
#define CRDATA(nm,aloc,rdx,wd,dep) RegCheck (#nm, (aloc), (rdx), (wd), 0, (dep), sizeof **(aloc), sizeof **(aloc))
|
||||
|
||||
#define SRDATA(nm,aloc,floc,rdx,wd,off,dep) \
|
||||
RegCheck (#nm, &((aloc)->floc), (rdx), (wd), (off), (dep), \
|
||||
sizeof ((aloc)->floc), sizeof (*(aloc)))
|
||||
|
||||
#define XRDATA(nm,loc,rdx,wd,off,dep,siz,str) \
|
||||
RegCheck (#nm, (loc), (rdx), (wd), (off), (dep), (siz), (str))
|
||||
|
||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||
#nm, &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#else
|
||||
#define ORDATA(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1
|
||||
#define DRDATA(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1
|
||||
#define HRDATA(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1
|
||||
#define FLDATA(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1
|
||||
#define GRDATA(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
|
||||
#define VBRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
|
||||
#define SAVEDATA(nm,loc) \
|
||||
"nm", &(loc), 8, 8, 0, sizeof(loc), REG_HRO
|
||||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||||
"nm", &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#endif
|
||||
RegCheck (#nm, &(loc), (rdx), (wd), (off), (dep), \
|
||||
sizeof (loc), sizeof (UNIT)), (fl)
|
||||
|
||||
#define SAVEDATA(nm,loc) RegCheck (#nm, &(loc), 8, 8, 0, sizeof (loc), 1, 1), REG_HRO
|
||||
|
||||
/* Typedefs for principal structures */
|
||||
|
||||
@@ -587,7 +684,41 @@ typedef struct sim_debtab DEBTAB;
|
||||
#include "sim_fio.h"
|
||||
#include "sim_sock.h"
|
||||
|
||||
/* V4 compatibility definitions
|
||||
/* V4 register definitions.
|
||||
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. Unfortunately, the requirement that "stringization" must occur at the
|
||||
first macro call level precludes defining these V4 macros in terms of
|
||||
their V3 equivalents. Hence, the V3 definitions must be repeated here.
|
||||
*/
|
||||
|
||||
#define ORDATAD(nm,loc,wd,desc) RegCheck (#nm, &(loc), 8, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define DRDATAD(nm,loc,wd,desc) RegCheck (#nm, &(loc), 10, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define HRDATAD(nm,loc,wd,desc) RegCheck (#nm, &(loc), 16, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define FLDATAD(nm,loc,off,desc) RegCheck (#nm, &(loc), 2, 1, (off), 1, sizeof (loc), 0)
|
||||
#define GRDATAD(nm,loc,rdx,wd,off,desc) RegCheck (#nm, &(loc), (rdx), (wd), (off), 1, sizeof (loc), 0)
|
||||
#define BRDATAD(nm,loc,rdx,wd,dep,desc) RegCheck (#nm, (loc), (rdx), (wd), 0, (dep), \
|
||||
sizeof *(loc), sizeof *(loc))
|
||||
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) RegCheck (#nm, &(loc), (rdx), (wd), (off), (dep), \
|
||||
sizeof (loc), sizeof (UNIT)), (fl)
|
||||
|
||||
#define ORDATADF(nm,loc,wd,desc,flds) RegCheck (#nm, &(loc), 8, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define DRDATADF(nm,loc,wd,desc,flds) RegCheck (#nm, &(loc), 10, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define HRDATADF(nm,loc,wd,desc,flds) RegCheck (#nm, &(loc), 16, (wd), 0, 1, sizeof (loc), 0)
|
||||
#define FLDATADF(nm,loc,off,desc,flds) RegCheck (#nm, &(loc), 2, 1, (off), 1, sizeof (loc), 0)
|
||||
#define GRDATADF(nm,loc,rdx,wd,off,desc,flds) RegCheck (#nm, &(loc), (rdx), (wd), (off), 1, sizeof (loc), 0)
|
||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc,flds) RegCheck (#nm, (loc), (rdx), (wd), 0, (dep), \
|
||||
sizeof *(loc), sizeof *(loc))
|
||||
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc,flds) RegCheck (#nm, &(loc), (rdx), (wd), (off), (dep), \
|
||||
sizeof (loc), sizeof (UNIT)), (fl)
|
||||
|
||||
#ifndef INT64_C
|
||||
#define INT64_C(x) (x##LL)
|
||||
#endif
|
||||
|
||||
/* V4 compatibility definitions.
|
||||
|
||||
The SCP API for version 4.0 introduces a number of "pointer-to-const"
|
||||
parameter qualifiers that were not present in the 3.x versions. To maintain
|
||||
@@ -596,46 +727,6 @@ typedef struct sim_debtab DEBTAB;
|
||||
when compiling for SIMH 3.x.
|
||||
*/
|
||||
|
||||
#if defined (__STDC__) || defined (_WIN32)
|
||||
#define ORDATAD(nm,loc,wd,desc) #nm, &(loc), 8, (wd), 0, 1
|
||||
#define DRDATAD(nm,loc,wd,desc) #nm, &(loc), 10, (wd), 0, 1
|
||||
#define HRDATAD(nm,loc,wd,desc) #nm, &(loc), 16, (wd), 0, 1
|
||||
#define FLDATAD(nm,loc,pos,desc) #nm, &(loc), 2, 1, (pos), 1
|
||||
#define GRDATAD(nm,loc,rdx,wd,pos,desc) #nm, &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATAD(nm,loc,rdx,wd,dep,desc) #nm, (loc), (rdx), (wd), 0, (dep)
|
||||
#define URDATAD(nm,loc,rdx,wd,off,dep,fl,desc) \
|
||||
#nm, &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#define ORDATADF(nm,loc,wd,desc) #nm, &(loc), 8, (wd), 0, 1
|
||||
#define DRDATADF(nm,loc,wd,desc) #nm, &(loc), 10, (wd), 0, 1
|
||||
#define HRDATADF(nm,loc,wd,desc) #nm, &(loc), 16, (wd), 0, 1
|
||||
#define FLDATADF(nm,loc,pos,desc) #nm, &(loc), 2, 1, (pos), 1
|
||||
#define GRDATADF(nm,loc,rdx,wd,pos,desc) #nm, &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATADF(nm,loc,rdx,wd,dep,desc) #nm, (loc), (rdx), (wd), 0, (dep)
|
||||
#define URDATADF(nm,loc,rdx,wd,off,dep,fl,desc) \
|
||||
#nm, &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#else
|
||||
#define ORDATAD(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1
|
||||
#define DRDATAD(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1
|
||||
#define HRDATAD(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1
|
||||
#define FLDATAD(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1
|
||||
#define GRDATAD(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATAD(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
|
||||
#define URDATAD(nm,loc,rdx,wd,off,dep,fl) \
|
||||
"nm", &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#define ORDATADF(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1
|
||||
#define DRDATADF(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1
|
||||
#define HRDATADF(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1
|
||||
#define FLDATADF(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1
|
||||
#define GRDATADF(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1
|
||||
#define BRDATADF(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
|
||||
#define URDATADF(nm,loc,rdx,wd,off,dep,fl) \
|
||||
"nm", &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||||
#endif
|
||||
|
||||
#ifndef INT64_C
|
||||
#define INT64_C(x) (x##LL)
|
||||
#endif
|
||||
|
||||
#ifdef PF_USER
|
||||
#undef PF_USER
|
||||
#endif /* PF_USER */
|
||||
|
||||
93
sim_rev.h
93
sim_rev.h
@@ -1,6 +1,6 @@
|
||||
/* sim_rev.h: simulator revisions and current rev level
|
||||
|
||||
Copyright (c) 1993-2020, Robert M Supnik
|
||||
Copyright (c) 1993-2021, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@@ -28,19 +28,60 @@
|
||||
#define _SIM_REV_H_ 0
|
||||
|
||||
#define SIM_MAJOR 3
|
||||
#define SIM_MINOR 11
|
||||
#define SIM_MINOR 12
|
||||
#define SIM_PATCH 2
|
||||
#define SIM_DELTA 0
|
||||
|
||||
/* V3.11 revision history
|
||||
/* V3.12 revision history
|
||||
|
||||
V3.11 incorporates SCP additions and extensions by Dave Bryan to support his
|
||||
HP simulators.
|
||||
V3.12 incorporates a major rework of the register sizing macros and access
|
||||
logic by Dave Bryan.
|
||||
|
||||
patch date module(s) and fix(es)
|
||||
|
||||
2 tbd scp.h
|
||||
2 26-Mar-2022 sim_defs.h, scp.c
|
||||
- deprecated UNIT_RAW, UNIT_TEXT
|
||||
- dropped non-C_STD string support
|
||||
|
||||
sim_tape.h, sim_tape.c
|
||||
- added extended tape format (Dave Bryan)
|
||||
|
||||
all magtape simulators
|
||||
- added extra case points for new MTSE definitions
|
||||
|
||||
pdp11_kg.c
|
||||
- fixed bug in repeated operations (Paul Koning)
|
||||
|
||||
pdp11_rq.c
|
||||
- added additional disk types
|
||||
|
||||
pdp8_fpp.c
|
||||
- fix fencepost error in FP multiply extended precision (Rick Murphy)
|
||||
|
||||
1 01-Nov-2021 scp.c
|
||||
- fixed bugs in ID and search on PDP11, VAX, etc.
|
||||
|
||||
sim_tape.c, sim_tape.h (Dave Bryan)
|
||||
- added sim_tape_erase routine
|
||||
- improved tape_erase_fwd corrupt image error checking
|
||||
|
||||
pdp11_cpumod.c, pdp11_cpumod.h
|
||||
- added MMU as settable option to 11/23, 11/40, 11/45
|
||||
|
||||
pdp8_cpu.c
|
||||
- fixed bug in reporting device conflicts (Hans-Bernd Eggenstein)
|
||||
|
||||
pdp8_fpp.c
|
||||
- added DEVNO reporting
|
||||
|
||||
pdp8_ttx.c
|
||||
- added DEVNO reporting from V4
|
||||
|
||||
0 15-Jun-2021 scp.h
|
||||
- changed sim_vm_init to build time option (Dave Bryan)
|
||||
- changed register structure to separate access size from display size (Dave Bryan)
|
||||
- added maximum value to register structure (Dave Bryan)
|
||||
- added UNIT_PIPE dynamic flag (Dave Bryan)
|
||||
|
||||
scp.c
|
||||
- changed sim_vm_init to build time option (Dave Bryan)
|
||||
@@ -48,16 +89,31 @@ patch date module(s) and fix(es)
|
||||
- flush terminal line logs at return from simulation (Dave Bryan)
|
||||
- close terminal line logs at exit from simulator (Dave Bryan)
|
||||
- fixed RUN problem if CPU reset clears PC (Mark Pizzolato)
|
||||
- separated register access size from display size (Dave Bryan)
|
||||
- added maximum value for register input (Dave Bryan)
|
||||
- added support for pipes as sequential IO sources (Dave Bryan)
|
||||
|
||||
sim_tmxr.h, sim_tmxr.c
|
||||
- added capability to flush/close log files (Dave Bryan)
|
||||
|
||||
i1401_defs.h, i1401_cpu.c
|
||||
- added maximum value for address registers
|
||||
|
||||
i1620_defs.h, i1620_cpu.c
|
||||
- added maximum value for address registers
|
||||
|
||||
i7094_mt.c
|
||||
- replaced dynamic buffer allocation with static (Mark Pizzolato)
|
||||
|
||||
nova_cpu.c
|
||||
- fixed bug in history handling of C bit (Samuel Deutsch)
|
||||
|
||||
pdp10_tu.c
|
||||
- fixed bad macro (Mark Pizzolato)
|
||||
|
||||
pdp11_cpumod.h
|
||||
- added MMU as settable option to 11/23, 11/40, 11/45
|
||||
|
||||
pdp11_cpumod.c
|
||||
- fixed KDJ11E programmable rate select (Paul Koning)
|
||||
|
||||
@@ -67,6 +123,19 @@ patch date module(s) and fix(es)
|
||||
pdp18b_dr15.c
|
||||
- zero out shared section on initial allocate (Dave Bryan)
|
||||
|
||||
pdp18b_dt.c, pdp18b_rf.c
|
||||
- fixed bug if read overwrites WC memory location
|
||||
|
||||
pdp8_clk.c
|
||||
- added diagnostic mode for timing dependency in TSS/8
|
||||
|
||||
pdp8_df.c, pdp8_dt.c, pdpd8_rf.c
|
||||
- fixed bug if read overwrites WC memory location
|
||||
|
||||
pdp8_sys.c
|
||||
- fixed treatment of RUBOUT in binary loader (Mark Pizzolato)
|
||||
- fixed decoding of RF/DF and LP intructions
|
||||
|
||||
s3_sys.c
|
||||
- fixed bldaddr length (Mark Pizzolatto)
|
||||
|
||||
@@ -76,20 +145,30 @@ patch date module(s) and fix(es)
|
||||
sds_cr.c, sds_cp.c
|
||||
- New devices (Ken Rector)
|
||||
|
||||
sds_cpu.c, sds_mt.c, sds_rad.c
|
||||
- Added C register support (Ken Rector)
|
||||
|
||||
sds_io.c
|
||||
- TOP disconnects the channel rather than setting CHF_EOR
|
||||
- Fixed overrun/underrun handling in single-word IO
|
||||
|
||||
sds_stddev.c
|
||||
- TTO recognizes no leader flag (Ken Rector)
|
||||
- Added C register support to PTR boot (Ken Rector)
|
||||
|
||||
sds_sys.c
|
||||
- Fixed handling of SDS character value 060 (Ken Rector)
|
||||
- Addec card reader and punch (Ken Rector)
|
||||
- Added card reader and punch (Ken Rector)
|
||||
- Added C register support to loader (Ken Rector)
|
||||
|
||||
vax_cpu.c
|
||||
- added idle test for VMS 5.0/5.1 (Mark Pizzolato)
|
||||
|
||||
/* V3.11 revision history
|
||||
|
||||
V3.11 incorporates SCP additions and extensions by Dave Bryan to support his
|
||||
HP simulators.
|
||||
|
||||
1 31-Mar-2020 scp.c and sim_tmxr_c
|
||||
- new extensions to support HP simulators
|
||||
- added SET <dev|unit> APPEND command
|
||||
|
||||
Reference in New Issue
Block a user