RESTRICTION: The PDP-15 FPP is only partially debugged. Do NOT enable this feature for normal operations. 1. New Features in 3.2-1 1.1 SCP and libraries - Added SET CONSOLE subhierarchy. - Added SHOW CONSOLE subhierarchy. - Added limited keyboard mapping capability. 1.2 HP2100 (new features from Dave Bryan) - Added instruction printout to HALT message. - Added M and T internal registers. - Added N, S, and U breakpoints. 1.3 PDP-11 and VAX - Added DHQ11 support (from John Dundas) 2. Bugs Fixed in 3.2-1 2.1 HP2100 (most fixes from Dave Bryan) - SBT increments B after store. - DMS console map must check dms_enb. - SFS x,C and SFC x,C work. - MP violation clears automatically on interrupt. - SFS/SFC 5 is not gated by protection enabled. - DMS enable does not disable mem prot checks. - DMS status inconsistent at simulator halt. - Examine/deposit are checking wrong addresses. - Physical addresses are 20b not 15b. - Revised DMS to use memory rather than internal format. - Revised IBL facility to conform to microcode. - Added DMA EDT I/O pseudo-opcode. - Separated DMA SRQ (service request) from FLG. - Revised peripherals to make SFS x,C and SFC x,C work. - Revised boot ROMs to use IBL facility. - Revised IBL treatment of SR to preserve SR<5:3>. - Fixed LPS, LPT timing. - Fixed DP boot interpretation of SR<0>. - Revised DR boot code to use IBL algorithm. - Fixed TTY input behavior during typeout for RTE-IV. - Suppressed nulls on TTY output for RTE-IV. - Added SFS x,C and SFC x,C to print/parse routines. - Fixed spurious timing error in magtape reads. 2.2 All DEC console devices - Removed SET TTI CTRL-C option. 2.3 PDP-11/VAX peripherals - Fixed bug in TQ reporting write protect status (reported by Lyle Bickley). - Fixed TK70 model number and media ID (found by Robert Schaffrath). - Fixed bug in autoconfigure (found by John Dundas). 2.4 VAX - Fixed bug in DIVBx and DIVWx (reported by Peter Trimmel).
612 lines
15 KiB
C
612 lines
15 KiB
C
/*
|
|
* (C) Copyright 2002, Brian Knittel.
|
|
* You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN
|
|
* RISK basis, there is no warranty of fitness for any purpose, and the rest of the
|
|
* usual yada-yada. Please keep this notice and the copyright in any distributions
|
|
* or modifications.
|
|
*
|
|
* This is not a supported product, but I welcome bug reports and fixes.
|
|
* Mail to sim@ibm1130.org
|
|
*/
|
|
|
|
// DISKVIEW - lists contents of an 1130 system disk image file. Not finished yet.
|
|
// needs LET/SLET listing routine.
|
|
//
|
|
// usage:
|
|
// diskview -v diskfile
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <stdarg.h>
|
|
#include "util_io.h"
|
|
|
|
#define BETWEEN(v,a,b) (((v) >= (a)) && ((v) <= (b)))
|
|
#define MIN(a,b) (((a) <= (b)) ? (a) : (b))
|
|
#define MAX(a,b) (((a) >= (b)) ? (a) : (b))
|
|
|
|
#ifndef TRUE
|
|
# define TRUE 1
|
|
# define FALSE 0
|
|
# define BOOL int
|
|
#endif
|
|
|
|
#define NOT_DEF 0x0658 // defective cylinder table entry means no defect
|
|
|
|
#define DSK_NUMWD 321 /* words/sector */
|
|
#define DSK_NUMCY 203 /* cylinders/drive */
|
|
#define DSK_SECCYL 8 /* sectors per cylinder */
|
|
#define SECLEN 320 /* data words per sector */
|
|
#define SLETLEN ((3*SECLEN)/4) /* length of slet in records */
|
|
|
|
typedef unsigned short WORD;
|
|
|
|
FILE *fp;
|
|
WORD buf[DSK_NUMWD];
|
|
WORD dcom[DSK_NUMWD];
|
|
|
|
#pragma pack(2)
|
|
struct tag_slet {
|
|
WORD phid;
|
|
WORD addr;
|
|
WORD nwords;
|
|
WORD sector;
|
|
} slet[SLETLEN];
|
|
|
|
#pragma pack()
|
|
|
|
WORD dcyl[3];
|
|
BOOL verbose = FALSE;
|
|
|
|
void checksectors (void);
|
|
void dump_id (void);
|
|
void dump_dcom (void);
|
|
void dump_resmon (void);
|
|
void dump_slet (void);
|
|
void dump_hdng (void);
|
|
void dump_scra (void);
|
|
void dump_let (void);
|
|
void dump_flet (void);
|
|
void dump_cib (void);
|
|
void getsector (int sec, WORD *sbuf);
|
|
void getdcyl (void);
|
|
char *lowcase (char *str);
|
|
|
|
void bail(char *fmt, ...);
|
|
char *trim (char *s);
|
|
|
|
int main (int argc, char **argv)
|
|
{
|
|
char *fname = NULL, *arg;
|
|
static char usestr[] = "Usage: diskview [-v] filename";
|
|
int i;
|
|
|
|
for (i = 1; i < argc;) {
|
|
arg = argv[i++];
|
|
if (*arg == '-') {
|
|
arg++;
|
|
lowcase(arg);
|
|
while (*arg) {
|
|
switch (*arg++) {
|
|
case 'v':
|
|
verbose = TRUE;
|
|
break;
|
|
|
|
default:
|
|
bail(usestr);
|
|
}
|
|
}
|
|
}
|
|
else if (fname == NULL)
|
|
fname = arg;
|
|
else
|
|
bail(usestr);
|
|
}
|
|
|
|
if (fname == NULL)
|
|
bail(usestr);
|
|
|
|
if ((fp = fopen(fname, "rb")) == NULL) {
|
|
perror(fname);
|
|
return 2;
|
|
}
|
|
|
|
printf("%s:\n", fname);
|
|
|
|
checksectors();
|
|
getdcyl();
|
|
|
|
dump_id(); // ID & coldstart
|
|
dump_dcom(); // DCOM
|
|
dump_resmon(); // resident image
|
|
dump_slet(); // SLET
|
|
dump_hdng(); // heading sector
|
|
dump_scra();
|
|
dump_flet();
|
|
dump_cib();
|
|
dump_let();
|
|
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
// checksectors - verify that all sectors are properly numbered
|
|
|
|
void checksectors ()
|
|
{
|
|
WORD sec = 0;
|
|
|
|
fseek(fp, 0, SEEK_SET);
|
|
|
|
for (sec = 0; sec < DSK_NUMCY*DSK_SECCYL; sec++) {
|
|
if (fxread(buf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)
|
|
bail("File read error or not a disk image file");
|
|
|
|
if (buf[0] != sec)
|
|
bail("Sector /%x is misnumbered, run checkdisk [-f]", sec);
|
|
}
|
|
}
|
|
|
|
// get defective cylinder list
|
|
|
|
void getdcyl (void)
|
|
{
|
|
fseek(fp, sizeof(WORD), SEEK_SET); // skip sector count
|
|
if (fxread(dcyl, sizeof(WORD), 3, fp) != 3)
|
|
bail("Unable to read defective cylinder table");
|
|
}
|
|
|
|
// getsector - read specified absolute sector
|
|
|
|
void getsector (int sec, WORD *sbuf)
|
|
{
|
|
int i, cyl, ssec;
|
|
|
|
sec &= 0x7FF; // mask of drive bits, if any
|
|
|
|
cyl = sec / DSK_SECCYL; // get cylinder
|
|
ssec = sec & ~(DSK_SECCYL-1); // mask to get starting sector of cylinder
|
|
for (i = 0; i < 3; i++) { // map through defective cylinder table
|
|
if (dcyl[i] == ssec) {
|
|
sec &= (DSK_SECCYL-1); // mask to get base sector
|
|
cyl = DSK_NUMCY-3+i; // replacements are last three on disk
|
|
sec += cyl*DSK_SECCYL; // add new cylinder offset
|
|
break;
|
|
}
|
|
}
|
|
// read the sector
|
|
if (fseek(fp, (sec*DSK_NUMWD+1)*sizeof(WORD), SEEK_SET) != 0)
|
|
bail("File seek failed");
|
|
|
|
if (fxread(sbuf, sizeof(WORD), DSK_NUMWD, fp) != DSK_NUMWD)
|
|
bail("File read error or not a disk image file");
|
|
}
|
|
|
|
void dump (int nwords)
|
|
{
|
|
int i, nline = 0;
|
|
|
|
for (i = 0; i < nwords; i++) {
|
|
if (nline == 16) {
|
|
putchar('\n');
|
|
nline = 0;
|
|
}
|
|
|
|
printf("%04x", buf[i]);
|
|
nline++;
|
|
}
|
|
putchar('\n');
|
|
}
|
|
|
|
void showmajor (char *label)
|
|
{
|
|
int i;
|
|
|
|
printf("\n--- %s ", label);
|
|
|
|
for (i = strlen(label); i < 40; i++)
|
|
putchar('-');
|
|
|
|
putchar('\n');
|
|
putchar('\n');
|
|
}
|
|
|
|
void name (char *label)
|
|
{
|
|
printf("%-32.32s ", label);
|
|
}
|
|
|
|
void pbf (char *label, WORD *buf, int nwords)
|
|
{
|
|
int i, nout;
|
|
|
|
name(label);
|
|
|
|
for (i = nout = 0; i < nwords; i++, nout++) {
|
|
if (nout == 8) {
|
|
putchar('\n');
|
|
name("");
|
|
nout = 0;
|
|
}
|
|
printf(" %04x", buf[i]);
|
|
}
|
|
|
|
putchar('\n');
|
|
}
|
|
|
|
void prt (char *label, char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
|
|
name(label);
|
|
|
|
putchar(' ');
|
|
va_start(args, fmt);
|
|
vprintf(fmt, args);
|
|
va_end(args);
|
|
|
|
putchar('\n');
|
|
}
|
|
|
|
void dump_id (void)
|
|
{
|
|
showmajor("Sector 0 - ID & coldstart");
|
|
getsector(0, buf);
|
|
|
|
pbf("DCYL def cyl table", buf+ 0, 3);
|
|
pbf("CIDN cart id", buf+ 3, 1);
|
|
pbf(" copy code", buf+ 4, 1);
|
|
pbf("DTYP disk type", buf+ 7, 1);
|
|
pbf(" diskz copy", buf+ 30, 8);
|
|
pbf(" cold start pgm",buf+270, 8);
|
|
}
|
|
|
|
// EQUIVALENCES FOR DCOM PARAMETERS
|
|
#define NAME 4 // NAME OF PROGRAM/CORE LOAD
|
|
#define DBCT 6 // BLOCK CT OF PROGRAM/CORE LOAD
|
|
#define FCNT 7 // FILES SWITCH
|
|
#define SYSC 8 // SYSTEM/NON-SYSTEM CARTRIDGE INDR
|
|
#define JBSW 9 // JOBT SWITCH
|
|
#define CBSW 10 // CLB-RETURN SWITCH
|
|
#define LCNT 11 // NO. OF LOCALS
|
|
#define MPSW 12 // CORE MAP SWITCH
|
|
#define MDF1 13 // NO. DUP CTRL RECORDS (MODIF)
|
|
#define MDF2 14 // ADDR OF MODIF BUFFER
|
|
#define NCNT 15 // NO. OF NOCALS
|
|
#define ENTY 16 // RLTV ENTRY ADDR OF PROGRAM
|
|
#define RP67 17 // 1442-5 SWITCH
|
|
#define TODR 18 // OBJECT WORK STORAGE DRIVE CODE
|
|
#define FHOL 20 // ADDR LARGEST HOLE IN FIXED AREA
|
|
#define FSZE 21 // BLK CNT LARGEST HOLE IN FXA
|
|
#define UHOL 22 // ADDR LAST HOLE IN USER AREA 2-10
|
|
#define USZE 23 // BLK CNT LAST HOLE IN UA 2-10
|
|
#define DCSW 24 // DUP CALL SWITCH
|
|
#define PIOD 25 // PRINCIPAL I/O DEVICE INDICATOR
|
|
#define PPTR 26 // PRINCIPAL PRINT DEVICE INDICATOR
|
|
#define CIAD 27 // RLTV ADDR IN @STRT OF CIL ADDR
|
|
#define ACIN 28 // AVAILABLE CARTRIDGE INDICATOR
|
|
#define GRPH 29 // 2250 INDICATOR 2G2
|
|
#define GCNT 30 // NO. G2250 RECORDS 2G2
|
|
#define LOSW 31 // LOCAL-CALLS-LOCAL SWITCH 2-2
|
|
#define X3SW 32 // SPECIAL ILS SWITCH 2-2
|
|
#define ECNT 33 // NO. OF *EQUAT RCDS 2-4
|
|
#define ANDU 35 // 1+BLK ADDR END OF UA (ADJUSTED)
|
|
#define BNDU 40 // 1+BLK ADDR END OF UA (BASE)
|
|
#define FPAD 45 // FILE PROTECT ADDR
|
|
#define PCID 50 // CARTRIDGE ID, PHYSICAL DRIVE
|
|
#define CIDN 55 // CARTRIDGE ID, LOGICAL DRIVE
|
|
#define CIBA 60 // SCTR ADDR OF CIB
|
|
#define SCRA 65 // SCTR ADDR OF SCRA
|
|
#define FMAT 70 // FORMAT OF PROG IN WORKING STG
|
|
#define FLET 75 // SCTR ADDR 1ST SCTR OF FLET
|
|
#define ULET 80 // SCTR ADDR 1ST SCTR OF LET
|
|
#define WSCT 85 // BLK CNT OF PROG IN WORKING STG
|
|
#define CSHN 90 // NO. SCTRS IN CUSHION AREA
|
|
|
|
struct tag_dcominfo {
|
|
char *nm;
|
|
int offset;
|
|
char *descr;
|
|
} dcominfo[] = {
|
|
"NAME", 4, "NAME OF PROGRAM/CORE LOAD",
|
|
"DBCT", 6, "BLOCK CT OF PROGRAM/CORE LOAD",
|
|
"FCNT", 7, "FILES SWITCH",
|
|
"SYSC", 8, "SYSTEM/NON-SYSTEM CARTRIDGE INDR",
|
|
"JBSW", 9, "JOBT SWITCH",
|
|
"CBSW", 10, "CLB-RETURN SWITCH",
|
|
"LCNT", 11, "NO. OF LOCALS",
|
|
"MPSW", 12, "CORE MAP SWITCH",
|
|
"MDF1", 13, "NO. DUP CTRL RECORDS (MODIF)",
|
|
"MDF2", 14, "ADDR OF MODIF BUFFER",
|
|
"NCNT", 15, "NO. OF NOCALS",
|
|
"ENTY", 16, "RLTV ENTRY ADDR OF PROGRAM",
|
|
"RP67", 17, "1442-5 SWITCH",
|
|
"TODR", 18, "OBJECT WORK STORAGE DRIVE CODE",
|
|
"FHOL", 20, "ADDR LARGEST HOLE IN FIXED AREA",
|
|
"FSZE", 21, "BLK CNT LARGEST HOLE IN FXA",
|
|
"UHOL", 22, "ADDR LAST HOLE IN USER AREA",
|
|
"USZE", 23, "BLK CNT LAST HOLE IN UA",
|
|
"DCSW", 24, "DUP CALL SWITCH",
|
|
"PIOD", 25, "PRINCIPAL I/O DEVICE INDICATOR",
|
|
"PPTR", 26, "PRINCIPAL PRINT DEVICE INDICATOR",
|
|
"CIAD", 27, "RLTV ADDR IN @STRT OF CIL ADDR",
|
|
"ACIN", 28, "AVAILABLE CARTRIDGE INDICATOR",
|
|
"GRPH", 29, "2250 INDICATOR",
|
|
"GCNT", 30, "NO. G2250 RECORDS",
|
|
"LOSW", 31, "LOCAL-CALLS-LOCAL SWITCH",
|
|
"X3SW", 32, "SPECIAL ILS SWITCH",
|
|
"ECNT", 33, "NO. OF *EQUAT RCDS",
|
|
"ANDU", 35, "1+BLK ADDR END OF UA (ADJUSTED)",
|
|
"BNDU", 40, "1+BLK ADDR END OF UA (BASE)",
|
|
"FPAD", 45, "FILE PROTECT ADDR",
|
|
"PCID", 50, "CARTRIDGE ID, PHYSICAL DRIVE",
|
|
"CIDN", 55, "CARTRIDGE ID, LOGICAL DRIVE",
|
|
"CIBA", 60, "SCTR ADDR OF CIB",
|
|
"SCRA", 65, "SCTR ADDR OF SCRA",
|
|
"FMAT", 70, "FORMAT OF PROG IN WORKING STG",
|
|
"FLET", 75, "SCTR ADDR 1ST SCTR OF FLET",
|
|
"ULET", 80, "SCTR ADDR 1ST SCTR OF LET",
|
|
"WSCT", 85, "BLK CNT OF PROG IN WORKING STG",
|
|
"CSHN", 90, "NO. SCTRS IN CUSHION AREA",
|
|
NULL
|
|
};
|
|
|
|
void dump_dcom (void)
|
|
{
|
|
struct tag_dcominfo *d;
|
|
char txt[50];
|
|
|
|
showmajor("Sector 1 - DCOM");
|
|
getsector(1, dcom);
|
|
|
|
for (d = dcominfo; d->nm != NULL; d++) {
|
|
sprintf(txt, "%-4.4s %s", d->nm, d->descr);
|
|
pbf(txt, dcom+d->offset, 1);
|
|
}
|
|
}
|
|
|
|
void dump_resmon (void)
|
|
{
|
|
showmajor("Sector 2 - Resident Image");
|
|
getsector(2, buf);
|
|
dump(verbose ? SECLEN : 32);
|
|
}
|
|
|
|
struct {
|
|
int pfrom, pto;
|
|
int printed;
|
|
char *name;
|
|
} sletinfo[] = {
|
|
0x01, 0x12, FALSE, "DUP",
|
|
0x1F, 0x39, FALSE, "Fortran",
|
|
0x51, 0x5C, FALSE, "Cobol",
|
|
0x6E, 0x74, FALSE, "Supervisor",
|
|
0x78, 0x84, FALSE, "Core Load Builder",
|
|
0x8C, 0x8C, FALSE, "Sys 1403 prt",
|
|
0x8D, 0x8D, FALSE, "Sys 1132 prt",
|
|
0x8E, 0x8E, FALSE, "Sys console prt",
|
|
0x8F, 0x8F, FALSE, "Sys 2501 rdr",
|
|
0x90, 0x90, FALSE, "Sys 1442 rdr/pun",
|
|
0x91, 0x91, FALSE, "Sys 1134 paper tape",
|
|
0x92, 0x92, FALSE, "Sys kbd",
|
|
0x93, 0x93, FALSE, "Sys 2501/1442 conv",
|
|
0x94, 0x94, FALSE, "Sys 1134 conv",
|
|
0x95, 0x95, FALSE, "Sys kbd conv",
|
|
0x96, 0x96, FALSE, "Sys diskz",
|
|
0x97, 0x97, FALSE, "Sys disk1",
|
|
0x98, 0x98, FALSE, "Sys diskn",
|
|
0x99, 0x99, FALSE, "(primary print)",
|
|
0x9A, 0x9A, FALSE, "(primary input)",
|
|
0x9B, 0x9B, FALSE, "(primary input excl kbd)",
|
|
0x9C, 0x9C, FALSE, "(primary sys conv)",
|
|
0x9D, 0x9D, FALSE, "(primary conv excl kbd)",
|
|
0xA0, 0xA1, FALSE, "Core Image Loader",
|
|
0xB0, 0xCC, FALSE, "RPG",
|
|
0xCD, 0xCE, FALSE, "Dup Part 2",
|
|
0xCF, 0xF6, FALSE, "Macro Assembler",
|
|
0
|
|
};
|
|
|
|
void dump_slet (void)
|
|
{
|
|
int i, j, iphase, nsecs, sec, max_sec = 0;
|
|
char sstr[16], *smark;
|
|
|
|
showmajor("Sectors 3-5 - SLET");
|
|
for (i = 0; i < 3; i++) {
|
|
getsector(3+i, buf);
|
|
memmove(((WORD *) slet)+SECLEN*i, buf, SECLEN*sizeof(WORD));
|
|
}
|
|
|
|
printf("# PHID Addr Len Sector Secs\n");
|
|
printf("------------------------------------------\n");
|
|
for (i = 0; i < SLETLEN; i++) {
|
|
if (slet[i].phid == 0)
|
|
break;
|
|
|
|
sec = slet[i].sector;
|
|
iphase = (int) (signed short) slet[i].phid;
|
|
nsecs = (slet[i].nwords + SECLEN-1)/SECLEN;
|
|
|
|
if (sec & 0xF800) {
|
|
smark = "*";
|
|
sec &= 0x7FF;
|
|
}
|
|
else
|
|
smark = " ";
|
|
|
|
for (j = 0; sletinfo[j].pfrom != 0; j++)
|
|
if (sletinfo[j].pfrom <= iphase && sletinfo[j].pto >= iphase)
|
|
break;
|
|
|
|
sprintf(sstr, "(%d.%d)", sec / DSK_SECCYL, slet[i].sector % DSK_SECCYL);
|
|
|
|
printf("%3d %04x %4d %04x %04x %04x %s %-7s %3x",
|
|
i, slet[i].phid, iphase, slet[i].addr, slet[i].nwords, slet[i].sector, smark, sstr, nsecs);
|
|
|
|
if (iphase < 0)
|
|
iphase = -iphase;
|
|
|
|
if (sletinfo[j].pfrom == 0)
|
|
printf(" ???");
|
|
else if (! sletinfo[j].printed) {
|
|
printf(" %s", sletinfo[j].name);
|
|
sletinfo[j].printed = TRUE;
|
|
}
|
|
|
|
for (j = 0; j < i; j++) {
|
|
if (sec == (slet[j].sector & 0x7FF)) {
|
|
printf(" (same as %04x)", slet[j].phid);
|
|
break;
|
|
}
|
|
}
|
|
|
|
max_sec = MAX(max_sec, sec+nsecs-1); // find last sector used
|
|
|
|
putchar('\n');
|
|
|
|
if (i >= 15 && ! verbose) {
|
|
printf("...\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int ascii_to_ebcdic_table[128] =
|
|
{
|
|
0x00,0x01,0x02,0x03,0x37,0x2d,0x2e,0x2f, 0x16,0x05,0x25,0x0b,0x0c,0x0d,0x0e,0x0f,
|
|
0x10,0x11,0x12,0x13,0x3c,0x3d,0x32,0x26, 0x18,0x19,0x3f,0x27,0x1c,0x1d,0x1e,0x1f,
|
|
0x40,0x5a,0x7f,0x7b,0x5b,0x6c,0x50,0x7d, 0x4d,0x5d,0x5c,0x4e,0x6b,0x60,0x4b,0x61,
|
|
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7, 0xf8,0xf9,0x7a,0x5e,0x4c,0x7e,0x6e,0x6f,
|
|
|
|
0x7c,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7, 0xc8,0xc9,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,
|
|
0xd7,0xd8,0xd9,0xe2,0xe3,0xe4,0xe5,0xe6, 0xe7,0xe8,0xe9,0xba,0xe0,0xbb,0xb0,0x6d,
|
|
0x79,0x81,0x82,0x83,0x84,0x85,0x86,0x87, 0x88,0x89,0x91,0x92,0x93,0x94,0x95,0x96,
|
|
0x97,0x98,0x99,0xa2,0xa3,0xa4,0xa5,0xa6, 0xa7,0xa8,0xa9,0xc0,0x4f,0xd0,0xa1,0x07,
|
|
};
|
|
|
|
int ebcdic_to_ascii (int ch)
|
|
{
|
|
int j;
|
|
|
|
for (j = 32; j < 128; j++)
|
|
if (ascii_to_ebcdic_table[j] == ch)
|
|
return j;
|
|
|
|
return '?';
|
|
}
|
|
|
|
#define HDR_LEN 120
|
|
|
|
void dump_hdng(void)
|
|
{
|
|
int i;
|
|
char str[HDR_LEN+1], *p = str;
|
|
|
|
showmajor("Sector 7 - Heading");
|
|
getsector(7, buf);
|
|
|
|
for (i = 0; i < (HDR_LEN/2); i++) {
|
|
*p++ = ebcdic_to_ascii((buf[i] >> 8) & 0xFF);
|
|
*p++ = ebcdic_to_ascii( buf[i] & 0xFF);
|
|
}
|
|
|
|
*p = '\0';
|
|
trim(str);
|
|
printf("%s\n", str);
|
|
}
|
|
|
|
BOOL mget (int offset, char *name)
|
|
{
|
|
char title[80];
|
|
|
|
if (dcom[offset] == 0)
|
|
return FALSE;
|
|
|
|
getsector(dcom[offset], buf);
|
|
sprintf(title, "Sector %x - %s", dcom[offset], name);
|
|
showmajor(title);
|
|
return TRUE;
|
|
}
|
|
|
|
void dump_scra (void)
|
|
{
|
|
if (! mget(SCRA, "SCRA"))
|
|
return;
|
|
|
|
dump(verbose ? SECLEN : 32);
|
|
}
|
|
|
|
void dump_let (void)
|
|
{
|
|
if (! mget(ULET, "LET"))
|
|
return;
|
|
}
|
|
|
|
void dump_flet (void)
|
|
{
|
|
if (! mget(FLET, "FLET"))
|
|
return;
|
|
}
|
|
|
|
void dump_cib (void)
|
|
{
|
|
if (! mget(CIBA, "CIB"))
|
|
return;
|
|
|
|
dump(verbose ? SECLEN : 32);
|
|
}
|
|
|
|
#define LFHD 5 // WORD COUNT OF LET/FLET HEADER PMN09970
|
|
#define LFEN 3 // NO OF WDS PER LET/FLET ENTRY PMN09980
|
|
#define SCTN 0 // RLTY ADDR OF LET/FLET SCTR NO. PMN09990
|
|
#define UAFX 1 // RLTV ADDR OF SCTR ADDR OF UA/FXA PMN10000
|
|
#define WDSA 3 // RLTV ADDR OF WDS AVAIL IN SCTR PMN10010
|
|
#define NEXT 4 // RLTV ADDR OF ADDR NEXT SCTR PMN10020
|
|
#define LFNM 0 // RLTV ADDR OF LET/FLET ENTRY NAME PMN10030
|
|
#define BLCT 2 // RLTV ADDR OF LET/FLET ENTRY DBCT PMN10040
|
|
|
|
void bail (char *fmt, ...)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, fmt);
|
|
fprintf(stderr, fmt, args);
|
|
va_end(args);
|
|
putchar('\n');
|
|
|
|
exit(1);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------
|
|
// trim - remove trailing whitespace from string s
|
|
// ---------------------------------------------------------------------------------
|
|
|
|
char *trim (char *s)
|
|
{
|
|
char *os = s, *nb;
|
|
|
|
for (nb = s-1; *s; s++)
|
|
if (*s > ' ')
|
|
nb = s;
|
|
|
|
nb[1] = '\0';
|
|
return os;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------------
|
|
* lowcase - force a string to lowercase (ASCII)
|
|
* ------------------------------------------------------------------------ */
|
|
|
|
char *lowcase (char *str)
|
|
{
|
|
char *s;
|
|
|
|
for (s = str; *s; s++) {
|
|
if (*s >= 'A' && *s <= 'Z')
|
|
*s += 32;
|
|
}
|
|
|
|
return str;
|
|
}
|
|
|