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:
parent
8efbc79059
commit
0ed44354b5
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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");
|
||||
|
||||
204
SEL32/sel32_mt.c
204
SEL32/sel32_mt.c
@ -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;
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user