1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-14 07:39:04 +00:00

SEL32: Merge branch 'master' of git://github.com/AZBevier/SEL32-rcsim

This commit is contained in:
Richard Cornwell 2019-11-03 13:27:34 -05:00
commit f3450ddccb
8 changed files with 2051 additions and 885 deletions

View File

@ -412,7 +412,8 @@ loop:
/* Check if not chaining data */
if ((chp->ccw_flags & FLAG_DC) == 0) {
chp->ccw_cmd = (word >> 24) & 0xff; /* not DC, so set command from IOCD wd 1 */
sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw No DC, flags %04x cmd %02x\n", chp->ccw_flags, chp->ccw_cmd);
sim_debug(DEBUG_EXP, &cpu_dev,
"load_ccw No DC, flags %04x cmd %02x\n", chp->ccw_flags, chp->ccw_cmd);
docmd = 1; /* show we have a command */
}
/* Set up for this command */
@ -449,6 +450,15 @@ loop:
if (uptr == 0)
return 1; /* if none, error */
#ifdef DO_DYNAMIC_DEBUG
if ((chp->chan_dev == 0x1000) && ((chp->ccw_cmd & 0xff) == 0x80)) {
uint32 addr = chp->ccw_addr; /* set the data address */
/* start debugging */
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP);
sim_debug(DEBUG_CMD, &cpu_dev, "cmd 80 MT wds @ addr %08x %08x %08x %08x %08x\n",
addr, M[addr>>2], M[(addr+4)>>2], M[(addr+8)>>2], M[(addr+12)>>2]);
}
#endif
#ifndef CON_BUG
#ifdef DO_DYNAMIC_DEBUG
if ((chp->chan_dev == 0x7efc) && ((chp->ccw_cmd & 0xff) == 0x03) && (chp->ccw_count == 0))
@ -969,13 +979,13 @@ t_stat startxio(uint16 lchsa, uint32 *status) {
/* start processing the IOCL */
if (load_ccw(chp, 0) || (chp->chan_status & STATUS_PCI)) {
/* we have an error or user requested interrupt, return status */
store_csw(chp); /* store the status in the inch status dw */
sim_debug(DEBUG_CMD, &cpu_dev, "startxio store csw CC1 chan %04x status %08x\n",
sim_debug(DEBUG_CMD, &cpu_dev, "startxio store csw CC2 chan %04x status %08x\n",
chan, chp->chan_status);
store_csw(chp); /* store the status in the inch status dw */
chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */
dev_status[chsa] = 0; /* no device status */
*status = CC1BIT; /* status stored, so CC1 */
return SCPE_OK; /* CC1 (0x40) status stored */
*status = CC2BIT; /* status stored, so CC2 */
return SCPE_OK; /* CC2 (0x20) status stored */
}
*status = CC1BIT; /* CCs = 1, SIO accepted & queued, will not echo status */

View File

@ -5824,7 +5824,7 @@ newpsd:
}
/* do not update pc for page fault */
case DEMANDPG_TRAP: /* 0xC4 Demand Page Fault Trap (V6&V9 Only) */
#ifndef DO_DYNAMIC_DEBUG
#ifdef DO_DYNAMIC_DEBUG
/* start debugging */
if (TRAPME == DEMANDPG_TRAP)
cpu_dev.dctrl |= (DEBUG_INST | DEBUG_CMD | DEBUG_EXP | DEBUG_IRQ);

View File

@ -111,10 +111,12 @@
#define NUM_UNITS_MT 4 /* 4 of 8 devices */
#define NUM_DEVS_DISK 1 /* 1 DP02 disk drive controller */
#define NUM_UNITS_DISK 4 /* 4 disk drive devices */
//#define NUM_DEVS_SCFI 1 /* 1 scfi (SCSI) disk drive units */
//#define NUM_UNITS_SCFI 1 /* 1 of 4 disk drive devices */
#define NUM_DEVS_SCFI 2 /* 2 scfi (SCSI) disk drive units */
#define NUM_UNITS_SCFI 2 /* 2 of 4 disk drive devices */
#define NUM_DEVS_HSDP 1 /* 1 HSPD disk drive controller */
#define NUM_UNITS_HSDP 2 /* 2 disk drive devices */
#define NUM_DEVS_SCFI 1 /* 1 scfi (SCSI) disk drive units */
#define NUM_UNITS_SCFI 1 /* 1 of 4 disk drive devices */
//#define NUM_DEVS_SCFI 2 /* 2 scfi (SCSI) disk drive units */
//#define NUM_UNITS_SCFI 2 /* 2 of 4 disk drive devices */
#define NUM_DEVS_RTOM 1 /* 1 IOP RTOM channel */
#define NUM_UNITS_RTOM 1 /* 1 IOP RTOM device (clock & interval timer) */
#define NUM_DEVS_LPR 1 /* 1 IOP Line printer */
@ -144,6 +146,12 @@ extern DEVICE dda_dev;
#if NUM_DEVS_DISK > 1
extern DEVICE ddb_dev;
#endif
#ifdef NUM_DEVS_HSDP
extern DEVICE dpa_dev;
#endif
#if NUM_DEVS_HSDP > 1
extern DEVICE dpb_dev;
#endif
#ifdef NUM_DEVS_SCFI
extern DEVICE sda_dev;
#endif

File diff suppressed because it is too large Load Diff

1128
SEL32/sel32_hsdp.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -139,12 +139,12 @@ OTAB EQU $
#define MT_MODEMSK 0xFF /* Mode Mask */
/* set mode bits for BTP (MT_SETM) */
#define MT_MODE_AUTO 0x80 /* =0 Perform auto error recodery on read */
#define MT_MODE_AUTO 0x80 /* =0 Perform auto error recovery on read */
#define MT_MODE_FORCE 0x80 /* =1 Read regardless if error recovery fails */
#define MT_MDEN_800 0x40 /* =0 select 800 BPI NRZI mode 9 track only */
#define MT_MDEN_1600 0x40 /* =1 select 1600 BPI PE mode 9 track only */
#define MT_MDEN_6250 0x20 /* =0 Use mode from bit one for NRZI/PE */
#define MT_MDEN_6250 0x20 /* =1 6250 BPI GCR mode 9 track only */
#define MT_MDEN_6250 0x02 /* =0 Use mode from bit one for NRZI/PE */
#define MT_MDEN_6250 0x02 /* =1 6250 BPI GCR mode 9 track only */
#define MT_MDEN_SCATGR 0x01 /* =1 HSTP scatter/gather mode */
#define MT_MDEN_MSK 0xc0 /* Density mask */
@ -445,24 +445,36 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd processing unit %04x cmd %02x\n", unit, cmd);
switch (cmd & 0xF) {
case 0x0: /* INCH command */
switch (cmd & 0xFF) {
case 0x00: /* INCH command */
/* POS has INCH buffer address and us9 the count */
/* just return OK and channel software will use POS as status buffer */
sim_debug(DEBUG_DETAIL, &mta_dev, "mt_startcmd INCH done unit %04x cmd %02x\n",
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd INCH done unit %04x cmd %02x\n",
unit, cmd);
/* UTX_needs_interrupt */
cmd = MT_CMDMSK; /* insert INCH cmd as 0xff */
/* fall through */
case 0x3: /* Tape motion commands */
/* UTX_needs_interrupt */
case 0x03: /* Tape motion commands or NOP */
case 0x13: /* Read and compare command */
case 0x23: /* Rewind command */
case 0x33: /* Rewind and unload */
case 0x43: /* Advance record */
case 0x53: /* Backspace record */
case 0x63: /* Advance filemark */
case 0x73: /* Backspace filemark */
case 0x83: /* Set Mode command */
case 0x93: /* Write Tape filemark */
case 0xA3: /* Erase 3.5 of tape */
/* UTX_needs_interrupt on NOP or INCH */
/* fall through */
case 0x1: /* Write command */
case 0x2: /* Read command */
case 0xc: /* Read backward */
case 0x01: /* Write command */
case 0x02: /* Read command */
case 0x0C: /* Read backward */
if (cmd != 0x03) /* if this is a nop do not zero status */
uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */
uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */
/* Fall through */
// case 0x4: /* Sense */
if (sim_tape_wrp(uptr))
uptr->SNS |= (SNS_WRP); /* write protected */
if (sim_tape_bot(uptr))
@ -472,27 +484,31 @@ uint8 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
/* Fall through */
case 0x4: /* Sense */
#ifndef FIX_DIAG
case 0x80: /* Unknown diag cmd with byte cnt of 0x0c */
#endif
uptr->CMD &= ~(MT_CMDMSK); /* clear out last cmd */
uptr->CMD |= cmd & MT_CMDMSK; /* insert new cmd */
CLR_BUF(uptr); /* buffer is empty */
/* INCH cmd has iNCH buffer address in POS, so leave it */
/* INCH cmd has INCH buffer address in POS, so leave it */
if (cmd != MT_CMDMSK)
uptr->POS = 0; /* reset buffer position pointer */
sim_activate(uptr, 100); /* Start unit off */
mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd sense return 0 chan %04x cmd %02x\n",
chan, cmd);
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd sense %08x return 0 chan %04x cmd %02x\n",
uptr->SNS, chan, cmd);
return 0;
default: /* invalid command */
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd CMDREJ return chan %04x cmd %02x\n", chan, cmd);
sim_debug(DEBUG_EXP, &mta_dev, "mt_startcmd CMDREJ return chan %04x cmd %02x\n",
chan, cmd);
uptr->SNS |= SNS_CMDREJ;
break;
}
if (uptr->SNS & 0xff000000) /* errors? */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
sim_debug(DEBUG_EXP, &mta_dev,
"mt_startcmd ret CHNEND|DEVEND chan %04x unit %04x cmd %02x\n", chan, unit, cmd);
"mt_startcmd ret CHNEND|DEVEND chan %04x unit %04x cmd %02x\n", chan, unit, cmd);
return SNS_CHNEND|SNS_DEVEND;
}
@ -556,8 +572,9 @@ t_stat mt_srv(UNIT *uptr)
t_mtrlnt reclen;
t_stat r = SCPE_ARG; /* Force error if not set */
uint8 ch;
uint8 zc = 0;
sim_debug(DEBUG_DATA, &mta_dev, "mt_srv unit %04x cmd %02x\n", unit, cmd);
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv unit %04x cmd %02x\n", unit, cmd);
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->SNS |= SNS_INTVENT; /* unit intervention required */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
@ -576,6 +593,33 @@ t_stat mt_srv(UNIT *uptr)
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
#ifndef FIX_DIAG
case 0x80: /* other? */ /* default to NOP */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv cmd 80 DIAG unit=%04x SNS %08x\n", unit, uptr->SNS);
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
sim_debug(DEBUG_DETAIL, &mta_dev, "sense unit %02x byte 0 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 0 */
ch = (uptr->SNS >> 16) & 0xff; /* get sense byte 1 status */
sim_debug(DEBUG_DETAIL, &mta_dev, "sense unit %02x byte 1 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 1 */
ch = (uptr->SNS >> 8) & 0xff; /* get sense byte 2 status */
sim_debug(DEBUG_DETAIL, &mta_dev, "sense unit %02x byte 2 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 2 */
ch = (uptr->SNS >> 0) & 0xff; /* get sense byte 3 status */
sim_debug(DEBUG_DETAIL, &mta_dev, "sense unit %02x byte 3 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 3 */
for (ch=4; ch < 0xc; ch++) {
// chan_write_byte(addr, &ch); /* write byte */
chan_write_byte(addr, &zc); /* write zero byte */
}
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv DIAG SNS %08x char complete unit=%02x\n",
uptr->SNS, unit);
break;
#endif
case MT_NOP: /* 0x03 */ /* NOP motion command */
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
@ -583,7 +627,7 @@ t_stat mt_srv(UNIT *uptr)
break;
case MT_SENSE: /* 0x04 */ /* get sense data */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv cmd 4 SENSE unit=%04x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv cmd 4 SENSE %08x unit=%04x\n", uptr->SNS, unit);
ch = (uptr->SNS >> 24) & 0xff; /* get sense byte 0 status */
sim_debug(DEBUG_DETAIL, &mta_dev, "sense unit %02x byte 0 %02x\n", unit, ch);
chan_write_byte(addr, &ch); /* write byte 0 */
@ -601,7 +645,7 @@ t_stat mt_srv(UNIT *uptr)
mt_busy[bufnum] &= ~1; /* make our buffer not busy */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv SENSE %08x char complete unit=%02x\n",
uptr->POS, unit);
uptr->SNS, unit);
break;
case MT_READ: /* 0x02 */ /* read a record from the device */
@ -616,8 +660,8 @@ t_stat mt_srv(UNIT *uptr)
mt_busy[bufnum] &= ~1; /* not busy anymore */
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* set chan end, dev end status */
sim_debug(DEBUG_CMD, &mta_dev,
"mt_srv READ %04x char complete unit=%02x sense %08x\n",
uptr->POS, unit, uptr->SNS);
"mt_srv READ %04x char complete unit=%02x sense %08x\n",
uptr->POS, unit, uptr->SNS);
break;
}
/* read is not completed, get an input char */
@ -703,90 +747,90 @@ t_stat mt_srv(UNIT *uptr)
break;
case MT_WRITE: /* 0x01 */ /* write record */
/* Check if write protected */
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_DETAIL, &mta_dev, "Write write protected unit=%02x\n", unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
/* Check if write protected */
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, &mta_dev, "Write write protected unit=%02x\n", unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
/* Grab data until channel has no more */
if (chan_read_byte(addr, &ch)) {
if (uptr->POS > 0) { /* Only if data in record */
reclen = uptr->hwmark;
sim_debug(DEBUG_DETAIL, &mta_dev, "Write unit=%02x Block %04x chars\n",
unit, reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
uptr->POS = 0;
uptr->CMD &= ~MT_CMDMSK;
mt_error(uptr, addr, r, dptr); /* Record errors */
}
} else {
/* Grab data until channel has no more */
if (chan_read_byte(addr, &ch)) {
if (uptr->POS > 0) { /* Only if data in record */
reclen = uptr->hwmark;
sim_debug(DEBUG_CMD, &mta_dev, "Write unit=%02x Block %04x chars\n",
unit, reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
uptr->POS = 0;
uptr->CMD &= ~MT_CMDMSK;
mt_error(uptr, addr, r, dptr); /* Record errors */
}
} else {
mt_buffer[bufnum][uptr->POS++] = ch;
sim_debug(DEBUG_DATA, &mta_dev, "Write data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
unit, uptr->POS, ch);
uptr->hwmark = uptr->POS;
}
sim_activate(uptr, 20);
break;
}
sim_activate(uptr, 20);
break;
case MT_RDBK: /* 0x0C */ /* Read Backwards */
if (uptr->CMD & MT_READDONE) {
if (uptr->CMD & MT_READDONE) {
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
return SCPE_OK;
}
}
/* If at end of record, fill buffer */
if (BUF_EMPTY(uptr)) {
/* If at end of record, fill buffer */
if (BUF_EMPTY(uptr)) {
if (sim_tape_bot(uptr)) {
uptr->CMD &= ~MT_CMDMSK;
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, &mta_dev, "Read backward unit=%02x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "Read backward unit=%02x\n", unit);
if ((r = sim_tape_rdrecr(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) {
uptr->CMD &= ~(MT_CMDMSK|MT_READDONE);
return mt_error(uptr, addr, r, dptr);
}
uptr->POS = reclen;
uptr->hwmark = reclen;
sim_debug(DEBUG_DETAIL, &mta_dev, "Binary Block %04x chars\n", reclen);
}
sim_debug(DEBUG_CMD, &mta_dev, "Binary Block %04x chars\n", reclen);
}
ch = mt_buffer[bufnum][--uptr->POS];
ch = mt_buffer[bufnum][--uptr->POS];
if (chan_write_byte(addr, &ch)) {
sim_debug(DEBUG_DATA, &mta_dev, "Read unit=%02x EOR cnt %04x\n",
unit, uptr->POS);
/* If not read whole record, skip till end */
if (uptr->POS >= 0) {
sim_activate(uptr, (uptr->POS) * 20);
uptr->CMD |= MT_READDONE;
return SCPE_OK;
}
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else {
sim_debug(DEBUG_DATA, &mta_dev, "Read data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
if (uptr->POS == 0) { /* In IRG */
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else
sim_activate(uptr, 20);
}
break;
if (chan_write_byte(addr, &ch)) {
sim_debug(DEBUG_CMD, &mta_dev, "Read unit=%02x EOR cnt %04x\n",
unit, uptr->POS);
/* If not read whole record, skip till end */
if (uptr->POS >= 0) {
sim_activate(uptr, (uptr->POS) * 20);
uptr->CMD |= MT_READDONE;
return SCPE_OK;
}
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else {
sim_debug(DEBUG_DATA, &mta_dev, "Read data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
if (uptr->POS == 0) { /* In IRG */
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
} else
sim_activate(uptr, 20);
}
break;
case MT_WTM: /* 0x93 */ /* Write tape filemark */
if (uptr->POS == 0) {
if (uptr->POS == 0) {
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~MT_CMDMSK;
@ -796,211 +840,223 @@ t_stat mt_srv(UNIT *uptr)
}
uptr->POS ++;
sim_activate(uptr, 500);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "Write Mark unit=%02x\n", unit);
} else {
sim_debug(DEBUG_CMD, &mta_dev, "Write Mark unit=%02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
r = sim_tape_wrtmk(uptr);
chan_end(addr, SNS_DEVEND);
chan_end(addr, SNS_DEVEND); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND);
mt_busy[bufnum] &= ~1;
}
break;
}
break;
case MT_BSR: /* 0x53 */ /* Backspace record */
sim_debug(DEBUG_DETAIL, &mta_dev, "mt_srv cmd 0x53 BSR unit %02x POS %04x\n",
unit, uptr->POS);
switch (uptr->POS ) {
case 0:
if (sim_tape_bot(uptr)) {
uptr->CMD &= ~MT_CMDMSK;
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
uptr->POS++;
sim_activate(uptr, 50);
break;
case 1:
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "Backspace rec unit %02x POS %04x\n",
unit, uptr->POS);
r = sim_tape_sprecr(uptr, &reclen);
/* We don't set EOF on BSR */
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "MARK\n");
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "Backspace reclen %04x\n", reclen);
sim_activate(uptr, 50);
}
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_BSF: /* 0x73 */ /* Backspace file */
sim_debug(DEBUG_DETAIL, &mta_dev, "mt_srv cmd 0x73 BSF unit %02x\n", unit);
switch(uptr->POS) {
case 0:
if (sim_tape_bot(uptr)) {
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
uptr->POS++;
sim_activate(uptr, 500);
break;
case 1:
sim_debug(DEBUG_DETAIL, &mta_dev, "Backspace file unit=%02x\n", unit);
r = sim_tape_sprecr(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_BOT) {
uptr->POS+= 2;
sim_activate(uptr, 50);
} else {
sim_activate(uptr, 20);
}
break;
case 2: /* File Mark */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND);
break;
case 3: /* BOT */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND);
break;
}
break;
case MT_FSR: /* 0x43 */ /* Advance record */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip rec entry unit=%02x ", unit);
uptr->POS++;
sim_activate(uptr, 50);
break;
case 1:
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip rec unit=%02x ", unit);
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS = 3;
sim_debug(DEBUG_DETAIL, &mta_dev, "FSR MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->POS = 4;
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "FSR skipped %04x byte record\n",
reclen);
sim_activate(uptr, 10 + (10 * reclen));
}
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND);
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip record Completed\n");
break;
case 4:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITCHK);
break;
}
break;
case MT_FSF: /* 0x63 */ /* advance filemark */
switch(uptr->POS) {
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv cmd 0x53 BSR unit %02x POS %04x\n",
unit, uptr->POS);
switch (uptr->POS ) {
case 0:
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip file entry unit=%02x\n", unit);
if (sim_tape_bot(uptr)) {
uptr->CMD &= ~MT_CMDMSK;
mt_busy[GET_DEV_BUF(dptr->flags)] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
return SCPE_OK;
}
uptr->POS++;
sim_activate(uptr, 50);
break;
case 1:
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip file unit=%02x\n", unit);
r = sim_tape_sprecf(uptr, &reclen);
uptr->POS++;
sim_debug(DEBUG_CMD, &mta_dev, "Backspace rec unit %02x POS %04x\n",
unit, uptr->POS);
r = sim_tape_sprecr(uptr, &reclen);
/* We don't set EOF on BSR */
if (r == MTSE_TMK) {
uptr->POS++;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_DETAIL, &mta_dev, "FSF MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->SNS |= SNS_EOT; /* set EOT status */
uptr->POS+= 2;
sim_debug(DEBUG_CMD, &mta_dev, "MARK\n");
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "FSF skipped %04x byte record\n", reclen);
sim_debug(DEBUG_CMD, &mta_dev, "Backspace reclen %04x\n", reclen);
sim_activate(uptr, 50);
}
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
sim_debug(DEBUG_DETAIL, &mta_dev, "Skip file done unit=%02x\n", unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITCHK|SNS_UNITCHK);
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_BSF: /* 0x73 */ /* Backspace file */
sim_debug(DEBUG_CMD, &mta_dev, "mt_srv cmd 0x73 BSF unit %02x\n", unit);
switch(uptr->POS) {
case 0:
if (sim_tape_bot(uptr)) {
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
uptr->POS++;
sim_activate(uptr, 500);
break;
case 1:
sim_debug(DEBUG_CMD, &mta_dev, "Backspace file unit=%02x\n", unit);
r = sim_tape_sprecr(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_BOT) {
uptr->POS+= 2;
sim_activate(uptr, 50);
} else {
sim_activate(uptr, 20);
}
break;
case 2: /* File Mark */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case 3: /* BOT */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
}
break;
case MT_FSR: /* 0x43 */ /* Advance record */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, &mta_dev, "Skip rec entry unit=%02x ", unit);
uptr->POS++;
sim_activate(uptr, 50);
break;
case 1:
uptr->POS++;
sim_debug(DEBUG_CMD, &mta_dev, "Skip rec unit=%02x ", unit);
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS = 3;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, &mta_dev, "FSR MARK\n");
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->POS = 4;
uptr->SNS |= SNS_EOT; /* set EOT status */
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_CMD, &mta_dev, "FSR skipped %04x byte record\n",
reclen);
sim_activate(uptr, 10 + (10 * reclen));
}
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, &mta_dev, "Skip record Completed\n");
chan_end(addr, SNS_DEVEND); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITEXP); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
sim_debug(DEBUG_CMD, &mta_dev, "Skip record at EOF\n");
break;
case 4:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, &mta_dev, "Skip record at EOT\n");
//BAD chan_end(addr, SNS_DEVEND|SNS_UNITCHK); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_FSF: /* 0x63 */ /* advance filemark */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, &mta_dev, "Skip file entry sense %08x unit %02x\n", uptr->SNS, unit);
uptr->POS++;
sim_activate(uptr, 50);
break;
case 1:
sim_debug(DEBUG_CMD, &mta_dev, "Skip file unit=%02x\n", unit);
r = sim_tape_sprecf(uptr, &reclen);
if (r == MTSE_TMK) {
uptr->POS++;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, &mta_dev, "FSF EOF MARK sense %08x\n", uptr->SNS);
sim_activate(uptr, 50);
} else if (r == MTSE_EOM) {
uptr->SNS |= SNS_EOT; /* set EOT status */
sim_debug(DEBUG_CMD, &mta_dev, "FSF EOT sense %08x\n", uptr->SNS);
uptr->POS+= 2;
sim_activate(uptr, 50);
} else {
sim_debug(DEBUG_CMD, &mta_dev, "FSF skipped %04x byte record\n", reclen);
sim_activate(uptr, 50);
}
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS &= ~SNS_LOAD; /* reset BOT */
sim_debug(DEBUG_CMD, &mta_dev, "Skip file done sense %08x unit %02x\n", uptr->SNS, unit);
chan_end(addr, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS &= ~SNS_LOAD; /* reset BOT */
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, &mta_dev, "Skip file got EOT sense %08x unit %02x\n", uptr->SNS, unit);
//BAD chan_end(addr, SNS_DEVEND|SNS_UNITCHK); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
chan_end(addr, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_ERG: /* 0xA3 */ /* Erace 3.5 in tape */
switch (uptr->POS) {
case 0:
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITCHK);
} else {
uptr->POS ++;
sim_activate(uptr, 500);
}
break;
case 1:
sim_debug(DEBUG_DETAIL, &mta_dev, "Erase unit=%02x\n", unit);
r = sim_tape_wrgap(uptr, 35);
sim_activate(uptr, 5000);
uptr->POS++;
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND);
}
break;
switch (uptr->POS) {
case 0:
if (sim_tape_wrp(uptr)) {
uptr->SNS |= SNS_CMDREJ;
uptr->CMD &= ~MT_CMDMSK;
mt_busy[bufnum] &= ~1;
chan_end(addr, SNS_DEVEND|SNS_UNITCHK); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
} else {
uptr->POS ++;
sim_activate(uptr, 500);
}
break;
case 1:
sim_debug(DEBUG_CMD, &mta_dev, "Erase unit=%02x\n", unit);
r = sim_tape_wrgap(uptr, 35);
sim_activate(uptr, 5000);
uptr->POS++;
break;
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
/* we are done dev|chan end */
chan_end(addr, SNS_DEVEND); //NEW chan_end(addr, SNS_CHNEND|SNS_DEVEND);
break;
}
break;
case MT_REW: /* 0x23 */ /* rewind tape */
if (uptr->POS == 0) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, &mta_dev, "Start rewind unit %02x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "Start rewind unit %02x\n", unit);
sim_activate(uptr, 1500);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "Rewind complete unit %02x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "Rewind complete unit %02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
r = sim_tape_rewind(uptr);
uptr->SNS |= SNS_LOAD; /* set BOT */
@ -1015,7 +1071,7 @@ t_stat mt_srv(UNIT *uptr)
mt_busy[bufnum] &= ~1;
sim_activate(uptr, 30000);
} else {
sim_debug(DEBUG_DETAIL, &mta_dev, "Unload unit=%02x\n", unit);
sim_debug(DEBUG_CMD, &mta_dev, "Unload unit=%02x\n", unit);
uptr->CMD &= ~(MT_CMDMSK);
r = sim_tape_detach(uptr);
}

