1
0
mirror of https://github.com/simh/simh.git synced 2026-01-25 11:46:37 +00:00

Notes For V3.5-0

The source set has been extensively overhauled.  For correct
viewing, set Visual C++ or Emacs to have tab stops every 4
characters.

1. New Features in 3.4-1

1.1 All Ethernet devices

- Added Windows user-defined adapter names (from Timothe Litt)

1.2 Interdata, SDS, HP, PDP-8, PDP-18b terminal multiplexors

- Added support for SET <unit>n DISCONNECT

1.3 VAX

- Added latent QDSS support
- Revised autoconfigure to handle QDSS

1.4 PDP-11

- Revised autoconfigure to handle more casees

2. Bugs Fixed in 3.4-1

2.1 SCP and libraries

- Trim trailing spaces on all input (for example, attach file names)
- Fixed sim_sock spurious SIGPIPE error in Unix/Linux
- Fixed sim_tape misallocation of TPC map array for 64b simulators

2.2 1401

- Fixed bug, CPU reset was clearing SSB through SSG

2.3 PDP-11

- Fixed bug in VH vector display routine
- Fixed XU runt packet processing (found by Tim Chapman)

2.4 Interdata

- Fixed bug in SHOW PAS CONN/STATS
- Fixed potential integer overflow exception in divide

2.5 SDS

- Fixed bug in SHOW MUX CONN/STATS

2.6 HP

- Fixed bug in SHOW MUX CONN/STATS

2.7 PDP-8

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.8 PDP-18b

- Fixed bug in SHOW TTIX CONN/STATS
- Fixed bug in SET/SHOW TTOXn LOG

2.9 Nova, Eclipse

- Fixed potential integer overflow exception in divide
This commit is contained in:
Bob Supnik
2005-09-09 18:09:00 -07:00
committed by Mark Pizzolato
parent ec60bbf329
commit b7c1eae41f
257 changed files with 107140 additions and 97195 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -19,12 +19,12 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
25-Apr-03 RMS Revised for extended file support
19-Sep-02 RMS Fixed declarations in gdev structure
25-Apr-03 RMS Revised for extended file support
19-Sep-02 RMS Fixed declarations in gdev structure
There are several discrepancies between the original GRI-909 Reference
Manual of 1969 and the only surviving code sample, the MIT Crystal Growing
@@ -50,174 +50,174 @@
Answer: arithmetic right shift, normalize.
*/
#include "sim_defs.h" /* simulator defns */
#include "sim_defs.h" /* simulator defns */
/* Simulator stop codes */
#define STOP_DEV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_ILLINT 4 /* illegal intr */
#define STOP_DEV 1 /* must be 1 */
#define STOP_HALT 2 /* HALT */
#define STOP_IBKPT 3 /* breakpoint */
#define STOP_ILLINT 4 /* illegal intr */
/* Memory */
#define MAXMEMSIZE 32768 /* max memory size */
#define AMASK 077777 /* logical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
#define MAXMEMSIZE 32768 /* max memory size */
#define AMASK 077777 /* logical addr mask */
#define MEMSIZE (cpu_unit.capac) /* actual memory size */
#define MEM_ADDR_OK(x) (((uint32) (x)) < MEMSIZE)
/* Architectural constants */
#define SIGN 0100000 /* sign */
#define DMASK 0177777 /* data mask */
#define CBIT (DMASK + 1) /* carry bit */
#define SIGN 0100000 /* sign */
#define DMASK 0177777 /* data mask */
#define CBIT (DMASK + 1) /* carry bit */
/* Instruction format */
#define I_M_SRC 077 /* source */
#define I_V_SRC 10
#define I_GETSRC(x) (((x) >> I_V_SRC) & I_M_SRC)
#define I_M_OP 017 /* operator */
#define I_V_OP 6
#define I_GETOP(x) (((x) >> I_V_OP) & I_M_OP)
#define I_M_DST 077 /* destination */
#define I_V_DST 0
#define I_GETDST(x) (((x) >> I_V_DST) & I_M_DST)
#define SF_V_REASON 1 /* SF reason */
#define I_M_SRC 077 /* source */
#define I_V_SRC 10
#define I_GETSRC(x) (((x) >> I_V_SRC) & I_M_SRC)
#define I_M_OP 017 /* operator */
#define I_V_OP 6
#define I_GETOP(x) (((x) >> I_V_OP) & I_M_OP)
#define I_M_DST 077 /* destination */
#define I_V_DST 0
#define I_GETDST(x) (((x) >> I_V_DST) & I_M_DST)
#define SF_V_REASON 1 /* SF reason */
/* IO return */
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
#define IORETURN(f,v) ((f)? (v): SCPE_OK) /* stop on error */
/* Operators */
#define U_ZERO 000 /* zero */
#define U_IR 001 /* instruction reg */
#define U_FSK 002 /* func out/skip */
#define U_TRP 003 /* trap */
#define U_ISR 004 /* intr status */
#define U_MA 005 /* mem addr */
#define U_MEM 006 /* mem data */
#define U_SC 007 /* seq counter */
#define U_SWR 010 /* switch register */
#define U_AX 011 /* arith in 1 */
#define U_AY 012 /* arith in 2 */
#define U_AO 013 /* arith out */
#define U_EAO 014 /* ext arith */
#define U_MSR 017 /* machine status */
#define U_BSW 024 /* byte swap */
#define U_BPK 025 /* byte pack */
#define U_GR 030 /* hex general regs */
#define U_RTC 075 /* clock */
#define U_HS 076 /* paper tape */
#define U_TTY 077 /* console */
#define U_ZERO 000 /* zero */
#define U_IR 001 /* instruction reg */
#define U_FSK 002 /* func out/skip */
#define U_TRP 003 /* trap */
#define U_ISR 004 /* intr status */
#define U_MA 005 /* mem addr */
#define U_MEM 006 /* mem data */
#define U_SC 007 /* seq counter */
#define U_SWR 010 /* switch register */
#define U_AX 011 /* arith in 1 */
#define U_AY 012 /* arith in 2 */
#define U_AO 013 /* arith out */
#define U_EAO 014 /* ext arith */
#define U_MSR 017 /* machine status */
#define U_BSW 024 /* byte swap */
#define U_BPK 025 /* byte pack */
#define U_GR 030 /* hex general regs */
#define U_RTC 075 /* clock */
#define U_HS 076 /* paper tape */
#define U_TTY 077 /* console */
struct gdev {
uint32 (*Src)(uint32); /* source */
t_stat (*Dst)(uint32, uint32); /* dest */
t_stat (*FO)(uint32); /* func out */
uint32 (*SF)(uint32); /* skip func */
uint32 (*Src)(uint32); /* source */
t_stat (*Dst)(uint32, uint32); /* dest */
t_stat (*FO)(uint32); /* func out */
uint32 (*SF)(uint32); /* skip func */
};
/* Trap (jump) */
#define TRP_DIR 00 /* direct */
#define TRP_DEF 01 /* defer */
#define TRP_DIR 00 /* direct */
#define TRP_DEF 01 /* defer */
/* Interrupt status */
#define ISR_OFF 01 /* int off */
#define ISR_ON 02 /* int on */
#define ISR_OFF 01 /* int off */
#define ISR_ON 02 /* int on */
/* Bus modifiers */
#define BUS_COM 002 /* complement */
#define BUS_FNC 014 /* function mask */
#define BUS_P1 004 /* + 1 */
#define BUS_L1 010 /* rotate left */
#define BUS_R1 014 /* rotate right */
#define BUS_COM 002 /* complement */
#define BUS_FNC 014 /* function mask */
#define BUS_P1 004 /* + 1 */
#define BUS_L1 010 /* rotate left */
#define BUS_R1 014 /* rotate right */
/* Memory address modes */
#define MEM_MOD 03
#define MEM_DIR 00 /* direct */
#define MEM_DEF 01 /* defer */
#define MEM_IMM 02 /* immediate */
#define MEM_IDF 03 /* immediate defer */
#define MEM_MOD 03
#define MEM_DIR 00 /* direct */
#define MEM_DEF 01 /* defer */
#define MEM_IMM 02 /* immediate */
#define MEM_IDF 03 /* immediate defer */
/* Arithmetic unit */
#define FO_V_FOA 8 /* arith func */
#define FO_M_FOA 03
#define OP_GET_FOA(x) (((x) >> (FO_V_FOA - I_V_OP)) & FO_M_FOA)
#define AO_ADD 00 /* add */
#define AO_AND 01 /* and */
#define AO_XOR 02 /* xor */
#define AO_IOR 03 /* or */
#define EAO_MUL 01 /* multiply */
#define EAO_DIV 02 /* divide */
#define EAO_ARS 03 /* arith rshft */
#define EAO_NORM 04 /* normalize */
#define FO_V_FOA 8 /* arith func */
#define FO_M_FOA 03
#define OP_GET_FOA(x) (((x) >> (FO_V_FOA - I_V_OP)) & FO_M_FOA)
#define AO_ADD 00 /* add */
#define AO_AND 01 /* and */
#define AO_XOR 02 /* xor */
#define AO_IOR 03 /* or */
#define EAO_MUL 01 /* multiply */
#define EAO_DIV 02 /* divide */
#define EAO_ARS 03 /* arith rshft */
#define EAO_NORM 04 /* normalize */
/* Machine status */
#define MSR_V_BOV 15 /* bus carry */
#define MSR_V_L 14 /* bus link */
#define MSR_V_FOA 8 /* arith func */
#define MSR_M_FOA 03
#define MSR_V_SOV 1 /* arith ovflo */
#define MSR_V_AOV 0 /* arith carry */
#define MSR_BOV (1u << MSR_V_BOV)
#define MSR_L (1u << MSR_V_L)
#define MSR_FOA (MSR_M_FOA << MSR_V_FOA)
#define MSR_SOV (1u << MSR_V_SOV)
#define MSR_AOV (1u << MSR_V_AOV)
#define MSR_GET_FOA(x) (((x) >> MSR_V_FOA) & MSR_M_FOA)
#define MSR_PUT_FOA(x,n) (((x) & ~(MSR_M_FOA << MSR_V_FOA)) | \
(((n) & MSR_M_FOA) << MSR_V_FOA))
#define MSR_RW (MSR_BOV|MSR_L|MSR_FOA|MSR_SOV|MSR_AOV)
#define MSR_V_BOV 15 /* bus carry */
#define MSR_V_L 14 /* bus link */
#define MSR_V_FOA 8 /* arith func */
#define MSR_M_FOA 03
#define MSR_V_SOV 1 /* arith ovflo */
#define MSR_V_AOV 0 /* arith carry */
#define MSR_BOV (1u << MSR_V_BOV)
#define MSR_L (1u << MSR_V_L)
#define MSR_FOA (MSR_M_FOA << MSR_V_FOA)
#define MSR_SOV (1u << MSR_V_SOV)
#define MSR_AOV (1u << MSR_V_AOV)
#define MSR_GET_FOA(x) (((x) >> MSR_V_FOA) & MSR_M_FOA)
#define MSR_PUT_FOA(x,n) (((x) & ~(MSR_M_FOA << MSR_V_FOA)) | \
(((n) & MSR_M_FOA) << MSR_V_FOA))
#define MSR_RW (MSR_BOV|MSR_L|MSR_FOA|MSR_SOV|MSR_AOV)
/* Real time clock */
#define RTC_OFF 001 /* off */
#define RTC_ON 002 /* clock on */
#define RTC_OV 010 /* clock flag */
#define RTC_CTR 0103 /* counter */
#define RTC_OFF 001 /* off */
#define RTC_ON 002 /* clock on */
#define RTC_OV 010 /* clock flag */
#define RTC_CTR 0103 /* counter */
/* Terminal */
#define TTY_ORDY 002 /* output flag */
#define TTY_IRDY 010 /* input flag */
#define TTY_ORDY 002 /* output flag */
#define TTY_IRDY 010 /* input flag */
/* Paper tape */
#define PT_STRT 001 /* start reader */
#define PT_ORDY 002 /* output flag */
#define PT_IRDY 010 /* input flag */
#define PT_STRT 001 /* start reader */
#define PT_ORDY 002 /* output flag */
#define PT_IRDY 010 /* input flag */
/* Interrupt masks (ISR) */
#define INT_V_TTO 0 /* console out */
#define INT_V_TTI 1 /* console in */
#define INT_V_HSP 2 /* paper tape punch */
#define INT_V_HSR 3 /* paper tape reader */
#define INT_V_RTC 11 /* clock */
#define INT_V_NODEF 16 /* nodefer */
#define INT_V_ON 17 /* enable */
#define INT_TTO (1u << INT_V_TTO)
#define INT_TTI (1u << INT_V_TTI)
#define INT_HSP (1u << INT_V_HSP)
#define INT_HSR (1u << INT_V_HSR)
#define INT_RTC (1u << INT_V_RTC)
#define INT_NODEF (1u << INT_V_NODEF)
#define INT_ON (1u << INT_V_ON)
#define INT_PENDING (INT_ON | INT_NODEF)
#define INT_V_TTO 0 /* console out */
#define INT_V_TTI 1 /* console in */
#define INT_V_HSP 2 /* paper tape punch */
#define INT_V_HSR 3 /* paper tape reader */
#define INT_V_RTC 11 /* clock */
#define INT_V_NODEF 16 /* nodefer */
#define INT_V_ON 17 /* enable */
#define INT_TTO (1u << INT_V_TTO)
#define INT_TTI (1u << INT_V_TTI)
#define INT_HSP (1u << INT_V_HSP)
#define INT_HSR (1u << INT_V_HSR)
#define INT_RTC (1u << INT_V_RTC)
#define INT_NODEF (1u << INT_V_NODEF)
#define INT_ON (1u << INT_V_ON)
#define INT_PENDING (INT_ON | INT_NODEF)
/* Vectors */
#define VEC_BKP 0000 /* breakpoint */
#define VEC_TTO 0011 /* console out */
#define VEC_TTI 0014 /* console in */
#define VEC_HSP 0017 /* paper tape punch */
#define VEC_HSR 0022 /* paper tape reader */
#define VEC_RTC 0100 /* clock */
#define VEC_BKP 0000 /* breakpoint */
#define VEC_TTO 0011 /* console out */
#define VEC_TTI 0014 /* console in */
#define VEC_HSP 0017 /* paper tape punch */
#define VEC_HSR 0022 /* paper tape reader */
#define VEC_RTC 0100 /* clock */

