1
0
mirror of https://github.com/simh/simh.git synced 2026-04-13 15:34:35 +00:00

Notes For V3.0-1

RESTRICTION: The FP15 and XVM features of the PDP-15 are only partially
debugged.  Do NOT enable these features for normal operations.

1. New Features in 3.0-1

1.1 PDP-1

- Added block loader format support to LOAD.
- Changed BOOT PTR to allow loading of all of the first bank of memory.

1.2 PDP-18b Family

- Added PDP-4 EAE support.
- Added PDP-15 FP15 support.
- Added PDP-15 XVM support.
- Added PDP-15 "re-entrancy ECO".
- Added PDP-7, PDP-9, PDP-15 hardware RIM loader support in BOOT PTR.

2. Bugs Fixed in 3.0-1

2.1 PDP-11/VAX

- Fixed bug in user disk size (found by Chaskiel M Grundman).

2.2 PDP-1

- Updated CPU, line printer, standard devices to detect indefinite I/O wait.
- Fixed incorrect logical, missing activate, break in drum simulator.
- Fixed bugs in instruction decoding, overprinting for line printer.

2.3 PDP-10

- Fixed bug in RP read header.

2.4 PDP-18b Family

- Fixed bug in PDP-4 line printer overprinting.
- Fixed bug in PDP-15 memory protect/skip interaction.
- Fixed bug in RF set size routine.
- Increased PTP TIME for PDP-15 operating systems.

2.5 PDP-8

- Fixed bug in DF, RF set size routine.

2.6 Nova

- Fixed bug in DSK set size routine.

2.7 1401

- Revised fetch to model hardware more closely.

2.8 Ibm1130

- Fixed bugs found by APL 1130.

2.9 Altairz80

- Fixed bug in real-time clock on Windows host.

2.10 HP2100

-- Fixed DR drum sizes.
-- Fixed DR variable capacity interaction with SAVE/RESTORE.

3. New Features in 3.0 vs prior releases

3.1 SCP and Libraries

- Added ASSIGN/DEASSIGN (logical name) commands.
- Changed RESTORE to unconditionally detach files.
- Added E11 and TPC format support to magtape library.
- Fixed bug in SHOW CONNECTIONS.
- Added USE_ADDR64 support

3.2 All magtapes

- Magtapes support SIMH format, E11 format, and TPC format (read only).
- SET <tape_unit> FORMAT=format sets the specified tape unit's format.
- SHOW <tape_unit> FORMAT displays the specified tape unit's format.
- Tape format can also be set as part of the ATTACH command, using
  the -F switch.

3.3 VAX

- VAX can be compiled without USE_INT64.
- If compiled with USE_INT64 and USE_ADDR64, RQ and TQ controllers support
  files > 2GB.
- VAX ROM has speed control (SET ROM DELAY/NODELAY).

4. Bugs Fixed in 3.0 vs prior releases

4.1 VAX

- Fixed CVTfi bug: integer overflow not set if exponent out of range
- Fixed EMODx bugs:
  o First and second operands reversed
  o Separated fraction received wrong exponent
  o Overflow calculation on separated integer incorrect
  o Fraction not set to zero if exponent out of range
- Fixed interval timer and ROM access to pass power-up self-test even on very
  fast host processors (fixes from Mark Pizzolato).

4.2 1401

- Fixed mnemonic, instruction lengths, and reverse scan length check bug for MCS.
- Fixed MCE bug, BS off by 1 if zero suppress.
- Fixed chaining bug, D lost if return to SCP.
- Fixed H branch, branch occurs after continue.
- Added check for invalid 8 character MCW, LCA.
- Fixed magtape load-mode end of record response.

4.3 Nova

- Fixed DSK variable size interaction with restore.

4.4 PDP-1

- Fixed DT variable size interaction with restore.

4.5 PDP-11

- Fixed DT variable size interaction with restore.
- Fixed bug in MMR1 update (found by Tim Stark).
- Added XQ features and fixed bugs:
  o Corrected XQ interrupts on IE state transition (code by Tom Evans).
  o Added XQ interrupt clear on soft reset.
  o Removed XQ interrupt when setting XL or RL (multiple people).
  o Added SET/SHOW XQ STATS.
  o Added SHOW XQ FILTERS.
  o Added ability to split received packet into multiple buffers.
  o Added explicit runt and giant packet processing.

4.6 PDP-18B

- Fixed DT, RF variable size interaction with restore.
- Fixed MT bug in MTTR.

4.7 PDP-8

- Fixed DT, DF, RF, RX variable size interaction with restore.
- Fixed MT bug in SKTR.

4.8 HP2100

- Fixed bug in DP (13210A controller only), DQ read status.
- Fixed bug in DP, DQ seek complete.

4.9 GRI

- Fixed bug in SC queue pointer management.
This commit is contained in:
Bob Supnik
2003-07-31 16:17:00 -07:00
committed by Mark Pizzolato
parent 4ffd3be790
commit f9564b81b9
74 changed files with 6938 additions and 2812 deletions

View File

@@ -72,7 +72,8 @@ BSC32_SBRS= \
$(INTDIR)/scp.sbr \
$(INTDIR)/scp_tty.sbr \
$(INTDIR)/sim_tmxr.sbr \
$(INTDIR)/sim_sock.sbr
$(INTDIR)/sim_sock.sbr \
$(INTDIR)/ibm1130_fmt.sbr
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
@@ -99,7 +100,8 @@ LINK32_OBJS= \
$(INTDIR)/scp.obj \
$(INTDIR)/scp_tty.obj \
$(INTDIR)/sim_tmxr.obj \
$(INTDIR)/sim_sock.obj
$(INTDIR)/sim_sock.obj \
$(INTDIR)/ibm1130_fmt.obj
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
@@ -149,7 +151,8 @@ BSC32_SBRS= \
$(INTDIR)/scp.sbr \
$(INTDIR)/scp_tty.sbr \
$(INTDIR)/sim_tmxr.sbr \
$(INTDIR)/sim_sock.sbr
$(INTDIR)/sim_sock.sbr \
$(INTDIR)/ibm1130_fmt.sbr
$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS)
$(BSC32) @<<
@@ -176,7 +179,8 @@ LINK32_OBJS= \
$(INTDIR)/scp.obj \
$(INTDIR)/scp_tty.obj \
$(INTDIR)/sim_tmxr.obj \
$(INTDIR)/sim_sock.obj
$(INTDIR)/sim_sock.obj \
$(INTDIR)/ibm1130_fmt.obj
$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS)
$(LINK32) @<<
@@ -249,7 +253,7 @@ $(INTDIR)/ibm1130_stddev.obj : $(SOURCE) $(DEP_IBM1130_) $(INTDIR)
SOURCE=.\ibm1130.rc
DEP_IBM1130_R=\
.\1130consoleblank.bmp\
.\HAND.CUR
.\hand.cur
$(INTDIR)/ibm1130.res : $(SOURCE) $(DEP_IBM1130_R) $(INTDIR)
$(RSC) $(RSC_PROJ) $(SOURCE)
@@ -354,6 +358,14 @@ DEP_SIM_S=\
$(INTDIR)/sim_sock.obj : $(SOURCE) $(DEP_SIM_S) $(INTDIR)
$(CPP) $(CPP_PROJ) $(SOURCE)
# End Source File
################################################################################
# Begin Source File
SOURCE=.\ibm1130_fmt.c
$(INTDIR)/ibm1130_fmt.obj : $(SOURCE) $(INTDIR)
# End Source File
# End Group
# End Project

View File

