1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-19 01:18:10 +00:00

SEL32: Fix SPAD address validation code for MPX3X.

SEL32: Add debug dump memory functions.
SEL32: Correct line count in sel32_lpr.c.
SEL32: Correct BSR/BSF code in sel32_mt.c for MPX3X SDT handling.
SEL32: General cleanup/speedup of sel32_mt.c code.
SEL32: Add master SDT tape creation in taptools/mkvmtape.c.
SEL32: Fix EOF detection code in taptools/tapdump.c.
This commit is contained in:
James C. Bevier 2021-06-21 14:57:55 -07:00
parent 8efbc79059
commit 0ed44354b5
14 changed files with 742 additions and 301 deletions

View File

@ -189,11 +189,11 @@ is operating correctly. The diags are located in the tests directory. Diag.tap
contains the diagnostic programs and diag.ini contains the directives to
configure and run the SEL32 simulator.
This simulator is capable of running UTX2.1A, UTX2.1B, MPX 1.5F, and a
test version of MPX 3.4. It is capable of creating a disk image for the
This simulator is capable of running UTX2.1A, UTX2.1B, MPX 1.5F, MPX 3.4,
MPX 3.5 and MPX 3.6. It is capable of creating a disk image for the
O/S from a UTX or MPX SDT tape. The disk image can be booted, initialized,
and can run many of the UTX and MPX utilities and programs. Ethernet is
supported on UTX and may be added to MPX in the future. Eight terminals
supported on UTX and will be added to MPX in the future. Eight terminals
can be used to access MPX via Telnet port 4747. The sumulator has support
for excess 64 floating point arithmetic and passes the 32/27 and 32/67 FP
diags. UTX is the SEL version of System V Unix and BSD Unix ported to the

View File

@ -9,14 +9,18 @@ added in the future.
# SEL Concept/32
This simulator is capable of running UTX2.1A, UTX2.1B, MPX 1.5F, and a
test version of MPX 3.4. It is capable of creating a disk image for the
This simulator is capable of running UTX2.1A, UTX2.1B, MPX 1.5F, MPX 3.4,
MPX 3.5, and MPX 3.6. It is capable of creating a disk image for the
O/S from a UTX or MPX SDT tape. The disk image can be booted, initialized,
and can run many of the UTX and MPX utilities and programs. Ethernet is
supported on UTX and may be added to MPX in the future. Eight terminals
supported on UTX and will be added to MPX in the future. Eight terminals
can be used to access MPX or UTX via Telnet port 4747. The sumulator has
support for excess 64 floating point arithmetic and passes the 32/27 and
32/67 FP diags.
32/67 FP diags. UTX is the SEL version of System V Unix and BSD Unix
ported to the V6 and V9 processors. UTX utilizes the basemode instruction
set and a virtual memory system supported by the V6 & V9 CPUs. The system
needs further testing to solidify the SEL32 simulator code in all of the
supported environmenets.
The sim32disk.gz file is a prebuilt MPX 1.5F system disk. It can be
uncompressed and booted with the sel32.27.sim32.disk.ini initialization
@ -99,11 +103,14 @@ utx21a1.tap bootable UTX install tape for testing basemode. The current
The virtual memory has been fully tested with the VM.MMM diag.
Other MPX verions support:
I am still looking for an MPX 3.X user or master SDT tape. I have
much of the source, but no loadable code to create a bootable system.
Please keep looking for anyone who can provide these tapes or a
disk image of a bootable MPX3.X system.
I have recently received some old MPX 3.X save tapes. Using these
I have been able to hand build a MPX3.6 SDT tape that can be used
to install MPX3.6. Once installed, the system can be used to build
a new user SDT tape and install it elsewhere. Both based and non-
based O/S images can be created. More images for installation will
be made available in the future as I work my way through the save
tapes.
James C. Bevier
04/14/2021
06/20/2021

View File

