1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-13 15:27:04 +00:00

KA10: Major cleanup of interrupt and floating point code.

Cleanup for compile without ITS or BBN options.
    Cleanup of interrupt handling.
    Floating point code now passes random instruction tests with
     minor off by +/-1 in lower half of long add/subtract instructions.
    RP10 proper handling of not ready flag.
    RP10 no seek interrupts while read/write to other drive.
    TM10 Clean up off by one bits in upper status.
    TM10 Added MT_LASTWD flag to indicate read of last word.
    TM10 Proper handling of Record length error.
    TM10 Added EOR flag.
    TM10 Rewind at BOT now Illegal operation.
    TM10A return channel flags as 1 rather then 0.
    RH10/disk Handle reset CONO flag.
    RH10/disk Generate parity on register read.
    RH10/disk No registers can be modified other then attention when
       one drive is doing read/write operation.
    RH10/disk write register 0 without GO update command.
    RH10/disk command to unready drive return RMR error.
    RH10/disk Search/seek to invalid CHS returns immediate error.
    RH10/RP06 write to error 2 and 3 registers work.
    RH10/disk no seek interrupts set when other drive read/write.
This commit is contained in:
Richard Cornwell 2018-04-02 14:09:31 -04:00
parent 43581c1739
commit f542569227
10 changed files with 492 additions and 330 deletions

View File