@@ -9,26 +9,27 @@
* Mail to sim@ibm1130.org
*/
// ctrl-M (Enter) => EOF
// ctrl-U => Erase field
// ctrl-Q => Interrupt request (not here)
// ctrl-C => Program stop (not here)
// \ => "not"
// Del => backspace
// Ctrl-H => backspace
// 03 ctrl-C => Program stop (not handled here)
// 05 ctrl-E => Simulator stop (not handled here)
// 08 ctrl-H => Backspace
// 0D ctrl-M (Enter) => EOF
// 11 ctrl-Q => Interrupt request (not handled here)
// 12 ctrl-R => "cent" (R because that's where cent is on the 1130 keyboard)
// 15 ctrl-U => Erase Field
// 7E ~ => "not"
// FF Del => Backspace again
static uint16 ascii_to_conin[] = /* ASCII to ((hollerith << 4) | special key flags) */
{
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
/* 00 */ 0, 0, 0, 0, 0, 0, 0, 0,0x0004, 0, 0, 0, 0,0x0008, 0, 0,
/* 01 */ 0, 0, 0, 0, 0,0x0002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 10 */ 0, 0,0x8820, 0, 0,0x0002, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 20 */ 0x0001,0x4820,0x0060,0x0420,0x4420,0x2220,0x8000,0x0120,0x8120,0x4120,0x4220,0x80a0,0x2420,0x4000,0x8420,0x3000,
/* 30 */ 0x2000,0x1000,0x0800,0x0400,0x0200,0x0100,0x0080,0x0040,0x0020,0x0010,0x0820,0x40a0,0x8220,0x00a0,0x20a0,0x2060,
/* 40 */ 0x0220,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
/* 50 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010,0xa420, 0,0xc420,0x4060,0x2120,
/* 50 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010, 0, 0, 0, 0,0x2120,
/* 60 */ 0,0x9000,0x8800,0x8400,0x8200,0x8100,0x8080,0x8040,0x8020,0x8010,0x5000,0x4800,0x4400,0x4200,0x4100,0x4080,
/* 70 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010,0xa420, 0,0x8060, 0,0x0004,
/* 70 */ 0x4040,0x4020,0x4010,0x2800,0x2400,0x2200,0x2100,0x2080,0x2040,0x2020,0x2010, 0,0xB060, 0, 0,0x0004,
/* 80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* a0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -38,4 +39,3 @@ static uint16 ascii_to_conin[] = /* ASCII to ((hollerith << 4) | special key
/* e0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* f0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0x0004,
};

View File

@@ -12,31 +12,47 @@
#define _0_ '\0'
#define CENT '\xA2'
#define REST IGNR
#define RDRSTP '?'
#define NOT '\xAC'
#define IGNR '\xFF'
#define CRLF '\r'
#define CENT_ '\xA2' /* cent and not: standard DOS mapping */
#define NOT_ '\xAC'
#define IGNR_ '\xFF'
#define CRLF_ '\r'
static char conout_to_ascii[] = /* console output code to ASCII */
#define COUT_IS_CTRL 0x01 /* conout characters with bit 1 set are controls: */
#define COUT_CTRL_BLACK 0x04 /* none or one of these bits */
#define COUT_CTRL_RED 0x08
#define COUT_CTRL_LINEFEED 0x02 /* plus none or one of these bits */
#define COUT_CTRL_BACKSPACE 0x10
#define COUT_CTRL_SPACE 0x20
#define COUT_CTRL_TAB 0x40
#define COUT_CTRL_RETURN 0x80
#ifdef _MSC_VER
# pragma warning(disable:4245) /* enable int->char demotion warning caused by characters with high-bit set */
#endif
static unsigned char conout_to_ascii[] = /* console output code to ASCII */
{
/* 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F */
/* 00 */ '.', _0_, CENT, '\n', '@', REST, '%', _0_, _0_,RDRSTP, _0_, _0_, _0_, _0_, _0_, _0_,
/* 10 */ 'f', '\b', 'F', _0_, 'g', _0_, 'G', _0_, 'b', _0_, 'B', _0_, 'c', _0_, 'C', _0_,
/* 20 */ 'i', ' ', 'I', _0_, 'h', _0_, 'H', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 30 */ 'd', _0_, 'D', _0_, 'e', _0_, 'E', _0_, _0_, _0_, _0_, _0_, 'a', _0_, 'A', _0_,
/* 40 */ '$', _0_, '!', _0_, '&', _0_, '>', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 50 */ 'o', _0_, 'O', _0_, 'p', _0_, 'P', _0_, 'k', _0_, 'K', _0_, 'l', _0_, 'L', _0_,
/* 60 */ 'r', _0_, 'R', _0_, 'q', _0_, 'Q', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 70 */ 'm', _0_, 'M', _0_, 'n', _0_, 'N', _0_, _0_, _0_, _0_, _0_, 'j', _0_, _0_, _0_,
/* 80 */ ',', CRLF, ':', _0_, '-', _0_, '?', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 90 */ 'w', _0_, 'W', _0_, 'x', _0_, 'X', _0_, 's', _0_, 'S', _0_, 't', _0_, 'T', _0_,
/* A0 */ 'z', _0_, 'Z', _0_, 'y', _0_, 'Y', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* B0 */ 'u', _0_, 'U', _0_, 'v', _0_, 'V', _0_, _0_, _0_, _0_, _0_, '/', _0_, '_', _0_,
/* C0 */ '#', _0_, '=', _0_, '0', _0_, '|', _0_, _0_, _0_, _0_, _0_, _0_, _0_, 'J', _0_,
/* 00 */ '.', IGNR_,CENT_, '\n', '@', IGNR_,'%', _0_, _0_, IGNR_,_0_, _0_, _0_, _0_, _0_, _0_,
/* 10 */ 'F', '\b', 'f', _0_, 'G', _0_, 'g', _0_, 'B', _0_, 'b', _0_, 'C', _0_, 'c', _0_,
/* 20 */ 'I', ' ', 'i', _0_, 'H', _0_, 'h', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 30 */ 'D', _0_, 'd', _0_, 'E', _0_, 'e', _0_, _0_, _0_, _0_, _0_, 'A', _0_, 'a', _0_,
/* 40 */ '$', '\t', '!', _0_, '&', _0_, '>', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 50 */ 'O', _0_, 'o', _0_, 'P', _0_, 'o', _0_, 'K', _0_, 'k', _0_, 'L', _0_, 'l', _0_,
/* 60 */ 'R', _0_, 'r', _0_, 'Q', _0_, 'q', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 70 */ 'M', _0_, 'm', _0_, 'N', _0_, 'n', _0_, _0_, _0_, _0_, _0_, 'J', _0_, 'j', _0_,
/* 80 */ ',', CRLF_, ':', _0_, '-', _0_, '?', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* 90 */ 'W', _0_, 'w', _0_, 'X', _0_, 'x', _0_, 'S', _0_, 's', _0_, 'T', _0_, 't', _0_,
/* A0 */ 'Z', _0_, 'z', _0_, 'Y', _0_, 'y', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* B0 */ 'U', _0_, 'u', _0_, 'V', _0_, 'v', _0_, _0_, _0_, _0_, _0_, '/', _0_, '_', _0_,
/* C0 */ '#', _0_, '=', _0_, '0', _0_, '|', _0_, _0_, _0_, _0_, _0_, 'J', _0_, 'j', _0_,
/* D0 */ '6', _0_, ';', _0_, '7', _0_, '*', _0_, '2', _0_, '+', _0_, '3', _0_, '<', _0_,
/* E0 */ '9', _0_, '"', _0_, '8', _0_, '\'', _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_, _0_,
/* F0 */ '4', _0_, NOT, _0_, '5', _0_, ')', _0_, _0_, _0_, _0_, _0_, '1', _0_, '(', _0_,
/* F0 */ '4', _0_, NOT_, _0_, '5', _0_, ')', _0_, _0_, _0_, _0_, _0_, '1', _0_, '(', _0_,
};
#ifdef _MSC_VER
# pragma warning(default:4245) /* enable int->char demotion warning */
#endif

View File

@@ -9,13 +9,14 @@
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
* Mail to simh@ibm1130.org
25-Jun-01 BLK Written
10-May-02 BLK Fixed bug in MDX instruction
27-Mar-02 BLK Made BOSC work even in short form
16-Aug-02 BLK Fixed bug in multiply instruction; didn't work with negative values
18-Mar-03 BLK Fixed bug in divide instruction; didn't work with negative values
23-Jul-03 BLK Prevented tti polling in CGI mode
The register state for the IBM 1130 CPU is:
@@ -470,23 +471,17 @@ t_stat sim_instr (void)
if (wait_state) { /* waiting? */
sim_interval = 0; /* run the clock out */
if (sim_qcount() <= 1) { /* waiting for keyboard only */
if (keyboard_is_locked()) { /* CPU is not expecting a keystroke */
if (sim_qcount() <= (cgi ? 0 : 1)) { /* one routine queued? we're waiting for keyboard only */
if (keyboard_is_busy()) { /* we are actually waiting for a keystroke */
if ((status = sim_process_event()) != 0) /* get it with wait_state still set */
reason = status;
}
else { /* CPU is not expecting a keystroke (keyboard interrupt) */
if (wait_state == WAIT_OP)
reason = STOP_WAIT; /* end the simulation */
reason = STOP_WAIT; /* end the simulation */
else
reason = STOP_INVALID_INSTR;
}
else { /* we are actually waiting for a keystroke */
if ((status = sim_process_event()) != 0) /* get it with wait_state still set */
reason = status;
}
}
else if (sim_clock_queue == NULL) { /* not waiting for anything */
if (wait_state == WAIT_OP)
reason = STOP_WAIT; /* end the simulation */
else
reason = STOP_INVALID_INSTR;
}
if (gdu_active()) /* but don't stop simulator if 2250 GDU is running */
@@ -1254,7 +1249,7 @@ void xio_error (char *msg)
* register_cmd - add a command to the extensible command table
* ------------------------------------------------------------------------ */
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help)
t_stat register_cmd (char *name, t_stat (*action)(int32 flag, char *ptr), int arg, char *help)
{
int i;

File diff suppressed because it is too large Load Diff

View File

@@ -258,23 +258,23 @@ void xio_2250_display (int32 addr, int32 func, int32 modify); // vector displ
void xio_error (char *msg);
void bail (char *msg);
t_stat load_cr_boot (int drv);
t_stat load_cr_boot (int drv, int switches);
t_stat cr_boot (int unitno, DEVICE *dptr);
void calc_ints (void); /* recalculate interrupt bitmask */
void trace_io (char *fmt, ...); /* debugging printout */
void scp_panic (char *msg); /* bail out of simulator */
char *upcase(char *str);
void break_simulation (t_stat reason); /* let a device halt the simulation */
char hollerith_to_ascii (int16 hol); /* for debugging use only */
char hollerith_to_ascii (uint16 hol); /* for debugging use only */
t_bool gdu_active (void);
void remark_cmd (char *remark);
void stuff_cmd (char *cmd);
void update_gui (t_bool force);
void sim_init (void);
t_stat register_cmd (char *name, t_stat (*action)(int32, char *), int arg, char *help);
t_stat register_cmd (char *name, t_stat (*action)(int32 flag, char *ptr), int arg, char *help);
/* GUI interface routines */
t_bool keyboard_is_locked (void);
t_bool keyboard_is_busy (void);
void forms_check (int set); /* device notification to console lamp display */
void print_check (int set);
void keyboard_selected (int select);

View File

@@ -13,14 +13,17 @@ commands may NOT be accurate. This should probably be fixed.
* 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
*
* Revision History
* 15-jun-03 moved actual read on XIO read to end of time interval,
* as the APL boot card required 2 instructions to run between the
* time read was initiated and the time the data was read (a jump and a wait)
*
* 01-sep-02 corrected treatment of -m and -r flags in dsk_attach
* in cgi mode, so that file is opened readonly but emulated
* disk is writable.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to simh@ibm1130.org
*/
#include "ibm1130_defs.h"
@@ -75,6 +78,7 @@ static int16 dsk_sec[DSK_NUMDR] = {0}; /* next-sector-up */
static char dsk_lastio[DSK_NUMDR]; /* last stdio operation: IO_READ or IO_WRITE */
int32 dsk_swait = 50; /* seek time -- see how short a delay we can get away with */
int32 dsk_rwait = 50; /* rotate time */
static t_bool raw_disk_debug = FALSE;
static t_stat dsk_svc (UNIT *uptr);
static t_stat dsk_reset (DEVICE *dptr);
@@ -141,6 +145,15 @@ static int32 dsk_ilswlevel[DSK_NUMDR] =
2, 2, 2, 2
};
typedef enum {DSK_FUNC_IDLE, DSK_FUNC_READ, DSK_FUNC_VERIFY, DSK_FUNC_WRITE, DSK_FUNC_SEEK, DSK_FUNC_FAILED} DSK_FUNC;
static struct tag_dsk_action { /* stores data needed for pending IO activity */
int32 io_address;
uint32 io_filepos;
int io_nwords;
int io_sector;
} dsk_action[DSK_NUMDR];
/* xio_disk - XIO command interpreter for the disk drives */
/*
* device status word:
@@ -167,7 +180,7 @@ extern void void_backtrace (int afrom, int ato);
void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
{
int i, rev, nsteps, newcyl, sec, nwords;
t_addr newpos;
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
char msg[80];
UNIT *uptr = dsk_unit+drv;
int16 buf[DSK_NUMWD];
@@ -195,7 +208,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
nwords = M[iocc_addr++ & mem_mask]; /* get word count w/o upsetting SAR/SBR */
if (nwords == 0) /* this is bad -- locks up disk controller ! */
if (nwords == 0) /* this is bad -- on real 1130, this locks up disk controller ! */
break;
if (! BETWEEN(nwords, 1, DSK_NUMWD)) { /* count bad */
@@ -205,49 +218,32 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
sec = modify & 0x07; /* get sector on cylinder */
if ((modify & 0x0080) == 0) { /* it's real if not a read check */
if ((modify & 0x0080) == 0) { /* it's a real read if it's not a read check */
// ah. We have a problem. The APL boot card counts on there being time for at least one
// more instruction to execute between the XIO read and the time the data starts loading
// into core. So, we have to defer the actual read operation a bit. Might as well wait
// until it's time to issue the operation complete interrupt. This means saving the
// IO information, then performing the actual read in dsk_svc.
newpos = (uptr->CYL*DSK_NUMSC*DSK_NUMSF + sec)*2*DSK_NUMWD;
if (MEM_MAPPED(uptr)) {
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
}
else {
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
fseek(uptr->fileref, newpos, SEEK_SET);
dsk_lastio[drv] = IO_READ;
}
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
uptr->pos = newpos + 2*DSK_NUMWD;
}
dsk_action[drv].io_address = iocc_addr;
dsk_action[drv].io_nwords = nwords;
dsk_action[drv].io_sector = sec;
dsk_action[drv].io_filepos = newpos;
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
// // this will help debug the monitor by letting me watch phase loading
// if (nwords >= 3)
// printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
// (iocc_addr + nwords - 1) & mem_mask);
i = uptr->CYL*8 + sec;
if (buf[0] != i)
printf("*DSK read bad sector#\n");
for (i = 0; i < nwords; i++)
M[(iocc_addr+i) & mem_mask] = buf[i];
#ifdef TRACE_DMS_IO
if (trace_dms)
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
#endif
uptr->FUNC = DSK_FUNC_READ;
}
else
else {
trace_io("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
uptr->FUNC = func;
sim_activate(uptr, dsk_rwait);
if (raw_disk_debug)
printf("* DSK%d verify %d.%d (%x)", drv, uptr->CYL, sec, uptr->CYL*8 + sec);
uptr->FUNC = DSK_FUNC_VERIFY;
}
sim_activate(uptr, dsk_rwait);
break;
case XIO_INITW:
@@ -279,7 +275,8 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
trace_io("* DSK%d wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)", drv, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
// printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
if (raw_disk_debug)
printf("* DSK%d XIO @ %04x wrote %d words from M[%04x-%04x] to %d.%d (%x, %x)\n", drv, prev_IAR, nwords, iocc_addr & mem_mask, (iocc_addr + nwords - 1) & mem_mask, uptr->CYL, sec, uptr->CYL*8 + sec, newpos);
#ifdef TRACE_DMS_IO
if (trace_dms)
@@ -309,7 +306,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
uptr->pos = newpos + 2*DSK_NUMWD;
}
uptr->FUNC = func;
uptr->FUNC = DSK_FUNC_WRITE;
sim_activate(uptr, dsk_rwait);
break;
@@ -332,7 +329,7 @@ void xio_disk (int32 iocc_addr, int32 func, int32 modify, int drv)
else if (newcyl >= DSK_NUMCY)
newcyl = DSK_NUMCY-1;
uptr->FUNC = func;
uptr->FUNC = DSK_FUNC_SEEK;
uptr->CYL = newcyl;
sim_activate(uptr, dsk_swait); /* schedule interrupt */
@@ -371,30 +368,78 @@ static void diskfail (UNIT *uptr, int errflag)
{
sim_cancel(uptr); /* cancel any pending ops */
SETBIT(uptr->flags, errflag); /* set the error flag */
uptr->FUNC = XIO_FAILED; /* tell svc routine why it failed */
uptr->FUNC = DSK_FUNC_FAILED; /* tell svc routine why it failed */
sim_activate(uptr, 1); /* schedule an immediate op complete interrupt */
}
t_stat dsk_svc (UNIT *uptr)
{
int drv = uptr - dsk_unit;
int drv = uptr - dsk_unit, i, nwords, sec;
int16 buf[DSK_NUMWD];
uint32 newpos; // changed from t_addr to uint32 in anticipation of simh 64-bit development
int32 iocc_addr;
if (uptr->FUNC == DSK_FUNC_IDLE) /* service function called with no activity? not good, but ignore */
return SCPE_OK;
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
CLRBIT(dsk_dsw[drv], DSK_DSW_DISK_BUSY); /* activate operation complete interrupt */
SETBIT(dsk_dsw[drv], DSK_DSW_OP_COMPLETE);
if (uptr->flags & (UNIT_OPERR|UNIT_HARDERR)) { /* word count error or data error */
SETBIT(dsk_dsw[drv], DSK_DSW_DATA_ERROR);
CLRBIT(uptr->flags, UNIT_OPERR); /* but don't clear hard error */
CLRBIT(uptr->flags, UNIT_OPERR); /* soft error is one time occurrence; don't clear hard error */
}
/* schedule interrupt */
SETBIT(ILSW[dsk_ilswlevel[drv]], dsk_ilswbit[drv]);
#ifdef XXXX
switch (uptr->FUNC) {
case XIO_CONTROL:
case XIO_INITR:
case XIO_INITW:
case XIO_FAILED:
switch (uptr->FUNC) { /* take care of business */
case DSK_FUNC_IDLE:
case DSK_FUNC_VERIFY:
case DSK_FUNC_WRITE:
case DSK_FUNC_SEEK:
case DSK_FUNC_FAILED:
break;
case DSK_FUNC_READ: /* actually read the data into core */
iocc_addr = dsk_action[drv].io_address; /* recover saved parameters */
nwords = dsk_action[drv].io_nwords;
newpos = dsk_action[drv].io_filepos;
sec = dsk_action[drv].io_sector;
if (MEM_MAPPED(uptr)) {
memcpy(buf, (char *) uptr->filebuf + newpos, 2*DSK_NUMWD);
}
else {
if (uptr->pos != newpos || dsk_lastio[drv] != IO_READ) {
fseek(uptr->fileref, newpos, SEEK_SET);
dsk_lastio[drv] = IO_READ;
uptr->pos = newpos;
}
fxread(buf, 2, DSK_NUMWD, uptr->fileref); // read whole sector so we're in position for next read
uptr->pos = newpos + 2*DSK_NUMWD;
}
void_backtrace(iocc_addr, iocc_addr + nwords - 1); // mark prev instruction as altered
trace_io("* DSK%d read %d words from %d.%d (%x, %x) to M[%04x-%04x]", drv, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
// // this will help debug the monitor by letting me watch phase loading
if (raw_disk_debug)
printf("* DSK%d XIO @ %04x read %d words from %d.%d (%x, %x) to M[%04x-%04x]\n", drv, prev_IAR, nwords, uptr->CYL, sec, uptr->CYL*8 + sec, newpos, iocc_addr & mem_mask,
(iocc_addr + nwords - 1) & mem_mask);
i = uptr->CYL*8 + sec;
if (buf[0] != i)
printf("*DSK read bad sector #\n");
for (i = 0; i < nwords; i++)
M[(iocc_addr+i) & mem_mask] = buf[i];
#ifdef TRACE_DMS_IO
if (trace_dms)
tracesector(0, nwords, iocc_addr & mem_mask, uptr->CYL*8 + sec);
#endif
break;
default:
@@ -402,8 +447,8 @@ t_stat dsk_svc (UNIT *uptr)
break;
}
uptr->FUNC = -1; // we're done with this operation
#endif
uptr->FUNC = DSK_FUNC_IDLE; // we're done with this operation
return SCPE_OK;
}
@@ -428,7 +473,7 @@ t_stat dsk_reset (DEVICE *dptr)
CLRBIT(uptr->flags, UNIT_OPERR|UNIT_HARDERR);
uptr->CYL = 0;
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = (uptr->flags & UNIT_ATT) ? DSK_DSW_CARRIAGE_HOME : 0;
}
@@ -450,7 +495,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
return rval;
uptr->CYL = 0; // reset the device
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = DSK_DSW_CARRIAGE_HOME;
CLRBIT(uptr->flags, UNIT_RO|UNIT_ROABLE|UNIT_BUFABLE|UNIT_BUF|UNIT_RONLY|UNIT_OPERR|UNIT_HARDERR);
@@ -479,6 +524,7 @@ static t_stat dsk_attach (UNIT *uptr, char *cptr)
}
enable_dms_tracing(sim_switches & SWMASK('D'));
raw_disk_debug = sim_switches & SWMASK('G');
return SCPE_OK;
}
@@ -498,7 +544,7 @@ static t_stat dsk_detach (UNIT *uptr)
calc_ints();
uptr->CYL = 0;
uptr->FUNC = -1;
uptr->FUNC = DSK_FUNC_IDLE;
dsk_dsw[drv] = DSK_DSW_NOT_READY;
if (drv == 0) {
@@ -518,7 +564,7 @@ static t_stat dsk_boot (int unitno, DEVICE *dptr)
if ((rval = reset_all(0)) != SCPE_OK)
return rval;
return load_cr_boot(unitno);
return load_cr_boot(unitno, sim_switches);
}
#ifdef TRACE_DMS_IO

303
Ibm1130/ibm1130_fmt.c Normal file
View File

@@ -0,0 +1,303 @@
// ibm1130_fmt.c : interpret tabs in 1130 Assembler or Fortran source
// Bob Flanders
// -------------------------------------------------------------------------------------------
//
// These routines are used by ibm1130_cr.c when the user has indicated
// that the input text is formatted with tabs. Input lines are edited
// into the appropriate column format. Three edit modes are recognized:
//
// Assembler mode:
// Input lines of the form
//
// [label]<whitespace>[opcode]<tab>[tag][L]<tab>[argument]
//
// are rearranged so that the input fields are placed in the appropriate columns
//
// The label must start on the first character of the line. If there is no label,
// the first character(s) before the opcode must be whitespace. Following the opcode, there
// MUST be a tab character, followed by the format and tag. Following the format and tag
// may be exactly one whitespace character, and then starts the argument.
//
// Input lines with * in column 1 and blank lines are turned into Assembler comments,
// with the * in the Opcode field.
//
// Assembler directive lines at the beginning of the deck must be preceded by
// ! to indicate that they are not comments. For example,
//
// !*LIST
// * This is a comment
//
// Fortran mode:
// Input lines of the form
//
// [label]<tab>statement
//
// or
//
// [label]<tab>Xcontinuation
//
// where X is a non alphabetic contination character are rearranged in the
// appropriate manner:
//
// 1 2
// 12345678901234567890...
// ------------------------
// label statement
// labelXcontinuation
//
// However, you must take care that you don't end up with statement text after column 72.
//
// Input lines with * or C in column 1 are left alone (comments and directives)
//
// (The ! escape is not used before Fortran directives as before Assembler directives)
//
// Tab mode:
// Tabs are replaced with spaces. Tab settings are assumed to be eight characters wide,
// as is standard for vi, notepad, etc.
// -------------------------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <memory.h>
#include <ctype.h>
#include "ibm1130_fmt.h"
#define MAXLINE 81 // maximum output line size
#define WORKSZ 256 // size for tab work area
#define TAGOFFSET 12 // offset for tag field
#define FMTOFFSET 11 // offset for format field
#define MIN(a,b) ((a < b) ? a : b)
#define AMSG " with Assembler Reformat"
#define FMSG " with FORTRAN Reformat"
#define AFORMAT "%20.20s%-60.60s"," "
#define ACOMMENTFMT "%20.20s%-60.60s"," "
#define ABLANKLINE "%20.20s*"," "
#define FFORMAT "%-5.5s %-74.74s"
#define FCONTFMT "%-5.5s%-75.75s"
char gszLabel[6]; // work area for label
char gszArg[MAXLINE]; // .. argument
char gszOutput[MAXLINE]; // .. output
short gaiAsmTabs[] = {7,12,15,20,25,30,35,40,45,52,0};// tab stops for assembler
short gaiPlainTabs[] = {9, 17, 25, 33, 41, 49, 57, 65, 73, 0};// tab stops for just plain tabs
// ///////////////
// helper routines
///////////////////////////////////////////////////
// ExpandTabs: Expand tabs to spaces
char* ExpandTabs(char* p_szInbuf, // expand tabs .. input buffer
char* p_szOutbuf, // .. output buffer
short* p_aiTabs) // .. array of tab stops (1 based) -- 0 end of array
{
short iI, // input position
iO, // output position
iT; // next tab stop
char cX; // character to test
iI = 0; // init input position
iO = 0; // init output position
iT = 0; // init tab stop
while (cX = *(p_szInbuf + iI)) // while there are characters
{
if (cX == '\t') // q. tab character?
{ // a. yes ..
while ((p_aiTabs[iT] <= iO + 1) // search for next valid stop ..
&& (p_aiTabs[iT] != 0)) // .. or end of table
iT++; // .. go to next tab
if (p_aiTabs[iT] != 0) // q. end of tab array?
{ // a. no ..
while (iO < (p_aiTabs[iT] - 1)) // fill to tab with blanks
*(p_szOutbuf + iO++) = ' '; // .. put in a blank
}
else // Otherwise ...
*(p_szOutbuf + iO++) = ' '; // .. Translate to blank
}
else // Otherwise .. not tab
*(p_szOutbuf + iO++) = cX; // .. save the input char
iI++; // next input character
}
*(p_szOutbuf + iO) = 0; // end the string..
return p_szOutbuf; // .. return output area addr
}
/////////////////////////////////////
// extract next token, modify pointer
char* GetToken(char* p_szOut, // output location
int p_iLen, // max output length
char**p_pszToken) // pointer to input token
{
int iI; // work integer
char* pszX; // work pointer
pszX = *p_pszToken; // get pointer to token
for (iI = 0; *(pszX + iI) && (!isspace(*(pszX + iI)));) // while not whitespace & not end
iI++; // .. count token length
memset(p_szOut, 0, p_iLen); // zero out output area
if (iI > 0) // q. any chars?
strncpy(p_szOut, *p_pszToken, MIN(iI, p_iLen-1)); // a. yes.. copy max of p_iLen-1
*p_pszToken += iI; // point beyond token
return p_szOut; // .. return token pointer
}
/////////////////////////////////////////////////////////
// EditToAsm - convert tab-formatted text line to 1130 Assembler format
char *EditToAsm (char* p_pszEdit) // convert line to 1130 assembler
{
char pszLine[MAXLINE]; // source line
char pszWork[WORKSZ]; // work buffer
char acTFWrk[2]; // tag/format work area
size_t iI; // work integer
if (p_pszEdit == NULL) // q. null request?
return AMSG; // a. yes .. return display message
if (*p_pszEdit == '!') // leave lines starting with ! alone
return EditToWhitespace(p_pszEdit+1);
if (*p_pszEdit == '*') // q. comment line?
{ // a. yes..
strncpy(pszWork, EditToWhitespace(p_pszEdit), MAXLINE); // .. convert any tabs
sprintf(gszOutput, ACOMMENTFMT, pszWork); // .. put the comment out there in the opcode column
return gszOutput; // .. and return it
}
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
ExpandTabs(pszLine, pszWork, gaiAsmTabs); // expand the tabs
strncpy(pszLine, pszWork, MAXLINE-1); // copy the line back
for (iI = strlen(pszLine); iI--;) // trim trailing whitespace
{
if (*(pszLine + iI) <= ' ') // q. space or less?
*(pszLine + iI) = 0; // a. yes .. remove it
else // otherwise
break; // .. done. Leave loop.
}
if (strlen(pszLine) == 0) // q. blank line?
{ // a. yes .. Assembler abhors these so
sprintf(gszOutput, ABLANKLINE); // format as comment statement
return gszOutput; // .. and return it
}
// TODO: Add code to process a strip switch
// comment?
if (strlen(pszLine) > (TAGOFFSET + 1)) // q. line long enough?
{ // a. yes.. reorder tag/format
memcpy(acTFWrk, pszLine + FMTOFFSET, 2); // get tag/format
memset((pszLine + FMTOFFSET), ' ', 2); // .. blank 'em out
for (iI = 0; iI < 2; iI ++)
if (isalpha(acTFWrk[iI])) // q. alpha char?
*(pszLine + FMTOFFSET) = acTFWrk[iI]; // a. yes .. make it format
else if (isdigit(acTFWrk[iI])) // q. digit?
*(pszLine + TAGOFFSET) = acTFWrk[iI]; // a. yes .. make it the tag
}
sprintf(gszOutput, AFORMAT, pszLine); // format the line
return gszOutput; // return formatted line
}
/////////////////////////////////////////////////////////
// EditToFortran - convert tab-formatted input text line to FORTRAN format
// (a la DEC Fortran)
char *EditToFortran(char* p_pszEdit) // convert line to 1130 assembler
{
char pszLine[MAXLINE]; // source line
char* pszWork; // work pointer
size_t iI; // work integer
char bContinue; // true if continue
if (p_pszEdit == NULL) // q. null request?
return FMSG; // a. yes .. return display message
if (strchr(p_pszEdit, '\t') == NULL) // q. no tab in the line?
return p_pszEdit; // a. nope, return line as is, assume it's formatted correctly
if (*p_pszEdit == 'C' || *p_pszEdit == '*' || *p_pszEdit == '\0') // q. comment or directive or blank line?
{ // a. yes.. don't restructure
return EditToWhitespace(p_pszEdit);
}
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
for (iI = strlen(pszLine); iI--;) // trim trailing whitespace
{
if (*(pszLine + iI) <= ' ') // q. space or less?
*(pszLine + iI) = 0; // a. yes .. remove it
else // otherwise
break; // .. done. Leave loop.
}
// TODO: Add code to process a strip switch
// comment?
pszWork = (char*) pszLine; // set pointer to line
GetToken(gszLabel, 6, &pszWork); // get the line, if any.
pszWork++; // skip tab/whitespace
// continuation...
bContinue = ((isdigit(*pszWork) && (*pszWork != '0')) // if first char non-zero digit
|| (!isspace(*pszWork) && !isalpha(*pszWork))); // .. or non-alpha non-blank
memset(gszArg, 0, MAXLINE); // .. and arguments
strncpy(gszArg, pszWork, 75); // copy rest to argument
sprintf(gszOutput, (bContinue) ? FCONTFMT : FFORMAT, // format the line
gszLabel, // .. statement #
gszArg); // .. code
return gszOutput; // return formatted line
}
/////////////////////////////////////////////////////////
// EditToWhitespace - expand tabs at 8 space intervals.
char* EditToWhitespace(char *p_pszEdit)
{
int iI; /* work integer */
char pszLine[MAXLINE]; // source line
char pszWork[WORKSZ]; // work buffer
if (p_pszEdit == NULL) // q. null request?
return AMSG; // a. yes .. return display message
strncpy(pszLine, p_pszEdit, MAXLINE-1); // copy the line local
ExpandTabs(pszLine, pszWork, gaiPlainTabs); // expand the tabs
strncpy(gszOutput, pszWork, MAXLINE-1); // copy the line back
for (iI = strlen(gszOutput); iI--;) // look at each character
{
if (*(gszOutput + iI) <= ' ') // q. space or less?
*(gszOutput + iI) = 0; // a. yes .. remove it
else // otherwise
break; // .. done. Leave loop.
}
return gszOutput; /* ... return buffer */
}

17
Ibm1130/ibm1130_fmt.h Normal file
View File

@@ -0,0 +1,17 @@
/*
* (C) Copyright 2003, Bob Flander.
* 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 bob@jftr.com
*/
/* ibm1130_asm.h: definition of routines in ibm1130_asm.c
*/
char* EditToAsm(char*); // convert edit format to 1130 assembler format
char* EditToFortran(char*); // convert edit format to Fortran format
char* EditToWhitespace(char*); // clean white space, tabstops every 8 positions

View File

@@ -18,7 +18,7 @@
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
* Mail to simh@ibm1130.org
*/
#define BLIT_MODE // normally defined, undefine when debugging generate_image()

View File

@@ -9,7 +9,7 @@
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
* Mail to simh@ibm1130.org
*
* 17-May-02 BLK Pulled out of ibm1130_cpu.c
*/
@@ -168,30 +168,30 @@ static int bmwid, bmht;
static struct tag_btn {
int x, y;
char *txt;
BOOL pushable;
BOOL pushable, state;
COLORREF clr;
HBRUSH hbrLit, hbrDark;
HWND hBtn;
} btn[] = {
0, 0, "KEYBOARD\nSELECT", FALSE, RGB(255,255,180), NULL, NULL, NULL,
0, 1, "DISK\nUNLOCK", FALSE, RGB(255,255,180), NULL, NULL, NULL,
0, 2, "RUN", FALSE, RGB(0,255,0), NULL, NULL, NULL,
0, 3, "PARITY\nCHECK", FALSE, RGB(255,0,0), NULL, NULL, NULL,
0, 0, "KEYBOARD\nSELECT", FALSE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
0, 1, "DISK\nUNLOCK", FALSE, TRUE, RGB(255,255,180), NULL, NULL, NULL,
0, 2, "RUN", FALSE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
0, 3, "PARITY\nCHECK", FALSE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
1, 0, "", FALSE, RGB(255,255,180), NULL, NULL, NULL,
1, 1, "FILE\nREADY", FALSE, RGB(0,255,0), NULL, NULL, NULL,
1, 2, "FORMS\nCHECK", FALSE, RGB(255,255,0), NULL, NULL, NULL,
1, 3, "POWER\nON", FALSE, RGB(255,255,180), NULL, NULL, NULL,
1, 0, "", FALSE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
1, 1, "FILE\nREADY", FALSE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
1, 2, "FORMS\nCHECK", FALSE, FALSE, RGB(255,255,0), NULL, NULL, NULL,
1, 3, "POWER\nON", FALSE, TRUE, RGB(255,255,180), NULL, NULL, NULL,
2, 0, "POWER", TRUE, RGB(255,255,180), NULL, NULL, NULL,
2, 1, "PROGRAM\nSTART", TRUE, RGB(0,255,0), NULL, NULL, NULL,
2, 2, "PROGRAM\nSTOP", TRUE, RGB(255,0,0), NULL, NULL, NULL,
2, 3, "LOAD\nIAR", TRUE, RGB(0,0,255), NULL, NULL, NULL,
2, 0, "POWER", TRUE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
2, 1, "PROGRAM\nSTART", TRUE, FALSE, RGB(0,255,0), NULL, NULL, NULL,
2, 2, "PROGRAM\nSTOP", TRUE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
2, 3, "LOAD\nIAR", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
3, 0, "KEYBOARD", TRUE, RGB(255,255,180), NULL, NULL, NULL,
3, 1, "IMM\nSTOP", TRUE, RGB(255,0,0), NULL, NULL, NULL,
3, 2, "CHECK\nRESET", TRUE, RGB(0,0,255), NULL, NULL, NULL,
3, 3, "PROGRAM\nLOAD", TRUE, RGB(0,0,255), NULL, NULL, NULL,
3, 0, "KEYBOARD", TRUE, FALSE, RGB(255,255,180), NULL, NULL, NULL,
3, 1, "IMM\nSTOP", TRUE, FALSE, RGB(255,0,0), NULL, NULL, NULL,
3, 2, "CHECK\nRESET", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
3, 3, "PROGRAM\nLOAD", TRUE, FALSE, RGB(0,0,255), NULL, NULL, NULL,
};
#define NBUTTONS (sizeof(btn) / sizeof(btn[0]))
@@ -318,7 +318,8 @@ static void RepaintRegion (HWND hWnd, int left, int top, int right, int bottom)
void update_gui (BOOL force)
{
int i, sts;
int i;
BOOL state;
static int in_here = FALSE;
static int32 displayed = 0;
@@ -385,25 +386,33 @@ void update_gui (BOOL force)
int_lamps = 0;
// this loop works with lamp buttons that are calculated on-the-fly only
for (i = 0; i < NBUTTONS; i++) {
if (btn[i].pushable)
continue;
switch (i) {
case IDC_RUN: sts = hFlashTimer || (running && ! wait_state); break;
// case IDC_PARITY_CHECK: sts = FALSE; break;
// case IDC_POWER_ON: sts = TRUE; break;
default:
continue;
case IDC_RUN:
state = hFlashTimer || (running && ! wait_state);
break;
// case IDC_FILE_READY: these windows are enabled&disabled directly
// this button is always off
// case IDC_PARITY_CHECK:
// these buttons are enabled/disabled directly
// case IDC_POWER_ON:
// case IDC_FILE_READY:
// case IDC_FORMS_CHECK:
// case IDC_KEYBOARD_SELECT:
// case IDC_DISK_UNLOCK:
default:
continue;
}
if (sts != IsWindowEnabled(btn[i].hBtn)) // status has changed
EnableWindow(btn[i].hBtn, sts);
if (state != btn[i].state) { // state has changed
EnableWindow(btn[i].hBtn, state);
btn[i].state = state;
}
}
in_here = FALSE;
@@ -423,6 +432,7 @@ LRESULT CALLBACK ButtonProc (HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (! btn[i].pushable) {
if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP || uMsg == WM_LBUTTONDBLCLK)
return 0;
if (uMsg == WM_CHAR)
if ((TCHAR) wParam == ' ')
return 0;
@@ -622,9 +632,9 @@ static DWORD WINAPI Pump (LPVOID arg)
class_defined = TRUE;
}
hbWhite = GetStockObject(WHITE_BRUSH); /* create or fetch useful GDI objects */
hbBlack = GetStockObject(BLACK_BRUSH); /* create or fetch useful GDI objects */
hbGray = GetStockObject(GRAY_BRUSH);
hbWhite = GetStockObject(WHITE_BRUSH); /* create or fetch useful GDI objects */
hbBlack = GetStockObject(BLACK_BRUSH); /* create or fetch useful GDI objects */
hbGray = GetStockObject(GRAY_BRUSH);
hSwitchPen = CreatePen(PS_SOLID, 5, RGB(255,255,255));
hWhitePen = GetStockObject(WHITE_PEN);
@@ -633,8 +643,8 @@ static DWORD WINAPI Pump (LPVOID arg)
hGreyPen = CreatePen(PS_SOLID, 1, RGB(128,128,128));
hDkGreyPen = CreatePen(PS_SOLID, 1, RGB(64,64,64));
hcArrow = LoadCursor(NULL, IDC_ARROW);
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_HAND));
hcArrow = LoadCursor(NULL, IDC_ARROW);
hcHand = LoadCursor(hInstance, MAKEINTRESOURCE(IDC_HAND));
if (hBitmap == NULL)
hBitmap = LoadBitmap(hInstance, MAKEINTRESOURCE(IDB_CONSOLE));
@@ -656,11 +666,12 @@ static DWORD WINAPI Pump (LPVOID arg)
bmwid = bm.bmWidth;
bmht = bm.bmHeight;
for (i = 0; i < NBUTTONS; i++)
for (i = 0; i < NBUTTONS; i++) {
CreateSubclassedButton(hConsoleWnd, i);
EnableWindow(btn[IDC_POWER_ON].hBtn, TRUE);
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, TRUE);
if (! btn[i].pushable)
EnableWindow(btn[i].hBtn, btn[i].state);
}
GetWindowRect(hConsoleWnd, &r); /* get window size as created */
wx = r.right - r.left + 1;
@@ -913,12 +924,19 @@ void HandleCommand (HWND hWnd, WPARAM wParam, LPARAM lParam)
reset_all(0);
if (running && ! power) { /* turning off */
reason = STOP_POWER_OFF;
while (running)
Sleep(10); /* wait for execution thread to exit */
// this prevents message pump from running, which unfortunately locks up
// the emulator thread when it calls gui_run(FALSE) which calls EnableWindow on the Run lamp
// while (running)
// Sleep(10); /* wait for execution thread to exit */
}
btn[IDC_POWER_ON].state = power;
EnableWindow(btn[IDC_POWER_ON].hBtn, power);
for (i = 0; i < NBUTTONS; i++)
InvalidateRect(btn[i].hBtn, NULL, TRUE);
for (i = 0; i < NBUTTONS; i++) /* repaint all of the lamps */
if (! btn[i].pushable)
InvalidateRect(btn[i].hBtn, NULL, TRUE);
break;
case IDC_PROGRAM_START: /* begin execution */
@@ -967,8 +985,11 @@ void HandleCommand (HWND hWnd, WPARAM wParam, LPARAM lParam)
case IDC_IMM_STOP:
if (running) {
reason = STOP_WAIT; /* terminate execution without setting wait_mode */
while (running)
Sleep(10); /* wait for execution thread to exit */
// this prevents message pump from running, which unfortunately locks up
// the emulator thread when it calls gui_run(FALSE) which calls EnableWindow on the Run lamp
// while (running)
// Sleep(10); /* wait for execution thread to exit */
}
break;
@@ -1084,10 +1105,14 @@ void forms_check (int set)
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
btn[IDC_FORMS_CHECK].state = printerstatus;
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
if (btn[IDC_FORMS_CHECK].hBtn != NULL) {
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
}
}
void print_check (int set)
@@ -1101,25 +1126,38 @@ void print_check (int set)
btn[IDC_FORMS_CHECK].clr = (printerstatus & PRINT_CHECK) ? RGB(255,0,0) : RGB(255,255,0);
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
btn[IDC_FORMS_CHECK].state = printerstatus;
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
if (btn[IDC_FORMS_CHECK].hBtn != NULL) {
EnableWindow(btn[IDC_FORMS_CHECK].hBtn, printerstatus);
if (btn[IDC_FORMS_CHECK].clr != oldcolor)
InvalidateRect(btn[IDC_FORMS_CHECK].hBtn, NULL, TRUE); // change color in any case
}
}
void keyboard_selected (int select)
{
EnableWindow(btn[IDC_KEYBOARD_SELECT].hBtn, select);
btn[IDC_KEYBOARD_SELECT].state = select;
if (btn[IDC_KEYBOARD_SELECT].hBtn != NULL)
EnableWindow(btn[IDC_KEYBOARD_SELECT].hBtn, select);
}
void disk_ready (int ready)
{
EnableWindow(btn[IDC_FILE_READY].hBtn, ready);
btn[IDC_FILE_READY].state = ready;
if (btn[IDC_FILE_READY].hBtn != NULL)
EnableWindow(btn[IDC_FILE_READY].hBtn, ready);
}
void disk_unlocked (int unlocked)
{
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, unlocked);
btn[IDC_DISK_UNLOCK].state = unlocked;
if (btn[IDC_DISK_UNLOCK].hBtn != NULL)
EnableWindow(btn[IDC_DISK_UNLOCK].hBtn, unlocked);
}
CRITICAL_SECTION critsect;

