1. New Features 1.1 Directory and documentation - Only common files (SCP and libraries) are in the top level directory. Individual simulator files are in their individual directories. - simh_doc.txt has been split up. simh_doc.txt now documents only SCP. The individual simulators are documented in separate text files in their own directories. - mingw_build.bat is a batch file for the MINGW/gcc environment that will build all the simulators, assuming the root directory structure is at c:\sim. - Makefile is a UNIX make file for the gcc environment that will build all the simulators, assuming the root directory is at c:\sim. 1.2 SCP - DO <file name> executes the SCP commands in the specified file. - Replicated registers in unit structures can now be declared as arrays for examine, modify, save, and restore. Most replicated unit registers (for example, mag tape position registers) have been changed to arrays. - The ADD/REMOVE commands have been replaced by SET unit ONLINE and SET unit OFFLINE, respectively. - Register names that are unique within an entire simulator do not have to be prefaced with the device name. - The ATTACH command can attach files read only, either under user option (-r), or because the attached file is ready only. - The SET/SHOW capabilities have been extended. New forms include: SET <dev> param{=value}{ param ...} SET <unit> param{=value}{ param ...} SHOW <dev> {param param ...} SHOW <unit> {param param ...} - Multiple breakpoints have been implemented. Breakpoints are set/cleared/displayed by: BREAK addr_list{[count]} NOBREAK addr_list SHOW BREAK addr_list 1.3 PDP-11 simulator - Unibus map implemented, with 22b RP controller (URH70) or 18b RP controller (URH11) (in debug). - All DMA peripherals rewritten to use map. - Many peripherals modified for source sharing with VAX. - RQDX3 implemented. - Bugs fixed in RK11 and RL11 write check. 1.4 PDP-10 simulator - ITS 1-proceed implemented. - Bugs fixed in ITS PC sampling and LPMR 1.5 18b PDP simulator - Interrupts split out to multiple levels to allow easier expansion. 1.5 IBM System 3 Simulator - Written by Charles (Dutch) Owen. 1.6 VAX Simulator (in debug) - Simulates MicroVAX 3800 (KA655) with 16MB-64MB memory, RQDX3, RLV12, TSV11, DZV11, LPV11, PCV11. - CDROM capability has been added to the RQDX3, to allow testing with VMS hobbyist images. 1.7 SDS 940 Simulator (not tested) - Simulates SDS 940, 16K-64K memory, fixed and moving head disk, magtape, line printer, console. 1.8 Altair Z80 - Revised from Charles (Dutch) Owen's original by Peter Schorn. - MITS 8080 with full Z80 simulation. - 4K and 8K BASIC packages, Prolog package. 1.9 Interdata The I4 simulator has been withdrawn for major rework. Look for a complete 16b/32b Interdata simulator sometime next year. 2. Release Notes 2.1 SCP SCP now allows replicated registers in unit structures to be modelled as arrays. All replicated register declarations have been replaced by register array declarations. As a result, save files from prior revisions will generate errors after restoring main memory. 2.2 PDP-11 The Unibus map code is in debug. The map was implemented primarily to allow source sharing with the VAX, which requires a DMA map. DMA devices work correctly with the Unibus map disabled. The RQDX3 simulator has run a complete RSTS/E SYSGEN, with multiple drives, and booted the completed system from scratch. 2.3 VAX The VAX simulator will run the boot code up to the >>> prompt. It can successfully process a SHOW DEVICE command. It runs the HCORE instruction diagnostic. It can boot the hobbyist CD through SYSBOOT and through the date/time dialog and restore the hobbyist CD, using standalone backup. On the boot of the restored disk, it gets to the date/time dialog, and then crashes. 2.4 SDS 940 The SDS 940 is untested, awaiting real code. 2.5 GCC Optimization At -O2 and above, GCC does not correctly compile the simulators which use setjmp-longjmp (PDP-11, PDP-10, VAX). A working hypothesis is that optimized state maintained in registers is being used in the setjmp processing routine. On the PDP-11 and PDP-10, all of this state has been either made global, or volatile, to encourage GCC to keep the state up to date in memory. The VAX is still vulnerable. 3. Work list 3.1 SCP - Better ENABLE/DISABLE. 3.2 PDP-11 RQDX3 Software mapped mode, RCT read simulation, VMS debug.
363 lines
14 KiB
C
363 lines
14 KiB
C
/* sim_defs.h: simulator definitions
|
||
|
||
Copyright (c) 1993-2001, 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"),
|
||
to deal in the Software without restriction, including without limitation
|
||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||
and/or sell copies of the Software, and to permit persons to whom the
|
||
Software is furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||
ROBERT M SUPNIK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||
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
|
||
in this Software without prior written authorization from Robert M Supnik.
|
||
|
||
07-Dec-01 RMS Added breakpoint package
|
||
01-Dec-01 RMS Added read-only unit support, extended SET/SHOW features,
|
||
improved error messages
|
||
24-Nov-01 RMS Added unit-based registers
|
||
27-Sep-01 RMS Added queue count prototype
|
||
17-Sep-01 RMS Removed multiple console support
|
||
07-Sep-01 RMS Removed conditional externs on function prototypes
|
||
31-Aug-01 RMS Changed int64 to t_int64 for Windoze
|
||
17-Jul-01 RMS Added additional function prototypes
|
||
27-May-01 RMS Added multiple console support
|
||
15-May-01 RMS Increased string buffer size
|
||
25-Feb-01 RMS Revisions for V2.6
|
||
15-Oct-00 RMS Editorial revisions for V2.5
|
||
11-Jul-99 RMS Added unsigned int data types
|
||
14-Apr-99 RMS Converted t_addr to unsigned
|
||
04-Oct-98 RMS Additional definitions for V2.4
|
||
|
||
The interface between the simulator control package (SCP) and the
|
||
simulator consists of the following routines and data structures
|
||
|
||
sim_name simulator name string
|
||
sim_devices[] array of pointers to simulated devices
|
||
sim_PC pointer to saved PC register descriptor
|
||
sim_interval simulator interval to next event
|
||
sim_stop_messages[] array of pointers to stop messages
|
||
sim_instr() instruction execution routine
|
||
sim_load() binary loader routine
|
||
sim_emax maximum number of words in an instruction
|
||
|
||
In addition, the simulator must supply routines to print and parse
|
||
architecture specific formats
|
||
|
||
print_sym print symbolic output
|
||
parse_sym parse symbolic input
|
||
*/
|
||
|
||
#include <stddef.h>
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <errno.h>
|
||
#include <limits.h>
|
||
|
||
#ifndef TRUE
|
||
#define TRUE 1
|
||
#define FALSE 0
|
||
#endif
|
||
|
||
/* Length specific integer declarations */
|
||
|
||
#define int8 char
|
||
#define int16 short
|
||
#define int32 int
|
||
typedef int t_stat; /* status */
|
||
typedef int t_bool; /* boolean */
|
||
typedef unsigned int8 uint8;
|
||
typedef unsigned int16 uint16;
|
||
typedef unsigned int32 uint32, t_addr; /* address */
|
||
#if defined (USE_INT64) && defined (_WIN32)
|
||
#define t_int64 __int64 /* for Windows */
|
||
#elif defined (USE_INT64) && defined (VMS) && defined (__ALPHA)
|
||
#define t_int64 __int64 /* for AVMS */
|
||
#elif defined (USE_INT64) && defined (__ALPHA) && defined (__unix__)
|
||
#define t_int64 long /* for DUNIX */
|
||
#elif defined (USE_INT64)
|
||
#define t_int64 long long /* for GCC */
|
||
#endif
|
||
#if defined (t_int64)
|
||
typedef unsigned t_int64 t_uint64, t_value; /* value */
|
||
typedef t_int64 t_svalue; /* signed value */
|
||
#else
|
||
typedef unsigned int32 t_value;
|
||
typedef int32 t_svalue;
|
||
#endif
|
||
|
||
/* System independent definitions */
|
||
|
||
typedef int32 t_mtrlnt; /* magtape rec lnt */
|
||
#define MTRF(x) ((x) & (1u << 31)) /* record error flg */
|
||
#define MTRL(x) ((x) & ((1u << 31) - 1)) /* record length */
|
||
#define FLIP_SIZE (1 << 16) /* flip buf size */
|
||
#if !defined (PATH_MAX) /* usually in limits */
|
||
#define PATH_MAX 512
|
||
#endif
|
||
#define CBUFSIZE (128 + PATH_MAX) /* string buf size */
|
||
#define CONS_SIZE 4096 /* console buffer */
|
||
|
||
/* Simulator status codes
|
||
|
||
0 ok
|
||
1 - (SCPE_BASE - 1) simulator specific
|
||
SCPE_BASE - n general
|
||
*/
|
||
|
||
#define SCPE_OK 0 /* normal return */
|
||
#define SCPE_BASE 32 /* base for messages */
|
||
#define SCPE_NXM (SCPE_BASE + 0) /* nxm */
|
||
#define SCPE_UNATT (SCPE_BASE + 1) /* no file */
|
||
#define SCPE_IOERR (SCPE_BASE + 2) /* I/O error */
|
||
#define SCPE_CSUM (SCPE_BASE + 3) /* loader cksum */
|
||
#define SCPE_FMT (SCPE_BASE + 4) /* loader format */
|
||
#define SCPE_NOATT (SCPE_BASE + 5) /* not attachable */
|
||
#define SCPE_OPENERR (SCPE_BASE + 6) /* open error */
|
||
#define SCPE_MEM (SCPE_BASE + 7) /* alloc error */
|
||
#define SCPE_ARG (SCPE_BASE + 8) /* argument error */
|
||
#define SCPE_STEP (SCPE_BASE + 9) /* step expired */
|
||
#define SCPE_UNK (SCPE_BASE + 10) /* unknown command */
|
||
#define SCPE_RO (SCPE_BASE + 11) /* read only */
|
||
#define SCPE_INCOMP (SCPE_BASE + 12) /* incomplete */
|
||
#define SCPE_STOP (SCPE_BASE + 13) /* sim stopped */
|
||
#define SCPE_EXIT (SCPE_BASE + 14) /* sim exit */
|
||
#define SCPE_TTIERR (SCPE_BASE + 15) /* console tti err */
|
||
#define SCPE_TTOERR (SCPE_BASE + 16) /* console tto err */
|
||
#define SCPE_EOF (SCPE_BASE + 17) /* end of file */
|
||
#define SCPE_REL (SCPE_BASE + 18) /* relocation error */
|
||
#define SCPE_NOPARAM (SCPE_BASE + 19) /* no parameters */
|
||
#define SCPE_ALATT (SCPE_BASE + 20) /* already attached */
|
||
#define SCPE_TIMER (SCPE_BASE + 21) /* hwre timer err */
|
||
#define SCPE_SIGERR (SCPE_BASE + 22) /* signal err */
|
||
#define SCPE_TTYERR (SCPE_BASE + 23) /* tty setup err */
|
||
#define SCPE_SUB (SCPE_BASE + 24) /* subscript err */
|
||
#define SCPE_NOFNC (SCPE_BASE + 25) /* func not imp */
|
||
#define SCPE_UDIS (SCPE_BASE + 26) /* unit disabled */
|
||
#define SCPE_LOGON (SCPE_BASE + 27) /* logging enabled */
|
||
#define SCPE_LOGOFF (SCPE_BASE + 28) /* logging disabled */
|
||
#define SCPE_NORO (SCPE_BASE + 29) /* rd only not ok */
|
||
#define SCPE_INVSW (SCPE_BASE + 30) /* invalid switch */
|
||
#define SCPE_MISVAL (SCPE_BASE + 31) /* missing value */
|
||
#define SCPE_2FARG (SCPE_BASE + 32) /* too few arguments */
|
||
#define SCPE_2MARG (SCPE_BASE + 33) /* too many arguments */
|
||
#define SCPE_NXDEV (SCPE_BASE + 34) /* nx device */
|
||
#define SCPE_NXUN (SCPE_BASE + 35) /* nx unit */
|
||
#define SCPE_NXREG (SCPE_BASE + 36) /* nx register */
|
||
#define SCPE_NXPAR (SCPE_BASE + 37) /* nx parameter */
|
||
#define SCPE_NEST (SCPE_BASE + 40) /* nested DO */
|
||
#define SCPE_IERR (SCPE_BASE + 41) /* internal error */
|
||
#define SCPE_KFLAG 01000 /* tti data flag */
|
||
|
||
/* Print value format codes */
|
||
|
||
#define PV_RZRO 0 /* right, zero fill */
|
||
#define PV_RSPC 1 /* right, space fill */
|
||
#define PV_LEFT 2 /* left justify */
|
||
|
||
/* Default timing parameters */
|
||
|
||
#define KBD_POLL_WAIT 5000 /* keyboard poll */
|
||
#define SERIAL_IN_WAIT 100 /* serial in time */
|
||
#define SERIAL_OUT_WAIT 10 /* serial output */
|
||
#define NOQUEUE_WAIT 10000 /* min check time */
|
||
|
||
/* Convert switch letter to bit mask */
|
||
|
||
#define SWMASK(x) (1u << (((int) (x)) - ((int) 'A')))
|
||
|
||
/* String match */
|
||
|
||
#define MATCH_CMD(ptr,cmd) strncmp ((ptr), (cmd), strlen (ptr))
|
||
|
||
/* Device data structure */
|
||
|
||
struct device {
|
||
char *name; /* name */
|
||
struct unit *units; /* units */
|
||
struct reg *registers; /* registers */
|
||
struct mtab *modifiers; /* modifiers */
|
||
int32 numunits; /* #units */
|
||
int32 aradix; /* address radix */
|
||
int32 awidth; /* address width */
|
||
int32 aincr; /* addr increment */
|
||
int32 dradix; /* data radix */
|
||
int32 dwidth; /* data width */
|
||
t_stat (*examine)(); /* examine routine */
|
||
t_stat (*deposit)(); /* deposit routine */
|
||
t_stat (*reset)(); /* reset routine */
|
||
t_stat (*boot)(); /* boot routine */
|
||
t_stat (*attach)(); /* attach routine */
|
||
t_stat (*detach)(); /* detach routine */
|
||
};
|
||
|
||
/* Unit data structure
|
||
|
||
Parts of the unit structure are device specific, that is, they are
|
||
not referenced by the simulator control package and can be freely
|
||
used by device simulators. Fields starting with 'buf', and flags
|
||
starting with 'UF', are device specific. The definitions given here
|
||
are for a typical sequential device.
|
||
*/
|
||
|
||
struct unit {
|
||
struct unit *next; /* next active */
|
||
t_stat (*action)(); /* action routine */
|
||
char *filename; /* open file name */
|
||
FILE *fileref; /* file reference */
|
||
void *filebuf; /* memory buffer */
|
||
t_addr hwmark; /* high water mark */
|
||
int32 time; /* time out */
|
||
int32 flags; /* flags */
|
||
t_addr capac; /* capacity */
|
||
t_addr pos; /* file position */
|
||
int32 buf; /* buffer */
|
||
int32 wait; /* wait */
|
||
int32 u3; /* device specific */
|
||
int32 u4; /* device specific */
|
||
};
|
||
|
||
/* Unit flags */
|
||
|
||
#define UNIT_ATTABLE 000001 /* attachable */
|
||
#define UNIT_RO 000002 /* read only */
|
||
#define UNIT_FIX 000004 /* fixed capacity */
|
||
#define UNIT_SEQ 000010 /* sequential */
|
||
#define UNIT_ATT 000020 /* attached */
|
||
#define UNIT_BINK 000040 /* K = power of 2 */
|
||
#define UNIT_BUFABLE 000100 /* bufferable */
|
||
#define UNIT_MUSTBUF 000200 /* must buffer */
|
||
#define UNIT_BUF 000400 /* buffered */
|
||
#define UNIT_ROABLE 001000 /* read only ok */
|
||
#define UNIT_DISABLE 002000 /* disable-able */
|
||
#define UNIT_DIS 004000 /* disabled */
|
||
#define UNIT_V_UF 12 /* device specific */
|
||
/* must be DIS+1!! */
|
||
#define UNIT_V_RSV 31 /* reserved!! */
|
||
|
||
/* Register data structure */
|
||
|
||
struct reg {
|
||
char *name; /* name */
|
||
void *loc; /* location */
|
||
int32 radix; /* radix */
|
||
int32 width; /* width */
|
||
int32 offset; /* starting bit */
|
||
int32 depth; /* save depth */
|
||
int32 flags; /* flags */
|
||
};
|
||
|
||
#define REG_FMT 003 /* see PV_x */
|
||
#define REG_RO 004 /* read only */
|
||
#define REG_HIDDEN 010 /* hidden */
|
||
#define REG_NZ 020 /* must be non-zero */
|
||
#define REG_UNIT 040 /* in unit struct */
|
||
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
|
||
|
||
/* Command table */
|
||
|
||
struct ctab {
|
||
char *name; /* name */
|
||
t_stat (*action)(); /* action routine */
|
||
int32 arg; /* argument */
|
||
};
|
||
|
||
/* Modifier table - only extended entries have disp, reg, or flags */
|
||
|
||
struct mtab {
|
||
int32 mask; /* mask or radix */
|
||
int32 match; /* match or max */
|
||
char *pstring; /* print string */
|
||
char *mstring; /* match string */
|
||
t_stat (*valid)(); /* validation routine */
|
||
t_stat (*disp)(); /* display routine */
|
||
void *desc; /* value descriptor */
|
||
/* REG * if MTAB_VAL */
|
||
/* int * if not */
|
||
};
|
||
|
||
#define MTAB_XTD (1u << UNIT_V_RSV) /* ext entry flag */
|
||
#define MTAB_VDV 001 /* valid for dev */
|
||
#define MTAB_VUN 002 /* valid for unit */
|
||
#define MTAB_VAL 004 /* takes a value */
|
||
#define MTAB_NMO 010 /* only if named */
|
||
#define MTAB_XTV (MTAB_XTD | MTAB_XTD) /* ext with value */
|
||
|
||
/* Search table */
|
||
|
||
struct schtab {
|
||
int logic; /* logical operator */
|
||
int bool; /* boolean operator */
|
||
t_value mask; /* mask for logical */
|
||
t_value comp; /* comparison for boolean */
|
||
};
|
||
|
||
/* The following macros define structure contents */
|
||
|
||
#define UDATA(act,fl,cap) NULL,act,NULL,NULL,NULL,0,0,(fl),(cap),0,0
|
||
|
||
#if defined (__STDC__) || defined (_WIN32)
|
||
#define ORDATA(nm,loc,wd) #nm, &(loc), 8, (wd), 0, 1
|
||
#define DRDATA(nm,loc,wd) #nm, &(loc), 10, (wd), 0, 1
|
||
#define HRDATA(nm,loc,wd) #nm, &(loc), 16, (wd), 0, 1
|
||
#define FLDATA(nm,loc,pos) #nm, &(loc), 2, 1, (pos), 1
|
||
#define GRDATA(nm,loc,rdx,wd,pos) #nm, &(loc), (rdx), (wd), (pos), 1
|
||
#define BRDATA(nm,loc,rdx,wd,dep) #nm, (loc), (rdx), (wd), 0, (dep)
|
||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||
#nm, &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||
#else
|
||
#define ORDATA(nm,loc,wd) "nm", &(loc), 8, (wd), 0, 1
|
||
#define DRDATA(nm,loc,wd) "nm", &(loc), 10, (wd), 0, 1
|
||
#define HRDATA(nm,loc,wd) "nm", &(loc), 16, (wd), 0, 1
|
||
#define FLDATA(nm,loc,pos) "nm", &(loc), 2, 1, (pos), 1
|
||
#define GRDATA(nm,loc,rdx,wd,pos) "nm", &(loc), (rdx), (wd), (pos), 1
|
||
#define BRDATA(nm,loc,rdx,wd,dep) "nm", (loc), (rdx), (wd), 0, (dep)
|
||
#define URDATA(nm,loc,rdx,wd,off,dep,fl) \
|
||
"nm", &(loc), (rdx), (wd), (off), (dep), ((fl) | REG_UNIT)
|
||
#endif
|
||
|
||
/* Typedefs for principal structures */
|
||
|
||
typedef struct device DEVICE;
|
||
typedef struct unit UNIT;
|
||
typedef struct reg REG;
|
||
typedef struct ctab CTAB;
|
||
typedef struct mtab MTAB;
|
||
typedef struct schtab SCHTAB;
|
||
|
||
/* Function prototypes */
|
||
|
||
t_stat sim_process_event (void);
|
||
t_stat sim_activate (UNIT *uptr, int32 interval);
|
||
t_stat sim_cancel (UNIT *uptr);
|
||
int32 sim_is_active (UNIT *uptr);
|
||
double sim_gtime (void);
|
||
uint32 sim_grtime (void);
|
||
int32 sim_qcount (void);
|
||
t_stat attach_unit (UNIT *uptr, char *cptr);
|
||
t_stat detach_unit (UNIT *uptr);
|
||
t_stat reset_all (int start_device);
|
||
size_t fxread (void *bptr, size_t size, size_t count, FILE *fptr);
|
||
size_t fxwrite (void *bptr, size_t size, size_t count, FILE *fptr);
|
||
t_stat get_yn (char *ques, t_stat deflt);
|
||
char *get_glyph (char *iptr, char *optr, char mchar);
|
||
char *get_glyph_nc (char *iptr, char *optr, char mchar);
|
||
t_value get_uint (char *cptr, int radix, t_value max, t_stat *status);
|
||
t_value strtotv (char *cptr, char **endptr, int radix);
|
||
int32 sim_rtc_init (int32 time);
|
||
int32 sim_rtc_calb (int32 ticksper);
|
||
t_stat sim_poll_kbd (void);
|
||
t_stat sim_putchar (int32 out);
|
||
t_bool sim_brk_test (t_addr bloc, int32 btyp);
|