1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-11 23:52:48 +00:00

SCP: Updated to current.

This commit is contained in:
Richard Cornwell 2019-05-05 18:33:04 -04:00
parent d137282519
commit 02a043a3fa
8 changed files with 2038 additions and 110 deletions

2
.gitattributes vendored
View File

@ -8,5 +8,7 @@
*.imd binary
*.rim binary
*.tap binary
*.dsk binary
*.vhd binary
sim_rev.h export-subst

View File

@ -75,6 +75,7 @@ static const char *window_name;
static uint32 *colors = NULL;
static uint32 ncolors = 0, size_colors = 0;
static uint32 *surface = NULL;
static uint32 ws_palette[2]; /* Monochrome palette */
typedef struct cursor {
Uint8 *data;
Uint8 *mask;
@ -394,11 +395,13 @@ ws_init(const char *name, int xp, int yp, int colors, void *dptr)
ypixels = yp;
window_name = name;
surface = (uint32 *)realloc (surface, xpixels*ypixels*sizeof(*surface));
for (i=0; i<xpixels*ypixels; i++)
surface[i] = vid_mono_palette[0];
ret = (0 == vid_open ((DEVICE *)dptr, name, xp*pix_size, yp*pix_size, 0));
if (ret)
vid_set_cursor (1, arrow_cursor->width, arrow_cursor->height, arrow_cursor->data, arrow_cursor->mask, arrow_cursor->hot_x, arrow_cursor->hot_y);
ws_palette[0] = vid_map_rgb (0x00, 0x00, 0x00); /* black */
ws_palette[1] = vid_map_rgb (0xFF, 0xFF, 0xFF); /* white */
for (i=0; i<xpixels*ypixels; i++)
surface[i] = ws_palette[0];
return ret;
}
@ -415,7 +418,7 @@ ws_color_rgb(int r, int g, int b)
{
uint32 color, i;
color = sim_end ? (0xFF000000 | ((r & 0xFF00) << 8) | (g & 0xFF00) | ((b & 0xFF00) >> 8)) : (0x000000FF | (r & 0xFF00) | ((g & 0xFF00) << 8) | ((b & 0xFF00) << 16));
color = vid_map_rgb ((r >> 8) & 0xFF, (g >> 8) & 0xFF, (b >> 8) & 0xFF);
for (i=0; i<ncolors; i++) {
if (colors[i] == color)
return &colors[i];
@ -424,8 +427,8 @@ ws_color_rgb(int r, int g, int b)
colors = (uint32 *)realloc (colors, (ncolors + 1000) * sizeof (*colors));
size_colors += 1000;
if (size_colors == 1000) {
colors[0] = vid_mono_palette[0];
colors[1] = vid_mono_palette[1];
colors[0] = ws_palette[0];
colors[1] = ws_palette[1];
ncolors = 2;
}
}
@ -437,13 +440,13 @@ ws_color_rgb(int r, int g, int b)
void *
ws_color_black(void)
{
return (void *)&vid_mono_palette[0];
return (void *)&ws_palette[0];
}
void *
ws_color_white(void)
{
return (void *)&vid_mono_palette[1];
return (void *)&ws_palette[1];
}
void

225
scp.c
View File

@ -600,6 +600,7 @@ static double sim_time;
static uint32 sim_rtime;
static int32 noqueue_time;
volatile t_bool stop_cpu = FALSE;
volatile t_bool sigterm_received = FALSE;
static unsigned int sim_stop_sleep_ms = 250;
static char **sim_argv;
static int sim_exit_status = EXIT_SUCCESS; /* optionally set by EXIT command */
@ -757,6 +758,7 @@ const struct scp_error {
{"AMBREG", "Ambiguous register name"},
{"REMOTE", "remote console command"},
{"INVEXPR", "invalid expression"},
{"SIGTERM", "SIGTERM received"},
};
const size_t size_map[] = { sizeof (int8),
@ -1811,7 +1813,7 @@ static const char simh_help[] =
"++NOPARAM, ALATT, TIMER, SIGERR, TTYERR, SUB, NOFNC, UDIS,\n"
"++NORO, INVSW, MISVAL, 2FARG, 2MARG, NXDEV, NXUN, NXREG,\n"
"++NXPAR, NEST, IERR, MTRLNT, LOST, TTMO, STALL, AFAIL,\n"
"++AMBREG\n\n"
"++AMBREG, SIGTERM\n\n"
" These values can be indicated by name or by their internal\n"
" numeric value (not recommended).\n"
/***************** 80 character line width template *************************/
@ -1831,6 +1833,15 @@ static const char simh_help[] =
"+ON CONTROL_C trap handler.\n"
" Note 2: The ON CONTROL_C trapping is not affected by the SET ON and\n"
"+SET NOON commands.\n"
"3SIGTERM Trapping\n"
" A special ON trap is available to describe action(s) to be taken\n"
" when a SIGTERM (or a Windows Shutdown) signal is delivered during\n"
" simulator instruction execution. After a SIGTERM has been delivered\n"
" to a simulator process, instruction execution will stop and control\n"
" will return to either the invoking do command procedure with a SIGTERM\n"
" status (and thus take SIGTERM ON condition) or if execution was\n"
" explicitly started from a sim> prompt, the program will exit\n"
#define HLP_PROCEED "*Commands Executing_Command_Files PROCEED"
#define HLP_IGNORE "*Commands Executing_Command_Files PROCEED"
/***************** 80 character line width template *************************/
@ -2667,7 +2678,8 @@ stat = SCPE_BARE_STATUS(stat); /* remove possible flag
while (stat != SCPE_EXIT) { /* in case exit */
if (stop_cpu) { /* SIGINT happened? */
stop_cpu = FALSE;
if (!sim_ttisatty()) {
if ((!sim_ttisatty()) ||
sigterm_received) {
stat = SCPE_EXIT;
break;
}
@ -2825,6 +2837,11 @@ for (cmdp = cmd_table; cmdp && (cmdp->name != NULL); cmdp++) {
max_cmdname_size = strlen(cmdp->name);
}
}
fprintf (st, "Help is available for devices\n\n");
fprintf (st, " HELP dev\n");
fprintf (st, " HELP dev SET\n");
fprintf (st, " HELP dev SHOW\n");
fprintf (st, " HELP dev REGISTERS\n\n");
fprintf (st, "Help is available for the following commands:\n\n ");
qsort (hlp_cmdp, cmd_cnt, sizeof(*hlp_cmdp), _cmd_name_compare);
line_offset = 4;
@ -3224,121 +3241,120 @@ t_stat help_cmd (int32 flag, CONST char *cptr)
{
char gbuf[CBUFSIZE], gbuf2[CBUFSIZE];
CTAB *cmdp;
DEVICE *dptr;
UNIT *uptr;
t_stat r;
t_bool explicit_device = FALSE;
GET_SWITCHES (cptr); /* get switches */
if (sim_switches & SWMASK ('F'))
flag = flag | SCP_HELP_FLAT;
if (*cptr) {
cptr = get_glyph (cptr, gbuf, 0);
if ((cmdp = find_cmd (gbuf))) {
if (*cptr) {
if ((cmdp->action == &set_cmd) || (cmdp->action == &show_cmd)) {
DEVICE *dptr;
UNIT *uptr;
t_stat r;
cptr = get_glyph (cptr, gbuf, 0);
dptr = find_unit (gbuf, &uptr);
if (dptr == NULL)
dptr = find_dev (gbuf);
if (dptr != NULL) {
r = help_dev_help (stdout, dptr, uptr, flag, (cmdp->action == &set_cmd) ? "SET" : "SHOW");
if (sim_log)
help_dev_help (sim_log, dptr, uptr, flag | SCP_HELP_FLAT, (cmdp->action == &set_cmd) ? "SET" : "SHOW");
return r;
}
if (cmdp->action == &set_cmd) { /* HELP SET xxx (not device or unit) */
if ((cmdp = find_ctab (set_glob_tab, gbuf)) &&
(cmdp->help))
return help_cmd_output (flag, cmdp->help, cmdp->help_base);
}
else { /* HELP SHOW xxx (not device or unit) */
SHTAB *shptr = find_shtab (show_glob_tab, gbuf);
if (0 == strcmp (gbuf, "DEVICE")) {
explicit_device = TRUE;
cptr = get_glyph (cptr, gbuf, 0);
}
dptr = find_unit (gbuf, &uptr);
if ((dptr == NULL) &&
((dptr = find_dev (gbuf)) == NULL)) {
if (explicit_device)
return sim_messagef (SCPE_ARG, "No such device %s\n", gbuf);
if ((cmdp = find_cmd (gbuf))) {
if (*cptr) {
if ((cmdp->action == &set_cmd) || (cmdp->action == &show_cmd)) {
DEVICE *dptr;
UNIT *uptr;
t_stat r;
if ((shptr == NULL) || (shptr->help == NULL) || (*shptr->help == '\0'))
return SCPE_ARG;
return help_cmd_output (flag, shptr->help, NULL);
cptr = get_glyph (cptr, gbuf, 0);
dptr = find_unit (gbuf, &uptr);
if (dptr == NULL)
dptr = find_dev (gbuf);
if (dptr != NULL) {
r = help_dev_help (stdout, dptr, uptr, flag, (cmdp->action == &set_cmd) ? "SET" : "SHOW");
if (sim_log)
help_dev_help (sim_log, dptr, uptr, flag | SCP_HELP_FLAT, (cmdp->action == &set_cmd) ? "SET" : "SHOW");
return r;
}
if (cmdp->action == &set_cmd) { /* HELP SET xxx (not device or unit) */
if ((cmdp = find_ctab (set_glob_tab, gbuf)) &&
(cmdp->help))
return help_cmd_output (flag, cmdp->help, cmdp->help_base);
}
else { /* HELP SHOW xxx (not device or unit) */
SHTAB *shptr = find_shtab (show_glob_tab, gbuf);
if ((shptr == NULL) || (shptr->help == NULL) || (*shptr->help == '\0'))
return SCPE_ARG;
return help_cmd_output (flag, shptr->help, NULL);
}
return SCPE_ARG;
}
return SCPE_ARG;
}
}
if (cmdp->help) {
if (strcmp (cmdp->name, "HELP") == 0) {
DEVICE *dptr;
int i;
if (cmdp->help) {
if (strcmp (cmdp->name, "HELP") == 0) {
DEVICE *dptr;
int i;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
if (dptr->help)
sim_printf ("h{elp} %-17s display help for device %s\n", dptr->name, dptr->name);
if (dptr->attach_help ||
(DEV_TYPE(dptr) == DEV_MUX) ||
(DEV_TYPE(dptr) == DEV_DISK) ||
(DEV_TYPE(dptr) == DEV_TAPE)) {
sim_printf ("h{elp} %s ATTACH\t display help for device %s ATTACH command\n", dptr->name, dptr->name);
}
if (dptr->registers) {
if (dptr->registers->name != NULL)
sim_printf ("h{elp} %s REGISTERS\t display help for device %s register variables\n", dptr->name, dptr->name);
}
if (dptr->modifiers) {
MTAB *mptr;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
if (dptr->help)
sim_printf ("h{elp} %-17s display help for device %s\n", dptr->name, dptr->name);
if (dptr->attach_help ||
(DEV_TYPE(dptr) == DEV_MUX) ||
(DEV_TYPE(dptr) == DEV_DISK) ||
(DEV_TYPE(dptr) == DEV_TAPE)) {
sim_printf ("h{elp} %s ATTACH\t display help for device %s ATTACH command\n", dptr->name, dptr->name);
}
if (dptr->registers) {
if (dptr->registers->name != NULL)
sim_printf ("h{elp} %s REGISTERS\t display help for device %s register variables\n", dptr->name, dptr->name);
}
if (dptr->modifiers) {
MTAB *mptr;
for (mptr = dptr->modifiers; mptr->pstring != NULL; mptr++) {
if (mptr->help) {
sim_printf ("h{elp} %s SET\t\t display help for device %s SET commands (modifiers)\n", dptr->name, dptr->name);
break;
for (mptr = dptr->modifiers; mptr->pstring != NULL; mptr++) {
if (mptr->help) {
sim_printf ("h{elp} %s SET\t\t display help for device %s SET commands (modifiers)\n", dptr->name, dptr->name);
break;
}
}
}
}
}
}
else {
if (((cmdp->action == &exdep_cmd) || (0 == strcmp(cmdp->name, "BOOT"))) &&
sim_dflt_dev->help) {
sim_dflt_dev->help (stdout, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name);
if (sim_log)
sim_dflt_dev->help (sim_log, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name);
else {
if (((cmdp->action == &exdep_cmd) || (0 == strcmp(cmdp->name, "BOOT"))) &&
sim_dflt_dev->help) {
sim_dflt_dev->help (stdout, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name);
if (sim_log)
sim_dflt_dev->help (sim_log, sim_dflt_dev, sim_dflt_dev->units, 0, cmdp->name);
}
}
strlcpy (gbuf2, cmdp->help, sizeof (gbuf2));
if (*cptr) {
strlcat (gbuf2, " ", sizeof (gbuf2));
strlcat (gbuf2, cptr, sizeof (gbuf2));
}
help_cmd_output (flag, gbuf2, cmdp->help_base);
}
strlcpy (gbuf2, cmdp->help, sizeof (gbuf2));
if (*cptr) {
strlcat (gbuf2, " ", sizeof (gbuf2));
strlcat (gbuf2, cptr, sizeof (gbuf2));
}
help_cmd_output (flag, gbuf2, cmdp->help_base);
}
else { /* no help so it is likely a command alias */
CTAB *cmdpa;
else { /* no help so it is likely a command alias */
CTAB *cmdpa;
for (cmdpa=cmd_table; cmdpa->name != NULL; cmdpa++)
if ((cmdpa->action == cmdp->action) && (cmdpa->help)) {
sim_printf ("%s is an alias for the %s command:\n%s",
cmdp->name, cmdpa->name, cmdpa->help);
break;
}
if (cmdpa->name == NULL) /* not found? */
sim_printf ("No help available for the %s command\n", cmdp->name);
for (cmdpa=cmd_table; cmdpa->name != NULL; cmdpa++)
if ((cmdpa->action == cmdp->action) && (cmdpa->help)) {
sim_printf ("%s is an alias for the %s command:\n%s",
cmdp->name, cmdpa->name, cmdpa->help);
break;
}
if (cmdpa->name == NULL) /* not found? */
sim_printf ("No help available for the %s command\n", cmdp->name);
}
}
}
else {
DEVICE *dptr;
UNIT *uptr;
t_stat r;
t_bool explicit_device = FALSE;
if (0 == strcmp (gbuf, "DEVICE")) {
explicit_device = TRUE;
cptr = get_glyph (cptr, gbuf, 0);
}
dptr = find_unit (gbuf, &uptr);
if (dptr == NULL) {
dptr = find_dev (gbuf);
if (dptr == NULL)
return sim_messagef (SCPE_ARG, "No HELP available for %s%s %s\n",
explicit_device ? "DEVICE " : "", gbuf, cptr);
if (dptr->flags & DEV_DISABLE)
sim_printf ("Device %s is currently disabled\n", dptr->name);
}
else {
if (dptr->flags & DEV_DISABLE)
sim_printf ("Device %s is currently disabled\n", dptr->name);
r = help_dev_help (stdout, dptr, uptr, flag, cptr);
if (sim_log)
help_dev_help (sim_log, dptr, uptr, flag | SCP_HELP_FLAT, cptr);
@ -4941,12 +4957,12 @@ else {
return sim_messagef (SCPE_ARG, "Invalid argument: %s\n", gbuf);
}
}
if (cond == SCPE_OK)
return sim_messagef (SCPE_ARG, "Invalid argument: %s\n", gbuf);
if ((NULL == cptr) || ('\0' == *cptr)) { /* Empty Action */
free(sim_on_actions[sim_do_depth][cond]); /* Clear existing condition */
sim_on_actions[sim_do_depth][cond] = NULL; }
else {
if ((cptr > sim_sub_instr_buf) && ((size_t)(cptr - sim_sub_instr_buf) < sim_sub_instr_size))
cptr = &sim_sub_instr[sim_sub_instr_off[cptr - sim_sub_instr_buf]]; /* get un-substituted string */
sim_on_actions[sim_do_depth][cond] =
(char *)realloc(sim_on_actions[sim_do_depth][cond], 1+strlen(cptr));
strcpy(sim_on_actions[sim_do_depth][cond], cptr);
@ -5684,9 +5700,12 @@ if ((dptr->dwidth / dptr->aincr) > 8)
width = "W";
else
width = "B";
if (psize < (kval * 10))
if ((psize < (kval * 10)) &&
(0 != (psize % kval))) {
scale = "";
else if (psize < (mval * 10)) {
}
else if ((psize < (mval * 10)) &&
(0 != (psize % mval))){
scale = "K";
psize = psize / kval;
}
@ -8000,6 +8019,10 @@ do {
sim_activate (&sim_step_unit, sim_step);
} while (1);
if ((SCPE_BARE_STATUS(r) == SCPE_STOP) &&
sigterm_received)
r = SCPE_SIGTERM;
if ((SCPE_BARE_STATUS(r) == SCPE_STOP) && /* WRU exit from sim_instr() */
(sim_on_actions[sim_do_depth][SCPE_STOP] == NULL) &&/* without a handler for a STOP condition */
(sim_on_actions[sim_do_depth][0] == NULL))
@ -8151,6 +8174,8 @@ return sim_cancel (&sim_step_unit);
void int_handler (int sig)
{
stop_cpu = TRUE;
if (sig == SIGTERM)
sigterm_received = TRUE;
}
/* Examine/deposit commands

View File

@ -43,6 +43,25 @@ struct ROM_File_Descriptor {
{"VAX/ka620.bin", "VAX/vax_ka620_bin.h", 65536, 0xFF7F930F, "vax_ka620_bin"},
{"VAX/ka630.bin", "VAX/vax_ka630_bin.h", 65536, 0xFF7F73EF, "vax_ka630_bin"},
{"VAX/ka610.bin", "VAX/vax_ka610_bin.h", 16384, 0xFFEF3312, "vax_ka610_bin"},
{"VAX/ka410.bin", "VAX/vax_ka410_bin.h", 262144, 0xFEDA0B61, "vax_ka410_bin"},
{"VAX/ka411.bin", "VAX/vax_ka411_bin.h", 262144, 0xFECB7EE3, "vax_ka411_bin"},
{"VAX/ka412.bin", "VAX/vax_ka412_bin.h", 262144, 0xFED96BB4, "vax_ka412_bin"},
{"VAX/ka41a.bin", "VAX/vax_ka41a_bin.h", 262144, 0xFECBAC7B, "vax_ka41a_bin"},
{"VAX/ka41d.bin", "VAX/vax_ka41d_bin.h", 262144, 0xFECB8513, "vax_ka41d_bin"},
{"VAX/ka42a.bin", "VAX/vax_ka42a_bin.h", 262144, 0xFED8967F, "vax_ka42a_bin"},
{"VAX/ka42b.bin", "VAX/vax_ka42b_bin.h", 262144, 0xFECBB2EF, "vax_ka42b_bin"},
{"VAX/ka43a.bin", "VAX/vax_ka43a_bin.h", 262144, 0xFEAB1DF9, "vax_ka43a_bin"},
{"VAX/ka46a.bin", "VAX/vax_ka46a_bin.h", 262144, 0xFE8D094C, "vax_ka46a_bin"},
{"VAX/ka47a.bin", "VAX/vax_ka47a_bin.h", 262144, 0xFE8D8DDA, "vax_ka47a_bin"},
{"VAX/ka48a.bin", "VAX/vax_ka48a_bin.h", 262144, 0xFEBB854D, "vax_ka48a_bin"},
{"VAX/is1000.bin", "VAX/vax_is1000_bin.h", 524288, 0xFCBCD74A, "vax_is1000_bin"},
{"VAX/ka410_xs.bin", "VAX/vax_ka410_xs_bin.h", 32768, 0xFFD8BD83, "vax_ka410_xs_bin"},
{"VAX/ka420_rdrz.bin", "VAX/vax_ka420_rdrz_bin.h", 131072, 0xFF747E93, "vax_ka420_rdrz_bin"},
{"VAX/ka420_rzrz.bin", "VAX/vax_ka420_rzrz_bin.h", 131072, 0xFF7A9A51, "vax_ka420_rzrz_bin"},
{"VAX/ka4xx_4pln.bin", "VAX/vax_ka4xx_4pln_bin.h", 65536, 0xFF9CD286, "vax_ka4xx_4pln_bin"},
{"VAX/ka4xx_8pln.bin", "VAX/vax_ka4xx_8pln_bin.h", 65536, 0xFFA2FF59, "vax_ka4xx_8pln_bin"},
{"VAX/ka4xx_dz.bin", "VAX/vax_ka4xx_dz_bin.h", 32768, 0xFFD84C02, "vax_ka4xx_dz_bin"},
{"VAX/ka4xx_spx.bin" , "VAX/vax_ka4xx_spx_bin.h", 131072, 0xFF765752, "vax_ka4xx_spx_bin"},
{"VAX/ka750_new.bin", "VAX/vax_ka750_bin_new.h", 1024, 0xFFFE7BE5, "vax_ka750_bin_new", "From ROM set: E40A9, E41A9, E42A9, E43A9 (Boots: A=DD, B=DB, C=DU"},
{"VAX/ka750_old.bin", "VAX/vax_ka750_bin_old.h", 1024, 0xFFFEBAA5, "vax_ka750_bin_old", "From ROM set: 990A9, 948A9, 906A9, 905A9 (Boots: A=DD, B=DM, C=DL, D=DU"},
{"VAX/vcb02.bin", "VAX/vax_vcb02_bin.h", 16384, 0xFFF1D2AD, "vax_vcb02_bin"},

View File

@ -3388,6 +3388,8 @@ static DWORD saved_output_mode;
console terminal is a useful character to be passed to the
simulator. This code does nothing to disable or affect that. */
#include <signal.h>
static BOOL WINAPI
ControlHandler(DWORD dwCtrlType)
{
@ -3398,7 +3400,7 @@ ControlHandler(DWORD dwCtrlType)
{
case CTRL_BREAK_EVENT: // Use CTRL-Break or CTRL-C to simulate
case CTRL_C_EVENT: // SERVICE_CONTROL_STOP in debug mode
int_handler(0);
int_handler(SIGINT);
return TRUE;
case CTRL_CLOSE_EVENT: // Window is Closing
case CTRL_LOGOFF_EVENT: // User is logging off
@ -3406,7 +3408,7 @@ ControlHandler(DWORD dwCtrlType)
return TRUE; // Not our User, so ignore
/* fall through */
case CTRL_SHUTDOWN_EVENT: // System is shutting down
int_handler(0);
int_handler(SIGTERM);
return TRUE;
}
return FALSE;

View File

@ -415,8 +415,9 @@ typedef uint32 t_addr;
#define SCPE_AMBREG (SCPE_BASE + 45) /* ambiguous register */
#define SCPE_REMOTE (SCPE_BASE + 46) /* remote console command */
#define SCPE_INVEXPR (SCPE_BASE + 47) /* invalid expression */
#define SCPE_SIGTERM (SCPE_BASE + 48) /* SIGTERM has been received */
#define SCPE_MAX_ERR (SCPE_BASE + 47) /* Maximum SCPE Error Value */
#define SCPE_MAX_ERR (SCPE_BASE + 48) /* Maximum SCPE Error Value */
#define SCPE_KFLAG 0x10000000 /* tti data flag */
#define SCPE_BREAK 0x20000000 /* tti break flag */
#define SCPE_NOMESSAGE 0x40000000 /* message display supression flag */

1743
sim_scsi.c Normal file

File diff suppressed because it is too large Load Diff

133
sim_scsi.h Normal file
View File

@ -0,0 +1,133 @@
/* sim_scsi.h: SCSI bus simulation
Copyright (c) 2019, Matt Burke
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
THE AUTHOR 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 the author shall not be
used in advertising or otherwise to promote the sale, use or other dealings
in this Software without prior written authorization from the author.
*/
#ifndef _SIM_SCSI_H_
#define _SIM_SCSI_H_ 0
#include "sim_defs.h"
/* SCSI device states */
#define SCSI_DISC 0 /* disconnected */
#define SCSI_TARG 1 /* target mode */
#define SCSI_INIT 2 /* initiator mode */
/* SCSI device types */
#define SCSI_DISK 0 /* direct access device */
#define SCSI_TAPE 1 /* sequential access device */
#define SCSI_PRINT 2 /* printer */
#define SCSI_PROC 3 /* processor */
#define SCSI_WORM 4 /* write-once device */
#define SCSI_CDROM 5 /* CD-ROM */
#define SCSI_SCAN 6 /* scanner */
#define SCSI_OPTI 7 /* optical */
#define SCSI_JUKE 8 /* jukebox */
#define SCSI_COMM 9 /* communications device */
/* SCSI bus phases */
#define SCSI_DATO 0 /* data out */
#define SCSI_DATI 1 /* data in */
#define SCSI_CMD 2 /* command */
#define SCSI_STS 3 /* status */
#define SCSI_MSGO 6 /* message out */
#define SCSI_MSGI 7 /* message in */
/* Debugging bitmaps */
#define SCSI_DBG_CMD 0x01000000 /* SCSI commands */
#define SCSI_DBG_MSG 0x02000000 /* SCSI messages */
#define SCSI_DBG_BUS 0x04000000 /* bus activity */
#define SCSI_DBG_DSK 0x08000000 /* disk activity */
#define SCSI_V_WLK (UNIT_V_UF + 5) /* hwre write lock */
#define SCSI_V_NOAUTO (UNIT_V_UF + 6) /* noautosize */
#define SCSI_V_UF (UNIT_V_UF + 7)
#define SCSI_WLK (1 << SCSI_V_WLK)
#define SCSI_NOAUTO (1 << SCSI_V_NOAUTO)
struct scsi_dev_t {
uint8 devtype; /* device type */
uint8 pqual; /* peripheral qualifier */
uint32 scsiver; /* SCSI version */
t_bool removeable; /* removable flag */
uint32 block_size; /* device block size */
uint32 lbn; /* device size (blocks) */
const char *manufacturer; /* manufacturer string */
const char *product; /* product string */
const char *rev; /* revision string */
const char *name; /* gap length for tapes */
uint32 gaplen;
};
struct scsi_bus_t {
DEVICE *dptr; /* SCSI device */
UNIT *dev[8]; /* target units */
int32 initiator; /* current initiator */
int32 target; /* current target */
t_bool atn; /* attention flag */
t_bool req; /* request flag */
uint8 *buf; /* transfer buffer */
uint8 cmd[10]; /* command buffer */
uint32 buf_b; /* buffer bottom ptr */
uint32 buf_t; /* buffer top ptr */
uint32 phase; /* current bus phase */
uint32 lun; /* selected lun */
uint32 status;
uint32 sense_key;
uint32 sense_code;
uint32 sense_qual;
uint32 sense_info;
};
typedef struct scsi_bus_t SCSI_BUS;
typedef struct scsi_dev_t SCSI_DEV;
t_bool scsi_arbitrate (SCSI_BUS *bus, uint32 initiator);
void scsi_release (SCSI_BUS *bus);
void scsi_set_atn (SCSI_BUS *bus);
void scsi_release_atn (SCSI_BUS *bus);
t_bool scsi_select (SCSI_BUS *bus, uint32 target);
uint32 scsi_write (SCSI_BUS *bus, uint8 *data, uint32 len);
uint32 scsi_read (SCSI_BUS *bus, uint8 *data, uint32 len);
uint32 scsi_state (SCSI_BUS *bus, uint32 id);
void scsi_add_unit (SCSI_BUS *bus, uint32 id, UNIT *uptr);
void scsi_set_unit (SCSI_BUS *bus, UNIT *uptr, SCSI_DEV *dev);
void scsi_reset_unit (UNIT *uptr);
void scsi_reset (SCSI_BUS *bus);
t_stat scsi_init (SCSI_BUS *bus, uint32 maxfr);
t_stat scsi_set_fmt (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat scsi_set_wlk (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat scsi_show_fmt (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat scsi_show_wlk (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat scsi_attach (UNIT *uptr, CONST char *cptr);
t_stat scsi_detach (UNIT *uptr);
t_stat scsi_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
#endif