View File

@@ -27,8 +27,8 @@ The following copyright notice applies to both the SIMH source and binary:
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
This memorandum documents the GRI-909 simulator.

View File

@@ -1,6 +1,6 @@
/* gri_stddev.c: GRI-909 standard devices
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,29 +19,29 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
tti S42-001 terminal input
tto S42-002 terminal output
hsr S42-004 high speed reader
hsp S42-006 high speed punch
rtc real time clock
tti S42-001 terminal input
tto S42-002 terminal output
hsr S42-004 high speed reader
hsp S42-006 high speed punch
rtc real time clock
29-Dec-03 RMS Added support for console backpressure
25-Apr-03 RMS Revised for extended file support
22-Dec-02 RMS Added break support
01-Nov-02 RMS Added 7b/8B support to terminal
29-Dec-03 RMS Added support for console backpressure
25-Apr-03 RMS Revised for extended file support
22-Dec-02 RMS Added break support
01-Nov-02 RMS Added 7b/8B support to terminal
*/
#include "gri_defs.h"
#include <ctype.h>
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_KSR (UNIT_V_UF + 1) /* KSR33 */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_KSR (1 << UNIT_V_KSR)
#define UNIT_V_8B (UNIT_V_UF + 0) /* 8B */
#define UNIT_V_KSR (UNIT_V_UF + 1) /* KSR33 */
#define UNIT_8B (1 << UNIT_V_8B)
#define UNIT_KSR (1 << UNIT_V_KSR)
uint32 hsr_stopioe = 1, hsp_stopioe = 1;
@@ -60,152 +60,166 @@ t_stat hsp_reset (DEVICE *dhsr);
t_stat rtc_svc (UNIT *uhsr);
t_stat rtc_reset (DEVICE *dhsr);
int32 rtc_tps = 1000;
/* TTI data structures
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
tti_mod TTI modifiers list
tti_dev TTI device descriptor
tti_unit TTI unit descriptor
tti_reg TTI register list
tti_mod TTI modifiers list
*/
UNIT tti_unit = { UDATA (&tti_svc, UNIT_KSR, 0), KBD_POLL_WAIT };
REG tti_reg[] = {
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (IRDY, dev_done, INT_V_TTI) },
{ FLDATA (IENB, ISR, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO },
{ NULL } };
{ ORDATA (BUF, tti_unit.buf, 8) },
{ FLDATA (IRDY, dev_done, INT_V_TTI) },
{ FLDATA (IENB, ISR, INT_V_TTI) },
{ DRDATA (POS, tti_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tti_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (UC, tti_unit.flags, UNIT_V_KSR), REG_HRO },
{ NULL }
};
MTAB tti_mod[] = {
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ 0 } };
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ 0 }
};
DEVICE tti_dev = {
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL };
"TTI", &tti_unit, tti_reg, tti_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tti_reset,
NULL, NULL, NULL
};
/* TTO data structures
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
tto_dev TTO device descriptor
tto_unit TTO unit descriptor
tto_reg TTO register list
*/
UNIT tto_unit = { UDATA (&tto_svc, UNIT_KSR, 0), SERIAL_OUT_WAIT };
REG tto_reg[] = {
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (ORDY, dev_done, INT_V_TTO) },
{ FLDATA (IENB, ISR, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL } };
{ ORDATA (BUF, tto_unit.buf, 8) },
{ FLDATA (ORDY, dev_done, INT_V_TTO) },
{ FLDATA (IENB, ISR, INT_V_TTO) },
{ DRDATA (POS, tto_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, tto_unit.wait, 24), PV_LEFT },
{ NULL }
};
MTAB tto_mod[] = {
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ 0 } };
{ UNIT_KSR+UNIT_8B, UNIT_KSR, "KSR", "KSR", &tty_set_mode },
{ UNIT_KSR+UNIT_8B, 0 , "7b" , "7B" , &tty_set_mode },
{ UNIT_KSR+UNIT_8B, UNIT_8B , "8b" , "8B" , &tty_set_mode },
{ 0 }
};
DEVICE tto_dev = {
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL };
"TTO", &tto_unit, tto_reg, tto_mod,
1, 10, 31, 1, 8, 8,
NULL, NULL, &tto_reset,
NULL, NULL, NULL
};
/* HSR data structures
hsr_dev HSR device descriptor
hsr_unit HSR unit descriptor
hsr_reg HSR register list
hsr_mod HSR modifiers list
hsr_dev HSR device descriptor
hsr_unit HSR unit descriptor
hsr_reg HSR register list
hsr_mod HSR modifiers list
*/
UNIT hsr_unit = {
UDATA (&hsr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_IN_WAIT };
UDATA (&hsr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_IN_WAIT
};
REG hsr_reg[] = {
{ ORDATA (BUF, hsr_unit.buf, 8) },
{ FLDATA (IRDY, dev_done, INT_V_HSR) },
{ FLDATA (IENB, ISR, INT_V_HSR) },
{ DRDATA (POS, hsr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, hsr_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, hsr_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, hsr_unit.buf, 8) },
{ FLDATA (IRDY, dev_done, INT_V_HSR) },
{ FLDATA (IENB, ISR, INT_V_HSR) },
{ DRDATA (POS, hsr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, hsr_unit.wait, 24), REG_NZ + PV_LEFT },
{ FLDATA (STOP_IOE, hsr_stopioe, 0) },
{ NULL }
};
DEVICE hsr_dev = {
"HSR", &hsr_unit, hsr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &hsr_reset,
NULL, NULL, NULL };
"HSR", &hsr_unit, hsr_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &hsr_reset,
NULL, NULL, NULL
};
/* HSP data structures
hsp_dev HSP device descriptor
hsp_unit HSP unit descriptor
hsp_reg HSP register list
hsp_dev HSP device descriptor
hsp_unit HSP unit descriptor
hsp_reg HSP register list
*/
UNIT hsp_unit = {
UDATA (&hsp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT };
UDATA (&hsp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
};
REG hsp_reg[] = {
{ ORDATA (BUF, hsp_unit.buf, 8) },
{ FLDATA (ORDY, dev_done, INT_V_HSP) },
{ FLDATA (IENB, ISR, INT_V_HSP) },
{ DRDATA (POS, hsp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, hsp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, hsp_stopioe, 0) },
{ NULL } };
{ ORDATA (BUF, hsp_unit.buf, 8) },
{ FLDATA (ORDY, dev_done, INT_V_HSP) },
{ FLDATA (IENB, ISR, INT_V_HSP) },
{ DRDATA (POS, hsp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, hsp_unit.wait, 24), PV_LEFT },
{ FLDATA (STOP_IOE, hsp_stopioe, 0) },
{ NULL }
};
DEVICE hsp_dev = {
"HSP", &hsp_unit, hsp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &hsp_reset,
NULL, NULL, NULL };
"HSP", &hsp_unit, hsp_reg, NULL,
1, 10, 31, 1, 8, 8,
NULL, NULL, &hsp_reset,
NULL, NULL, NULL
};
/* RTC data structures
rtc_dev RTC device descriptor
rtc_unit RTC unit descriptor
rtc_reg RTC register list
rtc_dev RTC device descriptor
rtc_unit RTC unit descriptor
rtc_reg RTC register list
*/
UNIT rtc_unit = { UDATA (&rtc_svc, 0, 0), 16000 };
REG rtc_reg[] = {
{ FLDATA (RDY, dev_done, INT_V_RTC) },
{ FLDATA (IENB, ISR, INT_V_RTC) },
{ DRDATA (TIME, rtc_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, rtc_tps, 8), REG_NZ + PV_LEFT + REG_HIDDEN },
{ NULL } };
{ FLDATA (RDY, dev_done, INT_V_RTC) },
{ FLDATA (IENB, ISR, INT_V_RTC) },
{ DRDATA (TIME, rtc_unit.wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TPS, rtc_tps, 8), REG_NZ + PV_LEFT + REG_HIDDEN },
{ NULL }
};
DEVICE rtc_dev = {
"RTC", &rtc_unit, rtc_reg, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, &rtc_reset,
NULL, NULL, NULL };
"RTC", &rtc_unit, rtc_reg, NULL,
1, 0, 0, 0, 0, 0,
NULL, NULL, &rtc_reset,
NULL, NULL, NULL
};
/* Console terminal function processors */
int32 tty_rd (int32 src, int32 ea)
{
return tti_unit.buf; /* return data */
return tti_unit.buf; /* return data */
}
t_stat tty_wr (uint32 dst, uint32 val)
{
tto_unit.buf = val & 0377; /* save char */
dev_done = dev_done & ~INT_TTO; /* clear ready */
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
tto_unit.buf = val & 0377; /* save char */
dev_done = dev_done & ~INT_TTO; /* clear ready */
sim_activate (&tto_unit, tto_unit.wait); /* activate unit */
return SCPE_OK;
}
@@ -229,15 +243,16 @@ t_stat tti_svc (UNIT *uptr)
{
int32 c;
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) tti_unit.buf = 0; /* break? */
else if (tti_unit.flags & UNIT_KSR) { /* KSR? */
c = c & 0177; /* force 7b */
if (islower (c)) c = toupper (c); /* cvt to UC */
tti_unit.buf = c | 0200; } /* add TTY bit */
sim_activate (&tti_unit, tti_unit.wait); /* continue poll */
if ((c = sim_poll_kbd ()) < SCPE_KFLAG) return c; /* no char or error? */
if (c & SCPE_BREAK) tti_unit.buf = 0; /* break? */
else if (tti_unit.flags & UNIT_KSR) { /* KSR? */
c = c & 0177; /* force 7b */
if (islower (c)) c = toupper (c); /* cvt to UC */
tti_unit.buf = c | 0200; /* add TTY bit */
}
else tti_unit.buf = c & ((tti_unit.flags & UNIT_8B)? 0377: 0177);
dev_done = dev_done | INT_TTI; /* set ready */
dev_done = dev_done | INT_TTI; /* set ready */
tti_unit.pos = tti_unit.pos + 1;
return SCPE_OK;
}
@@ -247,14 +262,16 @@ t_stat tto_svc (UNIT *uptr)
int32 c;
t_stat r;
if (tto_unit.flags & UNIT_KSR) { /* KSR? */
c = tto_unit.buf & 0177; /* force 7b */
if (islower (c)) c = toupper (c); } /* cvt to UC */
if (tto_unit.flags & UNIT_KSR) { /* KSR? */
c = tto_unit.buf & 0177; /* force 7b */
if (islower (c)) c = toupper (c); /* cvt to UC */
}
else c = tto_unit.buf & ((tto_unit.flags & UNIT_8B)? 0377: 0177);
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); } /* !stall? report */
dev_done = dev_done | INT_TTO; /* set ready */
if ((r = sim_putchar_s (c)) != SCPE_OK) { /* output; error? */
sim_activate (uptr, uptr->wait); /* try again */
return ((r == SCPE_STALL)? SCPE_OK: r); /* !stall? report */
}
dev_done = dev_done | INT_TTO; /* set ready */
tto_unit.pos = tto_unit.pos + 1;
return SCPE_OK;
}
@@ -263,17 +280,17 @@ return SCPE_OK;
t_stat tti_reset (DEVICE *dptr)
{
tti_unit.buf = 0; /* clear buffer */
dev_done = dev_done & ~INT_TTI; /* clear ready */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
tti_unit.buf = 0; /* clear buffer */
dev_done = dev_done & ~INT_TTI; /* clear ready */
sim_activate (&tti_unit, tti_unit.wait); /* activate unit */
return SCPE_OK;
}
t_stat tto_reset (DEVICE *dptr)
{
tto_unit.buf = 0; /* clear buffer */
dev_done = dev_done | INT_TTO; /* set ready */
sim_cancel (&tto_unit); /* deactivate unit */
tto_unit.buf = 0; /* clear buffer */
dev_done = dev_done | INT_TTO; /* set ready */
sim_cancel (&tto_unit); /* deactivate unit */
return SCPE_OK;
}
@@ -283,19 +300,19 @@ tti_unit.flags = (tti_unit.flags & ~(UNIT_KSR | UNIT_8B)) | val;
tto_unit.flags = (tto_unit.flags & ~(UNIT_KSR | UNIT_8B)) | val;
return SCPE_OK;
}
/* High speed paper tape function processors */
int32 hsrp_rd (int32 src, int32 ea)
{
return hsr_unit.buf; /* return data */
return hsr_unit.buf; /* return data */
}
t_stat hsrp_wr (uint32 dst, uint32 val)
{
hsp_unit.buf = val & 0377; /* save char */
dev_done = dev_done & ~INT_HSP; /* clear ready */
sim_activate (&hsp_unit, hsp_unit.wait); /* activate unit */
hsp_unit.buf = val & 0377; /* save char */
dev_done = dev_done & ~INT_HSP; /* clear ready */
sim_activate (&hsp_unit, hsp_unit.wait); /* activate unit */
return SCPE_OK;
}
@@ -318,30 +335,33 @@ t_stat hsr_svc (UNIT *uptr)
{
int32 temp;
if ((hsr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (hsr_stopioe, SCPE_UNATT);
if ((temp = getc (hsr_unit.fileref)) == EOF) { /* read char */
if (feof (hsr_unit.fileref)) { /* err or eof? */
if (hsr_stopioe) printf ("HSR end of file\n");
else return SCPE_OK; }
else perror ("HSR I/O error");
clearerr (hsr_unit.fileref);
return SCPE_IOERR; }
dev_done = dev_done | INT_HSR; /* set ready */
hsr_unit.buf = temp & 0377; /* save char */
if ((hsr_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (hsr_stopioe, SCPE_UNATT);
if ((temp = getc (hsr_unit.fileref)) == EOF) { /* read char */
if (feof (hsr_unit.fileref)) { /* err or eof? */
if (hsr_stopioe) printf ("HSR end of file\n");
else return SCPE_OK;
}
else perror ("HSR I/O error");
clearerr (hsr_unit.fileref);
return SCPE_IOERR;
}
dev_done = dev_done | INT_HSR; /* set ready */
hsr_unit.buf = temp & 0377; /* save char */
hsr_unit.pos = hsr_unit.pos + 1;
return SCPE_OK;
}
t_stat hsp_svc (UNIT *uptr)
{
dev_done = dev_done | INT_HSP; /* set ready */
if ((hsp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (hsp_stopioe, SCPE_UNATT);
if (putc (hsp_unit.buf, hsp_unit.fileref) == EOF) { /* write char */
perror ("HSP I/O error"); /* error? */
clearerr (hsp_unit.fileref);
return SCPE_IOERR; }
dev_done = dev_done | INT_HSP; /* set ready */
if ((hsp_unit.flags & UNIT_ATT) == 0) /* attached? */
return IORETURN (hsp_stopioe, SCPE_UNATT);
if (putc (hsp_unit.buf, hsp_unit.fileref) == EOF) { /* write char */
perror ("HSP I/O error"); /* error? */
clearerr (hsp_unit.fileref);
return SCPE_IOERR;
}
hsp_unit.pos = hsp_unit.pos + 1;
return SCPE_OK;
}
@@ -350,28 +370,28 @@ return SCPE_OK;
t_stat hsr_reset (DEVICE *dptr)
{
hsr_unit.buf = 0; /* clear buffer */
dev_done = dev_done & ~INT_HSR; /* clear ready */
sim_cancel (&hsr_unit); /* deactivate unit */
hsr_unit.buf = 0; /* clear buffer */
dev_done = dev_done & ~INT_HSR; /* clear ready */
sim_cancel (&hsr_unit); /* deactivate unit */
return SCPE_OK;
}
t_stat hsp_reset (DEVICE *dptr)
{
hsp_unit.buf = 0; /* clear buffer */
dev_done = dev_done | INT_HSP; /* set ready */
sim_cancel (&hsp_unit); /* deactivate unit */
hsp_unit.buf = 0; /* clear buffer */
dev_done = dev_done | INT_HSP; /* set ready */
sim_cancel (&hsp_unit); /* deactivate unit */
return SCPE_OK;
}
/* Clock function processors */
t_stat rtc_fo (int32 op)
{
if (op & RTC_OFF) sim_cancel (&rtc_unit); /* clock off? */
if ((op & RTC_ON) && !sim_is_active (&rtc_unit)) /* clock on? */
sim_activate (&rtc_unit, sim_rtc_init (rtc_unit.wait));
if (op & RTC_OV) dev_done = dev_done & ~INT_RTC; /* clr ovflo? */
if (op & RTC_OFF) sim_cancel (&rtc_unit); /* clock off? */
if ((op & RTC_ON) && !sim_is_active (&rtc_unit)) /* clock on? */
sim_activate (&rtc_unit, sim_rtc_init (rtc_unit.wait));
if (op & RTC_OV) dev_done = dev_done & ~INT_RTC; /* clr ovflo? */
return SCPE_OK;
}
@@ -383,15 +403,15 @@ return 0;
t_stat rtc_svc (UNIT *uptr)
{
M[RTC_CTR] = (M[RTC_CTR] + 1) & DMASK; /* incr counter */
if (M[RTC_CTR] == 0) dev_done = dev_done | INT_RTC; /* ovflo? set ready */
sim_activate (&rtc_unit, sim_rtc_calb (rtc_tps)); /* reactivate */
M[RTC_CTR] = (M[RTC_CTR] + 1) & DMASK; /* incr counter */
if (M[RTC_CTR] == 0) dev_done = dev_done | INT_RTC; /* ovflo? set ready */
sim_activate (&rtc_unit, sim_rtc_calb (rtc_tps)); /* reactivate */
return SCPE_OK;
}
t_stat rtc_reset (DEVICE *dptr)
{
dev_done = dev_done & ~INT_RTC; /* clear ready */
sim_cancel (&rtc_unit); /* stop clock */
dev_done = dev_done & ~INT_RTC; /* clear ready */
sim_cancel (&rtc_unit); /* stop clock */
return SCPE_OK;
}

View File

@@ -1,6 +1,6 @@
/* gri_sys.c: GRI-909 simulator interface
Copyright (c) 2001-2004, Robert M Supnik
Copyright (c) 2001-2005, Robert M Supnik
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
@@ -19,11 +19,11 @@
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the name of Robert M Supnik shall not
be used in advertising or otherwise to promote the sale, use or other dealings
Except as contained in this notice, the name of Robert M Supnik shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from Robert M Supnik.
18-Oct-02 RMS Fixed bug in symbolic decode (found by Hans Pufal)
18-Oct-02 RMS Fixed bug in symbolic decode (found by Hans Pufal)
*/
#include "gri_defs.h"
@@ -40,12 +40,12 @@ extern int32 sim_switches;
/* SCP data structures and interface routines
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
sim_name simulator name string
sim_PC pointer to saved PC register descriptor
sim_emax maximum number of words for examine/deposit
sim_devices array of pointers to simulated devices
sim_stop_messages array of pointers to stop messages
sim_load binary loader
*/
char sim_name[] = "GRI-909";
@@ -55,21 +55,23 @@ REG *sim_PC = &cpu_reg[0];
int32 sim_emax = 2;
DEVICE *sim_devices[] = {
&cpu_dev,
&tti_dev,
&tto_dev,
&hsr_dev,
&hsp_dev,
&rtc_dev,
NULL };
&cpu_dev,
&tti_dev,
&tto_dev,
&hsr_dev,
&hsp_dev,
&rtc_dev,
NULL
};
const char *sim_stop_messages[] = {
"Unknown error",
"Unimplemented unit",
"HALT instruction",
"Breakpoint",
"Invalid interrupt request" };
"Unknown error",
"Unimplemented unit",
"HALT instruction",
"Breakpoint",
"Invalid interrupt request"
};
/* Binary loader
Bootstrap loader format consists of blocks separated by zeroes. Each
@@ -85,78 +87,81 @@ uint32 org;
t_stat r;
char gbuf[CBUFSIZE];
if (*cptr != 0) { /* more input? */
cptr = get_glyph (cptr, gbuf, 0); /* get origin */
org = get_uint (gbuf, 8, AMASK, &r);
if (r != SCPE_OK) return r;
if (*cptr != 0) return SCPE_ARG; } /* no more */
else org = 0200; /* default 200 */
if (*cptr != 0) { /* more input? */
cptr = get_glyph (cptr, gbuf, 0); /* get origin */
org = get_uint (gbuf, 8, AMASK, &r);
if (r != SCPE_OK) return r;
if (*cptr != 0) return SCPE_ARG; /* no more */
}
else org = 0200; /* default 200 */
for (;;) { /* until EOF */
while ((c = getc (fileref)) == 0) ; /* skip starting 0's */
if (c == EOF) break; /* EOF? done */
for ( ; c != 0; ) { /* loop until ctl = 0 */
/* ign ctrl frame */
if ((c = getc (fileref)) == EOF) /* get high byte */
return SCPE_FMT; /* EOF is error */
if (!MEM_ADDR_OK (org)) return SCPE_NXM;
M[org] = ((c & 0377) << 8); /* store high */
if ((c = getc (fileref)) == EOF) /* get low byte */
return SCPE_FMT; /* EOF is error */
M[org] = M[org] | (c & 0377); /* store low */
org = org + 1; /* incr origin */
if ((c = getc (fileref)) == EOF) /* get ctrl frame */
return SCPE_OK; /* EOF is ok */
} /* end block for */
if (!(sim_switches & SWMASK ('C'))) return SCPE_OK;
} /* end tape for */
for (;;) { /* until EOF */
while ((c = getc (fileref)) == 0) ; /* skip starting 0's */
if (c == EOF) break; /* EOF? done */
for ( ; c != 0; ) { /* loop until ctl = 0 */
/* ign ctrl frame */
if ((c = getc (fileref)) == EOF) /* get high byte */
return SCPE_FMT; /* EOF is error */
if (!MEM_ADDR_OK (org)) return SCPE_NXM;
M[org] = ((c & 0377) << 8); /* store high */
if ((c = getc (fileref)) == EOF) /* get low byte */
return SCPE_FMT; /* EOF is error */
M[org] = M[org] | (c & 0377); /* store low */
org = org + 1; /* incr origin */
if ((c = getc (fileref)) == EOF) /* get ctrl frame */
return SCPE_OK; /* EOF is ok */
} /* end block for */
if (!(sim_switches & SWMASK ('C'))) return SCPE_OK;
} /* end tape for */
return SCPE_OK;
}
/* Symbol tables */
#define F_V_FL 16 /* class flag */
#define F_M_FL 017
#define F_V_FO 000 /* function out */
#define F_V_FOI 001 /* FO, impl reg */
#define F_V_SF 002 /* skip function */
#define F_V_SFI 003 /* SF, impl reg */
#define F_V_RR 004 /* reg reg */
#define F_V_ZR 005 /* zero reg */
#define F_V_RS 006 /* reg self */
#define F_V_JC 010 /* jump cond */
#define F_V_JU 011 /* jump uncond */
#define F_V_RM 012 /* reg mem */
#define F_V_ZM 013 /* zero mem */
#define F_V_MR 014 /* mem reg */
#define F_V_MS 015 /* mem self */
#define F_2WD 010 /* 2 words */
#define F_V_FL 16 /* class flag */
#define F_M_FL 017
#define F_V_FO 000 /* function out */
#define F_V_FOI 001 /* FO, impl reg */
#define F_V_SF 002 /* skip function */
#define F_V_SFI 003 /* SF, impl reg */
#define F_V_RR 004 /* reg reg */
#define F_V_ZR 005 /* zero reg */
#define F_V_RS 006 /* reg self */
#define F_V_JC 010 /* jump cond */
#define F_V_JU 011 /* jump uncond */
#define F_V_RM 012 /* reg mem */
#define F_V_ZM 013 /* zero mem */
#define F_V_MR 014 /* mem reg */
#define F_V_MS 015 /* mem self */
#define F_2WD 010 /* 2 words */
#define F_FO (F_V_FO << F_V_FL)
#define F_FOI (F_V_FOI << F_V_FL)
#define F_SF (F_V_SF << F_V_FL)
#define F_SFI (F_V_SFI << F_V_FL)
#define F_RR (F_V_RR << F_V_FL)
#define F_ZR (F_V_ZR << F_V_FL)
#define F_RS (F_V_RS << F_V_FL)
#define F_JC (F_V_JC << F_V_FL)
#define F_JU (F_V_JU << F_V_FL)
#define F_RM (F_V_RM << F_V_FL)
#define F_ZM (F_V_ZM << F_V_FL)
#define F_MR (F_V_MR << F_V_FL)
#define F_MS (F_V_MS << F_V_FL)
#define F_FO (F_V_FO << F_V_FL)
#define F_FOI (F_V_FOI << F_V_FL)
#define F_SF (F_V_SF << F_V_FL)
#define F_SFI (F_V_SFI << F_V_FL)
#define F_RR (F_V_RR << F_V_FL)
#define F_ZR (F_V_ZR << F_V_FL)
#define F_RS (F_V_RS << F_V_FL)
#define F_JC (F_V_JC << F_V_FL)
#define F_JU (F_V_JU << F_V_FL)
#define F_RM (F_V_RM << F_V_FL)
#define F_ZM (F_V_ZM << F_V_FL)
#define F_MR (F_V_MR << F_V_FL)
#define F_MS (F_V_MS << F_V_FL)
struct fnc_op {
uint32 inst; /* instr prot */
uint32 imask; /* instr mask */
uint32 oper; /* operator */
uint32 omask; }; /* oper mask */
uint32 inst; /* instr prot */
uint32 imask; /* instr mask */
uint32 oper; /* operator */
uint32 omask; /* oper mask */
};
static const int32 masks[] = {
0176000, 0176077, 0000077, 0176077,
0000300, 0176300, 0000300, 0177777,
0000077, 0177777, 0000377, 0176377,
0176300, 0176377 };
0176000, 0176077, 0000077, 0176077,
0000300, 0176300, 0000300, 0177777,
0000077, 0177777, 0000377, 0176377,
0176300, 0176377
};
/* Instruction mnemonics
@@ -174,17 +179,18 @@ static const int32 masks[] = {
*/
static const char *opcode[] = {
"FOM", "FOA", "FOI", "FO", /* FOx before FO */
"SFM", "SFA", "SFI", "SF", /* SFx before SF */
"ZM", "ZMD", "ZMI", "ZMID", /* ZM before RM */
"FOM", "FOA", "FOI", "FO", /* FOx before FO */
"SFM", "SFA", "SFI", "SF", /* SFx before SF */
"ZM", "ZMD", "ZMI", "ZMID", /* ZM before RM */
"MS", "MSD", "MSI", "MSID",
"RM", "RMD", "RMI", "RMID",
"MR", "MRD", "MRI", "MRID",
"JO", "JOD", "JN", "JND", /* JU before JC */
"JO", "JOD", "JN", "JND", /* JU before JC */
"JU", "JUD", "JC", "JCD",
"ZR", "ZRC", "RR", "RRC", /* ZR before RR */
"ZR", "ZRC", "RR", "RRC", /* ZR before RR */
"RS", "RSC",
NULL };
NULL
};
static const uint32 opc_val[] = {
0004000+F_FOI, 0004013+F_FOI, 0004004+F_FOI, 0004000+F_FO,
@@ -196,77 +202,84 @@ static const uint32 opc_val[] = {
0037003+F_JU, 0037103+F_JU, 0037203+F_JU, 0037303+F_JU,
0000403+F_JU, 0000503+F_JU, 0000003+F_JC, 0000103+F_JC,
0000000+F_ZR, 0000200+F_ZR, 0000000+F_RR, 0000200+F_RR,
0000000+F_RS, 0000200+F_RS };
0000000+F_RS, 0000200+F_RS
};
/* Unit mnemonics. All 64 units are decoded, most just to octal integers */
static const char *unsrc[64] = {
"0", "IR", "2", "TRP", "ISR", "MA", "MB", "SC", /* 00 - 07 */
"SWR", "AX", "AY", "AO", "14", "15", "16", "MSR", /* 10 - 17 */
"20", "21", "22", "23", "BSW", "BPK", "26", "27", /* 20 - 27 */
"GR1", "GR2", "GR3", "GR4", "GR5", "GR6", "36", "37", /* 30 - 37 */
"0", "IR", "2", "TRP", "ISR", "MA", "MB", "SC", /* 00 - 07 */
"SWR", "AX", "AY", "AO", "14", "15", "16", "MSR", /* 10 - 17 */
"20", "21", "22", "23", "BSW", "BPK", "26", "27", /* 20 - 27 */
"GR1", "GR2", "GR3", "GR4", "GR5", "GR6", "36", "37", /* 30 - 37 */
"40", "41", "42", "43", "44", "45", "46", "47",
"50", "51", "52", "53", "54", "55", "56", "57",
"60", "61", "62", "63", "64", "65", "66", "67",
"70", "71", "72", "73", "74", "RTC", "HSR", "TTI" }; /* 70 - 77 */
"70", "71", "72", "73", "74", "RTC", "HSR", "TTI" /* 70 - 77 */
};
static const char *undst[64] = {
"0", "IR", "2", "TRP", "ISR", "5", "MB", "SC", /* 00 - 07 */
"SWR", "AX", "AY", "13", "EAO", "15", "16", "MSR", /* 10 - 17 */
"20", "21", "22", "23", "BSW", "BPK", "26", "27", /* 20 - 27 */
"GR1", "GR2", "GR3", "GR4", "GR5", "GR6", "36", "37", /* 30 - 37 */
"0", "IR", "2", "TRP", "ISR", "5", "MB", "SC", /* 00 - 07 */
"SWR", "AX", "AY", "13", "EAO", "15", "16", "MSR", /* 10 - 17 */
"20", "21", "22", "23", "BSW", "BPK", "26", "27", /* 20 - 27 */
"GR1", "GR2", "GR3", "GR4", "GR5", "GR6", "36", "37", /* 30 - 37 */
"40", "41", "42", "43", "44", "45", "46", "47",
"50", "51", "52", "53", "54", "55", "56", "57",
"60", "61", "62", "63", "64", "65", "66", "67",
"70", "71", "72", "73", "74", "RTC", "HSP", "TTO" }; /* 70 - 77 */
"70", "71", "72", "73", "74", "RTC", "HSP", "TTO" /* 70 - 77 */
};
/* Operators */
/* Operators */
static const char *opname[4] = {
NULL, "P1", "L1", "R1" };
NULL, "P1", "L1", "R1"
};
/* Conditions */
static const char *cdname[8] = {
"NEVER", "ALWAYS", "ETZ", "NEZ", "LTZ", "GEZ", "LEZ", "GTZ" };
"NEVER", "ALWAYS", "ETZ", "NEZ", "LTZ", "GEZ", "LEZ", "GTZ"
};
/* Function out/sense function */
static const char *fname[] = {
"NOT", /* any SF */
"POK", "LNK", "BOV", /* SFM */
"SOV", "AOV", /* SFA */
"IRDY", "ORDY", /* any SF */
"CLL", "STL", "CML", "HLT", /* FOM */
"ICF", "ICO", /* FOI */
"ADD", "AND", "XOR", "OR", /* FOA */
"INP", "IRDY", "ORDY", "STRT", /* any FO */
NULL };
"NOT", /* any SF */
"POK", "LNK", "BOV", /* SFM */
"SOV", "AOV", /* SFA */
"IRDY", "ORDY", /* any SF */
"CLL", "STL", "CML", "HLT", /* FOM */
"ICF", "ICO", /* FOI */
"ADD", "AND", "XOR", "OR", /* FOA */
"INP", "IRDY", "ORDY", "STRT", /* any FO */
NULL
};
static const struct fnc_op fop[] = {
{ 0000002, 0000077, 001, 001 }, /* NOT */
{ 0000002, 0176077, 010, 010 }, /* POK */
{ 0000002, 0176077, 004, 004 }, /* LNK */
{ 0000002, 0176077, 002, 002 }, /* BOV */
{ 0026002, 0176077, 004, 004 }, /* SOV */
{ 0026002, 0176077, 002, 002 }, /* AOV */
{ 0000002, 0000077, 010, 010 }, /* IRDY */
{ 0000002, 0000077, 002, 002 }, /* ORDY */
{ 0004000, 0176077, 001, 003 }, /* CLL */
{ 0004000, 0176077, 002, 003 }, /* STL */
{ 0004000, 0176077, 003, 003 }, /* CML */
{ 0004000, 0176077, 004, 004 }, /* HLT */
{ 0004004, 0176077, 001, 001 }, /* ICF */
{ 0004004, 0176077, 002, 002 }, /* ICO */
{ 0004013, 0176077, 000, 014 }, /* ADD */
{ 0004013, 0176077, 004, 014 }, /* AND */
{ 0004013, 0176077, 010, 014 }, /* XOR */
{ 0004013, 0176077, 014, 014 }, /* OR */
{ 0004000, 0176000, 011, 011 }, /* INP */
{ 0004000, 0176000, 010, 010 }, /* IRDY */
{ 0004000, 0176000, 002, 002 }, /* ORDY */
{ 0004000, 0176000, 001, 001 } }; /* STRT */
{ 0000002, 0000077, 001, 001 }, /* NOT */
{ 0000002, 0176077, 010, 010 }, /* POK */
{ 0000002, 0176077, 004, 004 }, /* LNK */
{ 0000002, 0176077, 002, 002 }, /* BOV */
{ 0026002, 0176077, 004, 004 }, /* SOV */
{ 0026002, 0176077, 002, 002 }, /* AOV */
{ 0000002, 0000077, 010, 010 }, /* IRDY */
{ 0000002, 0000077, 002, 002 }, /* ORDY */
{ 0004000, 0176077, 001, 003 }, /* CLL */
{ 0004000, 0176077, 002, 003 }, /* STL */
{ 0004000, 0176077, 003, 003 }, /* CML */
{ 0004000, 0176077, 004, 004 }, /* HLT */
{ 0004004, 0176077, 001, 001 }, /* ICF */
{ 0004004, 0176077, 002, 002 }, /* ICO */
{ 0004013, 0176077, 000, 014 }, /* ADD */
{ 0004013, 0176077, 004, 014 }, /* AND */
{ 0004013, 0176077, 010, 014 }, /* XOR */
{ 0004013, 0176077, 014, 014 }, /* OR */
{ 0004000, 0176000, 011, 011 }, /* INP */
{ 0004000, 0176000, 010, 010 }, /* IRDY */
{ 0004000, 0176000, 002, 002 }, /* ORDY */
{ 0004000, 0176000, 001, 001 } /* STRT */
};
/* Print opcode field for FO, SF */
void fprint_op (FILE *of, uint32 inst, uint32 op)
@@ -274,13 +287,14 @@ void fprint_op (FILE *of, uint32 inst, uint32 op)
int32 i, nfirst;
for (i = nfirst = 0; fname[i] != NULL; i++) {
if (((inst & fop[i].imask) == fop[i].inst) &&
((op & fop[i].omask) == fop[i].oper)) {
op = op & ~fop[i].omask;
if (nfirst) fputc (' ', of);
nfirst = 1;
fprintf (of, "%s", fname[i]); }
}
if (((inst & fop[i].imask) == fop[i].inst) &&
((op & fop[i].omask) == fop[i].oper)) {
op = op & ~fop[i].omask;
if (nfirst) fputc (' ', of);
nfirst = 1;
fprintf (of, "%s", fname[i]);
}
}
if (op) fprintf (of, " %o", op);
return;
}
@@ -288,117 +302,136 @@ return;
/* Symbolic decode
Inputs:
*of = output stream
addr = current PC
*val = pointer to data
*uptr = pointer to unit
sw = switches
*of = output stream
addr = current PC
*val = pointer to data
*uptr = pointer to unit
sw = switches
Outputs:
return = status code
return = status code
*/
#define FMTASC(x) ((x) < 040)? "<%03o>": "%c", (x)
t_stat fprint_sym (FILE *of, t_addr addr, t_value *val,
UNIT *uptr, int32 sw)
UNIT *uptr, int32 sw)
{
int32 i, j;
uint32 inst, src, dst, op, bop;
inst = val[0];
if (sw & SWMASK ('A')) { /* ASCII? */
if (inst > 0377) return SCPE_ARG;
fprintf (of, FMTASC (inst & 0177));
return SCPE_OK; }
if (sw & SWMASK ('C')) { /* characters? */
fprintf (of, FMTASC ((inst >> 8) & 0177));
fprintf (of, FMTASC (inst & 0177));
return SCPE_OK; }
if (sw & SWMASK ('A')) { /* ASCII? */
if (inst > 0377) return SCPE_ARG;
fprintf (of, FMTASC (inst & 0177));
return SCPE_OK;
}
if (sw & SWMASK ('C')) { /* characters? */
fprintf (of, FMTASC ((inst >> 8) & 0177));
fprintf (of, FMTASC (inst & 0177));
return SCPE_OK;
}
if (!(sw & SWMASK ('M'))) return SCPE_ARG;
/* Instruction decode */
inst = val[0];
src = I_GETSRC (inst); /* get fields */
src = I_GETSRC (inst); /* get fields */
op = I_GETOP (inst);
dst = I_GETDST (inst);
bop = op >> 2; /* bus op */
for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */
j = (opc_val[i] >> F_V_FL) & F_M_FL; /* get class */
if ((opc_val[i] & DMASK) == (inst & masks[j])) { /* match? */
bop = op >> 2; /* bus op */
for (i = 0; opcode[i] != NULL; i++) { /* loop thru ops */
j = (opc_val[i] >> F_V_FL) & F_M_FL; /* get class */
if ((opc_val[i] & DMASK) == (inst & masks[j])) { /* match? */
switch (j) { /* case on class */
case F_V_FO: /* func out */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
fprintf (of, ",%s", undst[dst]);
break;
case F_V_FOI: /* func out impl */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
break;
case F_V_SF: /* skip func */
fprintf (of, "%s %s,", opcode[i], unsrc[src]);
fprint_op (of, inst, op);
break;
case F_V_SFI: /* skip func impl */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
break;
case F_V_RR: /* reg reg */
if (strcmp (unsrc[src], undst[dst]) == 0) {
if (bop) fprintf (of, "%s %s,%s", opcode[i + 2],
unsrc[src], opname[bop]);
else fprintf (of, "%s %s", opcode[i + 2], unsrc[src]); }
else {
if (bop) fprintf (of, "%s %s,%s,%s", opcode[i],
unsrc[src], opname[bop], undst[dst]);
else fprintf (of, "%s %s,%s", opcode[i],
unsrc[src], undst[dst]); }
break;
case F_V_ZR: /* zero reg */
if (bop) fprintf (of, "%s %s,%s", opcode[i],
opname[bop], undst[dst]);
else fprintf (of, "%s %s", opcode[i], undst[dst]);
break;
case F_V_JC: /* jump cond */
fprintf (of, "%s %s,%s,%o", opcode[i],
unsrc[src], cdname[op >> 1], val[1]);
break;
case F_V_JU: /* jump uncond */
fprintf (of, "%s %o", opcode[i], val[1]);
break;
case F_V_RM: /* reg mem */
if (bop) fprintf (of, "%s %s,%s,%o", opcode[i],
unsrc[src], opname[bop], val[1]);
else fprintf (of, "%s %s,%o", opcode[i], unsrc[src], val[1]);
break;
case F_V_ZM: /* zero mem */
if (bop) fprintf (of, "%s %s,%o", opcode[i],
opname[bop], val[1]);
else fprintf (of, "%s %o", opcode[i], val[1]);
break;
case F_V_MR: /* mem reg */
if (bop) fprintf (of, "%s %o,%s,%s", opcode[i],
val[1], opname[bop], undst[dst]);
else fprintf (of, "%s %o,%s", opcode[i], val[1], undst[dst]);
break;
case F_V_MS: /* mem self */
if (bop) fprintf (of, "%s %o,%s", opcode[i],
val[1], opname[bop]);
else fprintf (of, "%s %o", opcode[i], val[1]);
break; } /* end case */
return (j >= F_2WD)? -1: SCPE_OK; } /* end if */
} /* end for */
switch (j) { /* case on class */
case F_V_FO: /* func out */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
fprintf (of, ",%s", undst[dst]);
break;
case F_V_FOI: /* func out impl */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
break;
case F_V_SF: /* skip func */
fprintf (of, "%s %s,", opcode[i], unsrc[src]);
fprint_op (of, inst, op);
break;
case F_V_SFI: /* skip func impl */
fprintf (of, "%s ", opcode[i]);
fprint_op (of, inst, op);
break;
case F_V_RR: /* reg reg */
if (strcmp (unsrc[src], undst[dst]) == 0) {
if (bop) fprintf (of, "%s %s,%s", opcode[i + 2],
unsrc[src], opname[bop]);
else fprintf (of, "%s %s", opcode[i + 2], unsrc[src]);
}
else {
if (bop) fprintf (of, "%s %s,%s,%s", opcode[i],
unsrc[src], opname[bop], undst[dst]);
else fprintf (of, "%s %s,%s", opcode[i],
unsrc[src], undst[dst]);
}
break;
case F_V_ZR: /* zero reg */
if (bop) fprintf (of, "%s %s,%s", opcode[i],
opname[bop], undst[dst]);
else fprintf (of, "%s %s", opcode[i], undst[dst]);
break;
case F_V_JC: /* jump cond */
fprintf (of, "%s %s,%s,%o", opcode[i],
unsrc[src], cdname[op >> 1], val[1]);
break;
case F_V_JU: /* jump uncond */
fprintf (of, "%s %o", opcode[i], val[1]);
break;
case F_V_RM: /* reg mem */
if (bop) fprintf (of, "%s %s,%s,%o", opcode[i],
unsrc[src], opname[bop], val[1]);
else fprintf (of, "%s %s,%o", opcode[i], unsrc[src], val[1]);
break;
case F_V_ZM: /* zero mem */
if (bop) fprintf (of, "%s %s,%o", opcode[i],
opname[bop], val[1]);
else fprintf (of, "%s %o", opcode[i], val[1]);
break;
case F_V_MR: /* mem reg */
if (bop) fprintf (of, "%s %o,%s,%s", opcode[i],
val[1], opname[bop], undst[dst]);
else fprintf (of, "%s %o,%s", opcode[i], val[1], undst[dst]);
break;
case F_V_MS: /* mem self */
if (bop) fprintf (of, "%s %o,%s", opcode[i],
val[1], opname[bop]);
else fprintf (of, "%s %o", opcode[i], val[1]);
break;
} /* end case */
return (j >= F_2WD)? -1: SCPE_OK;
} /* end if */
} /* end for */
return SCPE_ARG;
}
/* Field parse routines
get_fnc get function field
get_ma get memory address
get_sd get source or dest
get_op get optional bus operator
get_fnc get function field
get_ma get memory address
get_sd get source or dest
get_op get optional bus operator
*/
char *get_fnc (char *cptr, t_value *val)
@@ -411,23 +444,27 @@ uint32 inst = val[0];
uint32 fncv = 0, fncm = 0;
while (*cptr) {
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
d = get_uint (gbuf, 8, 017, &r); /* octal? */
if (r == SCPE_OK) { /* ok? */
if (d & fncm) return NULL; /* already filled? */
fncv = fncv | d; /* save */
fncm = fncm | d; } /* field filled */
else { /* symbol? */
for (i = 0; fname[i] != NULL; i++) { /* search table */
if ((strcmp (gbuf, fname[i]) == 0) && /* match for inst? */
((inst & fop[i].imask) == fop[i].inst)) {
if (fop[i].oper & fncm) return NULL;/* already filled? */
fncm = fncm | fop[i].omask;
fncv = fncv | fop[i].oper;
break; } }
if (fname[i] == NULL) return NULL; } /* end else */
} /* end while */
val[0] = val[0] | (fncv << I_V_OP); /* store fnc */
cptr = get_glyph (cptr, gbuf, 0); /* get glyph */
d = get_uint (gbuf, 8, 017, &r); /* octal? */
if (r == SCPE_OK) { /* ok? */
if (d & fncm) return NULL; /* already filled? */
fncv = fncv | d; /* save */
fncm = fncm | d; /* field filled */
}
else { /* symbol? */
for (i = 0; fname[i] != NULL; i++) { /* search table */
if ((strcmp (gbuf, fname[i]) == 0) && /* match for inst? */
((inst & fop[i].imask) == fop[i].inst)) {
if (fop[i].oper & fncm) return NULL; /* already filled? */
fncm = fncm | fop[i].omask;
fncv = fncv | fop[i].oper;
break;
}
}
if (fname[i] == NULL) return NULL;
} /* end else */
} /* end while */
val[0] = val[0] | (fncv << I_V_OP); /* store fnc */
return cptr;
}
@@ -437,10 +474,10 @@ char gbuf[CBUFSIZE];
t_value d;
t_stat r;
cptr = get_glyph (cptr, gbuf, term); /* get glyph */
d = get_uint (gbuf, 8, DMASK, &r); /* [0,177777] */
cptr = get_glyph (cptr, gbuf, term); /* get glyph */
d = get_uint (gbuf, 8, DMASK, &r); /* [0,177777] */
if (r != SCPE_OK) return NULL;
val[1] = d; /* second wd */
val[1] = d; /* second wd */
return cptr;
}
@@ -450,14 +487,16 @@ char gbuf[CBUFSIZE];
int32 d;
t_stat r;
cptr = get_glyph (cptr, gbuf, term); /* get glyph */
for (d = 0; d < 64; d++) { /* symbol match? */
if ((strcmp (gbuf, unsrc[d]) == 0) ||
(strcmp (gbuf, undst[d]) == 0)) break; }
if (d >= 64) { /* no, [0,63]? */
d = get_uint (gbuf, 8, 077, &r);
if (r != SCPE_OK) return NULL; }
val[0] = val[0] | (d << (src? I_V_SRC: I_V_DST)); /* or to inst */
cptr = get_glyph (cptr, gbuf, term); /* get glyph */
for (d = 0; d < 64; d++) { /* symbol match? */
if ((strcmp (gbuf, unsrc[d]) == 0) ||
(strcmp (gbuf, undst[d]) == 0)) break;
}
if (d >= 64) { /* no, [0,63]? */
d = get_uint (gbuf, 8, 077, &r);
if (r != SCPE_OK) return NULL;
}
val[0] = val[0] | (d << (src? I_V_SRC: I_V_DST)); /* or to inst */
return cptr;
}
@@ -466,24 +505,26 @@ char *get_op (char *cptr, t_value *val, char term)
char gbuf[CBUFSIZE], *tptr;
int32 i;
tptr = get_glyph (cptr, gbuf, term); /* get glyph */
for (i = 1; i < 4; i++) { /* symbol match? */
if (strcmp (gbuf, opname[i]) == 0) {
val[0] = val[0] | (i << (I_V_OP + 2)); /* or to inst */
return tptr; } }
return cptr; /* original ptr */
tptr = get_glyph (cptr, gbuf, term); /* get glyph */
for (i = 1; i < 4; i++) { /* symbol match? */
if (strcmp (gbuf, opname[i]) == 0) {
val[0] = val[0] | (i << (I_V_OP + 2)); /* or to inst */
return tptr;
}
}
return cptr; /* original ptr */
}
/* Symbolic input
Inputs:
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
*cptr = pointer to input string
addr = current PC
*uptr = pointer to unit
*val = pointer to output values
sw = switches
Outputs:
status = error status
status = error status
*/
t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
@@ -491,92 +532,109 @@ t_stat parse_sym (char *cptr, t_addr addr, UNIT *uptr, t_value *val, int32 sw)
int32 i, j, k;
char *tptr, gbuf[CBUFSIZE];
while (isspace (*cptr)) cptr++; /* absorb spaces */
while (isspace (*cptr)) cptr++; /* absorb spaces */
if ((sw & SWMASK ('A')) || ((*cptr == '\'') && cptr++)) { /* ASCII char? */
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (t_value) cptr[0] & 0177;
return SCPE_OK; }
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (t_value) cptr[0] & 0177;
return SCPE_OK;
}
if ((sw & SWMASK ('C')) || ((*cptr == '"') && cptr++)) { /* char string? */
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (((t_value) cptr[0] & 0177) << 8) |
((t_value) cptr[1] & 0177);
return SCPE_OK; }
if (cptr[0] == 0) return SCPE_ARG; /* must have 1 char */
val[0] = (((t_value) cptr[0] & 0177) << 8) |
((t_value) cptr[1] & 0177);
return SCPE_OK;
}
/* Instruction parse */
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
cptr = get_glyph (cptr, gbuf, 0); /* get opcode */
for (i = 0; (opcode[i] != NULL) && (strcmp (opcode[i], gbuf) != 0) ; i++) ;
if (opcode[i] == NULL) return SCPE_ARG;
val[0] = opc_val[i] & DMASK; /* get value */
j = (opc_val[i] >> F_V_FL) & F_M_FL; /* get class */
val[0] = opc_val[i] & DMASK; /* get value */
j = (opc_val[i] >> F_V_FL) & F_M_FL; /* get class */
switch (j) { /* case on class */
case F_V_FO: /* func out */
tptr = strchr (cptr, ','); /* find dst */
if (!tptr) return SCPE_ARG; /* none? */
*tptr = 0; /* split fields */
cptr = get_fnc (cptr, val); /* fo # */
if (!cptr) return SCPE_ARG;
cptr = get_sd (tptr + 1, val, 0, FALSE); /* dst */
break;
case F_V_FOI: /* func out impl */
cptr = get_fnc (cptr, val); /* fo # */
break;
case F_V_SF: /* skip func */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
case F_V_SFI: /* skip func impl */
cptr = get_fnc (cptr, val); /* fo # */
break;
case F_V_RR: /* reg-reg */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_ZR: /* zero-reg */
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_RS: /* reg self */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
val[0] = val[0] | I_GETSRC (val[0]); /* duplicate */
cptr = get_op (cptr, val, 0); /* op */
break;
case F_V_JC: /* jump cond */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
cptr = get_glyph (cptr, gbuf, ','); /* cond */
for (k = 0; k < 8; k++) { /* symbol? */
if (strcmp (gbuf, cdname[k]) == 0) break; }
if (k >= 8) return SCPE_ARG;
val[0] = val[0] | (k << (I_V_OP + 1)); /* or to inst */
case F_V_JU: /* jump uncond */
cptr = get_ma (cptr, val, 0); /* addr */
break;
case F_V_RM: /* reg mem */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
case F_V_ZM: /* zero mem */
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_ma (cptr, val, 0); /* addr */
break;
case F_V_MR: /* mem reg */
cptr = get_ma (cptr, val, ','); /* addr */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_MS: /* mem self */
cptr = get_ma (cptr, val, ','); /* addr */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, 0); /* op */
break; }
if (!cptr || (*cptr != 0)) return SCPE_ARG; /* junk at end? */
switch (j) { /* case on class */
case F_V_FO: /* func out */
tptr = strchr (cptr, ','); /* find dst */
if (!tptr) return SCPE_ARG; /* none? */
*tptr = 0; /* split fields */
cptr = get_fnc (cptr, val); /* fo # */
if (!cptr) return SCPE_ARG;
cptr = get_sd (tptr + 1, val, 0, FALSE); /* dst */
break;
case F_V_FOI: /* func out impl */
cptr = get_fnc (cptr, val); /* fo # */
break;
case F_V_SF: /* skip func */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
case F_V_SFI: /* skip func impl */
cptr = get_fnc (cptr, val); /* fo # */
break;
case F_V_RR: /* reg-reg */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_ZR: /* zero-reg */
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_RS: /* reg self */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
val[0] = val[0] | I_GETSRC (val[0]); /* duplicate */
cptr = get_op (cptr, val, 0); /* op */
break;
case F_V_JC: /* jump cond */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
cptr = get_glyph (cptr, gbuf, ','); /* cond */
for (k = 0; k < 8; k++) { /* symbol? */
if (strcmp (gbuf, cdname[k]) == 0) break;
}
if (k >= 8) return SCPE_ARG;
val[0] = val[0] | (k << (I_V_OP + 1)); /* or to inst */
case F_V_JU: /* jump uncond */
cptr = get_ma (cptr, val, 0); /* addr */
break;
case F_V_RM: /* reg mem */
cptr = get_sd (cptr, val, ',', TRUE); /* src */
if (!cptr) return SCPE_ARG;
case F_V_ZM: /* zero mem */
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_ma (cptr, val, 0); /* addr */
break;
case F_V_MR: /* mem reg */
cptr = get_ma (cptr, val, ','); /* addr */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, ','); /* op */
if (!cptr) return SCPE_ARG;
cptr = get_sd (cptr, val, 0, FALSE); /* dst */
break;
case F_V_MS: /* mem self */
cptr = get_ma (cptr, val, ','); /* addr */
if (!cptr) return SCPE_ARG;
cptr = get_op (cptr, val, 0); /* op */
break;
} /* end case */
if (!cptr || (*cptr != 0)) return SCPE_ARG; /* junk at end? */
return (j >= F_2WD)? -1: SCPE_OK;
}