mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-21 10:12:30 +00:00
Merge branch 'master' of http://github.com/rcornwell/sims
This commit is contained in:
commit
252dff6ec7
247
PDP10/ks10_rp.c
247
PDP10/ks10_rp.c
@ -119,7 +119,7 @@
|
||||
#define CS2_DLT 0100000 /* data late NI */
|
||||
|
||||
/* RPDS - 176712 - drive status */
|
||||
#define STATUS us9
|
||||
#define STATUS us10
|
||||
|
||||
#define DS_DF5 0000001 /* Drive forward 5in/sec */
|
||||
#define DS_DF20 0000002 /* Drive forward 20in/sec */
|
||||
@ -163,17 +163,27 @@
|
||||
#define AS_U0 0000001 /* unit 0 flag */
|
||||
|
||||
/* RPLA - 176720 - look ahead register */
|
||||
#define LA_REG us9
|
||||
#define LA_V_SC 6 /* sector pos */
|
||||
#define LA_REG u6
|
||||
#define LA_V_SC 6 /* sector pos */
|
||||
|
||||
/* RPDB - 176722 - data buffer */
|
||||
|
||||
#define OF_HCI 0002000 /* hdr cmp inh NI */
|
||||
#define OF_ECI 0004000 /* ECC inhibit NI */
|
||||
#define OF_F22 0010000 /* format NI */
|
||||
#define OF_HCI 0002000 /* hdr cmp inh NI */
|
||||
#define OF_ECI 0004000 /* ECC inhibit NI */
|
||||
#define OF_F22 0010000 /* format NI */
|
||||
#define OF_MBZ 0161400
|
||||
|
||||
/* RPMR - 176724 - maintenace register */
|
||||
#define PMR_DMD 0000001 /* Enable Diag mode */
|
||||
#define PMR_DCLK 0000002 /* Diag Data Clock */
|
||||
#define PMR_DIND 0000004 /* Diag Index Pulse */
|
||||
#define PMR_DSCK 0000010 /* Diag Sector Clock */
|
||||
#define PMR_DRDD 0000020 /* Diag Read Data */
|
||||
#define PMR_DWRD 0000040 /* Diag Write Data */
|
||||
#define PMR_ECE 0000100 /* In ECE field */
|
||||
#define PMR_DFE 0000200 /* In Data Field */
|
||||
#define PMR_ZD 0000400 /* After ECE field */
|
||||
#define PMR_MSK 0000037 /* Mask bits in PMR */
|
||||
|
||||
/* RPDT - 176726 - drive type */
|
||||
|
||||
@ -182,11 +192,17 @@
|
||||
|
||||
/* us10 */
|
||||
/* RPOF - 176732 - offset register */
|
||||
|
||||
#define RPOF_OFF 0000077 /* Offset value */
|
||||
#define RPOF_OFNU 0000100
|
||||
#define RPOF_OFD 0000200 /* Offset direction */
|
||||
#define RPOF_HCI 0002000 /* Head compare inhibited */
|
||||
#define RPOF_ECI 0004000 /* Error correct inhibit */
|
||||
#define RPOF_FMT22 0010000 /* Format 22/20 sectors */
|
||||
#define RPOF_SCG 0100000 /* Sign change */
|
||||
/* u4 low */
|
||||
/* RPDC - 176734 - desired cylinder */
|
||||
#define DC_V_CY 0 /* cylinder pos */
|
||||
#define DC_M_CY 01777 /* cylinder mask */
|
||||
#define DC_V_CY 0 /* cylinder pos */
|
||||
#define DC_M_CY 01777 /* cylinder mask */
|
||||
#define DC_MBZ 0176000
|
||||
#define GET_CY(x) (((x) >> DC_V_CY) & DC_M_CY)
|
||||
#define GET_DA(c,d) ((((GET_CY (c) * rp_drv_tab[d].surf) + GET_SF (c)) \
|
||||
@ -202,7 +218,7 @@
|
||||
//#define ERR3 us10
|
||||
|
||||
|
||||
#define DATAPTR u6
|
||||
#define DATAPTR us9
|
||||
/* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||
/* RPEC2 - 176746 - ECC status 2 - unimplemented */
|
||||
|
||||
@ -214,6 +230,8 @@
|
||||
type #sectors/ #surfaces/ #cylinders/
|
||||
surface cylinder drive
|
||||
|
||||
RM03 30 5 823 =67MB
|
||||
RM05 30 19 823 =256MB
|
||||
RP04/5 20 19 411 =88MB
|
||||
RP06 20 19 815 =176MB
|
||||
RP07 43 32 630 =516MB
|
||||
@ -246,6 +264,20 @@
|
||||
#define RP07_DEV 020042
|
||||
#define RP07_SIZE (RP07_SECT * RP07_SURF * RP07_CYL * RP_NUMWD)
|
||||
|
||||
#define RM03_DTYPE 3
|
||||
#define RM03_SECT 30
|
||||
#define RM03_SURF 5
|
||||
#define RM03_CYL 823
|
||||
#define RM03_DEV 020024
|
||||
#define RM03_SIZE (RM03_SECT * RM03_SURF * RM03_CYL * RP_NUMWD)
|
||||
|
||||
#define RM05_DTYPE 4
|
||||
#define RM05_SECT 30
|
||||
#define RM05_SURF 19
|
||||
#define RM05_CYL 823
|
||||
#define RM05_DEV 020027
|
||||
#define RM05_SIZE (RM05_SECT * RM05_SURF * RM05_CYL * RP_NUMWD)
|
||||
|
||||
struct drvtyp {
|
||||
int32 sect; /* sectors */
|
||||
int32 surf; /* surfaces */
|
||||
@ -258,6 +290,8 @@ struct drvtyp rp_drv_tab[] = {
|
||||
{ RP04_SECT, RP04_SURF, RP04_CYL, RP04_SIZE, RP04_DEV },
|
||||
{ RP06_SECT, RP06_SURF, RP06_CYL, RP06_SIZE, RP06_DEV },
|
||||
{ RP07_SECT, RP07_SURF, RP07_CYL, RP07_SIZE, RP07_DEV },
|
||||
{ RM03_SECT, RM03_SURF, RM03_CYL, RM03_SIZE, RM03_DEV },
|
||||
{ RM05_SECT, RM05_SURF, RM05_CYL, RM05_SIZE, RM05_DEV },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
@ -265,6 +299,7 @@ struct drvtyp rp_drv_tab[] = {
|
||||
int rp_write(t_addr addr, uint16 data, int32 access);
|
||||
int rp_read(t_addr addr, uint16 *data, int32 access);
|
||||
uint16 rp_vect(struct pdp_dib *dibp);
|
||||
void rp_setattn(UNIT *uptr);
|
||||
|
||||
t_stat rp_svc(UNIT *);
|
||||
t_stat rp_boot(int32, DEVICE *);
|
||||
@ -278,10 +313,14 @@ t_stat rp_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
|
||||
const char *rp_description (DEVICE *dptr);
|
||||
uint64 rp_buf[RP_NUMWD];
|
||||
uint16 rp_wc;
|
||||
uint16 rp_db;
|
||||
uint16 rp_dba;
|
||||
uint16 rp_dbb;
|
||||
t_addr rp_ba;
|
||||
uint16 rp_cs2;
|
||||
uint8 rp_ie;
|
||||
uint16 rp_err2;
|
||||
uint16 rp_err3;
|
||||
uint16 rp_rmr[NUM_UNITS_RP];
|
||||
|
||||
|
||||
UNIT rpa_unit[] = {
|
||||
@ -313,6 +352,8 @@ MTAB rp_mod[] = {
|
||||
{UNIT_DTYPE, (RP07_DTYPE << UNIT_V_DTYPE), "RP07", "RP07", &rp_set_type },
|
||||
{UNIT_DTYPE, (RP06_DTYPE << UNIT_V_DTYPE), "RP06", "RP06", &rp_set_type },
|
||||
{UNIT_DTYPE, (RP04_DTYPE << UNIT_V_DTYPE), "RP04", "RP04", &rp_set_type },
|
||||
{UNIT_DTYPE, (RM03_DTYPE << UNIT_V_DTYPE), "RM03", "RM03", &rp_set_type },
|
||||
{UNIT_DTYPE, (RM05_DTYPE << UNIT_V_DTYPE), "RM05", "RM05", &rp_set_type },
|
||||
{MTAB_XTD|MTAB_VUN, 0, "FORMAT", "FORMAT", NULL, &disk_show_fmt },
|
||||
{MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "addr", "addr", &uba_set_addr, uba_show_addr,
|
||||
NULL, "Sets address of RH11" },
|
||||
@ -353,6 +394,11 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
/* u3 low */
|
||||
case 000: /* RPC - 176700 - control */
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o Status=%06o\n", rp_unit, uptr->CMD);
|
||||
if (rp_cs2 & CS2_PAT) {
|
||||
uba_set_parity(rpa_dib.uba_ctl);
|
||||
uptr->CMD |= (ER1_PAR << 16);
|
||||
break;
|
||||
}
|
||||
if (access == BYTE && addr & 1)
|
||||
break;
|
||||
|
||||
@ -365,9 +411,12 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
return 0;
|
||||
}
|
||||
rp_ba = ((data << 8) & 0600000) | (rp_ba & 0177777);
|
||||
uptr->CMD = data & 076;
|
||||
uptr->CMD &= ~077;
|
||||
uptr->CMD |= data & 076;
|
||||
/* Check if GO bit set */
|
||||
if ((data & 1) == 0) {
|
||||
if (data & CS1_TRE)
|
||||
rp_cs2 &= (CS2_IR|CS2_OR|CS2_UAI|CS2_PAT|CS2_UNIT);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o no go %06o\n", rp_unit, data);
|
||||
return 0; /* No, nop */
|
||||
}
|
||||
@ -376,37 +425,65 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
return 0; /* No, nop */
|
||||
}
|
||||
uba_clr_irq(&rpa_dib);
|
||||
uptr->CMD &= 0777;
|
||||
switch (GET_FNC(data)) {
|
||||
case FNC_NOP:
|
||||
break;
|
||||
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
uptr->DA &= ~0177777;
|
||||
uptr->STATUS |= DS_PIP;
|
||||
uptr->CMD |= CS1_GO;
|
||||
break;
|
||||
|
||||
case FNC_SEEK: /* seek */
|
||||
if (GET_FNC(data) == FNC_SEEK &&
|
||||
GET_CY(uptr->DA) == (uptr->CCYL & 01777)) {
|
||||
uptr->STATUS |= DS_ATA;
|
||||
rp_setattn(uptr);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case FNC_SEARCH: /* search */
|
||||
if (rp_rmr[rp_unit] & 1) {
|
||||
int sect = rp_drv_tab[dtype].sect;
|
||||
if (GET_CY(uptr->DA) != (uptr->CCYL & 01777)) {
|
||||
uptr->STATUS |= DS_PIP;
|
||||
}
|
||||
uptr->CCYL = (uptr->CCYL & (0177777 << 16)) | GET_CY(uptr->DA);
|
||||
if ((uptr->CCYL & (RPOF_FMT22 << 16)) != 0)
|
||||
sect += 2;
|
||||
if ((GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) ||
|
||||
(GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) ||
|
||||
(GET_SC(uptr->DA) >= sect)) {
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
rp_setattn(uptr);
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if ((GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl) ||
|
||||
(GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) ||
|
||||
(GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect)) {
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
rp_setattn(uptr);
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
|
||||
case FNC_RETURN: /* return to center */
|
||||
case FNC_OFFSET: /* offset */
|
||||
case FNC_UNLOAD: /* unload */
|
||||
/* Fall through */
|
||||
|
||||
case FNC_SEARCH: /* search */
|
||||
case FNC_SEEK: /* seek */
|
||||
case FNC_WCHK: /* write check */
|
||||
case FNC_WRITE: /* write */
|
||||
case FNC_WRITEH: /* write w/ headers */
|
||||
case FNC_READ: /* read */
|
||||
case FNC_READH: /* read w/ headers */
|
||||
uptr->STATUS |= DS_PIP;
|
||||
|
||||
if (GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl ||
|
||||
GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf) {
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
uptr->STATUS |= DS_ATA;
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
break;
|
||||
if (GET_CY(uptr->DA) != (uptr->CCYL & 01777)) {
|
||||
uptr->STATUS |= DS_PIP;
|
||||
}
|
||||
|
||||
if (GET_FNC(data) >= FNC_XFER)
|
||||
rp_ie |= CSX_BUSY;
|
||||
uptr->CMD |= CS1_GO;
|
||||
@ -419,6 +496,8 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
uptr->STATUS &= DS_VV;
|
||||
uptr->DA &= 003400177777;
|
||||
uptr->CCYL &= 0177777;
|
||||
rp_rmr[rp_unit] = 0;
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
break;
|
||||
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
@ -436,10 +515,11 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
uptr->CMD |= (ER1_ILF << 16);
|
||||
}
|
||||
if (GET_FNC(data) >= FNC_XFER)
|
||||
uptr->STATUS &= (DS_VV);
|
||||
if (uptr->CMD & CS1_GO)
|
||||
uptr->STATUS &= (DS_VV|DS_PIP);
|
||||
rp_cs2 &= (CS2_IR|CS2_OR|CS2_UAI|CS2_PAT|CS2_UNIT);
|
||||
if ((uptr->CMD & CS1_GO) != 0 && ((rp_rmr[rp_unit] & 1) == 0))
|
||||
sim_activate(uptr, 1000);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o AStatus=%06o\n", rp_unit, uptr->CMD);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o AStatus=%06o %06o %06o\n", rp_unit, uptr->CMD, rp_cs2, uptr->STATUS);
|
||||
break;
|
||||
case 002: /* RPWC - 176702 - word count */
|
||||
if ((rp_ie & (CSX_BUSY)) != 0) {
|
||||
@ -483,21 +563,19 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
break;
|
||||
|
||||
case 010: /* RPCS2 - 176710 - Control and Status register 2 */
|
||||
// if ((rp_ie & (CSX_BUSY)) != 0) {
|
||||
// uptr->CMD |= (ER1_RMR << 16);
|
||||
// sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
|
||||
// addr & 077, data);
|
||||
// return 0;
|
||||
// }
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | (rp_cs2 & 0377);
|
||||
}
|
||||
rp_cs2 = (CS2_UAI|CS2_PAT|07) & data;
|
||||
rp_cs2 = ((CS2_DLT|CS2_WCE|CS2_NED|CS2_NEM|CS2_PGE|CS2_MDPE) & rp_cs2) |
|
||||
((CS2_UAI|CS2_PAT|CS2_UNIT) & data);
|
||||
if (data & CS2_CLR) {
|
||||
rp_reset(&rpa_dev);
|
||||
}
|
||||
rp_cs2 |= CS2_IR;
|
||||
rp_unit = rp_cs2 & 07;
|
||||
if (rpa_unit[rp_cs2 & CS2_UNIT].flags & UNIT_DIS)
|
||||
rp_cs2 |= CS2_NED;
|
||||
break;
|
||||
|
||||
case 012: /* RPDS - 176712 - drive status */
|
||||
@ -525,21 +603,45 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
}
|
||||
break;
|
||||
|
||||
case 020: /* RPLA - 176720 - look ahead register */
|
||||
case 024: /* RPMR - 176724 - maintenace register */
|
||||
/* LA_REG has 10 bits for position in sector */
|
||||
if (data & 1) {
|
||||
if ((data & 076) == 0) {
|
||||
if (rp_rmr[rp_unit] & 010)
|
||||
uptr->LA_REG ++;
|
||||
if (rp_rmr[rp_unit] & 04)
|
||||
uptr->LA_REG = 0;
|
||||
}
|
||||
rp_rmr[rp_unit] = data;
|
||||
} else
|
||||
rp_rmr[rp_unit] = 0;
|
||||
break;
|
||||
case 020: /* RPLA - 176720 - look ahead register */
|
||||
case 026: /* RPDT - 176726 - drive type */
|
||||
break;
|
||||
case 022: /* RPDB - 176722 - data buffer */
|
||||
rp_db = data;
|
||||
if ((rp_cs2 & CS2_IR) == 0) {
|
||||
rp_cs2 |= CS2_DLT;
|
||||
break;
|
||||
}
|
||||
rp_dba = rp_dbb;
|
||||
rp_dbb = data;
|
||||
if (rp_cs2 & CS2_IR)
|
||||
rp_dba = rp_dbb;
|
||||
rp_cs2 |= CS2_OR;
|
||||
rp_cs2 &= ~CS2_IR;
|
||||
break;
|
||||
/* RPCS2 - 176710 - control/status 2 */
|
||||
case 032: /* RPOF - 176732 - offset register */
|
||||
uptr->CCYL &= 0177777;
|
||||
uptr->CCYL |= data << 16;
|
||||
break;
|
||||
case 034: /* RPDC - 176734 - desired cylinder */
|
||||
if ((uptr->CMD & CS1_GO) != 0) {
|
||||
uptr->CMD |= (ER1_RMR << 16);
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o not ready %02o %06o\n", rp_unit,
|
||||
addr & 077, data);
|
||||
break;
|
||||
}
|
||||
if (access == BYTE) {
|
||||
if (addr & 1)
|
||||
data = data | (uptr->DA & 0377);
|
||||
@ -549,8 +651,12 @@ rp_write(t_addr addr, uint16 data, int32 access) {
|
||||
uptr->DA &= ~0177777;
|
||||
uptr->DA |= data;
|
||||
break;
|
||||
case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
rp_err2 = data;
|
||||
break;
|
||||
case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */
|
||||
rp_err3 = data;
|
||||
break;
|
||||
case 030: /* RPSN - 176730 - serial number */
|
||||
case 036: /* RPCC - 176736 - current cylinder */
|
||||
case 044: /* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||
@ -569,7 +675,6 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
uint16 temp = 0;
|
||||
int i;
|
||||
|
||||
/* RPDB - 176722 - data buffer */
|
||||
switch(addr & 076) {
|
||||
case 000: /* RPC - 176700 - control */
|
||||
temp = uptr->CMD & 077;
|
||||
@ -600,12 +705,10 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
break;
|
||||
case 010: /* RPCS2 - 176710 - control/status 2 */
|
||||
temp = rp_cs2;
|
||||
if (uptr->flags & UNIT_DIS)
|
||||
temp |= CS2_NED;
|
||||
break;
|
||||
case 012: /* RPDS - 176712 - drive status */
|
||||
temp = uptr->STATUS;
|
||||
if (((uptr->CMD >> 16) & 0177777) != 0)
|
||||
if (((uptr->CMD >> 16) & 0177777) != 0 || rp_err2 != 0 || rp_err3 != 0)
|
||||
temp |= DS_ERR;
|
||||
if ((uptr->flags & UNIT_DIS) == 0)
|
||||
temp |= DS_DPR;
|
||||
@ -628,16 +731,26 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
}
|
||||
break;
|
||||
case 020: /* RPLA - 176720 - look ahead register */
|
||||
uptr->LA_REG += 0100;
|
||||
uptr->LA_REG &= 07700;
|
||||
temp = uptr->LA_REG;
|
||||
if ((uptr->LA_REG >> 10) >= 23)
|
||||
uptr->LA_REG = 0;
|
||||
temp = GET_SC(uptr->DA) << 6;
|
||||
temp ^= ((uptr->LA_REG + 1) >> 4) & 07760;
|
||||
if ((rp_rmr[rp_unit] & 1) == 0)
|
||||
uptr->LA_REG+=1024;
|
||||
break;
|
||||
case 022: /* RPDB - 176722 - data buffer */
|
||||
temp = rp_db;
|
||||
if ((rp_cs2 & CS2_OR) == 0) {
|
||||
rp_cs2 |= CS2_DLT;
|
||||
break;
|
||||
}
|
||||
temp = rp_dba;
|
||||
rp_dba = rp_dbb;
|
||||
rp_cs2 &= ~CS2_OR;
|
||||
rp_cs2 |= CS2_IR;
|
||||
break;
|
||||
case 024: /* RPMR - 176724 - maintenace register */
|
||||
if (rp_rmr[rp_unit] & 1)
|
||||
temp = rp_rmr[rp_unit] & PMR_MSK;
|
||||
break;
|
||||
case 026: /* RPDT - 176726 - drive type */
|
||||
temp = rp_drv_tab[GET_DTYPE(uptr->flags)].devtype;
|
||||
@ -649,16 +762,16 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
temp = (uptr->CCYL >> 16) & 0177777;
|
||||
break;
|
||||
case 034: /* RPDC - 176734 - desired cylinder */
|
||||
temp = uptr->DA & 0177777;
|
||||
temp = GET_CY(uptr->DA);
|
||||
break;
|
||||
case 036: /* RPCC - 176736 - current cylinder */
|
||||
temp = uptr->CCYL & 0177777;
|
||||
break;
|
||||
case 040: /* RPER2 - 176740 - error status 2 - drive unsafe conditions */
|
||||
// temp = uptr->ERR2;
|
||||
temp = rp_err2;
|
||||
break;
|
||||
case 042: /* RPER3 - 176742 - error status 3 - more unsafe conditions */
|
||||
// temp = uptr->ERR3;
|
||||
temp = rp_err3;
|
||||
break;
|
||||
case 044: /* RPEC1 - 176744 - ECC status 1 - unimplemented */
|
||||
case 046: /* RPEC2 - 176746 - ECC status 2 - unimplemented */
|
||||
@ -667,6 +780,10 @@ rp_read(t_addr addr, uint16 *data, int32 access) {
|
||||
*data = temp;
|
||||
sim_debug(DEBUG_DETAIL, &rpa_dev, "RP%o read %02o %06o %06o\n", rp_unit,
|
||||
addr & 076, temp, PC);
|
||||
if (rp_cs2 & CS2_PAT) {
|
||||
uba_set_parity(rpa_dib.uba_ctl);
|
||||
uptr->CMD |= (ER1_PAR << 16);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -718,10 +835,8 @@ t_stat rp_svc (UNIT *uptr)
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o seek %d %d\n", dptr->name, unit, cyl, uptr->CCYL);
|
||||
if (cyl >= rp_drv_tab[dtype].cyl) {
|
||||
uptr->STATUS &= ~DS_PIP;
|
||||
// uptr->STATUS |= DS_ATA;
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
// uptr->CMD &= ~CS1_GO;
|
||||
rp_setattn(uptr);
|
||||
sim_activate(uptr, 10);
|
||||
return SCPE_OK;
|
||||
}
|
||||
diff = cyl - (uptr->CCYL & 01777);
|
||||
if (diff < 0) {
|
||||
@ -754,6 +869,7 @@ t_stat rp_svc (UNIT *uptr)
|
||||
}
|
||||
}
|
||||
|
||||
/* Bump sector counter */
|
||||
switch (GET_FNC(uptr->CMD)) {
|
||||
case FNC_NOP:
|
||||
case FNC_DCLR: /* drive clear */
|
||||
@ -769,8 +885,9 @@ t_stat rp_svc (UNIT *uptr)
|
||||
case FNC_PRESET: /* read-in preset */
|
||||
case FNC_RECAL: /* recalibrate */
|
||||
case FNC_SEEK: /* seek */
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf ||
|
||||
GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl)
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
rp_setattn(uptr);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o seekdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
|
||||
@ -778,7 +895,8 @@ t_stat rp_svc (UNIT *uptr)
|
||||
|
||||
case FNC_SEARCH: /* search */
|
||||
if (GET_SC(uptr->DA) >= rp_drv_tab[dtype].sect ||
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf)
|
||||
GET_SF(uptr->DA) >= rp_drv_tab[dtype].surf ||
|
||||
GET_CY(uptr->DA) >= rp_drv_tab[dtype].cyl)
|
||||
uptr->CMD |= (ER1_IAE << 16);
|
||||
rp_setattn( uptr);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o searchdone %d %o\n", dptr->name, unit, cyl, uptr->CMD);
|
||||
@ -863,10 +981,12 @@ t_stat rp_svc (UNIT *uptr)
|
||||
uptr->STATUS |= DS_PIP;
|
||||
}
|
||||
}
|
||||
uptr->LA_REG = GET_SC(uptr->DA) << 10;
|
||||
sim_activate(uptr, 300);
|
||||
return SCPE_OK;
|
||||
}
|
||||
rd_end:
|
||||
uptr->LA_REG = GET_SC(uptr->DA) << 10;
|
||||
sim_debug(DEBUG_DETAIL, dptr, "%s%o read done\n", dptr->name, unit);
|
||||
uptr->CMD &= ~CS1_GO;
|
||||
rp_ie &= ~(CSX_BUSY);
|
||||
@ -951,6 +1071,7 @@ wr_done:
|
||||
}
|
||||
}
|
||||
|
||||
uptr->LA_REG = GET_SC(uptr->DA) << 10;
|
||||
if (sts) {
|
||||
sim_activate(uptr, 300);
|
||||
} else {
|
||||
@ -986,12 +1107,20 @@ rp_reset(DEVICE * dptr)
|
||||
{
|
||||
int i;
|
||||
rp_ba = 0;
|
||||
rp_wc = 0177777;
|
||||
rp_wc = 0;
|
||||
rp_ie = 0;
|
||||
rp_err2 = 0;
|
||||
rp_err3 = 0;
|
||||
rp_cs2 = CS2_IR;
|
||||
for (i = 0; i < 8; i++) {
|
||||
UNIT *u = &rpa_unit[i];
|
||||
u->STATUS &= DS_VV;
|
||||
u->CMD &= 0177776;
|
||||
u->CCYL &= ((OF_HCI|OF_ECI|OF_F22) << 16) | 0177777;
|
||||
if (rp_rmr[i] & 1) {
|
||||
u->CCYL = GET_CY(u->DA) | (((OF_HCI|OF_ECI|OF_F22) << 16) & u->CCYL);
|
||||
}
|
||||
rp_rmr[i] = 0;
|
||||
}
|
||||
uba_clr_irq(&rpa_dib);
|
||||
sim_debug(DEBUG_DETAIL, dptr, "RP reset done\n");
|
||||
|
||||
@ -57,6 +57,11 @@ uba_read(t_addr addr, int ctl, uint64 *data, int access)
|
||||
int i;
|
||||
int ubm = uba_device[ctl];
|
||||
|
||||
if (ctl == 0 && addr == 0100000) {
|
||||
*data = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ubm == -1) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "No UBA adaptor %02o %08o\n", ctl, addr);
|
||||
return 1;
|
||||
@ -101,6 +106,8 @@ uba_read(t_addr addr, int ctl, uint64 *data, int access)
|
||||
uint16 buf;
|
||||
int r = dibp->rd_io(addr, &buf, access);
|
||||
*data = (uint64)buf;
|
||||
if (r)
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
@ -116,6 +123,9 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
int i;
|
||||
int ubm = uba_device[ctl];
|
||||
|
||||
if (ctl == 0 && addr == 0100000) {
|
||||
return 1;
|
||||
}
|
||||
if (ubm == -1) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "No UBA adaptor %02o %08o %012llo\n", ctl, addr, data);
|
||||
return 1;
|
||||
@ -139,8 +149,8 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
return 0;
|
||||
} else if ((addr & 077) == 0) {
|
||||
uba_status[ubm] &= (uint32)(074000 ^ data) | 0746000;
|
||||
uba_status[ubm] |= (uint32)(0277 & data);
|
||||
if (data & 0100) {
|
||||
uba_status[ubm] = 0;
|
||||
for(i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
DIB *dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
@ -150,8 +160,9 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
if (ctl == dibp->uba_ctl)
|
||||
dibp->uba_irq_pend = 0;
|
||||
}
|
||||
clr_interrupt(ctl);
|
||||
clr_interrupt(ctl<<2);
|
||||
}
|
||||
uba_status[ubm] |= (uint32)(0277 & data);
|
||||
return 0;
|
||||
} else if ((addr & 077) == 1) {
|
||||
return 0;
|
||||
@ -166,7 +177,10 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
|
||||
continue;
|
||||
if (ctl == dibp->uba_ctl && dibp->uba_addr == (addr & (~dibp->uba_mask))) {
|
||||
uint16 buf = (uint16)(data & 0177777);
|
||||
return dibp->wr_io(addr, buf, access);
|
||||
int r = dibp->wr_io(addr, buf, access);
|
||||
if (r)
|
||||
uba_status[ubm] |= UBST_TIM | UBST_NED;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "No UBA device write %02o %08o %012llo\n", ctl, addr, data);
|
||||
@ -194,7 +208,7 @@ int
|
||||
uba_write_npr(t_addr addr, uint16 ctl, uint64 data)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
t_addr oaddr = addr;
|
||||
t_addr oaddr = addr;
|
||||
uint32 map = uba_map[ubm][(077) & (addr >> 11)];
|
||||
if ((addr & 0400000) != 0)
|
||||
return 0;
|
||||
@ -349,6 +363,14 @@ uba_get_vect(t_addr addr, int lvl, int *dev, int *new_lvl)
|
||||
return addr;
|
||||
}
|
||||
|
||||
void
|
||||
uba_set_parity(uint16 ctl)
|
||||
{
|
||||
int ubm = uba_device[ctl];
|
||||
if (ubm >= 0)
|
||||
uba_status[ubm] |= UBST_PAR;
|
||||
}
|
||||
|
||||
t_stat
|
||||
uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
|
||||
{
|
||||
|
||||
3087
PDP10/kx10_cpu.c
3087
PDP10/kx10_cpu.c
File diff suppressed because it is too large
Load Diff
@ -298,7 +298,7 @@ extern DEBTAB crd_debug[];
|
||||
#if KI|KL
|
||||
#define PRV_PUB 020000 /* Overflow in excutive mode */
|
||||
#else
|
||||
#define PRV_PUB 000000 /* Not on KA or PDP6 */
|
||||
#define PRV_PUB 000000 /* Not on KA, KS or PDP6 */
|
||||
#endif
|
||||
#ifdef ITS
|
||||
#ifdef PURE
|
||||
@ -551,6 +551,7 @@ int uba_write_npr_word(t_addr addr, uint16 ctl, uint16 data);
|
||||
void uba_set_irq(DIB *dibp);
|
||||
void uba_clr_irq(DIB *dibp);
|
||||
t_addr uba_get_vect(t_addr addr, int lvl, int *dev, int *new_lvl);
|
||||
void uba_set_parity(uint16 ctl);
|
||||
|
||||
t_stat uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc);
|
||||
t_stat uba_show_addr (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
|
||||
|
||||
@ -590,7 +590,7 @@ t_stat load_sav (FILE *fileref, int ftype)
|
||||
wc = (int32)(data >> 18);
|
||||
pa = (uint32) (data & RMASK);
|
||||
if (wc == (OP_JRST << 9)) {
|
||||
printf("Start addr=%06o\n", pa);
|
||||
sim_printf("Start addr=%06o\n", pa);
|
||||
PC = pa;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -809,6 +809,72 @@ display_point(int x, /* 0..xpixels (unscaled) */
|
||||
return lx*lx + ly*ly <= scaled_pen_radius_squared;
|
||||
} /* display_point */
|
||||
|
||||
#define ABS(_X) ((_X) >= 0 ? (_X) : -(_X))
|
||||
#define SIGN(_X) ((_X) >= 0 ? 1 : -1)
|
||||
|
||||
static void
|
||||
xline (int x, int y, int x2, int dx, int dy, int level)
|
||||
{
|
||||
int ix = SIGN(dx);
|
||||
int iy = SIGN(dy);
|
||||
int ay;
|
||||
|
||||
dx = ABS(dx);
|
||||
dy = ABS(dy);
|
||||
|
||||
ay = dy/2;
|
||||
for (;;) {
|
||||
display_point (x, y, level, 0);
|
||||
if (x == x2)
|
||||
break;
|
||||
if (ay > 0) {
|
||||
y += iy;
|
||||
ay -= dx;
|
||||
}
|
||||
ay += dy;
|
||||
x += ix;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
yline (int x, int y, int y2, int dx, int dy, int level)
|
||||
{
|
||||
int ix = SIGN(dx);
|
||||
int iy = SIGN(dy);
|
||||
int ax;
|
||||
|
||||
dx = ABS(dx);
|
||||
dy = ABS(dy);
|
||||
|
||||
ax = dx/2;
|
||||
for (;;) {
|
||||
display_point (x, y, level, 0);
|
||||
if (y == y2)
|
||||
break;
|
||||
if (ax > 0) {
|
||||
x += ix;
|
||||
ax -= dy;
|
||||
}
|
||||
ax += dx;
|
||||
y += iy;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
display_line(int x1, /* 0..xpixels (unscaled) */
|
||||
int y1, /* 0..ypixels (unscaled) */
|
||||
int x2, /* 0..xpixels (unscaled) */
|
||||
int y2, /* 0..ypixels (unscaled) */
|
||||
int level) /* DISPLAY_INT_xxx */
|
||||
{
|
||||
int dx = x2 - x1;
|
||||
int dy = y2 - y1;
|
||||
if (ABS (dx) > ABS(dy))
|
||||
xline (x1, y1, x2, dx, dy, level);
|
||||
else
|
||||
yline (x1, y1, y2, dx, dy, level);
|
||||
} /* display_line */
|
||||
|
||||
/*
|
||||
* calculate decay color table for a phosphor mixture
|
||||
* must be called AFTER refresh_rate initialized!
|
||||
|
||||
@ -112,6 +112,13 @@ extern int display_is_blank(void);
|
||||
*/
|
||||
extern int display_point(int,int,int,int);
|
||||
|
||||
/*
|
||||
* plot a line; arguments are start and end x, y, intensity
|
||||
*
|
||||
* Display initialized on first call.
|
||||
*/
|
||||
extern void display_line(int,int,int,int,int);
|
||||
|
||||
/*
|
||||
* force window system to output bits to screen;
|
||||
* call after adding points, or aging the screen
|
||||
|
||||
20
makefile
20
makefile
@ -358,10 +358,6 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||
INCPATH += $(foreach dir,$(wildcard /usr/local/Cellar/*/*),$(dir)/include)
|
||||
LIBPATH += $(foreach dir,$(wildcard /usr/local/Cellar/*/*),$(dir)/lib)
|
||||
endif
|
||||
ifeq (libXt,$(shell if ${TEST} -d /usr/X11/lib; then echo libXt; fi))
|
||||
LIBPATH += /usr/X11/lib
|
||||
OS_LDFLAGS += -L/usr/X11/lib
|
||||
endif
|
||||
else
|
||||
ifeq (Linux,$(OSTYPE))
|
||||
ifeq (Android,$(shell uname -o))
|
||||
@ -461,12 +457,6 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||
OS_LDFLAGS += -L/usr/pkg/lib -R/usr/pkg/lib
|
||||
OS_CCDEFS += -I/usr/pkg/include
|
||||
endif
|
||||
ifeq (X11R7,$(shell if ${TEST} -d /usr/X11R7/lib; then echo X11R7; fi))
|
||||
LIBPATH += /usr/X11R7/lib
|
||||
INCPATH += /usr/X11R7/include
|
||||
OS_LDFLAGS += -L/usr/X11R7/lib -R/usr/X11R7/lib
|
||||
OS_CCDEFS += -I/usr/X11R7/include
|
||||
endif
|
||||
ifeq (/usr/local/lib,$(findstring /usr/local/lib,${LIBPATH}))
|
||||
INCPATH += /usr/local/include
|
||||
OS_CCDEFS += -I/usr/local/include
|
||||
@ -491,6 +481,16 @@ ifeq (${WIN32},) #*nix Environments (&& cygwin)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq (,$(filter /lib/,$(LIBPATH)))
|
||||
ifeq (existlib,$(shell if $(TEST) -d /lib/; then echo existlib; fi))
|
||||
LIBPATH += /lib/
|
||||
endif
|
||||
endif
|
||||
ifeq (,$(filter /usr/lib/,$(LIBPATH)))
|
||||
ifeq (existusrlib,$(shell if $(TEST) -d /usr/lib/; then echo existusrlib; fi))
|
||||
LIBPATH += /usr/lib/
|
||||
endif
|
||||
endif
|
||||
# Some gcc versions don't support LTO, so only use LTO when the compiler is known to support it
|
||||
ifeq (,$(NO_LTO))
|
||||
ifneq (,$(GCC_VERSION))
|
||||
|
||||
249
scp.c
249
scp.c
@ -311,14 +311,16 @@
|
||||
else *(((uint32 *) mb) + ((uint32) j)) = v;
|
||||
#endif
|
||||
|
||||
#define SIM_DBG_EVENT_NEG 0x01000000 /* negative event dispatch activities */
|
||||
#define SIM_DBG_EVENT 0x02000000 /* event dispatch activities */
|
||||
#define SIM_DBG_ACTIVATE 0x04000000 /* queue insertion activities */
|
||||
#define SIM_DBG_AIO_QUEUE 0x08000000 /* asynch event queue activities */
|
||||
#define SIM_DBG_EXP_STACK 0x10000000 /* expression stack activities */
|
||||
#define SIM_DBG_EXP_EVAL 0x20000000 /* expression evaluation activities */
|
||||
#define SIM_DBG_BRK_ACTION 0x40000000 /* action activities */
|
||||
#define SIM_DBG_DO 0x80000000 /* do activities */
|
||||
#define SIM_DBG_EVENT_NEG 0x80000000 /* negative event dispatch activities */
|
||||
#define SIM_DBG_EVENT 0x40000000 /* event dispatch activities */
|
||||
#define SIM_DBG_ACTIVATE 0x20000000 /* queue insertion activities */
|
||||
#define SIM_DBG_AIO_QUEUE 0x10000000 /* asynch event queue activities */
|
||||
#define SIM_DBG_EXP_STACK 0x08000000 /* expression stack activities */
|
||||
#define SIM_DBG_EXP_EVAL 0x04000000 /* expression evaluation activities */
|
||||
#define SIM_DBG_BRK_ACTION 0x02000000 /* action activities */
|
||||
#define SIM_DBG_DO 0x01000000 /* do activities */
|
||||
#define SIM_DBG_SAVE 0x00800000 /* save activities */
|
||||
#define SIM_DBG_RESTORE 0x00400000 /* restore activities */
|
||||
|
||||
static DEBTAB scp_debug[] = {
|
||||
{"EVENT", SIM_DBG_EVENT, "Event Dispatch Activities"},
|
||||
@ -329,6 +331,8 @@ static DEBTAB scp_debug[] = {
|
||||
{"EXPEVAL", SIM_DBG_EXP_EVAL, "Expression Evaluation Activities"},
|
||||
{"ACTION", SIM_DBG_BRK_ACTION, "If/Breakpoint/Expect Action Activities"},
|
||||
{"DO", SIM_DBG_DO, "Do Command/Expansion Activities"},
|
||||
{"SAVE", SIM_DBG_SAVE, "Save Activities"},
|
||||
{"RESTORE", SIM_DBG_RESTORE, "Restore Activities"},
|
||||
{0}
|
||||
};
|
||||
|
||||
@ -904,26 +908,26 @@ static const char simh_help1[] =
|
||||
" The \"object list\" consists of one or more of the following, separated by\n"
|
||||
" commas:\n\n"
|
||||
/***************** 80 character line width template *************************/
|
||||
"++register the specified register\n"
|
||||
"++register[sub1-sub2] the specified register array locations,\n"
|
||||
"++ starting at location sub1 up to and\n"
|
||||
"++ including location sub2\n"
|
||||
"++register[sub1/length] the specified register array locations,\n"
|
||||
"++ starting at location sub1 up to but\n"
|
||||
"++ not including sub1+length\n"
|
||||
"++register[ALL] all locations in the specified register\n"
|
||||
"++ array\n"
|
||||
"++register1-register2 all the registers starting at register1\n"
|
||||
"++ up to and including register2\n"
|
||||
"++address the specified location\n"
|
||||
"++address1-address2 all locations starting at address1 up to\n"
|
||||
"++ and including address2\n"
|
||||
"++address/length all location starting at address up to\n"
|
||||
"++ but not including address+length\n"
|
||||
"++STATE all registers in the device\n"
|
||||
"++ALL all locations in the unit\n"
|
||||
"++$ the last value displayed by an EXAMINE command\n"
|
||||
" interpreted as an address\n"
|
||||
"++register the specified register\n"
|
||||
"++register[sub1-sub2] the specified register array locations,\n"
|
||||
"++++++++ starting at location sub1 up to and\n"
|
||||
"++++++++ including location sub2\n"
|
||||
"++register[sub1/length] the specified register array locations,\n"
|
||||
"++++++++ starting at location sub1 up to but\n"
|
||||
"++++++++ not including sub1+length\n"
|
||||
"++register[ALL] all locations in the specified register\n"
|
||||
"++++++++ array\n"
|
||||
"++register1-register2 all the registers starting at register1\n"
|
||||
"++++++++ up to and including register2\n"
|
||||
"++address the specified location\n"
|
||||
"++address1-address2 all locations starting at address1 up to\n"
|
||||
"++++++++ and including address2\n"
|
||||
"++address/length all location starting at address up to\n"
|
||||
"++++++++ but not including address+length\n"
|
||||
"++STATE all registers in the device\n"
|
||||
"++ALL all locations in the unit\n"
|
||||
"++$ the last value displayed by an EXAMINE\n"
|
||||
"++++++++ command interpreted as an address\n"
|
||||
"3Switches\n"
|
||||
" Switches can be used to control the format of display information:\n\n"
|
||||
/***************** 80 character line width template *************************/
|
||||
@ -938,17 +942,17 @@ static const char simh_help1[] =
|
||||
" simulator).\n\n"
|
||||
"3Examples\n"
|
||||
" Examples:\n\n"
|
||||
"++ex 1000-1100 examine 1000 to 1100\n"
|
||||
"++de PC 1040 set PC to 1040\n"
|
||||
"++ie 40-50 interactively examine 40:50\n"
|
||||
"++ie >1000 40-50 interactively examine the subset\n"
|
||||
"++ of locations 40:50 that are >1000\n"
|
||||
"++ex rx0 50060 examine 50060, RX unit 0\n"
|
||||
"++ex rx sbuf[3-6] examine SBUF[3] to SBUF[6] in RX\n"
|
||||
"++de all 0 set main memory to 0\n"
|
||||
"++de &77>0 0 set all addresses whose low order\n"
|
||||
"++ bits are non-zero to 0\n"
|
||||
"++ex -m @memdump.txt 0-7777 dump memory to file\n\n"
|
||||
"++ex 1000-1100 examine 1000 to 1100\n"
|
||||
"++de PC 1040 set PC to 1040\n"
|
||||
"++ie 40-50 interactively examine 40:50\n"
|
||||
"++ie >1000 40-50 interactively examine the subset\n"
|
||||
"+++++++++ of locations 40:50 that are >1000\n"
|
||||
"++ex rx0 50060 examine 50060, RX unit 0\n"
|
||||
"++ex rx sbuf[3-6] examine SBUF[3] to SBUF[6] in RX\n"
|
||||
"++de all 0 set main memory to 0\n"
|
||||
"++de &77>0 0 set all addresses whose low order\n"
|
||||
"+++++++++ bits are non-zero to 0\n"
|
||||
"++ex -m @memdump.txt 0-7777 dump memory to file\n\n"
|
||||
" Note: to terminate an interactive command, simply type a bad value\n"
|
||||
" (eg, XYZ) when input is requested.\n"
|
||||
#define HLP_EVALUATE "*Commands Evaluating_Instructions"
|
||||
@ -8064,6 +8068,8 @@ REG *rptr;
|
||||
|
||||
#define WRITE_I(xx) sim_fwrite (&(xx), sizeof (xx), 1, sfile)
|
||||
|
||||
sim_debug(SIM_DBG_SAVE, &sim_scp_dev, "sim_save ()\n");
|
||||
|
||||
/* Don't make changes below without also changing save_vercur above */
|
||||
|
||||
fprintf (sfile, "%s\n%s\n%s\n%s\n%s\n%.0f\n",
|
||||
@ -8090,6 +8096,7 @@ for (i = 0; i < (device_count + sim_internal_device_count); i++) {/* loop thru d
|
||||
dptr = sim_internal_devices[i - device_count];
|
||||
if (dptr->flags & DEV_NOSAVE)
|
||||
continue;
|
||||
sim_debug (SIM_DBG_SAVE, &sim_scp_dev, "Saving %s\n", dptr->name);
|
||||
fputs (dptr->name, sfile); /* device name */
|
||||
fputc ('\n', sfile);
|
||||
if (dptr->lname) /* [V3.0] logical name */
|
||||
@ -8220,7 +8227,7 @@ char **attnames = NULL;
|
||||
UNIT **attunits = NULL;
|
||||
int32 *attswitches = NULL;
|
||||
int32 attcnt = 0;
|
||||
void *mbuf;
|
||||
void *mbuf = NULL;
|
||||
int32 j, blkcnt, limit, unitno, time, flg;
|
||||
uint32 us, depth;
|
||||
t_addr k, high, old_capac;
|
||||
@ -8237,6 +8244,7 @@ t_bool dont_detach_attach = ((sim_switches & SWMASK ('D')) != 0);
|
||||
t_bool suppress_warning = ((sim_switches & SWMASK ('Q')) != 0);
|
||||
t_bool warned = FALSE;
|
||||
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "sim_rest (force=%d, dont_detach=%d, nowarnings=%d)\n", force_restore, dont_detach_attach, suppress_warning);
|
||||
sim_switches &= ~(SWMASK ('F') | SWMASK ('D') | SWMASK ('Q')); /* remove digested switches */
|
||||
#define READ_S(xx) if (read_line ((xx), sizeof(xx), rfile) == NULL) { \
|
||||
r = SCPE_IOERR; \
|
||||
@ -8252,6 +8260,7 @@ if (fstat (fileno (rfile), &rstat)) {
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
READ_S (buf); /* [V2.5+] read version */
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "version=%s\n", buf);
|
||||
v40 = v35 = v32 = FALSE;
|
||||
if (strcmp (buf, save_ver40) == 0) /* version 4.0? */
|
||||
v40 = v35 = v32 = TRUE;
|
||||
@ -8268,6 +8277,7 @@ if ((strcmp (buf, save_ver40) != 0) && (!sim_quiet) && (!suppress_warning)) {
|
||||
warned = TRUE;
|
||||
}
|
||||
READ_S (buf); /* read sim name */
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "sim_name=%s\n", buf);
|
||||
if (strcmp (buf, sim_savename)) { /* name match? */
|
||||
sim_printf ("Wrong system type: %s\n", buf);
|
||||
return SCPE_INCOMP;
|
||||
@ -8326,12 +8336,15 @@ for ( ;; ) { /* device loop */
|
||||
READ_S (buf); /* read device name */
|
||||
if (buf[0] == 0) /* last? */
|
||||
break;
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "DEVICE=%s\n", buf);
|
||||
if ((dptr = find_dev (buf)) == NULL) { /* locate device */
|
||||
sim_printf ("Invalid device name: %s\n", buf);
|
||||
r = SCPE_INCOMP;
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
READ_S (buf); /* [V3.0+] logical name */
|
||||
if (buf[0] != '\0')
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "logical name=%s\n", buf);
|
||||
deassign_device (dptr); /* delete old name */
|
||||
if ((buf[0] != 0) &&
|
||||
((r = assign_device (dptr, buf)) != SCPE_OK)) {
|
||||
@ -8339,6 +8352,7 @@ for ( ;; ) { /* device loop */
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
READ_I (flg); /* [V2.10+] ctlr flags */
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "DEVICE.flags=%0X\n", flg);
|
||||
if (!v32)
|
||||
flg = ((flg & DEV_UFMASK_31) << (DEV_V_UF - DEV_V_UF_31)) |
|
||||
(flg & ~DEV_UFMASK_31); /* [V3.2+] flags moved */
|
||||
@ -8437,36 +8451,34 @@ for ( ;; ) { /* device loop */
|
||||
sim_printf ("\n");
|
||||
}
|
||||
sz = SZ_D (dptr); /* allocate buffer */
|
||||
if ((mbuf = calloc (SRBSIZ, sz)) == NULL) {
|
||||
if ((mbuf = realloc (mbuf, SRBSIZ * sz)) == NULL) {
|
||||
r = SCPE_MEM;
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
for (k = 0; k < high; ) { /* loop thru mem */
|
||||
if (sim_fread (&blkcnt, sizeof (blkcnt), 1, rfile) == 0) {/* block count */
|
||||
free (mbuf);
|
||||
r = SCPE_IOERR;
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
if (blkcnt < 0) /* compressed? */
|
||||
limit = -blkcnt;
|
||||
else limit = (int32)sim_fread (mbuf, sz, blkcnt, rfile);
|
||||
else
|
||||
limit = (int32)sim_fread (mbuf, sz, blkcnt, rfile);
|
||||
if (limit <= 0) { /* invalid or err? */
|
||||
free (mbuf);
|
||||
r = SCPE_IOERR;
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
for (j = 0; j < limit; j++, k = k + (dptr->aincr)) {
|
||||
if (blkcnt < 0) /* compressed? */
|
||||
val = 0;
|
||||
else SZ_LOAD (sz, val, mbuf, j); /* saved value */
|
||||
else
|
||||
SZ_LOAD (sz, val, mbuf, j); /* saved value */
|
||||
r = dptr->deposit (val, k, uptr, SIM_SW_REST);
|
||||
if (r != SCPE_OK) {
|
||||
free (mbuf);
|
||||
goto Cleanup_Return;
|
||||
}
|
||||
} /* end for j */
|
||||
} /* end for k */
|
||||
free (mbuf); /* dealloc buffer */
|
||||
} /* end if high */
|
||||
} /* end unit loop */
|
||||
for ( ;; ) { /* register loop */
|
||||
@ -8474,6 +8486,7 @@ for ( ;; ) { /* device loop */
|
||||
if (buf[0] == 0) /* last? */
|
||||
break;
|
||||
READ_I (depth); /* [V2.10+] depth */
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "REGISTER=%s, depth=%u\n", buf, depth);
|
||||
if ((rptr = find_reg (buf, NULL, dptr)) == NULL) {
|
||||
sim_printf ("Invalid register name: %s %s\n", sim_dname (dptr), buf);
|
||||
for (us = 0; us < depth; us++) { /* skip values */
|
||||
@ -8493,8 +8506,10 @@ for ( ;; ) { /* device loop */
|
||||
if (val > mask) { /* 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);
|
||||
else {
|
||||
if (us < rptr->depth) /* in range? */
|
||||
put_rval(rptr, us, val);
|
||||
}
|
||||
}
|
||||
} /* end register loop */
|
||||
} /* end device loop */
|
||||
@ -8506,6 +8521,7 @@ for (j=0, r = SCPE_OK; j<attcnt; j++) {
|
||||
struct stat fstat;
|
||||
t_addr saved_pos;
|
||||
|
||||
sim_debug (SIM_DBG_RESTORE, &sim_scp_dev, "ATTACHING=%s to %s\n", sim_uname (attunits[j]), attnames[j]);
|
||||
dptr = find_dev_from_unit (attunits[j]);
|
||||
if ((!force_restore) &&
|
||||
(!stat(attnames[j], &fstat)))
|
||||
@ -8539,6 +8555,7 @@ for (j=0, r = SCPE_OK; j<attcnt; j++) {
|
||||
attnames[j] = NULL;
|
||||
}
|
||||
Cleanup_Return:
|
||||
free (mbuf);
|
||||
for (j=0; j < attcnt; j++)
|
||||
free (attnames[j]);
|
||||
free (attnames);
|
||||
@ -9071,6 +9088,7 @@ if (sim_dfunit == NULL) /* got a unit? */
|
||||
return SCPE_NXUN;
|
||||
cptr = get_glyph (cptr, gbuf, 0); /* get list */
|
||||
if ((flag == EX_D) && (*cptr == 0)) /* deposit needs more */
|
||||
|
||||
return SCPE_2FARG;
|
||||
ofile = sim_ofile? sim_ofile: stdout; /* no ofile? use stdout */
|
||||
|
||||
@ -9474,7 +9492,7 @@ if ((rptr->depth > 1) && (rptr->flags & REG_UNIT)) {
|
||||
#endif
|
||||
}
|
||||
else if ((rptr->depth > 1) && (rptr->flags & REG_STRUCT)) {
|
||||
ptr = (uint32 *)(((size_t) rptr->loc) + (idx * rptr->str_size));
|
||||
ptr = (uint32 *)(((size_t)rptr->loc) + (idx * rptr->str_size));
|
||||
#if defined (USE_INT64)
|
||||
if (sz <= sizeof (uint32))
|
||||
*((uint32 *) ptr) = (*((uint32 *) ptr) &
|
||||
@ -15630,6 +15648,127 @@ MClose (f);
|
||||
return stat;
|
||||
}
|
||||
|
||||
typedef const char *(*parse_function)(const char *input, char *output, char end_char);
|
||||
struct function_test_data {
|
||||
char end_char;
|
||||
const char *expected_result;
|
||||
const char *expected_remainder;
|
||||
};
|
||||
static struct parse_function_test {
|
||||
const char *function_name;
|
||||
parse_function function;
|
||||
const char *input;
|
||||
struct function_test_data test_data[10];
|
||||
} parse_function_tests[] = {
|
||||
{"get_glyph", get_glyph, "AbcDe", {
|
||||
{0, "ABCDE", ""} } },
|
||||
{"get_glyph", get_glyph, "AbcDe", {
|
||||
{'c', "AB", "De"},
|
||||
{'c', "DE", ""} } },
|
||||
{"get_glyph", get_glyph, "Ab cde", {
|
||||
{0, "AB", "cde"},
|
||||
{0, "CDE", ""} } },
|
||||
{"get_glyph_nc", get_glyph_nc, "AbcDe", {
|
||||
{0, "AbcDe", ""} } },
|
||||
{"get_glyph_nc", get_glyph_nc, "AbcDe", {
|
||||
{'c', "Ab", "De"},
|
||||
{'c', "De", ""} } },
|
||||
{"get_glyph_nc", get_glyph_nc, "Ab cde", {
|
||||
{0, "Ab", "cde"},
|
||||
{0, "cde", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "AbcDe", {
|
||||
{0, "AbcDe", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "AbcDe", {
|
||||
{'c', "Ab", "De"},
|
||||
{'c', "De", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "Abc De", {
|
||||
{0, "Abc", "De"},
|
||||
{0, "De", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'AbcDe\'",{
|
||||
{0, "\'AbcDe\'", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'AbcDe\'",{
|
||||
{'c', "\'AbcDe\'", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'Abc De\'",{
|
||||
{0, "\'Abc De\'", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\"AbcDe\"",{
|
||||
{0, "\"AbcDe\"", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\"AbcDe\"",{
|
||||
{'c', "\"AbcDe\"", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\"Abc De\"",{
|
||||
{0, "\"Abc De\"", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\"Abc\" De",{
|
||||
{0, "\"Abc\"", "De"},
|
||||
{0, "De", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'Abc\' De",{
|
||||
{'c', "\'Abc\'", "De"},
|
||||
{'c', "De", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'Abc\' \"De\"",{
|
||||
{0, "\'Abc\'", "\"De\""},
|
||||
{'c', "\"De\"", ""} } },
|
||||
{"get_glyph_quoted", get_glyph_quoted, "\'Ab\\c\' \"D\\e\"",{
|
||||
{0, "\'Ab\\c\'", "\"D\\e\""},
|
||||
{'c', "\"D\\e\"", ""} } },
|
||||
{NULL}
|
||||
};
|
||||
|
||||
static t_stat test_scp_parsing (void)
|
||||
{
|
||||
struct parse_function_test *t = parse_function_tests;
|
||||
t_stat result = SCPE_OK;
|
||||
|
||||
if (sim_switches & SWMASK ('T'))
|
||||
sim_messagef (SCPE_OK, "test_scp_parsing - starting\n");
|
||||
while (t->function_name) {
|
||||
struct function_test_data *d = t->test_data;
|
||||
char gbuf[CBUFSIZE + 1];
|
||||
const char *input = t->input;
|
||||
const char *remainder;
|
||||
|
||||
memset (gbuf, 0xFF, sizeof (gbuf));
|
||||
gbuf[sizeof (gbuf) - 1] = '\0';
|
||||
remainder = t->function ("", gbuf, 0);
|
||||
if (*remainder != '\0')
|
||||
return sim_messagef (SCPE_IERR, "function: %s (\"\", gbuf, 0); returned a non empty string: \"%s\"\n", t->function_name, remainder);
|
||||
|
||||
while ((input != NULL) && (*input != '\0')) {
|
||||
char end_char_string[32];
|
||||
|
||||
if (sim_isprint (d->end_char))
|
||||
sprintf (end_char_string, "\'%c\'", d->end_char);
|
||||
else
|
||||
if (d->end_char == '\0')
|
||||
strcpy (end_char_string, "0");
|
||||
else
|
||||
sprintf (end_char_string, "'\\%d'", d->end_char);
|
||||
memset (gbuf, 0xFF, sizeof (gbuf));
|
||||
gbuf[sizeof (gbuf) - 1] = '\0';
|
||||
remainder = t->function (input, gbuf, d->end_char);
|
||||
if (sim_switches & SWMASK ('T'))
|
||||
sim_messagef (SCPE_OK, "%s (\"%s\", gbuf, %s);\n", t->function_name, input, end_char_string);
|
||||
if ((0 != strcmp (gbuf, d->expected_result)) ||
|
||||
(remainder == NULL) || (0 != strcmp (remainder, d->expected_remainder))) {
|
||||
if (0 != strcmp (gbuf, d->expected_result))
|
||||
result = sim_messagef (SCPE_IERR, "function: %s (\"%s\", gbuf, %s); returned an unexpected result string: \"%s\" instead of \"%s\"\n", t->function_name, input, end_char_string, gbuf, d->expected_result);
|
||||
if (remainder == NULL)
|
||||
result = sim_messagef (SCPE_IERR, "function: %s (\"%s\", gbuf, %s); returned a NULL pointer for a remnant instead of \"%s\"\n", t->function_name, input, end_char_string, d->expected_result);
|
||||
else {
|
||||
if (0 != strcmp (remainder, d->expected_remainder))
|
||||
result = sim_messagef (SCPE_IERR, "function: %s (\"%s\", gbuf, %s); returned a remnant of \"%s\" instead of \"%s\"\n", t->function_name, input, end_char_string, remainder, d->expected_result);
|
||||
}
|
||||
remainder = d->expected_result;
|
||||
}
|
||||
input = remainder;
|
||||
++d;
|
||||
if ((*input != '\0') && (d->expected_result == NULL))
|
||||
return sim_messagef (SCPE_IERR, "Invalid test configuration detected\n");
|
||||
}
|
||||
++t;
|
||||
}
|
||||
if (sim_switches & SWMASK ('T'))
|
||||
sim_messagef (SCPE_OK, "test_scp_parsing - done\n");
|
||||
return result;
|
||||
}
|
||||
|
||||
static t_stat sim_scp_svc (UNIT *uptr)
|
||||
{
|
||||
sim_printf ("Unit %s fired at %.0f\n", sim_uname (uptr), sim_gtime ());
|
||||
@ -15756,7 +15895,7 @@ sim_switches = saved_switches;
|
||||
cptr = get_glyph (cptr, gbuf, 0);
|
||||
if (gbuf[0] == '\0')
|
||||
strcpy (gbuf, "ALL");
|
||||
if (strcmp (gbuf, "ALL") != 0) {
|
||||
if ((strcmp (gbuf, "ALL") != 0) && (strcmp (gbuf, "SCP") != 0)) {
|
||||
if (!find_dev (gbuf))
|
||||
return sim_messagef (SCPE_ARG, "No such device: %s\n", gbuf);
|
||||
}
|
||||
@ -15767,8 +15906,12 @@ if (sim_switches & SWMASK ('D')) {
|
||||
sim_set_debon (0, "STDOUT");
|
||||
sim_switches = saved_switches;
|
||||
}
|
||||
if (test_scp_event_sequencing () != SCPE_OK)
|
||||
return sim_messagef (SCPE_IERR, "SCP event sequencing test failed\n");
|
||||
if ((strcmp (gbuf, "ALL") == 0) || (strcmp (gbuf, "SCP") == 0)) {
|
||||
if (test_scp_parsing () != SCPE_OK)
|
||||
return sim_messagef (SCPE_IERR, "SCP parsing test failed\n");
|
||||
if (test_scp_event_sequencing () != SCPE_OK)
|
||||
return sim_messagef (SCPE_IERR, "SCP event sequencing test failed\n");
|
||||
}
|
||||
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
|
||||
t_stat tstat = SCPE_OK;
|
||||
t_bool was_disabled = ((dptr->flags & DEV_DIS) != 0);
|
||||
|
||||
28
sim_fio.c
28
sim_fio.c
@ -319,20 +319,36 @@ return rmdir (pathbuf);
|
||||
/* OS-dependent routines */
|
||||
|
||||
/* Optimized file open */
|
||||
|
||||
FILE *sim_fopen (const char *file, const char *mode)
|
||||
FILE* sim_fopen (const char *file, const char *mode)
|
||||
{
|
||||
FILE *f;
|
||||
char namebuf[PATH_MAX + 1];
|
||||
uint8 *without_quotes = NULL;
|
||||
uint32 dsize = 0;
|
||||
|
||||
if (((*file == '"') && (file[strlen (file) - 1] == '"')) ||
|
||||
((*file == '\'') && (file[strlen (file) - 1] == '\''))) {
|
||||
without_quotes = (uint8*)malloc (strlen (file) + 1);
|
||||
if (without_quotes == NULL)
|
||||
return NULL;
|
||||
if (SCPE_OK != sim_decode_quoted_string (file, without_quotes, &dsize)) {
|
||||
free (without_quotes);
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
file = (const char*)without_quotes;
|
||||
}
|
||||
_sim_expand_homedir (file, namebuf, sizeof (namebuf));
|
||||
#if defined (VMS)
|
||||
return fopen (namebuf, mode, "ALQ=32", "DEQ=4096",
|
||||
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
|
||||
f = fopen (namebuf, mode, "ALQ=32", "DEQ=4096",
|
||||
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
|
||||
#elif (defined (__linux) || defined (__linux__) || defined (__hpux) || defined (_AIX)) && !defined (DONT_DO_LARGEFILE)
|
||||
return fopen64 (namebuf, mode);
|
||||
f = fopen64 (namebuf, mode);
|
||||
#else
|
||||
return fopen (namebuf, mode);
|
||||
f = fopen (namebuf, mode);
|
||||
#endif
|
||||
free (without_quotes);
|
||||
return f;
|
||||
}
|
||||
|
||||
#if !defined (DONT_DO_LARGEFILE)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user