View File

@ -1,6 +1,6 @@
/* sel32_scfi.c: SEL-32 SCFI SCSI Disk controller
Copyright (c) 2018, James C. Bevier
Copyright (c) 2018-2019, James C. Bevier
Portions provided by Richard Cornwell and other SIMH contributers
Permission is hereby granted, free of charge, to any person obtaining a
@ -32,16 +32,15 @@ extern void set_devattn(uint16 addr, uint8 flags);
extern t_stat chan_boot(uint16 addr, DEVICE *dptr);
extern int test_write_byte_end(uint16 chsa);
extern uint32 M[]; /* our memory */
extern uint32 SPAD[]; /* cpu SPAD memory */
extern uint32 M[]; /* our memory */
extern uint32 SPAD[]; /* cpu SPAD memory */
#ifdef NUM_DEVS_SCFI
#define UNIT_V_TYPE (UNIT_V_UF + 0)
#define UNIT_TYPE (0xf << UNIT_V_TYPE)
#define GET_TYPE(x) ((UNIT_TYPE & (x)) >> UNIT_V_TYPE)
#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE))
//#define UNIT_SCFI UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE | UNIT_FIX | UNIT_IDLE
#define SET_TYPE(x) (UNIT_TYPE & ((x) << UNIT_V_TYPE))
#define UNIT_SCFI UNIT_ATTABLE | UNIT_IDLE
/* INCH command information */
@ -83,89 +82,89 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option
#define CMD u3
/* u3 */
/* in u3 is device command code and status */
#define DSK_CMDMSK 0x00ff /* Command being run */
#define DSK_STAR 0x0100 /* STAR value in u4 */
#define DSK_NU2 0x0200 /* */
#define DSK_READDONE 0x0400 /* Read finished, end channel */
#define DSK_ENDDSK 0x0800 /* Sensed end of disk */
#define DSK_SEEKING 0x1000 /* Disk is currently seeking */
#define DSK_READING 0x2000 /* Disk is reading data */
#define DSK_WRITING 0x4000 /* Disk is writing data */
#define DSK_BUSY 0x8000 /* Flag to send a CUE */
#define DSK_CMDMSK 0x00ff /* Command being run */
#define DSK_STAR 0x0100 /* STAR value in u4 */
#define DSK_NU2 0x0200 /* */
#define DSK_READDONE 0x0400 /* Read finished, end channel */
#define DSK_ENDDSK 0x0800 /* Sensed end of disk */
#define DSK_SEEKING 0x1000 /* Disk is currently seeking */
#define DSK_READING 0x2000 /* Disk is reading data */
#define DSK_WRITING 0x4000 /* Disk is writing data */
#define DSK_BUSY 0x8000 /* Flag to send a CUE */
/* commands */
#define DSK_INCH 0x00 /* Initialize channel */
#define DSK_WD 0x01 /* Write data */
#define DSK_RD 0x02 /* Read data */
#define DSK_NOP 0x03 /* No operation */
#define DSK_SNS 0x04 /* Sense */
#define DSK_SCK 0x07 /* Seek cylinder, track, sector */
#define DSK_TIC 0x08 /* Transfer in channel */
#define DSK_FNSK 0x0B /* Format for no skip */
#define DSK_LPL 0x13 /* Lock protected label */
#define DSK_LMR 0x1F /* Load mode register */
#define DSK_RES 0x23 /* Reserve */
#define DSK_WSL 0x31 /* Write sector label */
#define DSK_RSL 0x32 /* Read sector label */
#define DSK_REL 0x33 /* Release */
#define DSK_XEZ 0x37 /* Rezero */
#define DSK_POR 0x43 /* Priority Override */
#define DSK_IHA 0x47 /* Increment head address */
#define DSK_SRM 0x4F /* Set reserve track mode */
#define DSK_WTL 0x51 /* Write track label */
#define DSK_RTL 0x52 /* Read track label */
#define DSK_XRM 0x5F /* Reset reserve track mode */
#define DSK_RAP 0xA2 /* Read angular positions */
#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */
#define DSK_ICH 0xFF /* Initialize Controller */
#define DSK_INCH 0x00 /* Initialize channel */
#define DSK_WD 0x01 /* Write data */
#define DSK_RD 0x02 /* Read data */
#define DSK_NOP 0x03 /* No operation */
#define DSK_SNS 0x04 /* Sense */
#define DSK_SCK 0x07 /* Seek cylinder, track, sector */
#define DSK_TIC 0x08 /* Transfer in channel */
#define DSK_FNSK 0x0B /* Format for no skip */
#define DSK_LPL 0x13 /* Lock protected label */
#define DSK_LMR 0x1F /* Load mode register */
#define DSK_RES 0x23 /* Reserve */
#define DSK_WSL 0x31 /* Write sector label */
#define DSK_RSL 0x32 /* Read sector label */
#define DSK_REL 0x33 /* Release */
#define DSK_XEZ 0x37 /* Rezero */
#define DSK_POR 0x43 /* Priority Override */
#define DSK_IHA 0x47 /* Increment head address */
#define DSK_SRM 0x4F /* Set reserve track mode */
#define DSK_WTL 0x51 /* Write track label */
#define DSK_RTL 0x52 /* Read track label */
#define DSK_XRM 0x5F /* Reset reserve track mode */
#define DSK_RAP 0xA2 /* Read angular positions */
#define DSK_TESS 0xAB /* Test STAR (subchannel target address register) */
#define DSK_ICH 0xFF /* Initialize Controller */
#define STAR u4
/* u4 - sector target address register (STAR) */
/* Holds the current cylinder, head(track), sector */
#define DISK_CYL 0xFFFF0000 /* cylinder mask */
#define DISK_TRACK 0x0000FF00 /* track mask */
#define DISK_SECTOR 0x000000ff /* sector mask */
#define DISK_CYL 0xFFFF0000 /* cylinder mask */
#define DISK_TRACK 0x0000FF00 /* track mask */
#define DISK_SECTOR 0x000000ff /* sector mask */
#define SNS u5
/* u5 */
/* Sense byte 0 - mode register */
#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */
#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */
#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */
#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */
#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */
#define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */
#define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */
#define SNS_RESERV 0x01000000 /* Reserved */
#define SNS_DROFF 0x80000000 /* Drive Carriage will be offset */
#define SNS_TRKOFF 0x40000000 /* Track offset: 0=positive, 1=negative */
#define SNS_RDTMOFF 0x20000000 /* Read timing offset = 1 */
#define SNS_RDSTRBT 0x10000000 /* Read strobe timing: 1=positive, 0=negative */
#define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */
#define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */
#define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */
#define SNS_RESERV 0x01000000 /* Reserved */
/* Sense byte 1 */
#define SNS_CMDREJ 0x800000 /* Command reject */
#define SNS_INTVENT 0x400000 /* Unit intervention required */
#define SNS_SPARE1 0x200000 /* Spare */
#define SNS_EQUCHK 0x100000 /* Equipment check */
#define SNS_DATCHK 0x080000 /* Data Check */
#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */
#define SNS_DSKFERR 0x020000 /* Disk format error */
#define SNS_DEFTRK 0x010000 /* Defective track encountered */
#define SNS_CMDREJ 0x800000 /* Command reject */
#define SNS_INTVENT 0x400000 /* Unit intervention required */
#define SNS_SPARE1 0x200000 /* Spare */
#define SNS_EQUCHK 0x100000 /* Equipment check */
#define SNS_DATCHK 0x080000 /* Data Check */
#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */
#define SNS_DSKFERR 0x020000 /* Disk format error */
#define SNS_DEFTRK 0x010000 /* Defective track encountered */
/* Sense byte 2 */
#define SNS_LAST 0x8000 /* Last track flag encountered */
#define SNS_AATT 0x4000 /* At Alternate track */
#define SNS_WPER 0x2000 /* Write protection error */
#define SNS_WRL 0x1000 /* Write lock error */
#define SNS_MOCK 0x0800 /* Mode check */
#define SNS_INAD 0x0400 /* Invalid memory address */
#define SNS_RELF 0x0200 /* Release fault */
#define SNS_CHER 0x0100 /* Chaining error */
#define SNS_LAST 0x8000 /* Last track flag encountered */
#define SNS_AATT 0x4000 /* At Alternate track */
#define SNS_WPER 0x2000 /* Write protection error */
#define SNS_WRL 0x1000 /* Write lock error */
#define SNS_MOCK 0x0800 /* Mode check */
#define SNS_INAD 0x0400 /* Invalid memory address */
#define SNS_RELF 0x0200 /* Release fault */
#define SNS_CHER 0x0100 /* Chaining error */
/* Sense byte 3 */
#define SNS_REVL 0x80 /* Revolution lost */
#define SNS_DADE 0x40 /* Disc addressing or seek error */
#define SNS_BUCK 0x20 /* Buffer check */
#define SNS_ECCS 0x10 /* ECC error in sector label */
#define SNS_ECCD 0x08 /* ECC error iin data */
#define SNS_ECCT 0x04 /* ECC error in track label */
#define SNS_RTAE 0x02 /* Reserve track access error */
#define SNS_UESS 0x01 /* Uncorrectable ECC error */
#define SNS_REVL 0x80 /* Revolution lost */
#define SNS_DADE 0x40 /* Disc addressing or seek error */
#define SNS_BUCK 0x20 /* Buffer check */
#define SNS_ECCS 0x10 /* ECC error in sector label */
#define SNS_ECCD 0x08 /* ECC error iin data */
#define SNS_ECCT 0x04 /* ECC error in track label */
#define SNS_RTAE 0x02 /* Reserve track access error */
#define SNS_UESS 0x01 /* Uncorrectable ECC error */
#define ATTR u6
/* u6 */
@ -191,66 +190,47 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option
/* allocated during attach command for each unit defined */
struct ddata_t
{
uint8 rbuf[1024]; /* read buffer, Sector buffer 768 or 1024 */
uint8 wbuf[1024]; /* write buffer, Sector buffer 768 or 1024 */
uint32 cpos; /* Position of head of cylinder in file */
uint32 tstart; /* Location of start of cyl/track/sect in data */
uint32 spare; /* drive register spare */
uint16 tsize; /* Size of one track in byte */
uint16 ssize; /* Size of one sector in bytes */
uint16 ccyl; /* Current Cylinder number */
uint16 cyl; /* Cylinder head at */
uint16 tpos; /* Track position */
uint16 spos; /* Sector position */
uint16 dlen; /* remaining in data */
uint16 rec; /* Current record number */
uint16 count; /* Remaining in current operation */
uint16 cyl; /* Cylinder head at */
uint16 tpos; /* Track position */
uint16 spos; /* Sector position */
};
/* disk definition structure */
struct scfi_t
{
const char *name; /* Device ID Name */
uint32 taus; /* total allocation units */
uint16 bms; /* bit map size */
uint16 nhds; /* Number of heads */
uint16 ssiz; /* sector size in words */
uint16 spt; /* # sectors per track(cylinder) */
uint8 spau; /* # sectors per allocation unit */
uint8 spb; /* # sectors per block (192 WDS)*/
uint32 cyl; /* Number of cylinders */
uint8 type; /* Device type code */
const char *name; /* Device ID Name */
uint32 taus; /* total allocation units */
uint16 bms; /* bit map size */
uint16 nhds; /* Number of heads */
uint16 ssiz; /* sector size in words */
uint16 spt; /* # sectors per track(cylinder) */
uint8 spau; /* # sectors per allocation unit */
uint8 spb; /* # sectors per block (192 WDS)*/
uint32 cyl; /* Number of cylinders */
uint8 type; /* Device type code */
}
scfi_type[] =
{
/* Class E Disc Devices */
{"FE004", 5888, 184, 256, 192, 23, 1, 1, 1, 0x80}, /*0 4 M */
{"CE010", 12800, 200, 2, 96, 16, 1, 2, 400, 0x60}, /*1 10 M */
{"ME040", 23000, 719, 5, 192, 23, 2, 1, 400, 0x40}, /*2 40 M */
{"ME080", 46000, 1438, 5, 192, 23, 2, 1, 800, 0x40}, /*3 80 M */
{"ME300", 87400, 2732, 19, 192, 23, 4, 1, 800, 0x40}, /*4 300 M */
{"FE005", 5888, 184, 4, 192, 23, 1, 1, 64, 0x80}, /*5 5 M */
/* Class F Disc Devices */
{"FL001", 1334, 0, 2, 64, 26, 3, 3, 26, 0x40}, /*6 1 M */
{"MH040", 20000, 625, 5, 192, 20, 2, 1, 40, 0x40}, /*7 40 M */
{"MH080", 40000, 1250, 5, 192, 20, 2, 1, 80, 0x40}, /*8 80 M */
{"MH300", 76000, 2375, 19, 192, 20, 4, 1, 800, 0x40}, /*9 300 M */
{"MH1GB", 87400, 2732, 1, 192, 20,16, 1,69920, 0x40}, /*10 1000 M */
{"SG038", 54752, 1711, 1, 192, 20, 8, 1,21900, 0x40}, /*11 38 M */
{"SG120", 174848, 5464, 1, 192, 20, 8, 1,69939, 0x40}, /*12 120 M */
{"SG076", 116808, 3491, 1, 192, 20, 8, 1,46723, 0x40}, /*13 76 M */
{"FH005", 5120, 184, 4, 192, 20, 1, 1, 64, 0x80}, /*14 5 M */
{"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*15 32 M */
{"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*16 32 M */
{"CD064", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*17 64 M */
{"CD064", 24000, 750, 3, 192, 20, 2, 1, 800, 0x60}, /*18 64 M */
{"CD096", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*19 96 M */
{"CD096", 40000, 1250, 5, 192, 20, 2, 1, 800, 0x60}, /*20 96 M */
{"MH600", 80000, 2500, 40, 192, 20, 8, 1, 80, 0x40}, /*21 600 M */
{"FM600", 80000, 2500, 40, 192, 20, 8, 1, 80, 0x40}, /*22 600 M */
{"FM600", 1600, 50, 40, 192, 20, 1, 1, 2, 0x80}, /*23 600 M */
{"MH040", 20000, 625, 5, 192, 20, 2, 1, 400, 0x40}, /*0 411 40 M */
{"MH080", 40000, 1250, 5, 192, 20, 2, 1, 800, 0x40}, /*1 823 80 M */
{"MH160", 80000, 1250, 10, 192, 20, 4, 1, 1600, 0x40}, /*2 823 160 M */
{"MH300", 76000, 2375, 19, 192, 20, 4, 1, 800, 0x40}, /*3 823 300 M */
{"MH1GB", 87400, 2732, 1, 192, 20,16, 1,69920, 0x40}, /*4 69920 1000 M */
{"SG038", 54752, 1711, 1, 192, 20, 8, 1,21900, 0x40}, /*5 21900 38 M */
{"SG120", 174848, 5464, 1, 192, 20, 8, 1,69939, 0x40}, /*6 69939 120 M */
{"SG076", 116808, 3491, 1, 192, 20, 8, 1,46723, 0x40}, /*7 46723 76 M */
{"FH005", 5120, 184, 4, 192, 20, 1, 1, 64, 0x80}, /*8 64 5 M */
{"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*9 823 32 M */
{"CD032", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*10 823 32 M */
{"CD064", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*11 823 64 M */
{"CD064", 24000, 750, 3, 192, 20, 2, 1, 800, 0x60}, /*12 823 64 M */
{"CD096", 8000, 250, 1, 192, 20, 2, 1, 800, 0x60}, /*13 823 96 M */
{"CD096", 40000, 1250, 5, 192, 20, 2, 1, 800, 0x60}, /*14 823 96 M */
{"MH600", 80000, 2500, 40, 192, 20, 8, 1, 800, 0x40}, /*15 843 600 M */
{"FM600", 80000, 2500, 40, 192, 20, 8, 1, 800, 0x40}, /*16 843 600 M */
{"FM600", 1600, 50, 40, 192, 20, 1, 1, 2, 0x80}, /*17 10 600 M */
{NULL, 0}
};
@ -275,13 +255,6 @@ DID.TBL EQU $
* ......:..:..:...:....:....:.....:......:........:
DID FORM 32, 8, 8, 8, 8, 16, 16, 32, 64
SPACE
* CLASS 'E' DISC DEVICES
DID C'DE01', 1, 1, 23, 192, 256, 184, 5888, C'FE004'
DID C'DE02', 2, 1, 16, 96, 2, 200, 12800, C'CE010'
DID C'DE04', 1, 2, 23, 192, 5, 719, 23000, C'ME040'
DID C'DE05', 1, 2, 23, 192, 5, 1438, 46000, C'ME080'
DID C'DE06', 1, 4, 23, 192, 19, 2732, 87400, C'ME300'
DID C'DE07', 1, 1, 23, 192, 4, 184, 5888, C'FE005'
* CLASS 'F' EXTENDED I/O DISC DEVICES
DID C'DF01', 3, 3, 26, 64, 2, , 1334, C'FL001'
DID C'DF02', 1, 2, 20, 192, 5, 625, 20000, C'MH040'
@ -330,15 +303,15 @@ MTAB scfi_mod[] = {
};
UNIT sda_unit[] = {
/* SET_TYPE(12) SG120 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x400)}, /* 0 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x410)}, /* 1 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x420)}, /* 2 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x430)}, /* 3 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x440)}, /* 4 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x450)}, /* 5 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x460)}, /* 6 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(12), 0), 0, UNIT_ADDR(0x470)}, /* 7 */
/* SET_TYPE(6) SG120 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x400)}, /* 0 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x410)}, /* 1 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x420)}, /* 2 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x430)}, /* 3 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x440)}, /* 4 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x450)}, /* 5 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x460)}, /* 6 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(6), 0), 0, UNIT_ADDR(0x470)}, /* 7 */
};
//DIB sda_dib = {scfi_preio, scfi_startcmd, NULL, NULL, NULL, scfi_ini, sda_unit, sda_chp, NUM_UNITS_SCFI, 0x0f, 0x0400, 0, 0, 0};
@ -373,15 +346,15 @@ DEVICE sda_dev = {
CHANP sdb_chp[NUM_UNITS_SCFI] = {0};
UNIT sdb_unit[] = {
/* SET_TYPE(10) DM1GB */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC10)}, /* 1 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC20)}, /* 2 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC30)}, /* 3 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC40)}, /* 4 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC50)}, /* 5 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC60)}, /* 6 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(10), 0), 0, UNIT_ADDR(0xC70)}, /* 7 */
/* SET_TYPE(4) DM1GB */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC00)}, /* 0 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC10)}, /* 1 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC20)}, /* 2 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC30)}, /* 3 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC40)}, /* 4 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC50)}, /* 5 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC60)}, /* 6 */
{UDATA(&scfi_srv, UNIT_SCFI|SET_TYPE(4), 0), 0, UNIT_ADDR(0xC70)}, /* 7 */
};
//DIB sdb_dib = {scfi_preio, scfi_startcmd, NULL, NULL, NULL, scfi_ini, sdb_unit, sdb_chp, NUM_UNITS_SCFI, 0x0f, 0x0c00, 0, 0, 0};
@ -419,11 +392,11 @@ uint8 scfi_preio(UNIT *uptr, uint16 chan)
int unit = (uptr - dptr->units);
sim_debug(DEBUG_CMD, dptr, "scfi_preio u3 %08x unit=%02x\n", uptr->u3, unit);
if ((uptr->u3 & 0xff00) != 0) { /* just return if busy */
if ((uptr->u3 & 0xff00) != 0) { /* just return if busy */
return SNS_BSY;
}
sim_debug(DEBUG_CMD, dptr, "scfi_preio unit=%02x\n", unit);
return 0; /* good to go */
return 0; /* good to go */
}
uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
@ -433,23 +406,23 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
uint8 ch;
sim_debug(DEBUG_CMD, dptr, "scfi_startcmd unit %02x cmd %04x u3 %08x\n", unit, cmd, uptr->u3);
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->u5 |= SNS_INTVENT; /* unit intervention required */
if (cmd != DSK_SNS) /* we are completed with unit check status */
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
uptr->u5 |= SNS_INTVENT; /* unit intervention required */
if (cmd != DSK_SNS) /* we are completed with unit check status */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
}
if ((uptr->u3 & DSK_CMDMSK) != 0) {
uptr->u3 |= DSK_BUSY; /* Flag we we are busy */
uptr->u3 |= DSK_BUSY; /* Flag we we are busy */
return SNS_BSY;
}
if ((uptr->u3 & 0xff00) != 0) { /* if any status info, we are busy */
if ((uptr->u3 & 0xff00) != 0) { /* if any status info, we are busy */
return SNS_BSY;
}
sim_debug(DEBUG_CMD, dptr, "scfi_startcmd CMD 2 unit=%02x cmd %02x\n", unit, cmd);
if ((uptr->flags & UNIT_ATT) == 0) { /* see if unit is attached */
if (cmd == DSK_SNS) { /* not attached, is cmd Sense 0x04 */
if ((uptr->flags & UNIT_ATT) == 0) { /* see if unit is attached */
if (cmd == DSK_SNS) { /* not attached, is cmd Sense 0x04 */
sim_debug(DEBUG_CMD, dptr, "scfi_startcmd CMD sense\n");
/* bytes 0,1 - Cyl entry from STAR reg in u4 */
ch = (uptr->u4 >> 24) & 0xff;
@ -494,13 +467,13 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
chan_write_byte(addr, &ch) ;
chan_write_byte(addr, &ch) ;
uptr->u5 &= 0xff000000; /* clear status bytes, but leave mode data */
uptr->u5 &= 0xff000000; /* clear status bytes, but leave mode data */
return SNS_CHNEND|SNS_DEVEND;
}
if (cmd == 0x0) /* INCH cmd gives unit check */
if (cmd == 0x0) /* INCH cmd gives unit check */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
uptr->u5 |= (SNS_INTVENT|SNS_CMDREJ); /* set new error status */
uptr->u5 |= (SNS_INTVENT|SNS_CMDREJ); /* set new error status */
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* we done */
}
@ -509,9 +482,9 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
case DSK_INCH: /* INCH 0x00 */
{
uint32 mema; /* memory address */
uint32 mema; /* memory address */
uint32 i;
UNIT *up = dptr->units; /* first unit for this device */
UNIT *up = dptr->units; /* first unit for this device */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd starting inch cmd addr %04x u4 %08x\n", addr, uptr->u4);
/* u4 has IOCD word 1 contents. For the disk processor it contains */
@ -520,57 +493,56 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
/* us9 has the byte count from IOCD wd2 and should be 0x24 (36) */
/* the INCH buffer address must be returned in u4 and us9 left non-zero */
/* just return OK and channel software will use up8 as status buffer */
mema = (uint32)uptr->u4; /* get memory address of buffer */
uptr->u4 = M[mema>>2]; /* get status buffer address for XIO return status */
mema = (uint32)uptr->u4; /* get memory address of buffer */
uptr->u4 = M[mema>>2]; /* get status buffer address for XIO return status */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd starting inch cmd addr %04x u4 %08x mema %08x units %02x\n",
addr, uptr->u4, mema, dptr->numunits);
/* the next 8 words have drive data for each unit */
/* WARNING 8 drives must be defined for this controller */
/* so we will not have a map fault */
for (i=0; i<dptr->numunits && i<8; i++) { /* process all drives */
up->u6 = M[(mema>>2)+i+1]; /* save each unit's drive data */
for (i=0; i<dptr->numunits && i<8; i++) { /* process all drives */
up->u6 = M[(mema>>2)+i+1]; /* save each unit's drive data */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd ATTR data %08x unit %02x flags %02x sec %02x MHD %02x FHD %02x\n",
up->ATTR, i, (up->ATTR >> 24)&0xff, (up->ATTR >> 16)&0xff,
(up->ATTR >> 8)&0xff, (up->ATTR&0xff));
up++; /* next unit for this device */
up++; /* next unit for this device */
}
sim_debug(DEBUG_CMD, dptr, "scfi_startcmd done inch cmd addr %04x\n", addr);
// return SNS_CHNEND|SNS_DEVEND;
// break;
uptr->u3 |= DSK_CMDMSK; /* use 0xff for inch, just need int */
sim_activate(uptr, 20); /* start things off */
uptr->u3 |= DSK_CMDMSK; /* use 0xff for inch, just need int */
sim_activate(uptr, 20); /* start things off */
return (0);
break;
}
case DSK_SCK: /* Seek command 0x07 */
case DSK_XEZ: /* Rezero & Read IPL record 0x1f */
uptr->u3 &= ~(DSK_STAR); /* show we do not have seek STAR in u4 */
case DSK_WD: /* Write command 0x01 */
case DSK_RD: /* Read command 0x02 */
case DSK_LMR: /* read mode register */
case DSK_SCK: /* Seek command 0x07 */
case DSK_XEZ: /* Rezero & Read IPL record 0x1f */
uptr->u3 &= ~(DSK_STAR); /* show we do not have seek STAR in u4 */
case DSK_WD: /* Write command 0x01 */
case DSK_RD: /* Read command 0x02 */
case DSK_LMR: /* read mode register */
uptr->u3 |= cmd; /* save cmd */
uptr->u3 |= cmd; /* save cmd */
sim_debug(DEBUG_CMD, dptr,
"scfi_startcmd done with disk seek r/w cmd %02x addr %04x\n", cmd, addr);
sim_activate(uptr, 20); /* start things off */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_NOP: /* NOP 0x03 */
// return SNS_CHNEND|SNS_DEVEND; /* return OK */
uptr->u3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
// return SNS_CHNEND|SNS_DEVEND; /* return OK */
uptr->u3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
break;
case DSK_SNS: /* Sense 0x04 */
uptr->u3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
case DSK_SNS: /* Sense 0x04 */
uptr->u3 |= cmd; /* save cmd */
sim_activate(uptr, 20); /* start things off */
return 0;
// goto dosns; /* use code above */
break;
}
sim_debug(DEBUG_CMD, dptr,
@ -578,7 +550,7 @@ uint8 scfi_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
cmd, addr, uptr->u5);
if (uptr->u5 & 0xff)
return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK;
sim_activate(uptr, 20); /* start things off */
sim_activate(uptr, 20); /* start things off */
return SNS_CHNEND|SNS_DEVEND;
}
@ -587,23 +559,27 @@ t_stat scfi_srv(UNIT *uptr)
{
uint16 chsa = GET_UADDR(uptr->u3);
DEVICE *dptr = find_dev_from_unit(uptr);
DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to Dev Info Blk for this device */
DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to Dev Info Blk for this device */
CHANP *chp = (CHANP *)dibp->chan_prg; /* get pointer to channel program */
struct ddata_t *data = (struct ddata_t *)(uptr->up7);
int cmd = uptr->u3 & DSK_CMDMSK;
int type = GET_TYPE(uptr->flags);
int count = data->count;
int32 trk, cyl;
int unit = (uptr - dptr->units);
int len;
int dlen = 0; /* total bytes processed */
int i;
uint8 ch;
int tsize = scfi_type[type].spt * scfi_type[type].ssiz*4; /* get track size in bytes */
uint16 ssize = scfi_type[type].ssiz*4; /* Size of one sector in bytes */
int32 tstart; /* Location of start of cyl/track/sect in data */
uint8 buf2[768];
uint8 buf[768];
sim_debug(DEBUG_DETAIL, &sda_dev, "scfi_srv entry unit %02x cmd %02x chsa %04x chan %04x count %04x\n",
unit, cmd, chsa, chsa>>8, chp->ccw_count);
// if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
// if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
// return SCPE_OK;
// }
if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */
@ -620,14 +596,14 @@ t_stat scfi_srv(UNIT *uptr)
case DSK_CMDMSK: /* use 0xff for inch, just need int */
uptr->u3 &= ~(0xffff); /* remove old cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd INCH chsa %04x count %04x completed\n", chsa, chp->ccw_count);
"scfi_srv cmd INCH chsa %04x count %04x completed\n", chsa, chp->ccw_count);
chan_end(chsa, SNS_CHNEND); /* return just channel end */
break;
case DSK_NOP: /* NOP 0x03 */
uptr->u3 &= ~(0xffff); /* remove old cmd */
sim_debug(DEBUG_CMD, dptr,
"disk_srv cmd NOP chsa %04x count %04x completed\n", chsa, chp->ccw_count);
"scfi_srv cmd NOP chsa %04x count %04x completed\n", chsa, chp->ccw_count);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */
break;
@ -712,7 +688,7 @@ t_stat scfi_srv(UNIT *uptr)
for (i = 0; i < 4; i++) {
if (chan_read_byte(chsa, &buf[i])) {
/* we have error, bail out */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
@ -723,38 +699,36 @@ rezero:
unit, buf[0], buf[1], buf[2], buf[3]);
/* save STAR (target sector) data in u4 */
uptr->u4 = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]);
cyl = uptr->u4 >> 16; /* get the cylinder */
trk = buf[2]; /* get the track */
cyl = uptr->u4 >> 16; /* get the cylinder */
trk = buf[2]; /* get the track */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv SEEK %08x cyl %04x trk %02x sec %02x unit=%02x\n",
uptr->u4, cyl&0xffff, trk, buf[3], unit);
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Disk %s cyl %04x hds %02x sec/trk %02x unit=%02x\n",
scfi_type[type].name, scfi_type[type].cyl, scfi_type[type].nhds, scfi_type[type].spt, unit);
uptr->u3 |= DSK_STAR; /* show we have seek STAR in u4 */
uptr->u3 |= DSK_STAR; /* show we have seek STAR in u4 */
/* calc the sector address of data */
/* calculate file position in bytes of requested sector */
data->tstart = uptr->u4 * (scfi_type[type].spb * scfi_type[type].ssiz * 4); /* file offset in bytes */
data->tpos = trk; /* save the track/head number */
data->spos = buf[3]; /* save the sector number */
data->count = 0; /* no data seen yet */
data->rec = 0; /* number of bytes in this sector */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek start %08x trk %04x sec %02x\n", data->tstart, trk, buf[3]);
if ((sim_fseek(uptr->fileref, data->tstart, SEEK_SET)) != 0) { /* seek home */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Error on seek to %08x\n", data->tstart);
tstart = uptr->u4 * (scfi_type[type].spb * scfi_type[type].ssiz * 4); /* file offset in bytes */
data->tpos = trk; /* save the track/head number */
data->spos = buf[3]; /* save the sector number */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek start %08x trk %04x sec %02x\n", tstart, trk, buf[3]);
if ((sim_fseek(uptr->fileref, tstart, SEEK_SET)) != 0) { /* seek home */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv Error on seek to %08x\n", tstart);
}
/* Check if already on correct cylinder */
if (trk != data->cyl) {
/* Do seek */
uptr->u3 |= DSK_SEEKING; /* show we are seeking */
uptr->u3 |= DSK_SEEKING; /* show we are seeking */
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv seek unit=%02x trk %04x cyl %04x\n",
unit, trk, data->cyl);
unit, trk, data->cyl);
sim_activate(uptr, 20);
chan_end(chsa, SNS_CHNEND);
} else {
sim_debug(DEBUG_DETAIL, dptr, "scfi_srv calc sect addr seek start %08x trk %04x sec %02x\n",
data->tstart, trk, buf[3]);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
tstart, trk, buf[3]);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
sim_activate(uptr, 20);
chan_end(chsa, SNS_DEVEND|SNS_CHNEND);
}
@ -764,22 +738,22 @@ rezero:
sim_debug(DEBUG_CMD, dptr, "RD REZERO IPL unit=%02x seek 0\n", unit);
/* Do a seek to 0 */
uptr->u4 = 0; /* set STAR to 0, 0, 0 */
uptr->u3 &= ~(0xffff); /* remove old cmd */
uptr->u3 |= DSK_SCK; /* show as seek command */
data->tstart = 0; /* byte offset is 0 */
data->dlen = 0; /* no data written yet */
uptr->u4 = 0; /* set STAR to 0, 0, 0 */
uptr->u3 &= ~(0xffff); /* remove old cmd */
uptr->u3 |= DSK_SCK; /* show as seek command */
tstart = 0; /* byte offset is 0 */
dlen = 0; /* no data written yet */
/* Read in 1 dummy character for length to inhibit SLI posting */
if (chan_read_byte(chsa, &buf[0])) {
/* we have error, bail out */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
/* zero stuff */
buf[0] = buf[1] = buf[2] = buf[3] = 0;
goto rezero; /* murge with seek code */
goto rezero; /* murge with seek code */
break;
case DSK_LMR:
@ -787,125 +761,120 @@ rezero:
/* Read in 1 character of mode data */
if (chan_read_byte(chsa, &buf[0])) {
/* we have error, bail out */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u5 |= SNS_CMDREJ|SNS_EQUCHK;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
uptr->u3 &= ~(0xffff); /* remove old cmd */
uptr->u5 &= 0x00ffffff; /* clear old mode data */
uptr->u5 |= (buf[0] << 24); /* save mode value */
uptr->u3 &= ~(0xffff); /* remove old cmd */
uptr->u5 &= 0x00ffffff; /* clear old mode data */
uptr->u5 |= (buf[0] << 24); /* save mode value */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case DSK_RD: /* Read Data */
/* data->tstart has start of sector address in bytes */
/* tstart has start of sector address in bytes */
if ((uptr->u3 & DSK_READING) == 0) { /* see if we are reading data */
uptr->u3 |= DSK_READING; /* read from disk starting */
data->dlen = 0; /* no data read yet */
sim_debug(DEBUG_CMD, dptr, "DISK READ starting unit=%02x u3 %08x count %04x rec %04x\n",
unit, uptr->u3, count, data->rec);
uptr->u3 |= DSK_READING; /* read from disk starting */
dlen = 0; /* no data read yet */
sim_debug(DEBUG_CMD, dptr, "DISK READ starting unit=%02x u3 %08x count %04x\n",
unit, uptr->u3, chp->ccw_count);
}
if (uptr->u3 & DSK_READING) { /* see if we are reading data */
if (uptr->u3 & DSK_READING) { /* see if we are reading data */
/* read in a sector of data from disk */
if ((count=sim_fread(buf, 1, data->ssize, uptr->fileref)) != data->ssize) {
sim_debug(DEBUG_CMD, dptr, "Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n",
count, data->ssize, data->cyl, data->tpos, data->spos);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
// sim_activate(uptr, 20);
if ((len=sim_fread(buf, 1, ssize, uptr->fileref)) != ssize) {
sim_debug(DEBUG_CMD, dptr,
"Error %08x on read %04x of diskfile cyl %04x hds %02x sec %02x\n",
len, ssize, data->cyl, data->tpos, data->spos);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
sim_debug(DEBUG_CMD, dptr, "scfi_srv after READ chsa %04x count %04x\n", chsa, chp->ccw_count);
/* process the next sector of data */
data->rec = count; /* no bytes in sector yet */
count = 0; /* used here as a flag for short write */
for (i=0; i<(data->rec); i++) {
ch = buf[i]; /* get a char from buffer */
for (i=0; i<len; i++) {
ch = buf[i]; /* get a char from buffer */
if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */
sim_debug(DEBUG_DATAIO, dptr,
"DISK Read %04x bytes from diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen+i, data->cyl, data->tpos, data->spos, data->tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
dlen+i, data->cyl, data->tpos, data->spos, tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
goto rddone;
}
}
data->dlen += data->rec; /* add byte read to total count */
dlen += len; /* add byte read to total count */
sim_debug(DEBUG_CMD, dptr,
"DISK READ from sec end %04x bytes end %04x from diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen, data->ssize, data->cyl, data->tpos, data->spos, data->tstart);
dlen, ssize, data->cyl, data->tpos, data->spos, tstart);
data->spos++;
/* see if we are done reading data */
if (test_write_byte_end(chsa)) {
sim_debug(DEBUG_DATAIO, dptr,
"DISK Read complete Read %04x bytes from diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen, data->cyl, data->tpos, data->spos, data->tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
dlen, data->cyl, data->tpos, data->spos, tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
}
rddone:
// sim_activate(uptr, 20);
sim_activate(uptr, 10); /* wait to read next sector */
sim_activate(uptr, 10); /* wait to read next sector */
break;
}
break;
case DSK_WD: /* Write Data */
/* data->tstart has start of sector address in bytes */
if ((uptr->u3 & DSK_WRITING) == 0) { /* see if we are writing data */
uptr->u3 |= DSK_WRITING; /* write to disk starting */
data->dlen = 0; /* no data written yet */
sim_debug(DEBUG_CMD, dptr, "DISK WRITE starting unit=%02x u3 %08x bytes %04x rec %04x\n",
unit, uptr->u3, data->dlen, data->rec);
/* tstart has start of sector address in bytes */
if ((uptr->u3 & DSK_WRITING) == 0) { /* see if we are writing data */
uptr->u3 |= DSK_WRITING; /* write to disk starting */
dlen = 0; /* no data written yet */
sim_debug(DEBUG_CMD, dptr, "DISK WRITE starting unit=%02x u3 %08x bytes %04x\n",
unit, uptr->u3, dlen);
}
if (uptr->u3 & DSK_WRITING) { /* see if we are writing data */
if (uptr->u3 & DSK_WRITING) { /* see if we are writing data */
/* process the next sector of data */
data->rec = 0; /* no bytes in sector yet */
count = 0; /* used here as a flag for short read */
for (i=0; i<(data->ssize); i++) {
len = 0; /* used here as a flag for short read */
for (i=0; i<ssize; i++) {
if (chan_read_byte(chsa, &ch)) { /* get a byte from memory */
/* if error on reading 1st byte, we are done writing */
if (i == 0) {
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
sim_debug(DEBUG_DATAIO, dptr,
"DISK Wrote %04x bytes to diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen, data->cyl, data->tpos, data->spos, data->tstart);
ssize, data->cyl, data->tpos, data->spos, tstart);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
goto wrdone;
}
ch = 0; /* finish out the sector with zero */
count++; /* show we have no more data to write */
ch = 0; /* finish out the sector with zero */
len++; /* show we have no more data to write */
}
buf2[i] = ch; /* save the char */
buf2[i] = ch; /* save the char */
}
data->dlen += data->ssize; /* add 1 sector of bytes */
dlen += ssize; /* add 1 sector of bytes */
/* write the sector to disk */
if ((i=sim_fwrite(buf2, 1, data->ssize, uptr->fileref)) != data->ssize) {
if ((i=sim_fwrite(buf2, 1, ssize, uptr->fileref)) != ssize) {
sim_debug(DEBUG_CMD, dptr,
"Error %08x on write %04x to diskfile cyl %04x hds %02x sec %02x\n",
i, data->ssize, data->cyl, data->tpos, data->spos);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
i, ssize, data->cyl, data->tpos, data->spos);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
if (count != 0) { /* see if done with write command */
if (len != 0) { /* see if done with write command */
sim_debug(DEBUG_DATAIO, dptr,
"DISK WroteB %04x bytes to diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen, data->cyl, data->tpos, data->spos, data->tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
ssize, data->cyl, data->tpos, data->spos, tstart);
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we done */
break;
}
sim_debug(DEBUG_CMD, dptr,
"DISK WR to sec end %04x bytes end %04x to diskfile cyl %04x hds %02x sec %02x tstart %08x\n",
data->dlen, data->ssize, data->cyl, data->tpos, data->spos, data->tstart);
dlen, ssize, data->cyl, data->tpos, data->spos, tstart);
data->spos++;
wrdone:
// sim_activate(uptr, 20);
sim_activate(uptr, 10);
break;
}
@ -914,11 +883,12 @@ wrdone:
default:
sim_debug(DEBUG_DETAIL, dptr, "invalid command %02x unit %02x\n", cmd, unit);
uptr->u5 |= SNS_CMDREJ;
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
uptr->u3 &= ~(0xffff); /* remove old status bits & cmd */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
break;
}
sim_debug(DEBUG_CMD, dptr, "scfi_srv done cmd %02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
sim_debug(DEBUG_CMD, dptr,
"scfi_srv done cmd %02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count);
return SCPE_OK;
}
@ -928,7 +898,7 @@ void scfi_ini(UNIT *uptr, t_bool f)
DEVICE *dptr = find_dev_from_unit(uptr);
int i = GET_TYPE(uptr->flags);
uptr->u3 &= ~0xffff; /* clear out the flags but leave ch/sa */
uptr->u3 &= ~0xffff; /* clear out the flags but leave ch/sa */
/* capacity is total allocation units times sectors per allocation unit */
/* total sectors on disk */
uptr->capac = scfi_type[i].taus * scfi_type[i].spau;
@ -949,11 +919,12 @@ int scfi_format(UNIT *uptr) {
uint16 addr = GET_UADDR(uptr->u3);
int type = GET_TYPE(uptr->flags);
DEVICE *dptr = find_dev_from_unit(uptr);
uint16 tsize = data->tsize; /* get track size in bytes */
uint16 tsize = scfi_type[type].spt * scfi_type[type].ssiz*4; /* get track size in bytes */
int32 ssize = scfi_type[type].ssiz * 4; /* disk sector size in bytes */
uint32 cyl;
uint16 spc = scfi_type[type].nhds * scfi_type[type].spt; /* sectors/cyl */
uint32 cap = scfi_type[type].taus * scfi_type[type].spau; /* disk capacity in sectors */
uint32 cylv = cap / spc; /* calc number of cylinders */
uint32 cylv = cap / spc; /* calc number of cylinders */
uint8 *buff;
/* see if user wants to initialize the disk */
@ -976,10 +947,10 @@ int scfi_format(UNIT *uptr) {
buff[1] = 'E';
buff[2] = 'R';
buff[3] = 'O';
sim_debug(DEBUG_CMD, dptr, "Creating disk file of trk size %04x capacity %d\n", tsize, cap * data->ssize);
sim_debug(DEBUG_CMD, dptr, "Creating disk file of trk size %04x capacity %d\n", tsize, cap*ssize);
/* write zeros to each track of the disk */
for (cyl = 0; cyl < cylv; cyl++) {
if ((sim_fwrite(buff, 1, data->tsize, uptr->fileref)) != data->tsize) {
if ((sim_fwrite(buff, 1, tsize, uptr->fileref)) != tsize) {
sim_debug(DEBUG_CMD, dptr, "Error on write to diskfile cyl %04x\n", cyl);
}
if (cyl == 0) {
@ -994,12 +965,9 @@ int scfi_format(UNIT *uptr) {
fputc('\r', stderr);
fputc('\n', stderr);
/* seek home again */
sim_fseek(uptr->fileref, 0, SEEK_SET); /* seek home */
free(buff); /* free cylinder buffer */
data->cpos = 0;
data->ccyl = 0;
set_devattn(addr, SNS_DEVEND); /* start us up */
// sim_activate(uptr, 100);
sim_fseek(uptr->fileref, 0, SEEK_SET); /* seek home */
free(buff); /* free cylinder buffer */
set_devattn(addr, SNS_DEVEND); /* start us up */
return 0;
}
@ -1009,8 +977,8 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) {
int type = GET_TYPE(uptr->flags);
DEVICE *dptr = find_dev_from_unit(uptr);
t_stat r;
uint16 tsize; /* track size in bytes */
uint16 ssize; /* sector size in bytes */
uint16 tsize; /* track size in bytes */
uint16 ssize; /* sector size in bytes */
struct ddata_t *data;
uint8 buff[1024];
@ -1018,9 +986,9 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) {
if ((r = attach_unit(uptr, file)) != SCPE_OK)
return r;
if (scfi_type[type].name == 0) { /* does the assigned disk have a name */
detach_unit(uptr); /* no, reject */
return SCPE_FMT; /* error */
if (scfi_type[type].name == 0) { /* does the assigned disk have a name */
detach_unit(uptr); /* no, reject */
return SCPE_FMT; /* error */
}
/* get a buffer to hold scfi_t structure */
@ -1030,21 +998,19 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) {
return SCPE_FMT;
}
uptr->up7 = (void *)data; /* save pointer to structure in up7 */
uptr->up7 = (void *)data; /* save pointer to structure in up7 */
/* track size in bytes is sectors/track times words/sector time 4 bytse/word */
tsize = scfi_type[type].spt * scfi_type[type].ssiz * 4; /* get track size in bytes */
data->tsize = tsize; /* save size of track in bytes */
uptr->capac = scfi_type[type].taus * scfi_type[type].spau; /* disk capacity in sectors */
ssize = scfi_type[type].ssiz * 4; /* disk sector size in bytes */
uptr->capac *= ssize; /* disk capacity in bytes */
data->ssize = ssize; /* save sector size bytes */
ssize = scfi_type[type].ssiz * 4; /* disk sector size in bytes */
uptr->capac *= ssize; /* disk capacity in bytes */
sim_debug(DEBUG_CMD, dptr, "Disk taus %d spau %d ssiz %d cap %d\n",
scfi_type[type].taus, scfi_type[type].spau, scfi_type[type].ssiz * 4, uptr->capac); /* disk capacity */
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
}
/* read in the 1st sector of the 'disk' */
@ -1060,24 +1026,18 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) {
fmt:
/* format the drive */
if (scfi_format(uptr)) {
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
}
}
if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
detach_unit(uptr); /* if no space, error */
return SCPE_FMT; /* error */
}
data->ssize = ssize; /* save sector size in bytes */
data->tsize = tsize; /* save track size in bytes */
data->cpos = 0; /* current read/write position in cylinder*/
data->ccyl = 0; /* current cylinder number */
data->tpos = 0; /* current track position */
data->spos = 0; /* current sector position */
data->rec = 0; /* record length */
data->count = 0; /* clear count value */
data->tpos = 0; /* current track position */
data->spos = 0; /* current sector position */
sim_debug(DEBUG_CMD, &sda_dev, "Attach %8s hds %d spt %d spc %d cyl %d capacity %d\n",
scfi_type[type].name, scfi_type[type].nhds, scfi_type[type].spt,
@ -1094,22 +1054,22 @@ t_stat scfi_detach(UNIT *uptr) {
struct ddata_t *data = (struct ddata_t *)uptr->up7;
if (data != 0) {
free(data); /* free disk data structure */
free(data); /* free disk data structure */
}
uptr->up7 = 0; /* no pointer to disk data */
uptr->u3 &= ~0xffff; /* no cmd and flags */
return detach_unit(uptr); /* tell simh we are done with disk */
uptr->up7 = 0; /* no pointer to disk data */
uptr->u3 &= ~0xffff; /* no cmd and flags */
return detach_unit(uptr); /* tell simh we are done with disk */
}
/* boot from the specified disk unit */
t_stat scfi_boot(int32 unit_num, DEVICE *dptr) {
UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */
UNIT *uptr = &dptr->units[unit_num]; /* find disk unit number */
sim_debug(DEBUG_CMD, &sda_dev, "SCFI Disk Boot dev/unit %04x\n", GET_UADDR(uptr->u3));
SPAD[0xf4] = GET_UADDR(uptr->u3); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
SPAD[0xf4] = GET_UADDR(uptr->u3); /* put boot device chan/sa into spad */
SPAD[0xf8] = 0xF000; /* show as F class device */
if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_UNATT; /* attached? */
return SCPE_UNATT; /* attached? */
return chan_boot(GET_UADDR(uptr->u3), dptr); /* boot the ch/sa */
}

View File

@ -32,30 +32,29 @@ extern uint32 PSD[];
/* SCP data structures and interface routines
The interface between the simulator control package (SCP) and the
simulator consists of the following routines and data structures
The interface between the simulator control package (SCP) and the
simulator consists of the following routines and data structures
sim_name simulator name string
sim_devices[] array of pointers to simulated devices
sim_PC pointer to saved PC register descriptor
sim_interval simulator interval to next event (in sel32_cpu.c)
sim_stop_messages[] array of pointers to stop messages
sim_instr() instruction execution routine (in sel32_cpu.c)
sim_load() binary loader routine
sim_emax maximum number of words for examine
sim_name simulator name string
sim_devices[] array of pointers to simulated devices
sim_PC pointer to saved PC register descriptor
sim_interval simulator interval to next event (in sel32_cpu.c)
sim_stop_messages[] array of pointers to stop messages
sim_instr() instruction execution routine (in sel32_cpu.c)
sim_load() binary loader routine
sim_emax maximum number of words for examine
In addition, the simulator must supply routines to print and parse
architecture specific formats
In addition, the simulator must supply routines to print and parse
architecture specific formats
fprint_sym print symbolic output
fparse_sym parse symbolic input
fprint_sym print symbolic output
fparse_sym parse symbolic input
*/
char sim_name[] = "SEL 32"; /* our simulator name */
char sim_name[] = "SEL-32"; /* our simulator name */
REG *sim_PC = &cpu_reg[0];
//old int32 sim_emax = 1; /* maximum number of instructions/words to examine */
int32 sim_emax = 4; /* maximum number of instructions/words to examine */
DEVICE *sim_devices[] = {
@ -97,6 +96,12 @@ DEVICE *sim_devices[] = {
&sdb_dev,
#endif
#endif
#ifdef NUM_DEVS_HSDP
&dpa_dev,
#if NUM_DEVS_HSDP > 1
&dpb_dev,
#endif
#endif
#ifdef NUM_DEVS_COM
&coml_dev,
&com_dev,
@ -142,10 +147,8 @@ int get_word(FILE *fileref, uint32 *word)
if (sim_fread(cbuf, 1, 4, fileref) != 4)
return 1; /* read error or eof */
/* byte swap while reading data */
*word = ((cbuf[0]) << 24) |
((cbuf[1]) << 16) |
((cbuf[2]) << 8) |
((cbuf[3]));
*word = ((cbuf[0]) << 24) | ((cbuf[1]) << 16) |
((cbuf[2]) << 8) | ((cbuf[3]));
return 0; /* all OK */
}