View File

@@ -23,7 +23,7 @@
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
* Mail to simh@ibm1130.org
*/
#include "ibm1130_defs.h"

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@
* or modifications.
*
* This is not a supported product, but I welcome bug reports and fixes.
* Mail to sim@ibm1130.org
* Mail to simh@ibm1130.org
*/
#include "ibm1130_defs.h"

View File

@@ -58,9 +58,11 @@ ibm1130D = ./
ibm1130 = ${ibm1130D}ibm1130_sys.c ${ibm1130D}ibm1130_cpu.c \
${ibm1130D}ibm1130_cr.c ${ibm1130D}ibm1130_disk.c \
${ibm1130D}ibm1130_stddev.c ${ibm1130D}ibm1130_gdu.c \
${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c
${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c \
${ibm1130D}ibm1130_fmt.c
ibm1130_INC = ibm1130res.h ibm1130_conin.h ibm1130_conout.h \
ibm1130_defs.h ibm1130_prtwheel.h \
ibm1130_defs.h ibm1130_prtwheel.h ibm1130_fmt.h \
dmsr2v12phases.h dmsr2v12slet.h
#

View File

@@ -1,5 +1,10 @@
Here's the 1130 simulator as it stands now.
Status: 22Jul2003
* Added support for APL\1130 output translations
and some bug fixes uncovered by APL.
Status: 13Sep2002
* Added support for 1403 printer. It's MUCH faster

View File

@@ -1,7 +1,11 @@
Version: 18 March 2003
Version: 10 July 2003
History (partial):
2003-07-10 Fixed disk and console terminal bugs uncovered by
APL\1130. Added APL keyboard and output font support
to enable use of APL\1130. APL will be released soon.
2003-03-18 Fixed bug in asm1130 that produced an error message
with a (legal) offset of +127 in MDX instructions.

View File

@@ -13,6 +13,7 @@
// ASM1130 - IBM 1130 Cross Assembler
//
// Version
// 1.08 - 2003Mar18 - Fixed bug that complained about valid MDX displacement of +127
// 1.07 - 2003Jan05 - Filenames are now left in lower case. SYMBOLS.SYS stays all upper case
// 1.06 - 2002May02 - Fixed bug in ebdic constants (data goes into low byte)
// First stab at adding ISS level # info, this is iffy
@@ -156,7 +157,7 @@
#define TRUE 1
#define FALSE 0
#define VERSION "ASM1130 CROSS ASSEMBLER V1.07"
#define VERSION "ASM1130 CROSS ASSEMBLER V1.08"
#define ISTV 0x33 // magic number from DMS R2V12 monitorm symbol @ISTV
@@ -3392,7 +3393,7 @@ void mdx_op (struct tag_op *op, char *label, char *mods, char *arg)
else
getexpr(tok, FALSE, &incr);
if (incr.value < -128 || incr.value >= 127) // displacement style
if (incr.value < -128 || incr.value > 127) // displacement style (fixed in ver 1.08)
asm_error("Invalid increment value (8 bits signed)");
opcode |= (incr.value & 0xFF);

View File

@@ -426,7 +426,7 @@ void show_data (void)
(reloc == R_LIBF) ? 'L' : '@';
printf("%04x%c ", buf[9+i], ch);
rflag << 2;
rflag <<= 2;
nout++;
}
putchar('\n');

View File

@@ -337,7 +337,7 @@ void show_data (unsigned short *buf)
(reloc == R_LIBF) ? 'L' : '@';
printf("%04x%c ", buf[9+i], ch);
rflag << 2;
rflag <<= 2;
nout++;
}
putchar('\n');