@ -174,7 +174,7 @@ char page_fault; /* Page fail */
uint32 ac_stack; /* Register stack pointer */
uint32 pag_reload; /* Page reload pointer */
uint64 fault_data; /* Fault data from last fault */
int trap_flag; /* Last instruction was trapped */
int trap_flag; /* In trap cycle */
int last_page; /* Last page mapped */
int modify; /* Modify cycle */
char xct_flag; /* XCT flags */
@ -201,7 +201,7 @@ uint16 ofa; /* Output fault address */
uint32 qua_time; /* Quantum clock value */
#endif
char dev_irq[128]; /* Pending irq by device */
uint8 dev_irq[128]; /* Pending irq by device */
t_stat (*dev_tab[128])(uint32 dev, uint64 *data);
int (*dev_irqv[128])(uint32 dev, int addr);
t_stat rtc_srv(UNIT * uptr);
@ -658,8 +658,16 @@ int opflags[] = {
#define AOB(x) (x + 01000001LL)
#define SOB(x) (x + 0777776777777LL)
#endif
#if ITS
#define QITS (cpu_unit[0].flags & UNIT_ITSPAGE)
#else
#define QITS 0
#endif
#if BBN
#define QBBN (cpu_unit[0].flags & UNIT_BBNPAGE)
#else
#define QBBN 0
#endif
/*
* Set device to interrupt on a given level 1-7
@ -670,7 +678,8 @@ void set_interrupt(int dev, int lvl) {
if (lvl) {
dev_irq[dev>>2] = 0200 >> lvl;
pi_pending = 1;
sim_debug(DEBUG_IRQ, &cpu_dev, "set irq %o %o\n", dev & 0774, lvl);
sim_debug(DEBUG_IRQ, &cpu_dev, "set irq %o %o %03o %03o %03o\n",
dev & 0774, lvl, PIE, PIR, PIH);
}
}
@ -693,11 +702,14 @@ int check_irq_level() {
if (xct_flag != 0)
return 0;
check_apr_irq();
/* If not enabled, check if any pending Processor IRQ */
if (pi_enable == 0) {
if (PIR != 0) {
pi_enc = 1;
for(lvl = 0100; lvl != 0; lvl >>= 1) {
if (lvl & PIH)
break;
if (PIR & lvl)
return 1;
pi_enc++;
@ -737,6 +749,7 @@ void restore_pi_hold() {
for(lvl = 0100; lvl != 0; lvl >>= 1) {
if (lvl & PIH) {
PIR &= ~lvl;
sim_debug(DEBUG_IRQ, &cpu_dev, "restore irq %o %03o\n", lvl, PIH);
PIH &= ~lvl;
break;
}
@ -790,7 +803,7 @@ t_stat dev_pi(uint32 dev, uint64 *data) {
parity_irq = 1;
if (res & 0100000)
parity_irq = 0;
sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data);
sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data);
break;
case CONI:
@ -802,7 +815,7 @@ t_stat dev_pi(uint32 dev, uint64 *data) {
#endif
res |= (parity_irq << 15);
*data = res;
sim_debug(DEBUG_CONO, &cpu_dev, "CONO PI %012llo\n", *data);
sim_debug(DEBUG_CONI, &cpu_dev, "CONI PI %012llo\n", *data);
break;
case DATAO:
@ -943,10 +956,15 @@ t_stat dev_apr(uint32 dev, uint64 *data) {
clk_flg = 0;
clr_interrupt(4);
}
if (res & 0002000)
if (res & 0002000) {
clk_en = 1;
if (res & 0004000)
if (clk_flg)
set_interrupt(4, clk_irq);
}
if (res & 0004000) {
clk_en = 0;
clr_interrupt(4);
}
if (res & 0040000)
timer_irq = 1;
if (res & 0100000)
@ -956,7 +974,7 @@ t_stat dev_apr(uint32 dev, uint64 *data) {
if (res & 0400000)
timer_flg = 0;
check_apr_irq();
sim_debug(DEBUG_CONI, &cpu_dev, "CONO APR %012llo\n", *data);
sim_debug(DEBUG_CONO, &cpu_dev, "CONO APR %012llo\n", *data);
break;
case DATAO:
@ -1048,14 +1066,11 @@ void check_apr_irq() {
if (pi_enable && apr_irq) {
int flg = 0;
clr_interrupt(0);
clr_interrupt(4);
flg |= ((FLAGS & OVR) != 0) & ov_irq;
flg |= ((FLAGS & FLTOVR) != 0) & fov_irq;
flg |= nxm_flag | mem_prot | push_ovf;
if (flg)
set_interrupt(0, apr_irq);
if (clk_en & clk_flg)
set_interrupt(4, clk_irq);
}
}
@ -1082,7 +1097,6 @@ t_stat dev_apr(uint32 dev, uint64 *data) {
res = *data;
clk_irq = apr_irq = res & 07;
clr_interrupt(0);
clr_interrupt(4);
if (res & 010)
FLAGS &= ~OVR;
if (res & 020)
@ -1095,12 +1109,19 @@ t_stat dev_apr(uint32 dev, uint64 *data) {
fov_irq = 1;
if (res & 0400)
fov_irq = 0;
if (res & 01000)
if (res & 0001000) {
clk_flg = 0;
if (res & 02000)
clr_interrupt(4);
}
if (res & 0002000) {
clk_en = 1;
if (res & 04000)
if (clk_flg)
set_interrupt(4, clk_irq);
}
if (res & 0004000) {
clk_en = 0;
clr_interrupt(4);
}
if (res & 010000)
nxm_flag = 0;
if (res & 020000)
@ -1203,7 +1224,7 @@ int page_lookup(int addr, int flag, int *loc, int wr, int cur_context, int fetch
fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27)
| 021LL;
page_fault = 1;
fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5);
//fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5);
return !wr;
}
return 1;
@ -1237,7 +1258,7 @@ fprintf(stderr, "suprt PC=%06o, %012llo %06o\n\r", PC, M[addr], FLAGS << 5);
(!fetch || (M[*loc] & 00777040000000LL) != 0254040000000LL)) {
/* Handle public violation */
fault_data = (((uint64)(page))<<18) | ((uint64)(uf) << 27) | 021LL;
fprintf(stderr, "pub PC=%06o, %012llo\n\r", PC, fault_data);
//fprintf(stderr, "pub PC=%06o, %012llo\n\r", PC, fault_data);
page_fault = 1;
return fetch;
}
@ -1896,7 +1917,7 @@ int flag3;
int instr_count = 0; /* Number of instructions to execute */
uint32 IA;
#if ITS
char one_p_arm; /* One proceed arm */
char one_p_arm = 0; /* One proceed arm */
#endif
if (sim_step != 0) {
@ -1921,11 +1942,9 @@ if ((reason = build_dev_tab ()) != SCPE_OK) /* build, chk dib_tab */
#if KI | KL
page_fault = 0;
#endif
#if ITS
one_p_arm = 0;
#endif
#if ITS
if (QITS) {
one_p_arm = 0;
sim_activate(&cpu_unit[1], 10000);
qua_time = 0;
}
@ -2038,6 +2057,7 @@ no_fetch:
/* If there is a interrupt handle it. */
if (pi_rq) {
st_pi:
sim_debug(DEBUG_IRQ, &cpu_dev, "trap irq %o %03o %03o \n", pi_enc, PIR, PIH);
set_pi_hold(); /* Hold off all lower interrupts */
pi_cycle = 1;
pi_rq = 0;
@ -2092,7 +2112,7 @@ st_pi:
if (hst_lnt && /*(fm_sel || */PC > 020 && (PC & 0777774) != 0777040 &&
(PC & 0777700) != 023700 && (PC != 0526772)) {
#else
if (hst_lnt && /*(FLAGS & USER) &&*/ PC > 017/* && (PC & 0777774) != 0472174 && */
if (hst_lnt /*&& (FLAGS & USER) && PC > 017 && (PC & 0777774) != 0472174 && */
/* (PC & 0777700) != 0113700 && (PC != 0527154)*/) {
#endif
hst_p = hst_p + 1;
@ -2181,7 +2201,7 @@ unasign:
AB = ub_ptr | 0424;
Mem_write_nopage();
AB |= 1;
MB = (FLAGS << 23) | ((PC + (trap_flag == 0)) & RMASK);
MB = ((uint64)(FLAGS) << 23) | ((PC + (trap_flag == 0)) & RMASK);
Mem_write_nopage();
FLAGS &= ~ (BYTI|ADRFLT|TRP1|TRP2);
AB = ub_ptr | 0430;
@ -2481,7 +2501,6 @@ dpnorm:
case 0124: /* DMOVEM */
AR = get_reg(AC);
MQ = get_reg(AC + 1);
/* Handle each half as seperate instruction */
if ((FLAGS & BYTI) == 0) {
MB = AR;
@ -2489,6 +2508,7 @@ dpnorm:
goto last;
FLAGS |= BYTI;
}
MQ = get_reg(AC + 1);
if ((FLAGS & BYTI)) {
AB = (AB + 1) & RMASK;
MB = MQ;
@ -2771,6 +2791,7 @@ dpnorm:
goto unasign;
case 0247: /* UUO or ITS CIRC instruction */
#if ITS
if (QITS) {
BR = AR;
AR = get_reg(AC);
@ -2795,7 +2816,7 @@ dpnorm:
set_reg(AC+1, MQ);
break;
}
#endif
/* UUO */
case 0105: case 0106: case 0107:
case 0110: case 0111: case 0112: case 0113:
@ -2809,7 +2830,7 @@ unasign:
Mem_write(uuo_cycle, 0);
AB += 1;
#if ITS
if (one_p_arm) {
if (QITS && one_p_arm) {
FLAGS |= ONEP;
one_p_arm = 0;
}
@ -3006,19 +3027,22 @@ ldb_ptr:
BR <<= 27;
if (SCAD & 0400) {
SCAD = 01000 - SCAD;
if (SCAD < 28) {
AD = (BR & (SMASK<<27))? (FMASK<<27|MMASK) : 0;
if (SCAD < 54) {
AD = (BR & (SMASK<<27))? DCMASK : 0;
BR = (BR >> SCAD) | (AD << (54 - SCAD));
} else {
BR = 0;
if (SCAD < 64)
BR = (BR & (SMASK<<27))? DCMASK: 0;
else
BR = 0;
}
}
/* Do the addition now */
AR = (AR + BR);
/* Set flag1 to sign and make positive */
if (AR & FPSMASK) {
AR = (AR ^ FPFMASK) + 1;
if (AR & DNMASK) {
AR = (AR ^ DFMASK) + 1;
flag1 = 1;
} else {
flag1 = 0;
@ -3037,21 +3061,21 @@ fxnorm:
if ((AR & 00740000000000000000LL) == 0) { SC -= 4; AR <<= 4; }
if ((AR & 00600000000000000000LL) == 0) { SC -= 2; AR <<= 2; }
if ((AR & 00400000000000000000LL) == 0) { SC -= 1; AR <<= 1; }
if (!nrf && !flag1 &&
((IR & 04) != 0) && ((AR & BIT9) != 0)) {
AR += BIT8;
if (!nrf && ((IR & 04) != 0)) {
AR += BIT9;
AR &= ~MMASK;
if ((AR & FPNMASK) != 0) { SC += 1; AR >>= 1; }
nrf = 1;
goto fxnorm;
}
}
if (flag1) {
AR = (AR ^ FPCMASK) + 1;
}
MQ = AR & MMASK;
AR >>= 27;
if (flag1) {
MQ = (MQ ^ MMASK) + 1;
AR = (AR ^ MMASK);
if (MQ & BIT8)
AR++;
AR |= SMASK;
MQ |= SMASK;
}
} else if (flag1) {
AR = BIT9 | SMASK;
@ -3065,6 +3089,7 @@ fxnorm:
FLAGS |= OVR|FLTOVR|TRP1;
if (!fxu_hold_set) {
FLAGS |= FLTUND;
MQ = 0;
}
check_apr_irq();
}
@ -3074,12 +3099,17 @@ fxnorm:
/* FADL FSBL FMPL */
if ((IR & 07) == 1) {
SC = (SC + (0777 ^ 26)) & 0777;
if (MQ != 0) {
if ((SC & 0400) != 0)
MQ = 0;
if ((MQ & MMASK) != 0 && MQ != MMASK) {
MQ &= MMASK;
SC ^= (SC & SMASK) ? 0377 : 0;
MQ |= ((uint64)(SC & 0377)) << 27;
}
} else
MQ = 0;
}
if ((AR & MMASK) == 0)
AR = 0;
/* Handle UFA */
if (IR == 0130) {
@ -3125,8 +3155,7 @@ fxnorm:
case 0177: /* FDVRB */
flag1 = 0;
SC = (int)((((BR & SMASK) ? 0777 : 0) ^ (BR >> 27)) & 0777);
SC += (int)((((AR & SMASK) ? 0 : 0777) ^ (AR >> 27)) & 0777);
SC = (SC + 0201) & 0777;
SCAD = (int)((((AR & SMASK) ? 0777 : 0) ^ (AR >> 27)) & 0777);
if (BR & SMASK) {
BR = CM(BR) + 1;
flag1 = 1;
@ -3135,6 +3164,7 @@ fxnorm:
AR = CM(AR) + 1;
flag1 = !flag1;
}
SC = (SC + ((0777 ^ SCAD) + 1) + 0201) & 0777;
/* Clear exponents */
AR &= MMASK;
BR &= MMASK;
@ -3146,26 +3176,29 @@ fxnorm:
sac_inh = 1;
break; /* Done */
}
BR = (BR << 27) + MQ;
BR = (BR << 28);
MB = AR;
AR = BR / AR;
if (AR != 0) {
if (IR & 04) {
AR ++;
}
if ((AR & BIT8) != 0) {
SC += 1;
if ((AR & BIT7) != 0) {
AR >>= 1;
} else {
SC--;
}
if (SC >= 0600)
if (IR & 04) {
AR++;
}
AR >>= 1;
while ((AR & BIT9) == 0) {
AR <<= 1;
SC--;
}
if (((SC & 0400) != 0) ^ ((SC & 0200) != 0) || SC == 0600)
fxu_hold_set = 1;
if (flag1) {
AR = (AR ^ MMASK) + 1;
AR |= SMASK;
}
} else if (flag1) {
AR = SMASK | BIT9;
SC++;
flag1 = 0;
} else {
AR = 0;
SC = 0;
@ -3177,13 +3210,16 @@ fxnorm:
}
check_apr_irq();
}
if (flag1) {
AR = ((AR ^ MMASK) + 1) & MMASK;
AR |= SMASK;
}
SCAD = SC ^ ((AR & SMASK) ? 0377 : 0);
AR &= SMASK|MMASK;
AR |= ((uint64)(SCAD & 0377)) << 27;
break;
case 0171: /* FDVL */
flag1 = 0;
flag1 = flag3 = 0;
SC = (int)((((BR & SMASK) ? 0777 : 0) ^ (BR >> 27)) & 0777);
SC += (int)((((AR & SMASK) ? 0 : 0777) ^ (AR >> 27)) & 0777);
SC = (SC + 0201) & 0777;
@ -3194,6 +3230,7 @@ fxnorm:
if (MQ == 0)
BR = BR + 1;
flag1 = 1;
flag3 = 1;
}
MQ &= MMASK;
if (AR & SMASK) {
@ -3218,6 +3255,7 @@ fxnorm:
if (BR < AR) {
BR <<= 1;
SC--;
FE--;
}
for (SCAD = 0; SCAD < 27; SCAD++) {
AD <<= 1;
@ -3232,10 +3270,15 @@ fxnorm:
SC++;
if (AR != 0) {
if ((AR & BIT8) != 0) {
SC += 1;
SC++;
FE++;
AR >>= 1;
}
if (SC >= 0600)
while ((AR & BIT9) == 0) {
AR <<= 1;
SC--;
}
if (((SC & 0400) != 0) ^ ((SC & 0200) != 0))
fxu_hold_set = 1;
if (flag1) {
AR = (AR ^ MMASK) + 1;
@ -3261,14 +3304,18 @@ fxnorm:
if (MQ != 0) {
MQ &= MMASK;
if (SC & 0400) {
FE--;
if (flag3) {
MQ = (MQ ^ MMASK) + 1;
MQ |= SMASK;
}
FE ^= (AR & SMASK) ? 0377 : 0;
if (FE & 0400) {
MQ = 0;
FE = 0;
} else
FE ^= (flag3) ? 0377 : 0;
MQ |= ((uint64)(FE & 0377)) << 27;
}
break;
/* FWT */
case 0200: /* MOVE */
case 0201: /* MOVEI */
@ -3346,7 +3393,7 @@ fxnorm:
MQ += (AR << 18) & LMASK; /* low order bits */
AR >>= 18;
AR = (AR << 1) + (MQ >> 35);
MQ &= CMASK;
MQ &= CMASK; /* low order only has 35 bits */
if ((IR & 4) == 0) { /* IMUL */
if (AR > flag3 && !pi_cycle) {
FLAGS |= OVR|TRP1;
@ -3500,12 +3547,9 @@ fxnorm:
break;
case 0241: /* ROT */
#if KI | KL
SC = (AB & RSIGN) ?
((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377);
#else
SC = ((AB & RSIGN) ? (0377 ^ AB) + 1 : AB) & 0377;
#endif
((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400)
: (AB & 0377);
if (SC == 0)
break;
SC = SC % 36;
@ -3582,12 +3626,9 @@ fxnorm:
break;
case 0245: /* ROTC */
#if KI | KL
SC = (AB & RSIGN) ?
((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400) : (AB & 0377);
#else
SC = ((AB & RSIGN) ? (0777 ^ AB) + 1 : AB) & 0777;
#endif
((AB & 0377) ? (((0377 ^ AB) + 1) & 0377) : 0400)
: (AB & 0377);
if (SC == 0)
break;
SC = SC % 72;
@ -3757,7 +3798,7 @@ fxnorm:
PC = AR & RMASK;
/* JRSTF */
if (AC & 02) {
FLAGS &= ~(OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0);
FLAGS &= ~(OVR|NODIV|FLTUND|BYTI|FLTOVR|CRY1|CRY0|TRP1|TRP2);
AR >>= 23; /* Move into position */
/* If executive mode, copy USER and UIO */
if ((FLAGS & (PUBLIC|USER)) == 0)
@ -3956,8 +3997,7 @@ fxnorm:
break;
case 0264: /* JSR */ /* AR Frm PC */
MB = ((uint64)(FLAGS) << 23) |
((PC + !pi_cycle) & RMASK);
MB = ((uint64)(FLAGS) << 23) | ((PC + !pi_cycle) & RMASK);
if (uuo_cycle | pi_cycle) {
FLAGS &= ~(USER|PUBLIC); /* Clear USER */
}

View File

@ -242,7 +242,7 @@ t_stat dc_devio(uint32 dev, uint64 *data) {
int32 ch = *data & DATA;
ch = sim_tt_outcvt(ch, TT_GET_MODE (dc_unit.flags) | TTUF_KSR);
tmxr_putc_ln (lp, ch);
if (lp->xmte)
if (lp->xmte)
tx_enable |= (1 << ln);
else
tx_enable &= ~(1 << ln);

View File

@ -139,8 +139,10 @@ extern DEBTAB crd_debug[];
#define EMASK 00777000000000LL
#define MMASK 00000777777777LL
#define BIT1 00200000000000LL
#define BIT7 00002000000000LL
#define BIT8 00001000000000LL
#define BIT9 00000400000000LL
#define BIT10 00000200000000LL
#define BIT10_35 00000377777777LL
#define MANT 00000777777777LL
#define EXPO 00377000000000LL

View File

@ -35,7 +35,7 @@ void df10_writecw(struct df10 *df) {
void df10_bump_addr(struct df10 *df) {
#if KA & ITS
if (cpu_unit[0].flags & UNIT_ITSPAGE)
if (cpu_unit[0].flags & UNIT_ITSPAGE)
df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000);
else
#endif
@ -104,7 +104,7 @@ int df10_read(struct df10 *df) {
return 0;
}
#if KA & ITS
if (cpu_unit[0].flags & UNIT_ITSPAGE)
if (cpu_unit[0].flags & UNIT_ITSPAGE)
df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000);
else
#endif
@ -132,7 +132,7 @@ int df10_write(struct df10 *df) {
return 0;
}
#if KA & ITS
if (cpu_unit[0].flags & UNIT_ITSPAGE)
if (cpu_unit[0].flags & UNIT_ITSPAGE)
df->cda = (uint32)((df->cda + 1) & RMASK) | (df->cda & 07000000);
else
#endif

View File

@ -264,9 +264,9 @@ DIB dp_dib[] = {
MTAB dp_mod[] = {
{UNIT_WLK, 0, "write enabled", "WRITEENABLED", NULL},
{UNIT_WLK, UNIT_WLK, "write locked", "LOCKED", NULL},
{MTAB_XTD|MTAB_VDV, 0, NULL, "NOHEADERS",
{MTAB_XTD|MTAB_VDV, 0, NULL, "NOHEADERS",
&dp_set_hdr, &dp_show_hdr, "No Headers", "Disable header writing"},
{MTAB_XTD|MTAB_VDV, DEV_WHDR, "write header", "HEADERS",
{MTAB_XTD|MTAB_VDV, DEV_WHDR, "write header", "HEADERS",
&dp_set_hdr, &dp_show_hdr, "Headers", "Enable header writing"},
{UNIT_DTYPE, (RP03_DTYPE << UNIT_V_DTYPE), "RP03", "RP03", &dp_set_type },
{UNIT_DTYPE, (RP02_DTYPE << UNIT_V_DTYPE), "RP02", "RP02", &dp_set_type },
@ -440,8 +440,10 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
unit = (*data >> 30) & 07;
dp_cur_unit[ctlr] = unit;
uptr = &dp_unit[(ctlr * NUM_UNITS_DP) + unit];
uptr->STATUS &= ~(SUF_ERR|SEC_ERR|SRC_ERR|NXM_ERR|ILL_WR|
if ((uptr->STATUS & NOT_RDY) == 0) {
uptr->STATUS &= ~(SUF_ERR|SEC_ERR|SRC_ERR|NXM_ERR|ILL_WR|
NO_DRIVE|NOT_RDY|ILL_CMD|END_CYL|SRC_DONE);
}
cyl = ((*data >> 22) & 0377);
if (*data & CYL256)
cyl += 0400;
@ -490,14 +492,12 @@ t_stat dp_devio(uint32 dev, uint64 *data) {
case RC:
cyl = 0;
uptr->STATUS |= NOT_RDY;
/* Fall through */
case SK:
if ((uptr->flags & UNIT_ATT) == 0) {
return SCPE_OK;
}
uptr->STATUS |= NOT_RDY;
if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_OK;
uptr->UFLAGS = (cyl << 20) | (tmp<<3) | ctlr | SEEK_STATE;
break;
@ -677,7 +677,7 @@ t_stat dp_svc (UNIT *uptr)
case WH:
/* Cylinder, Surface, Sector all ok */
if (BUF_EMPTY(uptr)) {
if (uptr->DATAPTR == 0)
if (uptr->DATAPTR == 0)
sim_debug(DEBUG_DETAIL, dptr,
"DP %d cmd=%o cyl=%d (%o) sect=%d surf=%d %d\n",
ctlr, uptr->UFLAGS, cyl, cyl, sect, surf,uptr->CUR_CYL);
@ -761,7 +761,8 @@ t_stat dp_svc (UNIT *uptr)
uptr->UFLAGS |= SEEK_DONE;
uptr->UFLAGS &= ~SEEK_STATE;
uptr->STATUS &= ~(NOT_RDY);
df10_setirq(df10);
if ((df10->status & BUSY) == 0)
df10_setirq(df10);
} else if (diff < 10 && diff > -10) {
uptr->CUR_CYL += diffs;
if (uptr->CUR_CYL < 0) {
@ -769,13 +770,15 @@ t_stat dp_svc (UNIT *uptr)
uptr->UFLAGS &= ~SEEK_STATE;
uptr->STATUS &= ~(NOT_RDY);
uptr->CUR_CYL = 0;
df10_setirq(df10);
if ((df10->status & BUSY) == 0)
df10_setirq(df10);
} else if (uptr->CUR_CYL > dp_drv_tab[dtype].cyl) {
uptr->UFLAGS |= SEEK_DONE;
uptr->UFLAGS &= ~SEEK_STATE;
uptr->STATUS &= ~(NOT_RDY);
uptr->CUR_CYL = dp_drv_tab[dtype].cyl;
df10_setirq(df10);
if ((df10->status & BUSY) == 0)
df10_setirq(df10);
} else
sim_activate(uptr, 500);
} else if (diff > 100 || diff < -100) {
@ -829,7 +832,7 @@ t_stat dp_show_hdr (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
dptr = find_dev_from_unit(uptr);
if (dptr == NULL)
return SCPE_IERR;
if ((dptr->flags & DEV_WHDR) == val)
if ((dptr->flags & DEV_WHDR) == val)
fprintf (st, "%s", (char *)desc);
return SCPE_OK;
}

View File

@ -89,12 +89,12 @@
#define BOT_FLAG 00000100000
#define REW_FLAG 00000200000
#define TRAN_HUNG 00000400000
#define CHAR_COUNT 00017000000
#define WT_CW_DONE 00020000000
#define DATA_PARITY 00040000000
#define NXM_ERR 00100000000
#define CW_PAR_ERR 00200000000
#define B22_FLAG 01000000000
#define CHAR_COUNT 00007000000
#define WT_CW_DONE 00010000000
#define DATA_PARITY 00020000000
#define NXM_ERR 00040000000
#define CW_PAR_ERR 00100000000
#define B22_FLAG 00400000000
#define DATA_PIA 000000007 /* 0 */
#define FLAG_PIA 000000070 /* 3 */
@ -115,6 +115,7 @@
#define MT_BUFFUL 000000004 /* Buffer full of data */
#define MT_BRFUL 000000010 /* BR register full */
#define MT_STOP 000000020 /* DF10 End of Channel */
#define MT_LASTWD 000000040 /* Last data word of record */
/* in u3 is device address */
/* in u4 is current buffer position */
/* in u5 */
@ -135,6 +136,7 @@ struct df10 mt_df10;
uint16 pia;
uint8 unit;
uint8 next_unit;
uint8 wr_eor;
uint64 status;
uint64 hold_reg;
int cc;
@ -205,6 +207,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
res |= (uint64)(uptr->u3 & 077300);
res |= ((uint64)unit) << 15;
res |= ((uint64)next_unit) << 18;
res |= ((uint64)wr_eor) << 21;
if (dptr->flags & MTDF_TYPEB)
res |= 7LL; /* Force DATA PIA to 7 on type B */
*data = res;
@ -219,7 +222,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
pia = (uint16)(*data) & (NEXT_UNIT_ENAB|FLAG_PIA|DATA_PIA);
status &= ~(DATA_REQUEST|CHAN_ERR|JOB_DONE|DATA_LATE| \
BAD_TAPE|RLC_ERR|READ_CMP|EOF_FLAG|EOT_FLAG|BOT_FLAG| \
PARITY_ERR|ILL_OPR|REW_FLAG|TRAN_HUNG|CHAR_COUNT| \
PARITY_ERR|ILL_OPR|REW_FLAG|TRAN_HUNG| \
WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR|IDLE_UNIT| \
SEVEN_CHAN|NEXT_UNIT);
/* Check if we can switch to new unit */
@ -232,7 +235,6 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
set_interrupt(dev, pia >> 3);
}
uptr->u3 = (int32)(*data & 077300);
CLR_BUF(uptr);
mt_df10.buf = 0;
sim_debug(DEBUG_CONO, dptr,
"MT CONO %03o start %o %o %o %012llo %012llo PC=%06o\n",
@ -244,6 +246,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
switch(cmd & 07) {
case NOP_CLR:
uptr->u3 &= ~MT_BUSY;
wr_eor = 0;
status |= NEXT_UNIT;
if (cmd & 010) {
status |= JOB_DONE;
@ -255,12 +258,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
return SCPE_OK;
case REWIND:
case WTM:
break;
case READ:
CLR_BUF(uptr);
uptr->u5 = 0;
status |= REW_FLAG;
break;
case WRITE:
@ -270,14 +268,23 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
}
/* Fall through */
case WTM:
case READ:
case CMP:
CLR_BUF(uptr);
uptr->u5 = 0;
/* Fall through */
break;
case SPC_REV:
if (sim_tape_bot(uptr)) {
status |= JOB_DONE|ILL_OPR;
set_interrupt(MT_DEVNUM+4, pia >> 3);
return SCPE_OK;
}
/* Fall through */
case SPC_FWD:
if ((dptr->flags & MTDF_TYPEB) == 0) {
if ((dptr->flags & MTDF_TYPEB) == 0 && (cmd & 010) == 0) {
status |= DATA_REQUEST;
set_interrupt(MT_DEVNUM, pia);
}
@ -336,6 +343,8 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
res |= BOT_FLAG;
if (sim_tape_eot(uptr))
res |= EOT_FLAG;
if ((dptr->flags & MTDF_TYPEB) == 0)
res |= WT_CW_DONE|DATA_PARITY|NXM_ERR|CW_PAR_ERR;
#if KI_22BIT
if (dptr->flags & MTDF_TYPEB)
res |= B22_FLAG;
@ -349,7 +358,7 @@ t_stat mt_devio(uint32 dev, uint64 *data) {
if (*data & 1) {
uptr->u3 |= MT_STOP;
hri_mode = 0;
sim_debug(DEBUG_DETAIL, dptr, "MT stop %03o\n", dev);
sim_debug(DEBUG_DETAIL, dptr, "MT stop %03o %012llo\n", dev, status);
}
if (*data & 2) {
hold_reg ^= mt_df10.buf;
@ -468,7 +477,6 @@ t_stat mt_error(UNIT * uptr, t_stat r, DEVICE * dptr)
break;
case MTSE_INVRL: /* invalid rec lnt */
status |= RLC_ERR;
break;
case MTSE_EOM: /* end of medium */
@ -483,7 +491,7 @@ t_stat mt_error(UNIT * uptr, t_stat r, DEVICE * dptr)
}
status |= JOB_DONE;
uptr->u3 &= ~MT_BUSY;
sim_debug(DEBUG_EXP, dptr, "Setting status %012llo\n", status);
sim_debug(DEBUG_EXP, dptr, "Setting status %d %012llo\n", r, status);
set_interrupt(MT_DEVNUM+4, pia >> 3);
return SCPE_OK;
}
@ -505,7 +513,7 @@ t_stat mt_srv(UNIT * uptr)
return mt_error(uptr, MTSE_UNATT, dptr); /* attached? */
}
if ((uptr->u3 & DENS_MSK) != DENS_800) {
if ((cmd & 6) != 0 && (uptr->u3 & DENS_MSK) != DENS_800) {
uptr->u3 &= ~MT_MOTION;
return mt_error(uptr, MTSE_FMT, dptr); /* wrong density? */
}
@ -542,15 +550,15 @@ t_stat mt_srv(UNIT * uptr)
case READ:
case READ_NOEOR:
if (uptr->u3 & MT_STOP) {
if ((uint32)uptr->u6 < uptr->hwmark)
status |= RLC_ERR;
if ((uptr->u3 & MT_LASTWD) == 0)
status |= RLC_ERR;
if (dptr->flags & MTDF_TYPEB)
df10_writecw(&mt_df10);
return mt_error(uptr, MTSE_OK, dptr);
}
if (BUF_EMPTY(uptr)) {
uptr->u3 |= MT_MOTION;
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR);
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT);
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, "MT%o read error %d\n", unit, r);
@ -567,7 +575,7 @@ t_stat mt_srv(UNIT * uptr)
}
if (uptr->u3 & MT_BRFUL) {
status |= DATA_LATE;
sim_debug(DEBUG_DATA, dptr, "data late\n");
sim_debug(DEBUG_EXP, dptr, "data late\n");
break;
}
if ((uint32)uptr->u6 < uptr->hwmark) {
@ -591,6 +599,8 @@ t_stat mt_srv(UNIT * uptr)
}
uptr->u6++;
uptr->u5++;
if ((uptr->u6 + cc_max) >= uptr->hwmark)
uptr->u3 |= MT_LASTWD;
status &= ~CHAR_COUNT;
status |= (uint64)(uptr->u5) << 18;
if (uptr->u5 == cc_max)
@ -612,15 +622,13 @@ t_stat mt_srv(UNIT * uptr)
case CMP:
case CMP_NOEOR:
if (uptr->u3 & MT_STOP) {
if ((uint32)uptr->u6 < uptr->hwmark)
status |= RLC_ERR;
if (dptr->flags & MTDF_TYPEB)
df10_writecw(&mt_df10);
return mt_error(uptr, MTSE_OK, dptr);
}
if (BUF_EMPTY(uptr)) {
uptr->u3 |= MT_MOTION;
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR);
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT);
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_DETAIL, dptr, "MT%o read error %d\n", unit, r);
@ -636,10 +644,20 @@ t_stat mt_srv(UNIT * uptr)
status |= DATA_REQUEST;
set_interrupt(MT_DEVNUM, pia);
}
break;
}
if (uptr->u6 >= (int32)uptr->hwmark) {
if (cmd == CMP_NOEOR)
if (cmd == CMP_NOEOR) {
CLR_BUF(uptr);
uptr->u3 &= ~MT_LASTWD;
} else {
if (dptr->flags & MTDF_TYPEB) {
df10_bump_addr(&mt_df10);
df10_writecw(&mt_df10);
}
uptr->u3 &= ~(MT_MOTION|MT_BUSY);
return mt_error(uptr, MTSE_INVRL, dptr);
}
} else if ((uptr->u3 & MT_BRFUL) == 0) {
/* Write out first character. */
mt_df10_read(dptr, uptr);
@ -669,7 +687,7 @@ t_stat mt_srv(UNIT * uptr)
if ((dptr->flags & MTDF_TYPEB) == 0) {
uptr->u6 = uptr->hwmark;
status &= ~CHAR_COUNT;
status |= (uint64)(uptr->u5) << 18;
status |= (uint64)(uptr->u5+1) << 18;
uptr->u3 &= ~(MT_MOTION|MT_BUSY);
if (dptr->flags & MTDF_TYPEB)
df10_writecw(&mt_df10);
@ -678,12 +696,14 @@ t_stat mt_srv(UNIT * uptr)
}
uptr->u6++;
uptr->u5++;
if (uptr->u6 == uptr->hwmark)
uptr->u3 |= MT_LASTWD;
if (uptr->u5 == cc_max) {
uptr->u5 = 0;
uptr->u3 &= ~MT_BRFUL;
}
status &= ~CHAR_COUNT;
status |= (uint64)(uptr->u5) << 18;
status |= (uint64)(uptr->u5+1) << 18;
}
break;
@ -692,11 +712,16 @@ t_stat mt_srv(UNIT * uptr)
/* Writing and Type A, request first data word */
if (BUF_EMPTY(uptr)) {
uptr->u3 |= MT_MOTION;
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR);
status &= ~(IDLE_UNIT|BOT_FLAG|EOF_FLAG|EOT_FLAG|PARITY_ERR|CHAR_COUNT);
sim_debug(DEBUG_EXP, dptr, "MT%o Init write\n", unit);
uptr->hwmark = 0;
uptr->u5 = 0;
uptr->u6 = 0;
status |= (uint64)(1) << 18;
if ((dptr->flags & MTDF_TYPEB) == 0) {
status |= DATA_REQUEST;
set_interrupt(MT_DEVNUM, pia);
}
break;
}
/* Force error if we exceed buffer size */
@ -727,12 +752,13 @@ t_stat mt_srv(UNIT * uptr)
uptr->u3 &= ~MT_BRFUL;
}
status &= ~CHAR_COUNT;
status |= (uint64)(uptr->u5) << 18;
status |= (uint64)(uptr->u5+1) << 18;
}
if ((uptr->u3 & (MT_STOP|MT_BRFUL|MT_BUFFUL)) == MT_STOP) {
/* Write out the block */
wr_eor = 1;
reclen = uptr->hwmark;
status &= ~(BOT_FLAG|EOF_FLAG|EOT_FLAG);
status &= ~(BOT_FLAG|EOF_FLAG|EOT_FLAG|CHAR_COUNT);
r = sim_tape_wrrecf(uptr, &mt_buffer[0], reclen);
sim_debug(DEBUG_DETAIL, dptr, "MT%o Write %d\n", unit, reclen);
uptr->u6 = 0;
@ -747,10 +773,21 @@ t_stat mt_srv(UNIT * uptr)
case WTM:
if ((uptr->flags & MTUF_WLK) != 0)
return mt_error(uptr, MTSE_WRP, dptr);
uptr->u3 &= ~MT_MOTION;
status &= ~(IDLE_UNIT|BOT_FLAG|EOT_FLAG);
sim_debug(DEBUG_DETAIL, dptr, "MT%o WTM\n", unit);
return mt_error(uptr, sim_tape_wrtmk(uptr), dptr);
if (uptr->u5 == 0) {
status &= ~(IDLE_UNIT|BOT_FLAG|EOT_FLAG);
sim_debug(DEBUG_DETAIL, dptr, "MT%o WTM\n", unit);
r = sim_tape_wrtmk(uptr);
if (r != MTSE_OK)
return mt_error(uptr, r, dptr);
uptr->u5++;
wr_eor = 1;
} else {
wr_eor = 0;
status |= EOF_FLAG;
uptr->u3 &= ~MT_MOTION;
return mt_error(uptr, MTSE_OK, dptr);
}
break;
case ERG:
if ((uptr->flags & MTUF_WLK) != 0)
@ -780,6 +817,8 @@ t_stat mt_srv(UNIT * uptr)
case MTSE_EOM: /* end of medium */
/* Stop motion if we recieve any of these */
uptr->u3 &= ~MT_MOTION;
status &= ~DATA_REQUEST;
clr_interrupt(MT_DEVNUM);
return mt_error(uptr, r, dptr);
}
/* Clear tape mark, command, idle since we will need to change dir */
@ -939,7 +978,7 @@ mt_reset(DEVICE * dptr)
t_stat
mt_attach(UNIT * uptr, CONST char *file)
{
return sim_tape_attach(uptr, file);
return sim_tape_attach_ex(uptr, file, 0, 0);
}
t_stat

View File

@ -100,14 +100,14 @@ const char *pd_description (DEVICE *dptr)
t_stat pd_set_on(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr = &pd_dev;
dptr->flags &= ~PD_OFF;
dptr->flags &= ~PD_OFF;
return SCPE_OK;
}
t_stat pd_set_off(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
DEVICE *dptr = &pd_dev;
dptr->flags |= PD_OFF;
dptr->flags |= PD_OFF;
return SCPE_OK;
}

View File

@ -193,7 +193,7 @@
#define LA_V_SC 6 /* sector pos */
/* RPER2 - 10 - error status 2 - drive unsafe conditions - unimplemented */
/* u5 high */
/* us10 */
/* RPOF - 11 - offset register */
/* u4 low */
/* RPDC - 12 - desired cylinder */
@ -209,6 +209,7 @@
/* RPSN - 14 - serial number */
/* RPER3 - 15 - error status 3 - more unsafe conditions - unimplemented */
/* us9 */
/* RPDB - 176722 - data buffer */
@ -489,6 +490,17 @@ t_stat rp_devio(uint32 dev, uint64 *data) {
df10->status &= ~07LL;
df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
/* Clear flags */
if (*data & CONT_RESET) {
UNIT *uptr=dptr->units;
for(drive = 0; drive < NUM_UNITS_RP; drive++, uptr++) {
uptr->u3 &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
uptr->u4 &= 003400177777;
uptr->u5 &= 0177777;
uptr->up7 = 0;
uptr->us9 = 0;
uptr->us10 = 0;
}
}
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
if (*data & OVER_CLR)
@ -524,7 +536,13 @@ t_stat rp_devio(uint32 dev, uint64 *data) {
} else if (rp_reg[ctlr] == 054) {
*data = (t_uint64)(rp_rae[ctlr]);
} else if ((rp_reg[ctlr] & 040) == 0) {
int parity;
*data = (t_uint64)(rp_read(ctlr, rp_drive[ctlr], rp_reg[ctlr]) & 0177777);
parity = (*data >> 8) ^ *data;
parity = (parity >> 4) ^ parity;
parity = (parity >> 2) ^ parity;
parity = ((parity >> 1) ^ parity) & 1;
*data |= ((t_uint64)(parity ^ 1)) << 17;
*data |= ((t_uint64)(rp_drive[ctlr])) << 18;
}
*data |= ((t_uint64)(rp_reg[ctlr])) << 30;
@ -538,27 +556,29 @@ t_stat rp_devio(uint32 dev, uint64 *data) {
rp_reg[ctlr] = ((int)(*data >> 30)) & 077;
if (*data & LOAD_REG) {
if (rp_reg[ctlr] == 040) {
if (df10->status & BUSY) {
df10->status |= CC_CHAN_ACT;
return SCPE_OK;
}
if ((*data & 1) == 0) {
return SCPE_OK;
}
if (df10->status & BUSY) {
df10->status |= CC_CHAN_ACT;
return SCPE_OK;
}
df10->status &= ~(1 << df10->ccw_comp);
df10->status &= ~PI_ENABLE;
if (((*data >> 1) & 077) < FNC_XFER) {
df10->status |= CXR_ILC;
df10_setirq(df10);
sim_debug(DEBUG_DATAIO, dptr,
"RP %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
dev, *data, ctlr, rp_drive[ctlr], PC, df10->status);
sim_debug(DEBUG_DATAIO, dptr,
"RP %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
dev, *data, ctlr, rp_drive[ctlr], PC, df10->status);
return SCPE_OK;
}
rp_drive[ctlr] = (int)(*data >> 18) & 07;
/* Start command */
df10_setup(df10, (uint32)(*data >> 6));
rp_write(ctlr, rp_drive[ctlr], 0, (uint32)(*data & 077));
df10->status &= ~PI_ENABLE;
sim_debug(DEBUG_DATAIO, dptr,
"RP %03o command %012llo, %d[%d] PC=%06o %06o\n",
dev, *data, ctlr, rp_drive[ctlr], PC, df10->status);
@ -606,7 +626,7 @@ rp_devirq(uint32 dev, int addr) {
}
}
for (drive = 0; drive < NUM_DEVS_RP; drive++) {
if (dptr == rp_devs[drive])
if (dptr == rp_devs[drive])
return (rp_imode[drive] ? rp_ivect[drive] : addr);
}
return addr;
@ -614,89 +634,115 @@ rp_devirq(uint32 dev, int addr) {
void
rp_write(int ctlr, int unit, int reg, uint32 data) {
UNIT *uptr = &rp_unit[(ctlr * 8) + unit];
int i;
DEVICE *dptr = rp_devs[ctlr];
int i;
DEVICE *dptr = rp_devs[ctlr];
UNIT *uptr = &dptr->units[unit];
struct df10 *df10 = &rp_df10[ctlr];
int dtype = GET_DTYPE(uptr->flags);
if ((uptr->u3 & CR_GO) && reg != 04) {
uptr->u3 |= (ER1_RMR << 16)|DS_ERR;
return;
}
switch(reg) {
case 000: /* control */
sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d Status=%06o\n", unit, ctlr, uptr->u3);
/* Set if drive not writable */
if (uptr->flags & UNIT_WLK)
uptr->u3 |= DS_WRL;
df10->status &= ~(1 << df10->ccw_comp);
if ((data & 01) != 0 && (uptr->u3 & DS_DRY) != 0) {
uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->u3 |= data & 076;
switch (GET_FNC(data)) {
case FNC_NOP:
uptr->u3 |= DS_DRY;
break;
/* If drive not ready don't do anything */
if ((uptr->u3 & DS_DRY) == 0) {
uptr->u3 |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d busy\n", unit, ctlr);
return;
}
/* Check if GO bit set */
if ((data & 1) == 0) {
uptr->u3 &= ~076;
uptr->u3 |= data & 076;
sim_debug(DEBUG_DETAIL, dptr, "RPA%o %d no go\n", unit, ctlr);
return; /* No, nop */
}
uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->u3 |= data & 076;
switch (GET_FNC(data)) {
case FNC_NOP:
uptr->u3 |= DS_DRY;
break;
case FNC_RECAL: /* recalibrate */
uptr->u4 &= ~0177777;
/* Fall through */
case FNC_RECAL: /* recalibrate */
uptr->u4 &= ~0177777;
/* Fall through */
case FNC_SEARCH: /* search */
case FNC_SEEK: /* seek */
case FNC_RETURN: /* return to center */
case FNC_OFFSET: /* offset */
case FNC_UNLOAD: /* unload */
uptr->u3 &= ~DS_OFF;
/* Fall through */
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->u3 |= DS_PIP|CR_GO;
CLR_BUF(uptr);
uptr->u6 = 0;
break;
case FNC_DCLR: /* drive clear */
uptr->u3 |= DS_DRY;
uptr->u3 &= ~(DS_ATA|CR_GO);
case FNC_SEARCH: /* search */
case FNC_SEEK: /* seek */
if (GET_CY(uptr->u4) >= rp_drv_tab[dtype].cyl ||
GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) {
rp_attn[ctlr] &= ~(1<<unit);
clr_interrupt(df10->devnum);
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
if ((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0)
df10_setirq(df10);
break;
case FNC_PRESET: /* read-in preset */
uptr->u4 = 0;
uptr->u3 &= ~DS_OFF;
/* Fall through */
case FNC_RELEASE: /* port release */
case FNC_PACK: /* pack acknowledge */
if ((uptr->flags & UNIT_ATT) != 0)
uptr->u3 |= DS_VV;
uptr->u3 |= DS_DRY;
df10_setirq(df10);
break;
default:
uptr->u3 |= DS_DRY|DS_ERR|DS_ATA;
uptr->u3 |= (ER1_ILF << 16);
rp_attn[ctlr] |= (1<<unit);
}
if (uptr->u3 & DS_PIP)
sim_activate(uptr, 100);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o AStatus=%06o\n", unit,
uptr->u3);
} else {
/* Fall through */
case FNC_RETURN: /* return to center */
case FNC_OFFSET: /* offset */
case FNC_UNLOAD: /* unload */
uptr->u3 &= ~DS_OFF;
/* Fall through */
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->u3 |= DS_PIP|CR_GO;
CLR_BUF(uptr);
uptr->u6 = 0;
break;
case FNC_DCLR: /* drive clear */
uptr->u3 |= DS_DRY;
uptr->u3 &= ~(DS_ATA|CR_GO);
rp_attn[ctlr] &= ~(1<<unit);
clr_interrupt(df10->devnum);
if ((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0)
df10_setirq(df10);
break;
case FNC_PRESET: /* read-in preset */
uptr->u4 = 0;
uptr->u5 &= 0177777;
uptr->u3 &= ~DS_OFF;
/* Fall through */
case FNC_RELEASE: /* port release */
case FNC_PACK: /* pack acknowledge */
if ((uptr->flags & UNIT_ATT) != 0)
uptr->u3 |= DS_VV;
uptr->u3 |= DS_DRY;
df10_setirq(df10);
break;
default:
uptr->u3 |= DS_DRY|DS_ERR|DS_ATA;
uptr->u3 |= (ER1_ILF << 16);
rp_attn[ctlr] |= (1<<unit);
}
if (uptr->u3 & DS_PIP)
sim_activate(uptr, 1000);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o AStatus=%06o\n", unit, uptr->u3);
return;
case 001: /* status */
break;
case 002: /* error register 1 */
uptr->u3 &= 0177777;
uptr->u3 |= data << 16;
if (data != 0)
uptr->u3 &= ~DS_ERR;
if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0)
uptr->u3 |= DS_ERR;
break;
case 003: /* maintenance */
@ -708,31 +754,42 @@ rp_write(int ctlr, int unit, int reg, uint32 data) {
rp_attn[ctlr] &= ~(1<<i);
}
}
clr_interrupt(df10->devnum);
if (((df10->status & IADR_ATTN) != 0 && rp_attn[ctlr] != 0) ||
(df10->status & PI_ENABLE))
df10_setirq(df10);
if (df10->status & (IADR_ATTN|BUSY) == IADR_ATTN) {
if (rp_attn[ctlr] != 0)
df10_setirq(df10);
else
clr_interrupt(df10->devnum);
}
break;
case 005: /* sector/track */
uptr->u4 &= 0177777;
uptr->u4 |= data << 16;
break;
case 014: /* error register 2 */
if (data != 0)
uptr->us9 = data;
uptr->u3 &= ~DS_ERR;
if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0)
uptr->u3 |= DS_ERR;
uptr->u5 &= 0177777;
uptr->u5 |= data << 16;
break;
case 006: /* drive type */
case 007: /* look ahead */
break;
case 011: /* offset */
uptr->u5 &= 0177777;
uptr->u5 |= data << 16;
break;
case 012: /* desired cylinder */
uptr->u4 &= ~0177777;
uptr->u4 |= data;
break;
case 015: /* error register 3 */
uptr->us10 = data;
uptr->u3 &= ~DS_ERR;
if ((((uptr->u3 >> 16) & 0177777) | uptr->us9 | uptr->us10) != 0)
uptr->u3 |= DS_ERR;
break;
case 013: /* current cylinder */
case 010: /* serial no */
case 015: /* error register 3 */
case 016: /* ecc position */
case 017: /* ecc pattern */
break;
@ -744,7 +801,8 @@ rp_write(int ctlr, int unit, int reg, uint32 data) {
uint32
rp_read(int ctlr, int unit, int reg) {
UNIT *uptr = &rp_unit[(ctlr * 8) + unit];
DEVICE *dptr = rp_devs[ctlr];
UNIT *uptr = &dptr->units[unit];
struct df10 *df10;
uint32 temp = 0;
int i;
@ -764,6 +822,8 @@ rp_read(int ctlr, int unit, int reg) {
case 002: /* error register 1 */
temp = (uptr->u3 >> 16) & 0177777;
break;
case 003: /* maintenance */
break;
case 004: /* atten summary */
for (i = 0; i < 8; i++) {
if (rp_unit[(ctlr * 8) + i].u3 & DS_ATA) {
@ -789,10 +849,13 @@ rp_read(int ctlr, int unit, int reg) {
case 010: /* serial no */
temp = (020 * ctlr) + (unit + 1);
break;
case 003: /* maintenance */
case 007: /* look ahead */
case 014: /* error register 2 */
temp = uptr->us9;
break;
case 015: /* error register 3 */
temp = uptr->us10;
break;
case 007: /* look ahead */
case 016: /* ecc position */
case 017: /* ecc pattern */
break;
@ -811,7 +874,7 @@ t_stat rp_svc (UNIT *uptr)
int unit;
DEVICE *dptr;
struct df10 *df;
int cyl = uptr->u4 & 01777;
int cyl = GET_CY(uptr->u4);
int diff, da;
t_stat r;
@ -831,7 +894,7 @@ t_stat rp_svc (UNIT *uptr)
/* Check if seeking */
if (uptr->u3 & DS_PIP) {
sim_debug(DEBUG_DETAIL, dptr, "RPA%o seek %d %d\n", unit, cyl, uptr->u5);
if (cyl > rp_drv_tab[dtype].cyl) {
if (cyl >= rp_drv_tab[dtype].cyl) {
uptr->u3 &= ~DS_PIP;
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
}
@ -882,11 +945,13 @@ t_stat rp_svc (UNIT *uptr)
case FNC_PRESET: /* read-in preset */
case FNC_RECAL: /* recalibrate */
case FNC_SEEK: /* seek */
if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf)
uptr->u3 |= (ER1_IAE << 16)|DS_ERR;
rp_attn[ctlr] |= 1<<unit;
uptr->u3 |= DS_DRY|DS_ATA;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
if (df->status & IADR_ATTN)
if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN)
df10_setirq(df);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o seekdone %d %o\n", unit, cyl, uptr->u3);
break;
@ -898,8 +963,7 @@ t_stat rp_svc (UNIT *uptr)
rp_attn[ctlr] |= 1<<unit;
uptr->u3 |= DS_DRY|DS_ATA;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
if (df->status & IADR_ATTN)
if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN)
df10_setirq(df);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o searchdone %d %o\n", unit, cyl, uptr->u3);
break;
@ -913,15 +977,12 @@ t_stat rp_svc (UNIT *uptr)
if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) {
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
rp_attn[ctlr] |= 1<<unit;
df->status &= ~BUSY;
uptr->u3 &= ~CR_GO;
sim_debug(DEBUG_DETAIL, dptr, "RPA%o readx done\n", unit);
if (df->status & IADR_ATTN)
df10_setirq(df);
df10_finish_op(df, 0);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o readx done\n", unit);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, dptr, "RPA%o read (%d,%d,%d)\n", unit, cyl,
sim_debug(DEBUG_DETAIL, dptr, "RPA%o read (%d,%d,%d)\n", unit, cyl,
GET_SC(uptr->u4), GET_SF(uptr->u4));
da = GET_DA(uptr->u4, dtype) * RP_NUMWD;
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
@ -934,7 +995,8 @@ t_stat rp_svc (UNIT *uptr)
}
df->buf = rp_buf[ctlr][uptr->u6++];
sim_debug(DEBUG_DATA, dptr, "RPA%o read word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr);
sim_debug(DEBUG_DATA, dptr, "RPA%o read word %d %012llo %09o %06o\n",
unit, uptr->u6, df->buf, df->cda, df->wcr);
if (df10_write(df)) {
if (uptr->u6 == uptr->hwmark) {
/* Increment to next sector. Set Last Sector */
@ -957,8 +1019,7 @@ t_stat rp_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, "RPA%o read done\n", unit);
uptr->u3 |= DS_DRY;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
df10_setirq(df);
df10_finish_op(df, 0);
return SCPE_OK;
}
break;
@ -969,12 +1030,9 @@ t_stat rp_svc (UNIT *uptr)
if (GET_SC(uptr->u4) >= rp_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rp_drv_tab[dtype].surf) {
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
rp_attn[ctlr] |= 1<<unit;
df->status &= ~BUSY;
uptr->u3 &= ~CR_GO;
sim_debug(DEBUG_DETAIL, dptr, "RPA%o writex done\n", unit);
if (df->status & IADR_ATTN)
df10_setirq(df);
df10_finish_op(df, 0);
sim_debug(DEBUG_DETAIL, dptr, "RPA%o writex done\n", unit);
return SCPE_OK;
}
uptr->u6 = 0;
@ -982,11 +1040,12 @@ t_stat rp_svc (UNIT *uptr)
}
r = df10_read(df);
rp_buf[ctlr][uptr->u6++] = df->buf;
sim_debug(DEBUG_DATA, dptr, "RPA%o write word %d %012llo %06o\n", unit, uptr->u6, df->buf, df->wcr);
sim_debug(DEBUG_DATA, dptr, "RPA%o write word %d %012llo %06o\n",
unit, uptr->u6, df->buf, df->wcr);
if (r == 0 || uptr->u6 == RP_NUMWD) {
while (uptr->u6 < RP_NUMWD)
rp_buf[ctlr][uptr->u6++] = 0;
sim_debug(DEBUG_DETAIL, dptr, "RPA%o write (%d,%d,%d)\n", unit, cyl,
sim_debug(DEBUG_DETAIL, dptr, "RPA%o write (%d,%d,%d)\n", unit, cyl,
GET_SC(uptr->u4), GET_SF(uptr->u4));
da = GET_DA(uptr->u4, dtype) * RP_NUMWD;
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
@ -1014,8 +1073,7 @@ t_stat rp_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, "RPA%o write done\n", unit);
uptr->u3 |= DS_DRY;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
df10_setirq(df);
df10_finish_op(df, 0);
return SCPE_OK;
}
break;
@ -1073,12 +1131,10 @@ rp_boot(int32 unit_num, DEVICE * rptr)
uptr->u3 |= DS_VV;
addr = rp_buf[0][ptr] & RMASK;
wc = (rp_buf[0][ptr++] >> 18) & RMASK;
fprintf(stderr, "Boot %06o %06o\n\r", addr, wc);
while (wc != 0) {
wc = (wc + 1) & RMASK;
addr = (addr + 1) & RMASK;
word = rp_buf[0][ptr++];
fprintf(stderr, "data: %06o %06o %012llo\n\r", addr, wc, word);
if (addr < 020)
FM[addr] = word;
else

View File

@ -311,7 +311,7 @@ t_stat rs_devio(uint32 dev, uint64 *data) {
if (dptr == NULL)
return SCPE_OK;
for (ctlr = 0; ctlr < NUM_DEVS_RS; ctlr++) {
if (dptr == rs_devs[ctlr])
if (dptr == rs_devs[ctlr])
break;
}
df10 = &rs_df10[ctlr];
@ -335,6 +335,14 @@ t_stat rs_devio(uint32 dev, uint64 *data) {
df10->status &= ~07LL;
df10->status |= *data & (07LL|IADR_ATTN|IARD_RAE);
/* Clear flags */
if (*data & CONT_RESET) {
UNIT *uptr=dptr->units;
for(drive = 0; drive < NUM_UNITS_RS; drive++, uptr++) {
uptr->u3 &= DS_MOL|DS_WRL|DS_DPR|DS_DRY|DS_VV|076;
uptr->u4 &= 003400177777;
uptr->u5 &= 0177777;
}
}
if (*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR))
df10->status &= ~(*data & (DBPE_CLR|DR_EXC_CLR|CHN_CLR));
if (*data & OVER_CLR)
@ -351,8 +359,8 @@ t_stat rs_devio(uint32 dev, uint64 *data) {
set_interrupt(dev, df10->status);
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
set_interrupt(dev, df10->status);
sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n",
dev, (uint32)*data, ctlr, PC, df10->status);
sim_debug(DEBUG_CONO, dptr, "RS %03o CONO %06o %d PC=%06o %06o\n",
dev, (uint32)*data, ctlr, PC, df10->status);
return SCPE_OK;
case DATAI:
@ -370,8 +378,15 @@ t_stat rs_devio(uint32 dev, uint64 *data) {
} else if (rs_reg[ctlr] == 054) {
*data = (t_uint64)(rs_rae[ctlr]);
} else if ((rs_reg[ctlr] & 040) == 0) {
*data = (t_uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777);
*data |= ((t_uint64)(rs_drive[ctlr])) << 18;
int parity;
*data = (t_uint64)(rs_read(ctlr, rs_drive[ctlr], rs_reg[ctlr]) & 0177777);
parity = (*data >> 8) ^ *data;
parity = (parity >> 4) ^ parity;
parity = (parity >> 2) ^ parity;
parity = ((parity >> 1) ^ parity) & 1;
*data |= ((t_uint64)(parity ^ 1)) << 17;
*data |= ((t_uint64)(rs_drive[ctlr])) << 18;
}
*data |= ((t_uint64)(rs_reg[ctlr])) << 30;
sim_debug(DEBUG_DATAIO, dptr, "RS %03o DATI %012llo, %d %d PC=%06o\n",
@ -384,27 +399,29 @@ t_stat rs_devio(uint32 dev, uint64 *data) {
rs_reg[ctlr] = ((int)(*data >> 30)) & 077;
if (*data & LOAD_REG) {
if (rs_reg[ctlr] == 040) {
if (df10->status & BUSY) {
df10->status |= CC_CHAN_ACT;
return SCPE_OK;
}
if ((*data & 1) == 0) {
return SCPE_OK;
}
if (df10->status & BUSY) {
df10->status |= CC_CHAN_ACT;
return SCPE_OK;
}
df10->status &= ~(1 << df10->ccw_comp);
df10->status &= ~PI_ENABLE;
if (((*data >> 1) & 077) < FNC_XFER) {
df10->status |= CXR_ILC;
df10_setirq(df10);
sim_debug(DEBUG_DATAIO, dptr,
"RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
sim_debug(DEBUG_DATAIO, dptr,
"RS %03o command abort %012llo, %d[%d] PC=%06o %06o\n",
dev, *data, ctlr, rs_drive[ctlr], PC, df10->status);
return SCPE_OK;
}
rs_drive[ctlr] = (int)(*data >> 18) & 07;
/* Start command */
df10_setup(df10, (uint32)(*data >> 6));
df10->status &= ~PI_ENABLE;
rs_write(ctlr, rs_drive[ctlr], 0, (uint32)(*data & 077));
sim_debug(DEBUG_DATAIO, dptr,
"RS %03o command %012llo, %d[%d] PC=%06o %06o\n",
@ -453,7 +470,7 @@ rs_devirq(uint32 dev, int addr) {
}
}
for (drive = 0; drive < NUM_DEVS_RS; drive++) {
if (dptr == rs_devs[drive])
if (dptr == rs_devs[drive])
return (rs_imode[drive] ? rs_ivect[drive] : addr);
}
return addr;
@ -461,65 +478,76 @@ rs_devirq(uint32 dev, int addr) {
void
rs_write(int ctlr, int unit, int reg, uint32 data) {
UNIT *uptr = &rs_unit[(ctlr * 8) + unit];
int i;
DEVICE *dptr = rs_devs[ctlr];
int i;
DEVICE *dptr = rs_devs[ctlr];
struct df10 *df10 = &rs_df10[ctlr];
UNIT *uptr = &dptr->units[unit];
if ((uptr->u3 & CR_GO) && reg != 04) {
uptr->u3 |= (ER1_RMR << 16)|DS_ERR;
return;
}
switch(reg) {
case 000: /* control */
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d Status=%06o\n", unit, ctlr, uptr->u3);
/* Set if drive not writable */
if (uptr->flags & UNIT_WLK)
uptr->u3 |= DS_WRL;
df10->status &= ~(1 << df10->ccw_comp);
if ((data & 01) != 0 && (uptr->u3 & DS_DRY) != 0) {
uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->u3 |= data & 077;
switch (GET_FNC(data)) {
case FNC_NOP:
uptr->u3 |= DS_DRY;
break;
case FNC_SEARCH: /* search */
case FNC_WCHK: /* write check */
case FNC_WRITE: /* write */
case FNC_READ: /* read */
uptr->u3 |= DS_PIP|CR_GO;
uptr->u6 = 0;
break;
case FNC_PRESET: /* read-in preset */
uptr->u4 = 0;
if ((uptr->flags & UNIT_ATT) != 0)
uptr->u3 |= DS_VV;
uptr->u3 |= DS_DRY;
df10_setirq(df10);
break;
case FNC_DCLR: /* drive clear */
uptr->u3 |= DS_DRY;
uptr->u3 &= ~(DS_ATA|CR_GO);
rs_attn[ctlr] = 0;
clr_interrupt(df10->devnum);
for (i = 0; i < 8; i++) {
if (rs_unit[(ctlr * 8) + i].u3 & DS_ATA)
rs_attn[ctlr] = 1;
}
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
df10_setirq(df10);
break;
default:
uptr->u3 |= DS_DRY|DS_ERR|DS_ATA;
uptr->u3 |= (ER1_ILF << 16);
}
if (uptr->u3 & DS_PIP)
sim_activate(uptr, 100);
sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit,
uptr->u3);
} else {
df10->status &= ~BUSY;
df10_setirq(df10);
/* If drive not ready don't do anything */
if ((uptr->u3 & DS_DRY) == 0) {
uptr->u3 |= (ER1_RMR << 16)|DS_ERR;
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d busy\n", unit, ctlr);
return;
}
/* Check if GO bit set */
if ((data & 1) == 0) {
uptr->u3 &= ~076;
uptr->u3 |= data & 076;
sim_debug(DEBUG_DETAIL, dptr, "RSA%o %d no go\n", unit, ctlr);
return; /* No, nop */
}
uptr->u3 &= DS_ATA|DS_VV|DS_DPR|DS_MOL|DS_WRL;
uptr->u3 |= data & 076;
switch (GET_FNC(data)) {
case FNC_NOP:
uptr->u3 |= DS_DRY;
break;
case FNC_SEARCH: /* search */
case FNC_WCHK: /* write check */
case FNC_WRITE: /* write */
case FNC_READ: /* read */
uptr->u3 |= DS_PIP|CR_GO;
uptr->u6 = 0;
break;
case FNC_PRESET: /* read-in preset */
uptr->u4 = 0;
if ((uptr->flags & UNIT_ATT) != 0)
uptr->u3 |= DS_VV;
uptr->u3 |= DS_DRY;
df10_setirq(df10);
break;
case FNC_DCLR: /* drive clear */
uptr->u3 |= DS_DRY;
uptr->u3 &= ~(DS_ATA|CR_GO);
rs_attn[ctlr] = 0;
clr_interrupt(df10->devnum);
for (i = 0; i < 8; i++) {
if (rs_unit[(ctlr * 8) + i].u3 & DS_ATA)
rs_attn[ctlr] = 1;
}
if ((df10->status & IADR_ATTN) != 0 && rs_attn[ctlr] != 0)
df10_setirq(df10);
break;
default:
uptr->u3 |= DS_DRY|DS_ERR|DS_ATA;
uptr->u3 |= (ER1_ILF << 16);
}
if (uptr->u3 & DS_PIP)
sim_activate(uptr, 100);
sim_debug(DEBUG_DETAIL, dptr, "RSA%o AStatus=%06o\n", unit, uptr->u3);
return;
case 001: /* status */
break;
@ -558,20 +586,19 @@ rs_write(int ctlr, int unit, int reg, uint32 data) {
uint32
rs_read(int ctlr, int unit, int reg) {
UNIT *uptr = &rs_unit[(ctlr * 8) + unit];
struct df10 *df10;
DEVICE *dptr = rs_devs[ctlr];
struct df10 *df10 = &rs_df10[ctlr];
UNIT *uptr = &dptr->units[unit];
uint32 temp = 0;
int i;
if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */
df10 = &rs_df10[ctlr];
df10->status |= 0002000000000;
return 0;
}
switch(reg) {
case 000: /* control */
df10 = &rs_df10[ctlr];
temp = uptr->u3 & 077;
if (uptr->flags & UNIT_ATT)
temp |= CS1_DVA;
@ -657,7 +684,7 @@ t_stat rs_svc (UNIT *uptr)
uptr->u3 |= DS_DRY|DS_ATA;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
if (df->status & IADR_ATTN)
if ((df->status & (IADR_ATTN|BUSY)) == IADR_ATTN)
df10_setirq(df);
sim_debug(DEBUG_DETAIL, dptr, "RSA%o searchdone\n", unit);
break;
@ -669,15 +696,13 @@ t_stat rs_svc (UNIT *uptr)
if (GET_SC(uptr->u4) >= rs_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rs_drv_tab[dtype].surf) {
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
rs_attn[ctlr] = 1;
df->status &= ~BUSY;
uptr->u3 &= ~CR_GO;
sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit);
if (df->status & IADR_ATTN)
df10_setirq(df);
sim_debug(DEBUG_DETAIL, dptr, "RSA%o readx done\n", unit);
df10_finish_op(df, 0);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit,
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read (%d,%d)\n", unit,
GET_SC(uptr->u4), GET_SF(uptr->u4));
da = GET_DA(uptr->u4, dtype) * RS_NUMWD;
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
@ -689,7 +714,8 @@ t_stat rs_svc (UNIT *uptr)
}
df->buf = rs_buf[ctlr][uptr->u6++];
sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr);
sim_debug(DEBUG_DATA, dptr, "RSA%o read word %d %012llo %09o %06o\n",
unit, uptr->u6, df->buf, df->cda, df->wcr);
if (df10_write(df)) {
if (uptr->u6 == uptr->hwmark) {
/* Increment to next sector. Set Last Sector */
@ -707,8 +733,7 @@ t_stat rs_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, "RSA%o read done\n", unit);
uptr->u3 |= DS_DRY;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
df10_setirq(df);
df10_finish_op(df, 0);
return SCPE_OK;
}
break;
@ -718,22 +743,20 @@ t_stat rs_svc (UNIT *uptr)
if (GET_SC(uptr->u4) >= rs_drv_tab[dtype].sect ||
GET_SF(uptr->u4) >= rs_drv_tab[dtype].surf) {
uptr->u3 |= (ER1_IAE << 16)|DS_ERR|DS_DRY|DS_ATA;
rs_attn[ctlr] = 1;
df->status &= ~BUSY;
uptr->u3 &= ~CR_GO;
sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit);
if (df->status & IADR_ATTN)
df10_setirq(df);
sim_debug(DEBUG_DETAIL, dptr, "RSA%o writex done\n", unit);
df10_finish_op(df, 0);
return SCPE_OK;
}
}
r = df10_read(df);
rs_buf[ctlr][uptr->u6++] = df->buf;
sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n", unit, uptr->u6, df->buf, df->cda, df->wcr);
sim_debug(DEBUG_DATA, dptr, "RSA%o write word %d %012llo %09o %06o\n",
unit, uptr->u6, df->buf, df->cda, df->wcr);
if (r == 0 || uptr->u6 == RS_NUMWD) {
while (uptr->u6 < RS_NUMWD)
rs_buf[ctlr][uptr->u6++] = 0;
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit,
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write (%d,%d)\n", unit,
GET_SC(uptr->u4), GET_SF(uptr->u4));
da = GET_DA(uptr->u4, dtype) * RS_NUMWD;
(void)sim_fseek(uptr->fileref, da * sizeof(uint64), SEEK_SET);
@ -756,8 +779,7 @@ t_stat rs_svc (UNIT *uptr)
sim_debug(DEBUG_DETAIL, dptr, "RSA%o write done\n", unit);
uptr->u3 |= DS_DRY;
uptr->u3 &= ~CR_GO;
df->status &= ~BUSY;
df10_setirq(df);
df10_finish_op(df, 0);
return SCPE_OK;
}
break;

View File

@ -444,7 +444,7 @@ tu_devirq(uint32 dev, int addr) {
}
}
for (drive = 0; drive < NUM_DEVS_TU; drive++) {
if (dptr == tu_devs[drive])
if (dptr == tu_devs[drive])
return (tu_imode[drive] ? tu_ivect[drive] : addr);
}
return addr;
@ -1075,7 +1075,7 @@ tu_attach(UNIT * uptr, CONST char *file)
uptr->u3 = 0;
uptr->u5 = 0;
r = sim_tape_attach(uptr, file);
r = sim_tape_attach_ex(uptr, file, 0, 0);
if (r == SCPE_OK) {
uptr->u3 = CS_ATA|CS_CHANGE;
tu_attn[ctlr] = 1;