@ -336,7 +336,11 @@ uint32 find_int_lev(uint16 chsa)
/* get the device entry for channel in SPAD */
uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */
if (spadent == 0 || spadent == 0xffffffff) { /* see if valid entry */
#ifdef FIX3X
if ((spadent == 0) || (spadent == 0xffffffff)) { /* see if valid entry */
#else
if ((spadent == 0) || ((spadent&MASK24) == MASK24)) { /* see if valid entry */
#endif
sim_debug(DEBUG_EXP, &cpu_dev,
"find_int_lev ERR chsa %04x spadent %08x\n", chsa, spadent);
return 0; /* not found */
@ -701,11 +705,14 @@ loop:
}
/* DC can only be used with a read/write cmd */
if (chp->ccw_flags & FLAG_DC) {
/* TODO move ccw code to LPR processing */
/* TEMP FIX FOR LPR */
// if (chp->ccw_flags & FLAG_DC) {
if ((chp->ccw_flags & FLAG_DC) && (chsa != 0x7ef8)) {
if ((chp->ccw_cmd != 0x02) && (chp->ccw_cmd != 0x01)) {
chp->chan_status |= STATUS_PCHK; /* program check for invalid DC */
sim_debug(DEBUG_EXP, &cpu_dev,
"disk_iocl DC ERROR chan_status[%02x]=%04x\n", chan, chp->chan_status);
"load_ccw DC ERROR chan_status[%02x]=%04x\n", chan, chp->chan_status);
return 1; /* error return */
}
}
@ -942,7 +949,7 @@ void chan_end(uint16 chsa, uint16 flags) {
uint16 tstat, tcnt;
CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */
sim_debug(DEBUG_DETAIL, &cpu_dev,
sim_debug(DEBUG_CMD, &cpu_dev,
"chan_end entry chsa %04x flags %04x status %04x cmd %02x\n",
chsa, flags, chp->chan_status, chp->ccw_cmd);
// fflush(sim_deb);
@ -1193,8 +1200,8 @@ void store_csw(CHANP *chp)
/* store the device status into the first entry of the status FIFO for the channel */
void push_csw(CHANP *chp)
{
uint32 stwd1, stwd2; /* words 1&2 of stored status */
uint32 chsa = chp->chan_dev; /* get ch/sa information */
int32 stwd1, stwd2; /* words 1&2 of stored status */
uint32 chsa = chp->chan_dev; /* get ch/sa information */
/* put sub address in byte 0 */
stwd1 = ((chsa & 0xff) << 24) | chp->chan_caw; /* subaddress and IOCD address to SW 1 */
@ -2580,7 +2587,11 @@ uint32 scan_chan(uint32 *ilev) {
for (i=0; i<112; i++) {
if (SPAD[i+0x80] == 0) /* not initialize? */
continue; /* skip this one */
#ifdef FIX3X
if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */
#else
if ((SPAD[i+0x80]&MASK24) == MASK24) /* not initialize? */
#endif
continue; /* skip this one */
if (INTS[i] & INTS_REQ) /* if already requesting, skip */
continue; /* skip this one */
@ -2616,10 +2627,18 @@ uint32 scan_chan(uint32 *ilev) {
for (i=0; i<112; i++) {
if (SPAD[i+0x80] == 0) /* not initialize? */
continue; /* skip this one */
#ifdef FIX3X
if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */
#else
if ((SPAD[i+0x80]&MASK24) == MASK24) /* not initialize? */
#endif
continue; /* skip this one */
/* this is a bug fix for MPX 1.x restart command */
#ifdef FIX3X
if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */
#else
if ((SPAD[i+0x80]&MASK24) == MASK24) /* not initialize? */
#endif
continue; /* skip this one */
if ((INTS[i]&INTS_ACT) || (SPAD[i+0x80]&SINT_ACT)) { /* look for level active */
sim_debug(DEBUG_DETAIL, &cpu_dev,

View File

@ -1855,6 +1855,7 @@ t_stat sim_instr(void) {
int32 int32b; /* temp int */
int32 int32c; /* temp int */
//#define MPXTEST
//#define LOOK_MAP_05272021
#ifdef MPXTEST
int32 ii; /* temp int */
#endif
@ -3704,13 +3705,21 @@ skipit:
if ((PSD1 & 2) != 0) /* is it lf hw instruction */
goto inv; /* invalid instr if in rt hw */
addr = SPAD[0xf0]; /* get trap table memory address from SPAD (def 80) */
if (addr == 0 || addr == 0xffffffff) { /* see if secondary vector table set up */
#ifdef FIX3X
if ((addr == 0) || (addr == 0xffffffff)) { /* see if secondary vector table set up */
#else
if ((addr == 0) || ((addr&MASK24) == MASK24)) { /* see if secondary vector table set up */
#endif
TRAPME = ADDRSPEC_TRAP; /* Not setup, error */
goto newpsd; /* program error */
}
addr = addr + (0x0A << 2); /* addr has mem addr of CALM trap vector (def A8) */
t = M[addr >> 2]; /* get the ICB address from memory */
if (t == 0 || t == 0xffffffff) { /* see if ICB set up */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) { /* see if ICB set up */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) { /* see if ICB set up */
#endif
TRAPME = ADDRSPEC_TRAP; /* Not setup, error */
goto newpsd; /* program error */
}
@ -5323,8 +5332,8 @@ doovr2:
uint32 sq59 = M[0x930>>2]; /* get C.SQ59 headcell */
uint32 dqe = M[0x8e8>>2]; /* get DQE of current task */
// sim_debug(DEBUG_IRQ, &cpu_dev,
// "SVC start sq59 %04x dqe %04x\n",sq59, dqe);
sim_debug(DEBUG_IRQ, &cpu_dev,
"SVC start sq59 %04x dqe %04x\n",sq59, dqe);
if (sq59 != 0x930)
goto skipdqe2; /* not running on mpx, skip */
for (j=0; j<8; j++) { /* get the task name */
@ -5338,19 +5347,31 @@ skipdqe2:
int32c = CPUSTATUS; /* keep for retain blocking state */
addr = SPAD[0xf0]; /* get trap table memory address from SPAD (def 80) */
int32a = addr;
#ifdef FIX3X
if (addr == 0 || addr == 0xffffffff) { /* see if secondary vector table set up */
#else
if (addr == 0 || ((addr&MASK24) == MASK24)) { /* see if secondary vector table set up */
#endif
TRAPME = ADDRSPEC_TRAP; /* Not setup, error */
goto newpsd; /* program error */
}
addr = addr + (0x06 << 2); /* addr has mem addr of SVC trap vector (def 98) */
temp = M[addr >> 2]; /* get the secondary trap table address from memory */
#ifdef FIX3X
if (temp == 0 || temp == 0xffffffff) { /* see if ICB set up */
#else
if (temp == 0 || ((temp&MASK24) == MASK24)) { /* see if ICB set up */
#endif
TRAPME = ADDRSPEC_TRAP; /* Not setup, error */
goto newpsd; /* program error */
}
temp2 = ((IR>>12) & 0x0f) << 2; /* get SVC index from IR */
t = M[(temp+temp2)>>2]; /* get secondary trap vector address ICB address */
#ifdef FIX3X
if (t == 0 || t == 0xffffffff) { /* see if ICB set up */
#else
if (temp == 0 || ((temp&MASK24) == MASK24)) { /* see if ICB set up */
#endif
TRAPME = ADDRSPEC_TRAP; /* Not setup, error */
goto newpsd; /* program error */
}
@ -5376,6 +5397,30 @@ skipdqe2:
}
#endif
#endif
#if DYNAMIC_DEBUG
if (((temp2>>2) == 0) && ((IR&0xFFF) == 0xb01)) { /* SVC 0,VOMM,1 */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
#endif
#ifdef DO_DYNAMIC_DEBUG
if (((temp2>>2) == 0) && ((IR&0xFFF) == 0x303)) { /* SVC 0,TAMM,1 */
if (GPR[3] == 0x3a000)
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
#endif
#ifdef DO_DYNAMIC_DEBUG
if (((temp2>>2) == 2) && ((IR&0xFFF) == 0x028)) { /* SVC 2,28 H.VOMM,9 */
if (cpu_dev.dctrl & DEBUG_INST)
cpu_dev.dctrl &= ~DEBUG_INST; /* stop instruction trace */
else
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
#endif
#ifdef DO_DYNAMIC_DEBUG
if (((temp2>>2) == 0) && ((IR&0xFFF) == 0xa11)) { /* SVC 0,REMM,17 */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
#endif
#ifdef DO_DYNAMIC_DEBUG
if (((temp2>>2) == 0) && ((IR&0xFFF) == 0x910)) { /* SVC 0,REXS,16 */
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
@ -6021,8 +6066,10 @@ skipdqe2:
ii, GPR[ii], ii+1, GPR[ii+1], ii+2, GPR[ii+2], ii+3, GPR[ii+3]);
}
/* DYNAMIC 05282021 */
#if 0
if ((GPR[0] == 0x840017f0) && (GPR[1] == 0x00004908))
cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
#endif
#endif
/* set the mode bits and CCs from the new PSD */
CC = PSD1 & 0x78000000; /* extract bits 1-4 from PSD1 */
@ -6121,7 +6168,6 @@ skipdqe:
if (PSD2 & MAPBIT) {
/* set mapped mode in cpu status */
CPUSTATUS |= BIT8; /* set bit 8 of cpu status */
//#define LOOK_MAP_05272021
#ifdef LOOK_MAP_05272021
sim_debug(DEBUG_IRQ, &cpu_dev,
"B4 LPSDCM temp %06x TPSD %08x %08x PSD %08x %08x\n",
@ -6155,7 +6201,7 @@ skipdqe:
uint32 cpix = PSD2 & 0x3ff8; /* get cpix 11 bit offset from psd wd 2 */
uint32 midl = RMW(mpl+cpix); /* get midl entry for given user cpix */
uint32 spc = midl & MASK16; /* get 16 bit user segment description count */
#ifndef TRY_TEST_05182021
#ifdef TRY_TEST_05182021
/* output O/S and User MPL entries */
sim_debug(DEBUG_EXP, &cpu_dev,
"#LPSDCM MEM %06x MPL %06x MPL[0] %08x %06x MPL[%04x] %08x %06x\n",
@ -6302,8 +6348,11 @@ skipdqe:
break; /* ignore */
/* SPAD entries for interrupts begin at 0x80 */
t = SPAD[prior+0x80]; /* get spad entry for interrupt */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) /* if unused, ignore instruction */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */
#endif
break; /* ignore */
if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */
@ -6337,7 +6386,11 @@ skipdqe:
/* SPAD entries for interrupts begin at 0x80 */
t = SPAD[prior+0x80]; /* get spad entry for interrupt */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) /* if unused, ignore instruction */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */
#endif
break; /* ignore */
if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */
@ -6371,8 +6424,11 @@ skipdqe:
break; /* ignore */
/* SPAD entries for interrupts begin at 0x80 */
t = SPAD[prior+0x80]; /* get spad entry for interrupt */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) /* if unused, ignore instruction */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */
#endif
break; /* ignore */
if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */
@ -6387,8 +6443,11 @@ skipdqe:
break; /* ignore */
/* SPAD entries for interrupts begin at 0x80 */
t = SPAD[prior+0x80]; /* get spad entry for interrupt */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) /* if unused, ignore instruction */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */
#endif
break; /* ignore */
if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */
@ -6404,8 +6463,11 @@ skipdqe:
break; /* ignore */
/* SPAD entries for interrupts begin at 0x80 */
t = SPAD[prior+0x80]; /* get spad entry for interrupt */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff)) /* if unused, ignore instruction */
#else
if ((t == 0) || ((t&MASK24) == MASK24)) /* if unused, ignore instruction */
#endif
break; /* ignore */
if ((t & 0x0f800000) == 0x0f000000) /* if class F ignore instruction */
@ -6511,7 +6573,11 @@ skipdqe:
/* the channel must be defined as a class F I/O channel in SPAD */
/* if not class F, the system will generate a system check trap */
t = SPAD[lchan]; /* get spad entry for channel */
if ((t == 0 || t == 0xffffffff) || /* if not set up, system check */
#ifdef FIX3X
if ((t == 0) || (t == 0xffffffff) || /* if not set up, system check */
#else
if ((t == 0) || ((t&MASK24) == MASK24) || /* if not set up, system check */
#endif
((t & 0x0f800000) != 0x0f000000)) { /* class in bits 4-7 */
TRAPME = SYSTEMCHK_TRAP; /* trap condition if F class */
TRAPSTATUS |= BIT0; /* class F error bit */
@ -6966,7 +7032,11 @@ newpsd:
/* SPAD location 0xf0 has trap vector base address */
uint32 tta = SPAD[0xf0]; /* get trap table address in memory */
uint32 tvl; /* trap vector location */
if (tta == 0 || tta == 0xffffffff)
#ifdef FIX3X
if ((tta == 0) || (tta == 0xffffffff)
#else
if ((tta == 0) || ((tta&MASK24) == MASK24))
#endif
tta = 0x80; /* if not set, assume 0x80 FIXME */
/* Trap Table Address in memory is pointed to by SPAD 0xF0 */
/* TODO update cpu status and trap status words with reason too */

View File

@ -521,5 +521,8 @@ extern int32 RDYQ_Put(uint32 entry);
extern int32 RDYQ_Get(uint32 *old);
extern int32 RDYQ_Num(void);
extern char *dump_mem(uint32 mp, int cnt);
extern char *dump_buf(uint8 *mp, int32 off, int cnt);
#define get_chan(chsa) ((chsa>>8)&0x7f) /* get channel number from ch/sa */

View File

@ -1142,6 +1142,7 @@ t_stat disk_srv(UNIT *uptr)
uint8 ch;
uint16 ssize = disk_type[type].ssiz * 4; /* disk sector size in bytes */
uint32 tstart;
char *bufp;
uint8 lbuf[32];
uint8 buf[1024];
uint8 buf2[1024];
@ -1933,11 +1934,41 @@ iha_error:
sim_debug(DEBUG_CMD, dptr,
"disk_srv after READ chsa %04x buffer %06x count %04x\n",
chsa, chp->ccw_addr, chp->ccw_count);
bufp = dump_buf(buf, 0, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 16, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 32, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
#ifdef EXTRA_WORDS
bufp = dump_buf(buf, 48, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
if ((chp->ccw_addr == 0x3cde0) && (buf[0] == 0x4a)) {
bufp = dump_buf(buf, 64, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 80, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 96, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 112, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 128, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 144, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 160, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
bufp = dump_buf(buf, 176, 16);
sim_debug(DEBUG_CMD, dptr, "disk_srv READ buf %s\n", bufp);
}
#endif
#if 0
sim_debug(DEBUG_DETAIL, dptr,
"disk_srv READ data %02x%02x%02x%02x %02x%02x%02x%02x "
"%02x%02x%02x%02x %02x%02x%02x%02x\n",
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7],
buf[8], buf[9], buf[10], buf[11], buf[12], buf[13], buf[14], buf[15]);
#endif
uptr->CHS++; /* next sector number */
/* process the next sector of data */

View File

@ -240,7 +240,7 @@ t_stat lpr_preio(UNIT *uptr, uint16 chan) {
}
sim_debug(DEBUG_CMD, dptr,
"lpr_preio unit %02x chsa %04xOK\n", unit, chsa);
"lpr_preio unit %02x chsa %04x OK\n", unit, chsa);
return SCPE_OK; /* good to go */
}
@ -298,8 +298,6 @@ t_stat lpr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
uptr->CMD &= ~(LPR_CMDMSK); /* zero cmd */
uptr->CMD |= (cmd & LPR_CMDMSK); /* save new command in CMD */
sim_activate(uptr, 100); /* Start unit off */
uptr->SNS = 0; /* no status */
uptr->CBP = 0; /* start of buffer */
return 0; /* we are good to go */
case 0x4: /* Sense Status */
@ -309,8 +307,6 @@ t_stat lpr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd)
uptr->CMD &= ~(LPR_CMDMSK); /* zero cmd */
uptr->CMD |= (cmd & LPR_CMDMSK); /* save new command in CMD */
sim_activate(uptr, 100); /* Start unit off */
uptr->SNS = 0; /* no status */
uptr->CBP = 0; /* start of buffer */
return 0; /* we are good to go */
default: /* invalid command */
@ -330,18 +326,41 @@ t_stat lpr_srv(UNIT *uptr) {
int chsa = GET_UADDR(uptr->CMD);
int u = (uptr - lpr_unit);
int cmd = (uptr->CMD & 0xff);
CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */
DEVICE *dptr = get_dev(uptr); /* get device pointer */
sim_debug(DEBUG_CMD, dptr,
"lpr_srv called chsa %04x cmd %02x CMD %08x cnt %04x\r\n",
chsa, cmd, uptr->CMD, uptr->CBP);
"lpr_srv called chsa %04x cmd %02x CMD %08x addr %06x cnt %04x\n",
chsa, cmd, uptr->CMD, chp->ccw_addr, chp->ccw_count);
/* FIXME, need IOP lp status bit assignments */
if (cmd == 0x04) { /* sense? */
uint8 ch = uptr->SNS; /* get current status */
uptr->CMD &= ~(LPR_CMDMSK); /* clear command */
chan_write_byte(chsa, &ch); /* write the status to memory */
uptr->CBP = 0; /* reset to beginning of buffer */
uint8 ch; /* get current status */
ch = uptr->SNS & SNS_BOF; /* BOF? */
if (chan_write_byte(chsa, &ch)) { /* write the status to memory */
sim_debug(DEBUG_CMD, dptr,
"lpr_srv write1 error CMD %08x read %02x SNS %02x ccw_count %02x\n",
uptr->CMD, ch, uptr->SNS, chp->ccw_count);
uptr->CMD &= ~(LPR_CMDMSK); /* clear command */
uptr->SNS = 0; /* no status */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */
return SCPE_OK;
}
ch = uptr->SNS & SNS_BOF; /* BOF? */
if (chan_write_byte(chsa, &ch)) { /* write the status to memory */
sim_debug(DEBUG_CMD, dptr,
"lpr_srv write2 error CMD %08x read %02x SNS %02x ccw_count %02x\n",
uptr->CMD, ch, uptr->SNS, chp->ccw_count);
uptr->CMD &= ~(LPR_CMDMSK); /* clear command */
uptr->SNS = 0; /* no status */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */
return SCPE_OK;
}
sim_debug(DEBUG_CMD, dptr,
"lpr_srv sense write CMD %08x read %02x SNS %02x ccw_count %02x\n",
uptr->CMD, ch, uptr->SNS, chp->ccw_count);
uptr->CMD &= LMASK; /* make non-busy */
uptr->SNS = 0; /* no status */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */
return SCPE_OK;
}
@ -446,13 +465,16 @@ t_stat lpr_srv(UNIT *uptr) {
if (uptr->CMD & LPR_FULL || uptr->CBP >= 156) {
lpr_data[u].lbuff[uptr->CBP] = 0x00; /* NULL terminate */
sim_fwrite(&lpr_data[u].lbuff, 1, uptr->CBP, uptr->fileref); /* Print our buffer */
sim_debug(DEBUG_DETAIL, dptr, "LPR %s", (char*)&lpr_data[u].lbuff);
sim_debug(DEBUG_DETAIL, dptr, "LPR %d %s\n", uptr->CNT, (char*)&lpr_data[u].lbuff);
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK); /* clear old status */
uptr->CBP = 0; /* start at beginning of buffer */
uptr->CNT++; /* increment the line count */
// uptr->CNT++; /* increment the line count */
if ((uint32)uptr->CNT > uptr->capac) { /* see if at max lines/page */
uptr->CNT = 0; /* yes, restart count */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */
uptr->SNS |= SNS_BOF; /* set BOF for SENSE */
sim_debug(DEBUG_CMD, dptr, "lpr_srv Got BOF\n");
// chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */
chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */
} else
chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */
/* done, so no time out */
@ -541,6 +563,7 @@ t_stat lpr_attach(UNIT *uptr, CONST char *file)
uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK);
uptr->CNT = 0;
uptr->SNS = 0;
uptr->capac = 66;
/* check for valid configured lpr */
/* must have valid DIB and Channel Program pointer */
@ -561,7 +584,7 @@ t_stat lpr_attach(UNIT *uptr, CONST char *file)
/* help information for lpr */
t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{
fprintf (st, "SEL32 924x High Speed Line Printer\r\n");
fprintf (st, "SEL32 924x High Speed Line Printer\n");
fprintf (st, "The Line printer can be configured to any number of\n");
fprintf (st, "lines per page with the:\n");
fprintf (st, "sim> SET LPRn LINESPERPAGE=n\n\n");

View File

@ -39,6 +39,7 @@
#include "sel32_defs.h"
#include "sim_tape.h"
//#define SLOW
#if NUM_DEVS_MT > 0
#define BUFFSIZE (64 * 1024)
@ -59,8 +60,8 @@
#define MT_RUN 0x33 /* Rewind and unload */
#define MT_FSR 0x43 /* Advance record */
#define MT_BSR 0x53 /* Backspace record */
#define MT_FSF 0x63 /* Advance filemark */
#define MT_BSF 0x73 /* Backspace filemark */
#define MT_FSF 0x63 /* Advance to filemark */
#define MT_BSF 0x73 /* Backspace to filemark */
#define MT_SETM 0x83 /* Set Mode command */
#define MT_WTM 0x93 /* Write Tape filemark */
#define MT_ERG 0xA3 /* Erase 3.5 of tape */
@ -129,7 +130,7 @@
#define SNS_MREG7 0x0100 /* 1 - HSDP scatter/gather mode */
/* Sense byte 3 */
/* data returned for SENSE cnd (0x04) */
/* data returned for SENSE cmd (0x04) */
#define SNS_RDY 0x80 /* Drive Ready */
#define SNS_ONLN 0x40 /* Drive Online */
#define SNS_WRP 0x20 /* Drive is file protected (write ring missing) */
@ -810,7 +811,8 @@ t_stat mt_error(UNIT *uptr, uint16 chsa, t_stat r, DEVICE *dptr)
case MTSE_BOT: /* beginning of tape */
uptr->SNS |= SNS_LOAD; /* tape at BOT */
sim_debug(DEBUG_CMD, dptr, "BOT\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
//77 chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done with command */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
case MTSE_INVRL: /* invalid rec lnt */
@ -835,11 +837,14 @@ t_stat mt_srv(UNIT *uptr)
t_mtrlnt reclen;
t_stat r = SCPE_ARG; /* Force error if not set */
int i;
uint32 mema;
char *bufp;
uint32 mema, m, skip;
uint16 len;
uint8 ch;
sim_debug(DEBUG_CMD, dptr, "mt_srv unit %04x cmd %02x\n", unit, cmd);
sim_debug(DEBUG_DETAIL, dptr,
"mt_srv unit %02x cmd %02x POS %x hwmark %03x\n",
unit, cmd, uptr->POS, uptr->hwmark);
switch (cmd) {
case MT_CMDMSK: /* 0x0ff for inch 0x00 */ /* INCH is for channel, nothing for us */
@ -945,6 +950,8 @@ t_stat mt_srv(UNIT *uptr)
case MT_SETM: /* 0x83 */ /* set mode byte */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x83 SETM unit=%02x\n", unit);
/*DYNAMIC DEBUG*/
//cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
/* Grab data until channel has no more */
if (chan_read_byte(chsa, &ch)) {
if (uptr->POS > 0) { /* Only if data in record */
@ -986,8 +993,10 @@ t_stat mt_srv(UNIT *uptr)
switch (cmd) {
case MT_READ: /* 0x02 */ /* read a record from the device */
sim_debug(DEBUG_DETAIL, dptr, "mt_srv cmd 2 READ unit=%02x\n", unit);
#ifndef SPEED
// sim_debug(DEBUG_DETAIL,
// dptr, "mt_srv cmd(2)READ unit %02x bufnum %x hwmark %03x\n",
// unit, bufnum, uptr->hwmark);
#ifndef SLOW
reread:
#endif
if (uptr->CMD & MT_READDONE) { /* is the read complete */
@ -1002,12 +1011,16 @@ reread:
sim_debug(DEBUG_CMD, dptr,
"mt_srv READ %04x char complete unit=%02x sense %08x\n",
uptr->POS, unit, uptr->SNS);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* set CE, DE */
if (uptr->SNS & SNS_EOT)
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* set CE, DE, UE */
else
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* set CE, DE */
break;
}
/* read is not completed, get an input char */
/* If empty buffer, fill */
if (BUF_EMPTY(uptr)) {
m = chp->ccw_addr & MASK24; /* memory buffer address */
/* buffer is empty, so fill it with next record data */
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) {
sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer unit=%02x\n", unit);
@ -1017,13 +1030,30 @@ reread:
uptr->SNS &= ~(SNS_LOAD|SNS_EOT); /* reset BOT & EOT */
uptr->POS = 0; /* reset buffer position */
uptr->hwmark = reclen; /* set buffer chars read in */
sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer complete count %04x\n", reclen);
sim_debug(DEBUG_CMD, dptr,
"mt_srv READ MemBuf %06x cnt %04x %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x%02x%02x\n",
chp->ccw_addr, chp->ccw_count,
mt_buffer[0][0], mt_buffer[0][1], mt_buffer[0][2], mt_buffer[0][3],
mt_buffer[0][4], mt_buffer[0][5], mt_buffer[0][6], mt_buffer[0][7],
mt_buffer[0][8], mt_buffer[0][9], mt_buffer[0][10], mt_buffer[0][11]);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ fill buffer %06x complete count %04x\n", m, reclen);
bufp = dump_buf(&mt_buffer[bufnum][0], 0, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp);
bufp = dump_buf(&mt_buffer[bufnum][0], 16, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp);
bufp = dump_buf(&mt_buffer[bufnum][0], 32, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ buf %s\n", bufp);
m = chp->ccw_addr & MASK24; /* memory buffer address */
bufp = dump_mem(m, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp);
bufp = dump_mem(m+16, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp);
bufp = dump_mem(m+32, 16);
sim_debug(DEBUG_CMD, dptr, "mt_srv READ mem %s\n", bufp);
/*DYNAMIC DEBUG*/
/* J */
//if ((chp->ccw_addr == 0x54e00) && (mt_buffer[0][0] == 0x4a))
//cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
//if ((chp->ccw_addr == 0x7f96c0) && (mt_buffer[0][0] == 0x80))
//cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
}
/* get a char from the buffer */
ch = mt_buffer[bufnum][uptr->POS++];
@ -1031,7 +1061,7 @@ reread:
/* Send character over to channel */
if (chan_write_byte(chsa, &ch)) {
sim_debug(DEBUG_CMD, dptr,
"Read unit %02x EOR cnt %04x hwm %04x\n", unit, uptr->POS, uptr->hwmark);
"Read unit %02x EOR cnt %04x hwm %04x\n", unit, uptr->POS-1, uptr->hwmark);
/* If not read whole record, skip till end */
if ((uint32)uptr->POS < uptr->hwmark) {
/* Send dummy character to force SLI */
@ -1039,17 +1069,24 @@ reread:
sim_debug(DEBUG_CMD, dptr, "Read unit %02x send dump SLI\n", unit);
//5 sim_activate(uptr, (uptr->hwmark-uptr->POS) * 10); /* wait again */
sim_activate(uptr, (uptr->hwmark-uptr->POS) * 4); /* wait again */
//77 sim_activate(uptr, 50);
uptr->CMD |= MT_READDONE; /* read is done */
break;
}
sim_debug(DEBUG_CMD, dptr,
"Read data @1 unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
#ifndef OLDWAY
uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */
mt_busy[bufnum] &= ~1; /* set not busy */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */
#else
sim_activate(uptr, 50);
uptr->CMD |= MT_READDONE; /* read is done */
break;
#endif
} else {
sim_debug(DEBUG_DETAIL, dptr,
sim_debug(DEBUG_DATA, dptr,
"Read data @2 unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
if ((uint32)uptr->POS >= uptr->hwmark) { /* In IRG */
@ -1058,7 +1095,7 @@ reread:
"Read end of data unit %02x cnt %04x ch %02x hwm %04x\n",
unit, uptr->POS, ch, uptr->hwmark);
uptr->CMD |= MT_READDONE; /* read is done */
#ifdef SPEED
#ifdef SLOW
//5 sim_activate(uptr, 40); /* wait again */
sim_activate(uptr, 30); /* wait again */
} else
@ -1083,7 +1120,7 @@ reread:
break;
}
#ifndef SPEED
#ifndef SLOW
rewrite:
#endif
/* Grab data until channel has no more */
@ -1099,17 +1136,17 @@ rewrite:
}
} else {
mt_buffer[bufnum][uptr->POS++] = ch;
sim_debug(DEBUG_DETAIL, dptr, "Write data unit=%02x %04x %02x\n",
sim_debug(DEBUG_DATA, dptr, "Write data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
uptr->hwmark = uptr->POS;
#ifndef SPEED
#ifndef SLOW
goto rewrite;
#endif
}
#ifdef SPEED
//#ifdef SLOW
//5 sim_activate(uptr, 40);
sim_activate(uptr, 30); /* wait again */
#endif
// sim_activate(uptr, 30); /* wait again */
//#endif
break;
case MT_RDBK: /* 0x0C */ /* Read Backwards */
@ -1154,7 +1191,7 @@ rewrite:
mt_busy[bufnum] &= ~1;
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
} else {
sim_debug(DEBUG_DETAIL, dptr, "Read data unit=%02x %04x %02x\n",
sim_debug(DEBUG_CMD, dptr, "Read data unit=%02x %04x %02x\n",
unit, uptr->POS, ch);
if (uptr->POS == 0) { /* In IRG */
uptr->CMD &= ~MT_CMDMSK;
@ -1188,8 +1225,9 @@ rewrite:
break;
case MT_BSR: /* 0x53 */ /* Backspace record */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x53 BSR unit %02x POS %04x\n",
unit, uptr->POS);
//77 chp->ccw_count = 0; /* zero the count */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x53 BSR unit %02x POS %x SNS %08x\n",
unit, uptr->POS, uptr->SNS);
switch (uptr->POS ) {
case 0:
if (sim_tape_bot(uptr)) {
@ -1199,27 +1237,31 @@ rewrite:
return SCPE_OK;
}
uptr->POS++;
//5 sim_activate(uptr, 50);
//5 sim_activate(uptr, 500);
sim_activate(uptr, 30);
break;
case 1:
//66 skip = 1; /* skip back 1 record */
uptr->POS++;
sim_debug(DEBUG_CMD, dptr, "Backspace rec unit %02x POS %04x\n",
unit, uptr->POS);
//77 uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */
//66 r = sim_tape_sprecsr(uptr, skip, &reclen);
r = sim_tape_sprecr(uptr, &reclen);
sim_debug(DEBUG_CMD, dptr, "Backspace rec unit %02x POS %x r %x\n",
unit, uptr->POS, r);
/* SEL requires Unit Except & EOF on EOF */
if (r == MTSE_TMK) { /* test for EOF */
uptr->POS++;
sim_debug(DEBUG_CMD, dptr, "BSR MARK\n");
sim_debug(DEBUG_CMD, dptr, "BSR got EOF MARK\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
/* SEL requires Unit Except & BOT on BOT */
} else if (r == MTSE_BOT) {
uptr->POS+= 2;
sim_debug(DEBUG_CMD, dptr, "BSR got BOT\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
} else {
sim_debug(DEBUG_CMD, dptr, "Backspace reclen %04x\n", reclen);
sim_debug(DEBUG_CMD, dptr, "Backspace reclen %04x SNS %08x\n", reclen, uptr->SNS);
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
}
@ -1227,25 +1269,30 @@ rewrite:
case 2:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Backspace record completed with NO status\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
case 3: /* EOF */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, dptr, "Backspace record completed with EOF status\n");
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
break;
case 4: /* BOT */
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_LOAD; /* set BOT detected */
sim_debug(DEBUG_CMD, dptr, "Backspace record completed with BOT status\n");
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_BSF: /* 0x73 */ /* Backspace file */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x73 BSF unit %02x\n", unit);
//77 chp->ccw_count = 0; /* zero the count */
sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x73 BSF unit %02x POS %04x\n",
unit, uptr->POS);
switch(uptr->POS) {
case 0:
if (sim_tape_bot(uptr)) {
@ -1259,60 +1306,108 @@ rewrite:
sim_activate(uptr, 100);
break;
case 1:
sim_debug(DEBUG_CMD, dptr, "Backspace file unit=%02x\n", unit);
//#define NBSF
#ifdef NBSF
skip = 1; /* skip 1 file */
#endif
uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */
#ifdef NBSF
/* using the backspace file call does not work with MPX */
//77?? r = sim_tape_spfiler(uptr, skip, &reclen);
r = sim_tape_spfiler(uptr, skip, &reclen);
uptr->POS++;
#else
r = sim_tape_sprecr(uptr, &reclen);
#endif
sim_debug(DEBUG_CMD, dptr, "Backspace file unit=%02x r %x\n", unit, r);
if (r == MTSE_TMK) {
uptr->POS++;
sim_debug(DEBUG_DETAIL, dptr, "BSF MARK\n");
sim_debug(DEBUG_CMD, dptr, "BSF got EOF MARK\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
} else if (r == MTSE_BOT) {
uptr->POS+= 2;
sim_debug(DEBUG_CMD, dptr, "BSF got BOT\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
} else {
/* already there */
sim_debug(DEBUG_CMD, dptr, "Backspace file reclen %04x\n", reclen);
sim_activate(uptr, 20);
}
break;
#ifdef NBSF
case 2:
uptr->CMD &= ~(MT_CMDMSK);
/* no EOF detected, but we did go back 1 record */
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with NO EOF status\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
//00 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
//88 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
#endif
#ifdef NBSF
case 3: /* File Mark */
#else
case 2: /* File Mark */
#endif
uptr->CMD &= ~(MT_CMDMSK);
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
mt_busy[bufnum] &= ~1;
chan_end(chsa, SNS_DEVEND);
sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with EOF status\n");
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
//00 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
//88 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
break;
#ifdef NBSF
case 4: /* BOT */
#else
case 3: /* BOT */
#endif
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
uptr->SNS |= SNS_LOAD; /* set BOT */
chan_end(chsa, SNS_DEVEND);
uptr->SNS |= SNS_LOAD; /* set BOT detected */
sim_debug(DEBUG_CMD, dptr, "Backspace file Completed with BOT status\n");
#ifdef NBSF
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
//77?? chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
#else
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
//00 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
//88 chan_end(chsa, SNS_CHNEND|SNS_DEVEND);
#endif
break;
}
break;
case MT_FSR: /* 0x43 */ /* Advance record */
//77 chp->ccw_count = 0; /* zero the count */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, dptr, "Skip rec entry unit=%02x ", unit);
sim_debug(DEBUG_CMD, dptr, "Skip rec entry unit=%02x POS %x\n", unit, uptr->POS);
uptr->POS++;
//5 sim_activate(uptr, 50);
//5 sim_activate(uptr, 500);
sim_activate(uptr, 30);
break;
case 1:
//66 skip = 1; /* skip 1 record */
uptr->POS++;
sim_debug(DEBUG_CMD, dptr, "Skip rec unit=%02x ", unit);
uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */
//66 r = sim_tape_sprecsf(uptr, skip, &reclen);
r = sim_tape_sprecf(uptr, &reclen);
sim_debug(DEBUG_CMD, dptr, "Skip rec unit=%02x r %x\n", unit, r);
if (r == MTSE_TMK) {
uptr->POS = 3;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
sim_debug(DEBUG_CMD, dptr, "FSR MARK\n");
sim_debug(DEBUG_CMD, dptr, "FSR got EOF MARK\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
} else if (r == MTSE_EOM) {
uptr->POS = 4;
uptr->SNS |= SNS_EOT; /* set EOT status */
sim_debug(DEBUG_CMD, dptr, "FSR EOT\n");
sim_debug(DEBUG_CMD, dptr, "FSR got EOT\n");
//5 sim_activate(uptr, 50);
sim_activate(uptr, 30);
} else {
@ -1326,36 +1421,43 @@ rewrite:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Skip record Completed\n");
chan_end(chsa, SNS_DEVEND);
/*DYNAMIC DEBUG*/
//cpu_dev.dctrl |= DEBUG_INST; /* start instruction trace */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Skip record now at EOF\n");
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
//77 chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
case 4:
uptr->CMD &= ~(MT_CMDMSK);
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr, "Skip record now at EOT\n");
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
//77 chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
}
break;
case MT_FSF: /* 0x63 */ /* advance filemark */
//77 chp->ccw_count = 0; /* zero the count */
switch(uptr->POS) {
case 0:
sim_debug(DEBUG_CMD, dptr,
"Skip file entry sense %08x unit %02x\n", uptr->SNS, unit);
uptr->POS++;
//5 sim_activate(uptr, 50);
//5 sim_activate(uptr, 500);
sim_activate(uptr, 30);
break;
case 1:
sim_debug(DEBUG_CMD, dptr, "Skip file unit=%02x\n", unit);
skip = 1; /* skip back 1 file */
uptr->SNS &= ~(SNS_LOAD|SNS_EOT|SNS_FMRKDT); /* reset BOT, EOT, EOF */
r = sim_tape_sprecf(uptr, &reclen);
//77 r = sim_tape_spfilef(uptr, skip, &reclen);
sim_debug(DEBUG_CMD, dptr, "Skip file unit=%02x r %x\n", unit, r);
if (r == MTSE_TMK) {
uptr->POS++;
uptr->SNS |= SNS_FMRKDT; /* file mark detected */
@ -1379,7 +1481,9 @@ rewrite:
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr,
"Skip file done sense %08x unit %02x\n", uptr->SNS, unit);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
//88 chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
//00 chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
case 3:
uptr->CMD &= ~(MT_CMDMSK);
@ -1387,7 +1491,9 @@ rewrite:
mt_busy[bufnum] &= ~1;
sim_debug(DEBUG_CMD, dptr,
"Skip file got EOT sense %08x unit %02x\n", uptr->SNS, unit);
chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
//88 chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
//00 chan_end(chsa, SNS_DEVEND|SNS_UNITEXP);
chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
break;
}
break;

View File

@ -28,6 +28,8 @@ extern REG cpu_reg[];
extern uint32 M[MAXMEMSIZE];
extern uint32 SPAD[];
extern uint32 PSD[];
char *dump_mem(uint32 mp, int cnt);
char *dump_buf(uint8 *mp, int32 off, int cnt);
/* SCP data structures and interface routines
@ -144,6 +146,93 @@ const char *sim_stop_messages[SCPE_BASE] = {
"Memory management trap during trap",
};
#define PRINTABLE(x) ((x < 32) || (x > 126)) ? '.' : x
static char line[257];
/* function to dump SEL32 memory up to 16 bytes with side by side ascii values */
char *dump_mem(uint32 mp, int cnt)
{
char buff[257];
uint32 ma = mp; /* save memory address */
char *cp = &line[0]; /* output buffer */
int cc=0, ch, bp=0, bl=cnt;
if (cnt > 16)
bl = 16; /* stop at 16 chars */
while (bp < bl) {
if (!bp) {
cc = sprintf(cp, " %06x : ", ma); /* output location address */
cp += cc; /* next print location */
}
ch = RMB(ma) & 0xff; /* get a char from memory */
ma++; /* next loc */
cc += sprintf(cp, "%02x", ch); /* print out current char */
cp += 2; /* next print location */
buff[bp++] = PRINTABLE(ch); /* get printable version of char */
if (!(bp % 4)) { /* word boundry yet? */
cc += sprintf(cp, " "); /* space between words */
cp += 1; /* next print location */
}
}
while (bp < 16) {
cc += sprintf(cp, " "); /* print out one space */
cp += 1; /* next print location */
buff[bp++] = 0x20; /* blank char buffer */
if (!(bp % 4)) {
cc += sprintf(cp, " "); /* space between words */
cp += 1; /* next print location */
}
}
buff[bp] = 0; /* terminate line */
cc += sprintf(cp, "|%s|\n", buff); /* print out ascii text */
return (line); /* return pointer to caller */
}
/* function to dump caller buffer upto 16 bytes with side by side ascii values */
/* off is offset in buffer to start */
char *dump_buf(uint8 *mp, int32 off, int cnt)
{
char buff[257];
uint32 ma = off; /* save memory address */
char *cp = &line[0]; /* output buffer */
int cc=0, ch, bp=0, bl=cnt;
if (cnt > 16)
bl = 16; /* stop at 16 chars */
while (bp < bl) {
if (!bp) {
cc = sprintf(cp, " %06x : ", ma); /* output location offset */
cp += cc; /* next print location */
}
ch = mp[ma++] & 0xff; /* get a char from memory */
cc += sprintf(cp, "%02x", ch); /* print out current char */
cp += 2; /* next print location */
buff[bp++] = PRINTABLE(ch); /* get printable version of char */
if (!(bp % 4)) { /* word boundry yet? */
cc += sprintf(cp, " "); /* space between words */
cp += 1; /* next print location */
}
}
while (bp < 16) {
cc += sprintf(cp, " "); /* print out one space */
cp += 1; /* next print location */
buff[bp++] = 0x20; /* blank char buffer */
if (!(bp % 4)) {
cc += sprintf(cp, " "); /* space between words */
cp += 1; /* next print location */
}
}
buff[bp] = 0; /* terminate line */
cc += sprintf(cp, "|%s|\n", buff); /* print out ascii text */
return (line); /* return pointer to caller */
}
/*
* get_word - function to load a 32 bit word from the input file
* return 1 - OK

View File

@ -32,7 +32,6 @@ PROGS = \
$(ROOT)/mkdiagtape \
$(ROOT)/tapdump \
$(ROOT)/tape2disk \
## $(ROOT)/fileread \
$(ROOT)/disk2tap \
$(ROOT)/tapscan \
$(ROOT)/eomtap \
@ -46,6 +45,7 @@ PROGS = \
$(ROOT)/tap2disk \
$(ROOT)/cutostap \
$(ROOT)/small
## $(ROOT)/fileread
all: $(PROGS)

View File

@ -14,17 +14,42 @@
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#ifdef _WIN32
#include <stddef.h>
#endif
//#include <unistd.h>
#define BLKSIZE 768 /* MPX file sector size */
unsigned char data[7680]; /* room for 10*768=(7680) 768 byte sectors per 7680 byte block */
#if defined(_MSC_VER) && (_MSC_VER < 1600)
typedef __int8 int8;
typedef __int16 int16;
typedef __int32 int32;
typedef unsigned __int8 uint8;
typedef unsigned __int16 uint16;
typedef unsigned __int32 uint32;
typedef signed __int64 t_int64;
typedef unsigned __int64 t_uint64;
typedef t_int64 off_t;
#else
/* All modern/standard compiler environments */
/* any other environment needa a special case above */
#include <stdint.h>
typedef int8_t int8;
typedef int16_t int16;
typedef int32_t int32;
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
#endif /* end standard integers */
#define BLKSIZE 768 /* MPX file sector size */
unsigned char data[7680]; /* room for 10*768=(7680) 768 byte sectors per 7680 byte block */
/* write 1 file to tape in 768 byte records */
/* mblks is the maximum blockes to write from a file, 0=all */
/* chunks is the number of sectors to wrote at a time 1-8 */
int writefile(FILE *tp, char *fnp, u_int32_t mblks, int32_t chunks) {
u_int32_t word, blks=mblks; /* just a temp word variable */
u_int32_t size, bsize, csize; /* size in 768 byte sectors */
int writefile(FILE *tp, char *fnp, uint32 mblks, int32 chunks) {
int32 word, blks=mblks; /* just a temp word variable */
int32 size, bsize, csize; /* size in 768 byte sectors */
FILE *fp;
int32_t n1, n2, hc, nw, cs;
@ -82,6 +107,7 @@ int writefile(FILE *tp, char *fnp, u_int32_t mblks, int32_t chunks) {
//printf("write file %s (size %d bytes) (%d sect) (%d blocks) (%d chunks)\n",
// fnp, word, size, mblks, blks);
fclose(fp);
exit(0);
}
/* read program file and output to a simulated diagnostic tape */
@ -90,15 +116,12 @@ int main(argc, argv)
int argc;
char *argv[];
{
FILE *dp, *fp, *cp, *fopen();
int targc;
FILE *dp, *fp, *fopen();
char **targv;
char *p, *cmdp;
int i;
unsigned char *fnp; /* file name pointer */
unsigned int size; /* size in 768 byte sectors */
unsigned int word; /* just a temp word variable */
int goteof, goteom; /* end flags */
int goteof; /* end flags */
int writing; /* writing output */
memset((char *)data, 0, 4608); /* zero data storage */
@ -159,8 +182,6 @@ char *argv[];
/* got input tapefile and options, handle output file now */
// printf("AT 3 argc %d argv %s\n", argc, *argv);
if (--argc > 0) {
int blks;
p = *argv++;
printf("argc %d argv3 %s\n", argc, p);
if ((fp = fopen(p, "w")) == NULL) {

View File

@ -82,13 +82,19 @@ char mstrout[] = "mstrout";
/* write 1 file to tape in 768 byte records */
/* mblks is the maximum blockes to write from a file, 0=all */
/* mblks is rounded to next sector */
/* chunks is the number of sectors to wrote at a time 1-8 */
int writefile(FILE *tp, char *fnp, uint32 mblks, int32 chunks) {
/* rem is byte excess in last sector based on program size */
/* sysinit reads exact bytes from file. If rounded we get RM82 error */
int writefile(FILE *tp, char *fnp, uint32 mblks, int32 chunks, int32 rem) {
uint32 word, blks=mblks; /* just a temp word variable */
uint32 size, bsize, csize; /* size in 768 byte sectors */
FILE *fp;
int32 n1, n2, hc, nw, cs;
/* setting rem to 0 will always write full sectors */
/* doing partial sectors did not fix anything */
rem = 0; /* do not use remainders */
memset((char *)data, 0, sizeof(data)); /* zero data storage */
/* write file to tape */
if ((fp = fopen(fnp, "r")) == NULL) {
@ -97,24 +103,36 @@ int writefile(FILE *tp, char *fnp, uint32 mblks, int32 chunks) {
}
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
printf("MPX file %s is %x (%d) bytes\n", fnp, word, word);
printf("MPX file %s is %x (%d) bytes rem %x (%d) mblks %x (%d)\n", fnp, word, word, rem, rem, mblks, mblks);
fseek(fp, 0, SEEK_SET); /* rewind file */
size = (word/768); /* filesize in sectors */
if (word%768 != 0) /* see if byte left over */
if (word%768 != 0) /* see if bytes left over */
size += 1; /* partial sector, add 1 */
/* size has #768 blocks in file */
if (mblks == 0) {
mblks = (word/768); /* blocks */
if ((word%768) != 0) /* round up blks if remainder */
mblks++; /* total block to write */
// mblks = (word/768); /* blocks */
// if ((word%768) != 0) /* round up blks if remainder */
// mblks++; /* total block to write */
mblks = size; /* use file size */
rem = 0; /* no rem if no mblks */
}
blks = mblks/chunks; /* chunks */
if (mblks%768 != 0) /* see if blks left over */
blks += 1; /* partial blks, add 1 */
if (rem != 0) {
mblks--; /* last block will be rem bytes */
}
printf("MPX0 file %s is %x (%d) bytes mblks %d chunk %d rem %d\n",
fnp, word, word, mblks, chunks, rem);
// blks = mblks/chunks; /* chunks */
// if (mblks%768 != 0) /* see if blks left over */
// blks += 1; /* partial blks, add 1 */
/// bsize = mblks/chunks; /* chunks */
/// if (mblks%chunks != 0) /* see if blks left over */
/// bsize += 1; /* partial blks, add 1 */
/// blks = bsize; /* save # blks */
bsize = mblks; /* save # blks */
printf("MPX file %s is %x (%d) bytes blks %d chk %d\n",
fnp, word, word, bsize, (bsize+1)/chunks);
printf("MPX1 file %s is %x (%d) bytes mblks %d bsize %d rem %d\n",
fnp, word, word, mblks, bsize, rem);
csize = 0;
/* read in the image file */
while (bsize > 0) {
@ -138,10 +156,29 @@ printf("MPX file %s is %x (%d) bytes blks %d chk %d\n",
exit(1);
}
bsize -= csize; /* do next chunk */
memset((char *)data, 0, csize); /* zero data storage */
memset((char *)data, 0, csize*768); /* zero data storage */
if ((bsize <= 0) && (rem != 0)) {
fprintf(stderr, "writing last block to %s rem = %x (%d)\n", fnp, rem, rem);
cs = fread((char *)data, rem, 1, fp); /* read last "real" bytes */
/* we have data to write */
hc = (rem + 1) & ~1; /* make byte count even */
/* write actual byte count to 32 bit word as header */
n1 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), tp);
/* write the data mod 2 */
nw = fwrite((unsigned char *)data, 1, (size_t)hc, tp);
/* write the byte count in 32 bit word as footer */
n2 = fwrite((char *)(&hc), 1, (size_t)sizeof(hc), tp);
fprintf(stderr, "done with last block to %s rem %x n1 %x nw %x n2 %x\n", fnp, rem, n1, nw, n2);
if (n1 != sizeof(hc) || nw != hc || n2 != sizeof(hc))
{
fprintf(stderr, "write to %s failure\n", fnp);
fprintf(stderr, "Operation aborted\n");
exit(1);
}
}
}
printf("write file %s (size %d bytes) (%d sect) (%d blocks) (%d chunks)\n",
fnp, word, size, mblks, blks);
printf("write file %s (size %d bytes) (%d sect) (%d blocks) (%d chunks) (%d rem)\n",
fnp, word, size, mblks, blks, rem);
fclose(fp);
return(0);
}
@ -178,14 +215,15 @@ uint32 flip(uint32 val) {
}
/* get number of 768 byte blocks in file */
uint32 getblks(char *imgp)
/* returned number of sectors is rounded up */
/* rem is bytes in last sect */
uint32 getblks(char *imgp, uint32 *rem)
{
unsigned int size; /* size in 768 byte sectors */
unsigned int word; /* just a temp word variable */
FILE *fp;
int32 n1, n2, w2, blks;
memset((char *)M, 0, 192); /* zero data storage */
memset((char *)M, 0, 768); /* zero data storage */
if ((fp = fopen(imgp, "r")) == NULL) {
fprintf(stderr, "error: can't open image file %s\n", imgp);
exit(1); /* we are done here */
@ -199,15 +237,16 @@ printf("image file %s is %x (%d) bytes\n", imgp, word, word);
n2 = flip(M[0x64/4]); /* get PR.SFADR sec addr of rel matrix */
if (n2 == 0) { /* if zero use PR.SFAD rel addr of dsect */
n1 = flip(M[0x5C/4]); /* get PR.BYTED bytes in dsect */
n2 = flip(M[0x58/4]); /* get PR.SFADR sec addr of dsect */
n2 = flip(M[0x58/4]); /* get PR.SFAD sec addr of dsect */
n2 += 1; /* add 1 blk for sys debug blk */
}
blks = n1/768; /* get #block rounded mod 768 */
*rem = n1%768; /* get excess bytes */
if ((n1%768) != 0) /* round up blks if remainder */
blks++;
blks += n2; /* get total blks to read */
printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d)\n",
imgp, n1, n1, n2, n2, blks, blks);
printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d) rem %x (%d)\n",
imgp, n1, n1, n2, n2, blks, blks, *rem, *rem);
fseek(fp, 0, SEEK_SET); /* rewind file */
fclose(fp);
@ -430,7 +469,8 @@ error1:
fseek(dp, 0, SEEK_END); /* seek to end */
bytes = ftell(dp); /* get filesize in bytes */
printf("1 file length %ld %lx bytes\n", bytes, bytes);
printf("1 start writing at %ld %lx bytes offset\n", bytes-8, bytes-8);
//67 printf("1 start writing at %ld %lx bytes offset\n", bytes-8, bytes-8);
printf("1 start writing at %ld %lx bytes offset\n", bytes-4, bytes-4);
fseek(dp, 0, SEEK_SET); /* rewind file to beginning */
/* at this point, we are at the end of the tape */
/* we should see 3 EOF's w/ or w/o an EOM */
@ -444,8 +484,9 @@ readmore:
if (n1 <=0) /* check for read error */
goto doabort; /* bad tape format */
//printf("2 file length %ld %lx bytes\n", bytes, bytes);
//printf("2 start writing at %ld %lx bytes offset\n", bytes-8, bytes-8);
printf("2 file length %ld %lx bytes\n", bytes, bytes);
//67printf("2 start writing at %ld %lx bytes offset\n", bytes-8, bytes-8);
printf("2 start writing at %ld %lx bytes offset\n", bytes-4, bytes-4);
if (hc & 0xffff0000) /* check for garbage */
hc = 0; /* assume EOF on disk */
@ -520,7 +561,7 @@ getout:
}
/* process the bootfile first */
if (option & DOBOOT) {
int32 w2, n1, n2, nw, hc, blks;
int32 w2, n1, n2, nw, hc, blks, rem;
fnp = bootp; /* get file name pointer */
memset((char *)data, 0, 0x800); /* zero data storage */
#define USE_FILENAME
@ -563,64 +604,64 @@ printf("bootfile %s is %x (%d) bytes\n", bootp, word, word);
}
printf("write boot file %s (size %d bytes)\n", bootp, word, word);
/* setup for mpx image file */
memset((char *)data, 0, 0x800); /* zero data storage */
memset((char *)data, 0, 0x800); /* zero data storage */
if (option & DOMSTR) {
/* get blocks in image file */
blks = getblks(mstrall);
/* write mpx image file */
writefile(dp, mstrall, blks, 1); /* write max of "blks" blocks to file */
blks = getblks(mstrall, &rem);
/* write 1st mpx image file */
writefile(dp, mstrall, blks, 1, rem); /* write max of "blks" blocks to file */
/* write EOF (zero) to file */
filen = 0; /* zero count */
filen = 0; /* zero count */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
blks = getblks(mstrext);
/* write mpx image file */
writefile(dp, mstrext, blks, 1); /* write max of "blks" blocks to file */
blks = getblks(mstrext, &rem);
/* write 2nd mpx image file */
writefile(dp, mstrext, blks, 1, rem); /* write max of "blks" blocks to file */
/* write EOF (zero) to file */
filen = 0; /* zero count */
filen = 0; /* zero count */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
blks = getblks(mstrout);
/* write mpx image file */
writefile(dp, mstrout, blks, 1); /* write max of "blks" blocks to file */
blks = getblks(mstrout, &rem);
/* write 3rd mpx image file */
writefile(dp, mstrout, blks, 1, rem); /* write max of "blks" blocks to file */
/* write EOF (zero) to file */
filen = 0; /* zero count */
filen = 0; /* zero count */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
} else {
/* get blocks in image file */
blks = getblks(imgp);
blks = getblks(imgp, &rem);
/* write mpx image file */
writefile(dp, imgp, blks, 1); /* write max of "blks" blocks to file */
writefile(dp, imgp, blks, 1, rem); /* write max of "blks" blocks to file */
}
/* get blocks in j.vfmt file */
// blks = getblks(vfmtp);
blks = getblks(vfmtp, &rem);
/* write j.vfmt file */
// writefile(dp, vfmtp, blks, 1); /* write 1 blk at a time */
writefile(dp, vfmtp, 0, 1); /* write 1 blk at a time */
writefile(dp, vfmtp, blks, 1, rem); /* write 1 blk at a time */
// writefile(dp, vfmtp, 0, 1); /* write 1 blk at a time */
/* write EOF (zero) to file */
filen = 0; /* zero count */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
/* write j.mount file */
// blks = getblks("j.mount");
// writefile(dp, "j.mount", blks, 1); /* one blk at a time */
writefile(dp, "j.mount", 0, 1); /* one blk at a time */
blks = getblks("j.mount", &rem);
writefile(dp, "j.mount", blks, 1, rem); /* one blk at a time */
// writefile(dp, "j.mount", 0, 1); /* one blk at a time */
/* write j.swapr file */
// blks = getblks("j.swapr");
// writefile(dp, "j.swapr", blks, 1); /* one blk at a time */
writefile(dp, "j.swapr", 0, 1); /* one blk at a time */
blks = getblks("j.swapr", &rem);
writefile(dp, "j.swapr", blks, 1, rem); /* one blk at a time */
// writefile(dp, "j.swapr", 0, 1); /* one blk at a time */
/* write volmgr file */
// blks = getblks("volmgr");
// writefile(dp, "volmgr", blks, 1); /* one blk at a time */
writefile(dp, "volmgr", 0, 1); /* all of file 1 blk at a time */
blks = getblks("volmgr", &rem);
writefile(dp, "volmgr", blks, 1, rem); /* one blk at a time */
// writefile(dp, "volmgr", 0, 1); /* all of file 1 blk at a time */
/* write EOF (zero) to file */
filen = 0; /* zero count */
@ -628,6 +669,9 @@ printf("write boot file %s (size %d bytes)\n", bootp, word, word);
/* do second EOF */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
/* do third EOF */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
filen = -1; /* make in -1 for EOM */
/* do EOM */
fwrite((char *)(&filen), 1, (size_t)sizeof(filen), dp);
@ -647,7 +691,7 @@ printf("setting at %ld bytes in file after EOM\n", ftell(dp));
goto error1; /* we are done here */
}
/*------------------------------------------------------------------------*/
savecnt = 0; /* no files yet */
savecnt = 0; /* no files "yet */
/* make first pass over files and get filenames and sizes */
/* got tapefile and options, handle files now */
targc = argc; /* save argc to reread list */
@ -784,10 +828,11 @@ printf("AT write file list with %d entries\n", filen);
// int32 n1, n2, nw, k;
int32 n1, n2, nw;
int32 hc = (1536 + 1) & ~1; /* make byte count even */
// int blks;
int blks, rem;
p = *argv++;
printf("at 4 argc %d argv %s\n", argc, p);
blks = getblks(p, &rem);
if ((fp = fopen(p, "r")) == NULL) {
fprintf(stderr, "error: can't open user file %s\n", p);
@ -795,14 +840,18 @@ printf("at 4 argc %d argv %s\n", argc, p);
}
fnp = p; /* get file name pointer */
/* we need to write the resource descriptor in 2 blks to file */
/* followed by file content is 8 blk chunks */
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
fseek(fp, 0, SEEK_SET); /* rewind file */
size = (word/768); /* filesize in sectors */
if (word%768 != 0) /* see if byte left over */
size += 1; /* partial sector, add 1 */
if (typ != 0xca) {
/* we need to write the resource descriptor in 2 blks to file */
/* followed by file content is 8 blk chunks */
fseek(fp, 0, SEEK_END); /* seek to end */
word = ftell(fp); /* get filesize in bytes */
fseek(fp, 0, SEEK_SET); /* rewind file */
size = (word/768); /* filesize in sectors */
if (word%768 != 0) /* see if byte left over */
size += 1; /* partial sector, add 1 */
} else {
size = blks;
}
/* round up mod 4 */
size += 3;
size &= ~3;
@ -813,156 +862,136 @@ printf("at 4 argc %d argv %s\n", argc, p);
resdes[0] = 0x02000000; /* 2 byte swapped */
/* 48 char file/directory/volume name (122 wds) */
/* copy name from dirlist written earlier */
resdes[2] = dirlist[n+0]; /* file */
resdes[3] = dirlist[n+1];
resdes[4] = dirlist[n+2];
resdes[5] = dirlist[n+3];
resdes[6] = dirlist[n+4]; /* directory, system*/
resdes[7] = dirlist[n+5];
resdes[8] = dirlist[n+6];
resdes[9] = dirlist[n+7];
resdes[10] = dirlist[n+8]; /* volume, system */
resdes[11] = dirlist[n+9];
resdes[12]= dirlist[n+10];
resdes[13]= dirlist[n+11];
resdes[0+2] = dirlist[n+0]; /* file */
resdes[1+2] = dirlist[n+1];
resdes[2+2] = dirlist[n+2];
resdes[3+2] = dirlist[n+3];
resdes[4+2] = dirlist[n+4]; /* directory, system*/
resdes[5+2] = dirlist[n+5];
resdes[6+2] = dirlist[n+6];
resdes[7+2] = dirlist[n+7];
resdes[8+2] = dirlist[n+8]; /* volume, system */
resdes[9+2] = dirlist[n+9];
resdes[10+2]= dirlist[n+10];
resdes[11+2]= dirlist[n+11];
/* 16 word resource create block */
resdes[14] = dirlist[n+8]; /* owner, system */
resdes[15] = dirlist[n+9]; /* only 8 bytes */
// resdes[16]= dirlist[n+10];
// resdes[17]= dirlist[n+11];
/// resdes[18] = dirlist[n+8]; /* group, system */
/// resdes[19] = dirlist[n+9]; /* only 8 bytes */
resdes[16] = dirlist[n+8]; /* group, system */
resdes[17] = dirlist[n+9]; /* only 8 bytes */
// resdes[20]= dirlist[n+10];
// resdes[21]= dirlist[n+11];
n += 12;
#ifdef OLDOLD
resdes[22]=flip(0x80f00000); /* owner rights */
resdes[23]=flip(0x80b00000); /* group rights */
resdes[24]=flip(0x80800000); /* other rights */
resdes[0+12+2] = dirlist[n+8]; /* RCB.OWNR owner, system */
resdes[1+12+2] = dirlist[n+9]; /* only 8 bytes */
resdes[2+12+2] = dirlist[n+8]; /* RCB.USER group, system */
resdes[3+12+2] = dirlist[n+9]; /* only 8 bytes */
//SS n += 12;
resdes[4+12+2]=flip(0x80f00000); /* RCB.OWRI owner rights */
resdes[5+12+2]=flip(0x80b00000); /* RCB.UGRI group rights */
resdes[6+12+2]=flip(0x80800000); /* RCB.OTRI other rights */
if (typ == 0xca)
resdes[25]=flip(0x00040110); /* res mgmt flags */
resdes[7+12+2]=flip(0x00040110); /* res mgmt flags */
else
resdes[25]=flip(0x00040110); /* res mgmt flags */
// resdes[25]=flip(0x0004011c); /* res mgmt flags */
resdes[29]=flip(size); /* org file size */
resdes[31]=flip(1000); /* file starting address n/u */
resdes[33]=flip(0x00fbfeef); /* option flags */
#else
resdes[18]=flip(0x80f00000); /* owner rights */
resdes[19]=flip(0x80b00000); /* group rights */
resdes[20]=flip(0x80800000); /* other rights */
if (typ == 0xca)
resdes[21]=flip(0x00040110); /* res mgmt flags */
else
resdes[21]=flip(0x00040110); /* res mgmt flags */
resdes[7+12+2]=flip(0x00040110); /* res mgmt flags */
// resdes[21]=flip(0x0004011c); /* res mgmt flags */
resdes[25]=flip(size); /* org file size */
resdes[27]=flip(1000); /* file starting address n/u */
resdes[29]=flip(0x00fbfeef); /* option flags */
#endif
/* reset of block is zero */
resdes[11+12+2]=flip(285); /* RCB.OSIZ org dir (0x120) size */
// resdes[11+12+2]=flip(size); /* org file size */
resdes[13+12+2]=flip(0x53480); /* RCB.FAST Res ID buffer address n/u */
// resdes[27]=flip(1000); /* file starting address n/u */
resdes[15+12+2]=flip(0x00fbfeef); /* RCB.OPTS option flags */
// resdes[29]=flip(0x00fbfeef); /* RCB.OPTS option flags */
/* rest of block is zero */
/* second block is resosurce descriptor from disk */
resdes[192] = dirlist[n+8]; /* volume, system */
resdes[193] = dirlist[n+9];
resdes[194]= dirlist[n+10];
resdes[195]= dirlist[n+11];
/* second block is resosurce descriptor from disk M.RDCOM */
resdes[0+192] = dirlist[n+8]; /* RD.IDNAM volume, system */
resdes[1+192] = dirlist[n+9];
resdes[2+192]= dirlist[n+10];
resdes[3+192]= dirlist[n+11];
resdes[196]=flip(0x00003190); /* creation date */
resdes[197]=flip(0x0e8c8000); /* creation time */
resdes[198]=flip(0x000003c0); /* abs blk if res des */
resdes[199]=flip(0x0000000a); /* resource type, perm file */
resdes[4+192]=flip(0x00003190); /* RD.DATE creation date */
resdes[5+192]=flip(0x0e8c8000); /* RD.TIME creation time */
resdes[6+192]=flip(0x000003c0); /* RD.DOFF abs blk of res des */
resdes[7+192]=flip(0x0000000a); /* RD.RDFLG / RD.RTYPE resource type, perm file */
resdes[200]=flip(0x000029cf); /* creation date */
resdes[201]=flip(0x1dd8e074); /* creation time */
//202
//203
resdes[8+192]=flip(0x000029cf); /* RD.CRDAT creation date */
resdes[9+192]=flip(0x1dd8e074); /* RD.CRTIM creation time */
//202 10+192 RD.XPDAT
//203 11+192 RD.XPTIM
//204
//205
resdes[206]=flip(0x000029cf); /* last chge date */
resdes[207]=flip(0x1dd8e074); /* last chge time */
//204 12+192 RD.RDDAT
//205 13+192 RD.RDTIM
resdes[14+192]=flip(0x000029cf); /* RD.CHDAT last chge date */
resdes[15+192]=flip(0x1dd8e074); /* RD.CHTIM last chge time */
resdes[208]=flip(0x00003190); /* creation date */
resdes[209]=flip(0x0e8c8000); /* creation time */
//210
//211
resdes[16+192]=flip(0x00003190); /* RD.SVDAT last save date */
resdes[17+192]=flip(0x0e8c8000); /* RD.SVTIM last save time */
//210 18+192 RD.RSDAT
//211 19+192 RD.RSTIM
/// resdes[212] = dirlist[n+8]; /* ownername last changer, system */
/// resdes[213] = dirlist[n+9];
resdes[214] = dirlist[n+8]; /* ownername creator, system */
resdes[215] = dirlist[n+9];
resdes[20+192] = dirlist[n+8]; /* RD.CHOWN ownername last changer, system */
resdes[21+192] = dirlist[n+9];
resdes[22+192] = dirlist[n+8]; /* RD.CROWN ownername creator, system */
resdes[23+192] = dirlist[n+9];
//216
//217
resdes[218] = dirlist[n+8]; /* ownername of resource, system */
resdes[219] = dirlist[n+9];
//216 24+192 RD.RDCNT
//217 25+192 RD.AFLGS
resdes[26+192] = dirlist[n+8]; /* RD.OWNR ownername of resource, system */
resdes[27+192] = dirlist[n+9];
resdes[220] = dirlist[n+8]; /* group of resource, system */
resdes[221] = dirlist[n+9];
resdes[222]=flip(0xf8400000); /* owner access */
// resdes[223]=flip(0xf8e00000); /* group access */
resdes[223]=flip(0xf8400000); /* group access */
resdes[28+192] = dirlist[n+8]; /* RD.UGRP group of resource, system */
resdes[29+192] = dirlist[n+9];
resdes[30+192]=flip(0xf8400000); /* RD.AOWNR owner access */
resdes[31+192]=flip(0xf8400000); /* RD.AUGRP group access */
// resdes[223]=flip(0xf8e00000); /* RD.AUGRP group access */
resdes[32+192]=flip(0x80000000); /* RD.AOTHR other access */
//225 33+192 reserved
resdes[34+192]=flip(0x00000001); /* RD.LNKCT resource link count */
//227 35+192 Port numbers
resdes[224]=flip(0x80000000); /* other access */
//225
resdes[226]=flip(0x00000001); /* resource link count */
//227
//228-244
resdes[52+192] = dirlist[n+8]; /* RD.RDOWN ownername at last access, system */
resdes[53+192] = dirlist[n+9];
//247-255
//228-255
resdes[256]=flip(0xca100010); /* space definition flags */
resdes[64+192]=flip(0xca1000f0); /* RD.SFLGS space definition flags */
if (typ == 0xca)
resdes[256]=flip(0xca100010); /* space definition flags */
resdes[64+192]=flip(0xca1000f0); /* RD.SFLGS space definition flags */
else
if (typ == 0xee)
resdes[256]=flip(0xee1000f1); /* space definition flags */
resdes[64+192]=flip(0xee1000f1); /* RD.SFLGS space definition flags */
else
if (typ == 0x00)
resdes[256]=flip(0x001000f1); /* space definition flags */
// resdes[257]=flip(0x00000018); /* max extends */
// resdes[258]=flip(0x00000008); /* min incr */
resdes[257]=flip(0x00000040); /* max extends */
resdes[258]=flip(0x00000010); /* min incr */
//259
resdes[64+192]=flip(0x001000f1); /* RD.SFLGS space definition flags */
resdes[65+192]=flip(0x00000040); /* RD.MXEXT max extends */
resdes[66+192]=flip(0x00000010); /* RD.MNEXT min incr */
//259 67+192 RD.MXSIZ
// resdes[260]=flip(size-1); /* eof */
// resdes[261]=flip(size); /* eom */
/// resdes[260]=flip(size); /* eof */
/// resdes[261]=flip(size+1); /* eom */
resdes[260]=0; /* eof */
resdes[261]=flip(size); /* eom */
resdes[262]=flip(0x00000001); /* segment */
//263
resdes[68+192]=flip(size-1); /* RD.EOFBL eof block */
resdes[69+192]=flip(size); /* RD.EOMBL eom block */
resdes[70+192]=flip(0x00000001); /* RD.NUMSG # of segment */
//263 71+192 RD.XSABA
resdes[264]=resdes[6]; /* directory, system*/
resdes[265]=resdes[7];
resdes[266]=resdes[8];
resdes[267]=resdes[9];
resdes[72+192]=resdes[6]; /* RD.DNAME directory, system*/
resdes[73+192]=resdes[7];
resdes[74+192]=resdes[8];
resdes[75+192]=resdes[9];
resdes[268]=flip(0x00000100); /* parent blk number */
resdes[269]=flip(0x00000001); /* segments at creation */
//270
//271
resdes[76+192]=flip(0x00000cd6); /* RD.PAREN parent blk number */
resdes[77+192]=flip(0x00000001); /* RD.NUMCR segments at creation */
//270 78+192 reserved
//271 79+192 reserved
resdes[272]=resdes[2]; /* filename*/
resdes[273]=resdes[3];
resdes[274]=resdes[4];
resdes[275]=resdes[5];
resdes[80+192]=resdes[2]; /* RD.DIRP filename*/
resdes[81+192]=resdes[3];
resdes[82+192]=resdes[4];
resdes[83+192]=resdes[5];
resdes[276]=flip(0x00000100); /* parent blk number */
resdes[277]=flip(0x000005c0); /* parent didr index number */
//277
//278
resdes[84+192]=flip(0x00000100); /* RD.DADD parent blk number */
resdes[85+192]=flip(0x000005c0); /* RD.DIDX parent dir index number */
//278 86+192 res
// to
//287 95+192 res
//279-286
resdes[288]=flip(0x0000fda8); /* file blk number */
resdes[289]=flip(size); /* eom */
/* Segment definitions (RD.SEGDF) Wds 96/97 */
resdes[96+192]=flip(0x0000fda8); /* file abs blk addr */
resdes[97+192]=flip(size); /* eom block */
/* all others are zero */
n += 12; /* next directory entry */
/* we have data to write */
/* write actual byte count to 32 bit word as header */
@ -979,7 +1008,11 @@ printf("at 4 argc %d argv %s\n", argc, p);
}
/*******************************/
/* write file up to 8 blks at a time */
writefile(dp, fnp, 0, 8); /* all of file 1 blk at a time */
if (typ != 0xca) {
writefile(dp, fnp, 0, 8, 0); /* all of file 8 blk at a time */
} else {
writefile(dp, fnp, size, 8, 0); /* all of file 8 blk at a time */
}
printf("File written at 4 argc %d argv %s\n", argc, fnp);

View File

@ -13,6 +13,7 @@
//#include <unistd.h>
//#include <string.h>
//#include <errno.h>
#define NOTDUMP
int filen = 1;
int EOFcnt = 0;
@ -123,7 +124,7 @@ int main (int argc, char *argv[])
int ll, gotboth = 0;
int lfilen = filen;
unsigned int fileaddr, file_byte_count=0, curchar, buffptr, bufflen;
int skipfile = 0;
int skipfile = 0, skip, cc;
if (argc != 2) {
fprintf(stderr, "usage: %s infile\n", argv[0]);
@ -152,6 +153,8 @@ int main (int argc, char *argv[])
buffptr = 0;
bufflen = 16;
fileaddr = 0;
skip = 0;
cc = 0;
file_byte_count = 0;
printf("\nfile %d:\n", filen);
@ -163,23 +166,37 @@ int main (int argc, char *argv[])
file_byte_count = 0;
fileaddr = 0;
printf("\nfile %d:\n", filen);
buffptr = 0;
} else {
int cc = 0;
// int cc = 0;
char buff[257];
int ans;
buffptr = 0;
// buffptr = 0;
/* see if skipping to next file */
if (skipfile == 1) {
buffptr = 0;
cc = 0;
skip = 0;
continue;
}
/* process the returned buffer */
while (cc < ll) {
curchar = (unsigned int)buf[cc++] & 0xff;
file_byte_count++;
if (skip != 0) {
printf(" %06x : ",fileaddr);
while (buffptr < skip) {
buff[buffptr++] = 0x20;
printf(" ");
if (!(buffptr % 4))
printf(" ");
} /* end of while */
skip = 0;
}
if (!buffptr)
printf(" %06x : ",fileaddr);
curchar = (unsigned int)buf[cc++] & 0xff;
file_byte_count++;
printf("%02x", curchar & 0xff);
buff[buffptr++] = PRINTABLE(curchar);
if (!(buffptr % 4))
@ -189,7 +206,8 @@ int main (int argc, char *argv[])
printf(" |%s|\n",buff);
buffptr = 0;
fileaddr += bufflen;
if (!(file_byte_count % 256)) {
if (!(fileaddr % 256)) {
// if (!(file_byte_count % 256)) {
// if (!(file_byte_count % 768)) {
printf("\n<cr> - continue, q = quit, s = skip > ");
ans = getchar();
@ -199,8 +217,11 @@ int main (int argc, char *argv[])
free(buf);
exit(1);
}
if (ans == 's')
if (ans == 's') {
skipfile = 1;
cc = 0;
skip = 0;
}
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
@ -210,8 +231,14 @@ int main (int argc, char *argv[])
} /* end of if */
} /* end of while */
if ((ll % 256) == 0) {
cc = 0;
continue;
}
if (buffptr && !skipfile) {
buff[buffptr] = 0;
// fileaddr += buffptr;
skip = buffptr;
while (buffptr++ < bufflen) {
printf(" ");
if (!(buffptr % 4))
@ -231,7 +258,13 @@ int main (int argc, char *argv[])
if (ans != '\n')
while ((ans=getchar()) != '\n' )
;
buffptr = 0;
file_byte_count = 0;
// else
// skipfile = 0;
} /* end of if */
printf("ll %x buf_size %x skip %x skipfile %x fileaddr %x\n",
ll, buf_size, skip, skipfile, fileaddr);
}
}
// close(inp);

View File

@ -13,7 +13,6 @@
#include <stdio.h>
#include <sys/types.h>
#include <sys/signal.h>
//#include <sys/mtio.h>
#include <stdlib.h> /* for exit() */
#ifdef _WIN32
@ -26,6 +25,7 @@
#else
#include <sys/fcntl.h> /* for O_RDONLY, O_WRONLY, O_CREAT */
#include <unistd.h> /* for open, read, write */
#include <sys/signal.h>
#endif
#if defined(_MSC_VER) && (_MSC_VER < 1600)
@ -55,7 +55,9 @@ int usefmgr = 1; /* use fmgr format with 2 EOF's, else 3 EOF'
char *buff; /* buffer for read/write */
int filen = 1; /* file number being processed */
long count=0, lcount=0; /* number of blocks for file */
#ifndef _WIN32
extern void RUBOUT(); /* handle user DELETE key signal */
#endif
off_t size=0, tsize=0; /* number of bytes in file, total */
int ln;
char *inf, *outf;
@ -112,8 +114,10 @@ char **argv;
fprintf(stderr, "Can't allocate memory for tapecopy\n");
exit(4);
}
#ifndef _WIN32
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
(void)signal(SIGINT, RUBOUT);
#endif
ln = -2;
for (;;) {
@ -231,6 +235,7 @@ char **argv;
exit(0);
}
#ifndef _WIN32
/* entered when user hit the DELETE key */
void RUBOUT()
{
@ -245,3 +250,4 @@ void RUBOUT()
(void)printf("total length: %ld bytes\n", tsize + size);
exit(1);
}
#endif