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:
commit
f3450ddccb
@ -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 */
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
1128
SEL32/sel32_hsdp.c
Normal file
File diff suppressed because it is too large
Load Diff
554
SEL32/sel32_mt.c
554
SEL32/sel32_mt.c
@ -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);
|
||||
}
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
@ -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 */
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user