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:
committed by
Mark Pizzolato
parent
4ffd3be790
commit
f9564b81b9
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
1092
Ibm1130/ibm1130_cr.c
1092
Ibm1130/ibm1130_cr.c
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
@@ -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
303
Ibm1130/ibm1130_fmt.c
Normal 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
17
Ibm1130/ibm1130_fmt.h
Normal 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
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
#
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user