View File

@@ -15,25 +15,61 @@
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
typedef int BOOL;
int hollerith_to_ascii (unsigned short h);
void bail (char *msg);
void format_coldstart (unsigned short *buf);
int main (int argc, char **argv)
{
FILE *fd;
char line[82];
char *fname = NULL, line[82], *arg;
BOOL coldstart = FALSE;
unsigned short buf[80];
int i, lastnb;
static char usestr[] =
"Usage: viewdeck [-c] deckfile\n"
"\n"
"-c: convert cold start card to 16-bit format as a C array initializer\n";
if (argc != 2)
bail("Usage: viewdeck deckfile");
for (i = 1; i < argc; i++) { // process command line arguments
arg = argv[i];
if ((fd = fopen(argv[1], "rb")) == NULL) {
perror(argv[1]);
if (*arg == '-') {
arg++;
while (*arg) {
switch (*arg++) {
case 'c':
coldstart = TRUE;
break;
default:
bail(usestr);
}
}
}
else if (fname == NULL) // first non-switch arg is file name
fname = arg;
else
bail(usestr); // there can be only one name
}
if (fname == NULL) // there must be a name
bail(usestr);
if ((fd = fopen(fname, "rb")) == NULL) {
perror(fname);
return 1;
}
while (fread(buf, sizeof(short), 80, fd) == 80) {
if (coldstart) {
format_coldstart(buf);
break;
}
lastnb = -1;
for (i = 0; i < 80; i++) {
line[i] = hollerith_to_ascii(buf[i]);
@@ -45,11 +81,39 @@ int main (int argc, char **argv)
fputs(line, stdout);
}
if (coldstart) {
if (fread(buf, sizeof(short), 1, fd) == 1)
bail("Coldstart deck has more than one card");
}
fclose(fd);
return 0;
}
void format_coldstart (unsigned short *buf)
{
int i, nout = 0;
unsigned short word;
for (i = 0; i < 80; i++) {
word = buf[i]; // expand 12-bit card data to 16-bit instruction
word = (word & 0xF800) | ((word & 0x0400) ? 0x00C0 : 0x0000) | ((word & 0x03F0) >> 4);
if (nout >= 8) {
fputs(",\n", stdout);
nout = 0;
}
else if (i > 0)
fputs(", ", stdout);
printf("0x%04x", word);
nout++;
}
putchar('\n');
}
typedef struct {
unsigned short hollerith;
char ascii;
@@ -103,7 +167,7 @@ static CPCODE cardcode_029[] =
0x0120, '\'',
0x00A0, '=',
0x0060, '"',
0x8820, 'c', // cent
0x8820, '\xA2', // cent, in MS-DOS encoding
0x8420, '.',
0x8220, '<', // ) in 026 Fortran
0x8120, '(',
@@ -114,13 +178,47 @@ static CPCODE cardcode_029[] =
0x4220, '*',
0x4120, ')',
0x40A0, ';',
0x4060, 'n', // not
0x2820, 'x', // what?
0x4060, '\xAC', // not, in MS-DOS encoding
0x2420, ',',
0x2220, '%', // ( in 026 Fortran
0x2120, '_',
0x20A0, '>',
0x2060, '>',
0xB000, 'a',
0xA800, 'b',
0xA400, 'c',
0xA200, 'd',
0xA100, 'e',
0xA080, 'f',
0xA040, 'g',
0xA020, 'h',
0xA010, 'i',
0xD000, 'j',
0xC800, 'k',
0xC400, 'l',
0xC200, 'm',
0xC100, 'n',
0xC080, 'o',
0xC040, 'p',
0xC020, 'q',
0xC010, 'r',
0x6800, 's',
0x6400, 't',
0x6200, 'u',
0x6100, 'v',
0x6080, 'w',
0x6040, 'x',
0x6020, 'y',
0x6010, 'z', // these odd punch codes are used by APL:
0x1010, '\001', // no corresponding ASCII using ^A
0x0810, '\002', // SYN using ^B
0x0410, '\003', // no corresponding ASCII using ^C
0x0210, '\004', // PUNCH ON using ^D
0x0110, '\005', // READER STOP using ^E
0x0090, '\006', // UPPER CASE using ^F
0x0050, '\013', // EOT using ^K
0x0030, '\016', // no corresponding ASCII using ^N
0x1030, '\017', // no corresponding ASCII using ^O
0x0830, '\020', // no corresponding ASCII using ^P
};
int hollerith_to_ascii (unsigned short h)