diff --git a/PDP10/kl10_dn.c b/PDP10/kl10_dn.c
index d75ca68..d464d1b 100644
--- a/PDP10/kl10_dn.c
+++ b/PDP10/kl10_dn.c
@@ -278,7 +278,7 @@ REG dn_reg[] = {
DEVICE dn_dev = {
"DN", dn_unit, dn_reg, dn_mod,
- 4, 10, 31, 1, 8, 8,
+ 3, 10, 31, 1, 8, 8,
NULL, NULL, &dn_reset,
NULL, NULL, NULL, &dn_dib, DEV_DEBUG, 0, dev_debug,
NULL, NULL, &dn_help, NULL, NULL, &dn_description
@@ -762,23 +762,6 @@ cty:
break;
case PRI_EMRDS: /* Request device status */
- if (dev == PRI_EMLPT) {
- if (cmd->data[0] != 0) {
- data1[0] = 2 << 8;
- data1[1] = 0;
- data1[2] = 0;
- if (dn_queue(PRI_EMHDS+PRI_IND_FLG, PRI_EMLPT,
- 3, data1) == 0)
- return;
- } else {
- data1[0] = 2 << 8;
- data1[1] = 0;
- data1[2] = 0;
- if (dn_queue(PRI_EMHDS+PRI_IND_FLG, PRI_EMLPT,
- 3, data1) == 0)
- return;
- }
- }
if (dev == PRI_EMCTY) {
data1[0] = 0;
data1[1] = 0;
@@ -1145,9 +1128,7 @@ t_stat dn_reset (DEVICE *dptr)
dn_unit[0].STATUS = DTE_SEC;
dn_unit[1].STATUS = 0;
dn_unit[2].STATUS = 0;
- dn_unit[3].STATUS = 0;
cty_done = 0;
- sim_activate(&dn_unit[3], 1000);
sim_activate(&dn_unit[2], 1000);
return SCPE_OK;
}
diff --git a/PDP10/ks10_uba.c b/PDP10/ks10_uba.c
index 3841e15..2642b46 100644
--- a/PDP10/ks10_uba.c
+++ b/PDP10/ks10_uba.c
@@ -58,7 +58,6 @@ uba_read(t_addr addr, int ctl, uint64 *data, int access)
int ubm = uba_device[ctl];
if (ubm == -1) {
- uba_status[ubm] |= UBST_TIM | UBST_NED;
sim_debug(DEBUG_EXP, &cpu_dev, "No UBA adaptor %02o %08o\n", ctl, addr);
return 1;
}
@@ -118,7 +117,6 @@ uba_write(t_addr addr, int ctl, uint64 data, int access)
int ubm = uba_device[ctl];
if (ubm == -1) {
- uba_status[ubm] |= UBST_TIM | UBST_NED;
sim_debug(DEBUG_EXP, &cpu_dev, "No UBA adaptor %02o %08o %012llo\n", ctl, addr, data);
return 1;
}
@@ -359,8 +357,6 @@ uba_set_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_value newaddr;
t_stat r;
- if (dibp == NULL)
- return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
@@ -400,8 +396,6 @@ uba_set_br(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_value br;
t_stat r;
- if (dibp == NULL)
- return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
@@ -444,8 +438,6 @@ uba_set_vect(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_value vect;
t_stat r;
- if (dibp == NULL)
- return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
@@ -486,8 +478,6 @@ uba_set_ctl(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
t_value ctl;
t_stat r;
- if (dibp == NULL)
- return SCPE_IERR;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
@@ -505,7 +495,7 @@ uba_set_ctl(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
if (r != SCPE_OK)
return r;
- if (ctl != 1 || ctl != 3)
+ if (ctl != 1 && ctl != 3)
return SCPE_ARG;
dibp->uba_ctl = (uint16)ctl;
return SCPE_OK;
diff --git a/PDP10/kx10_cpu.c b/PDP10/kx10_cpu.c
index d70d731..3829ed5 100644
--- a/PDP10/kx10_cpu.c
+++ b/PDP10/kx10_cpu.c
@@ -6687,6 +6687,8 @@ ldb_ptr:
} else {
#if KL | KS
ptr_flg = 0;
+#endif
+#if KL
ld_exe:
#endif
f = 0;
diff --git a/PDP10/kx10_dpy.c b/PDP10/kx10_dpy.c
index 58f0beb..1db3ae9 100644
--- a/PDP10/kx10_dpy.c
+++ b/PDP10/kx10_dpy.c
@@ -454,37 +454,63 @@ cpu_set_switches(unsigned long w1, unsigned long w2) {
#if NUM_DEVS_WCNSLS > 0
#define WCNSLS_DEVNUM 0420
-#define UNIT_JOY (1 << DEV_V_UF)
+#define UNIT_JOY (1 << DEV_V_UF) /* Use USB gaming devices. */
+#define UNIT_CSCOPE (1 << (DEV_V_UF+1)) /* Enable color scope. */
t_stat wcnsls_devio(uint32 dev, uint64 *data);
+t_stat wcnsls_svc (UNIT *uptr);
+t_stat wcnsls_reset (DEVICE *dptr);
const char *wcnsls_description (DEVICE *dptr);
+static uint64 dev420_cono = 0;
+static uint8 cscope_r = 0;
+static uint8 cscope_g = 0;
+static uint8 cscope_b = 0;
+static VID_DISPLAY *cscope_display = NULL;
+static uint32 fade[512 * 512];
+static uint32 dot[7 * 7];
+
DIB wcnsls_dib[] = {
{ WCNSLS_DEVNUM, 1, &wcnsls_devio, NULL }};
MTAB wcnsls_mod[] = {
{ UNIT_JOY, UNIT_JOY, "JOYSTICK", "JOYSTICK", NULL, NULL, NULL,
"Use USB joysticks"},
+ { UNIT_CSCOPE, UNIT_CSCOPE, "CSCOPE", "CSCOPE", NULL, NULL, NULL,
+ "Enable color scope"},
{ 0 }
};
UNIT wcnsls_unit[] = {
- { UDATA (NULL, UNIT_IDLE, 0) }};
+ { UDATA (wcnsls_svc, UNIT_IDLE, 0) }};
+
+REG wcnsls_reg[] = {
+ {ORDATA(CONO, dev420_cono, 18)},
+ {0}
+};
DEVICE wcnsls_dev = {
- "WCNSLS", wcnsls_unit, NULL, wcnsls_mod,
+ "WCNSLS", wcnsls_unit, wcnsls_reg, wcnsls_mod,
NUM_DEVS_WCNSLS, 0, 0, 0, 0, 0,
+ NULL, NULL, wcnsls_reset,
NULL, NULL, NULL,
- NULL, NULL, NULL,
- &wcnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, NULL,
+ &wcnsls_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG, 0, dev_debug,
NULL, NULL, NULL, NULL, NULL, &wcnsls_description
};
const char *wcnsls_description (DEVICE *dptr)
{
- return "MIT Spacewar Consoles";
+ return "MIT Spacewar Consoles, and DEC color scope";
}
+/* Device 420 CONO bits. */
+#define CONO_BLUE 0000020 /* Color scope blue enable */
+#define CONO_SPCWAR 0000040 /* Spacewar consoles */
+#define CONO_GREEN 0002000 /* Color scope green enable */
+#define CONO_RANDOM 0004000 /* Random switches */
+#define CONO_RED 0200000 /* Color scope red enable */
+#define CONO_KNIGHT 0400000 /* Switches in TK's office */
+
/*
* map 32-bit "spacewar_switches" value to what PDP-6/10 game expects
* (four 9-bit bytes)
@@ -512,55 +538,86 @@ const char *wcnsls_description (DEVICE *dptr)
#define BUT2 (JOY_MAX_BUTTONS*2)
#define BUT3 (JOY_MAX_BUTTONS*3)
+static void
+cscope_init (void)
+{
+ int i;
+ fade[0] = vid_map_rgba_window (cscope_display, 0, 0, 0, 240);
+ for (i = 1; i < 512 * 512; i++)
+ fade[i] = fade[0];
+}
+
+static void
+cscope_plot(int x, int y)
+{
+ int i, j;
+ for (i = 0; i < 7; i++) {
+ for (j = 0; j < 7; j++) {
+ int dx = i - 3, dy = j - 3;
+ int r2 = dx*dx + dy*dy;
+ double focus = 0.2;
+ double intensity = 0xFF/15.0;
+ double alpha = 0xFF*exp(-focus*r2);
+ dot[i + 7*j] = vid_map_rgba_window (cscope_display,
+ (uint8)(intensity*(cscope_r << 4)),
+ (uint8)(intensity*(cscope_g << 4)),
+ (uint8)(intensity*(cscope_b << 4)),
+ (uint8)alpha);
+ }
+ }
+
+ vid_draw_window (cscope_display, x - 3, 511 - y - 3, 7, 7, dot);
+}
+
static uint64 joystick_switches (void)
{
- uint64 switches = 0777777777777LL;
+ uint64 switches = 0777777777777LL;
- if (joy_axes[JOY0] > JOY_TRIG)
- switches &= ~(CCW << UR);
- else if (joy_axes[JOY0] < -JOY_TRIG)
- switches &= ~(CW << UR);
- if (joy_axes[JOY0+1] < -JOY_TRIG)
- switches &= ~(THRUST << UR);
- if (joy_buttons[BUT0])
- switches &= ~(FIRE << UR);
- if (joy_buttons[BUT0+1])
- switches &= ~(HYPER << UR);
+ if (joy_axes[JOY0] > JOY_TRIG)
+ switches &= ~(CCW << UR);
+ else if (joy_axes[JOY0] < -JOY_TRIG)
+ switches &= ~(CW << UR);
+ if (joy_axes[JOY0+1] < -JOY_TRIG)
+ switches &= ~(THRUST << UR);
+ if (joy_buttons[BUT0])
+ switches &= ~(FIRE << UR);
+ if (joy_buttons[BUT0+1])
+ switches &= ~(HYPER << UR);
- if (joy_axes[JOY1] > JOY_TRIG)
- switches &= ~(CCW << LR);
- else if (joy_axes[JOY1] < -JOY_TRIG)
- switches &= ~(CW << LR);
- if (joy_axes[JOY1+1] < -JOY_TRIG)
- switches &= ~(THRUST << LR);
- if (joy_buttons[BUT1])
- switches &= ~(FIRE << LR);
- if (joy_buttons[BUT1+1])
- switches &= ~(HYPER << LR);
+ if (joy_axes[JOY1] > JOY_TRIG)
+ switches &= ~(CCW << LR);
+ else if (joy_axes[JOY1] < -JOY_TRIG)
+ switches &= ~(CW << LR);
+ if (joy_axes[JOY1+1] < -JOY_TRIG)
+ switches &= ~(THRUST << LR);
+ if (joy_buttons[BUT1])
+ switches &= ~(FIRE << LR);
+ if (joy_buttons[BUT1+1])
+ switches &= ~(HYPER << LR);
- if (joy_axes[JOY2] > JOY_TRIG)
- switches &= ~(CCW << LL);
- else if (joy_axes[JOY2] < -JOY_TRIG)
- switches &= ~(CW << LL);
- if (joy_axes[JOY2+1] < -JOY_TRIG)
- switches &= ~(THRUST << LL);
- if (joy_buttons[BUT2])
- switches &= ~(FIRE << LL);
- if (joy_buttons[BUT2+1])
- switches &= ~(HYPER << LL);
+ if (joy_axes[JOY2] > JOY_TRIG)
+ switches &= ~(CCW << LL);
+ else if (joy_axes[JOY2] < -JOY_TRIG)
+ switches &= ~(CW << LL);
+ if (joy_axes[JOY2+1] < -JOY_TRIG)
+ switches &= ~(THRUST << LL);
+ if (joy_buttons[BUT2])
+ switches &= ~(FIRE << LL);
+ if (joy_buttons[BUT2+1])
+ switches &= ~(HYPER << LL);
- if (joy_axes[JOY3] > JOY_TRIG)
- switches &= ~((uint64)CCW << UL);
- else if (joy_axes[JOY3] < -JOY_TRIG)
- switches &= ~((uint64)CW << UL);
- if (joy_axes[JOY3+1] < -JOY_TRIG)
- switches &= ~((uint64)THRUST << UL);
- if (joy_buttons[BUT3])
- switches &= ~((uint64)FIRE << UL);
- if (joy_buttons[BUT3+1])
- switches &= ~(HYPER << UL);
+ if (joy_axes[JOY3] > JOY_TRIG)
+ switches &= ~((uint64)CCW << UL);
+ else if (joy_axes[JOY3] < -JOY_TRIG)
+ switches &= ~((uint64)CW << UL);
+ if (joy_axes[JOY3+1] < -JOY_TRIG)
+ switches &= ~((uint64)THRUST << UL);
+ if (joy_buttons[BUT3])
+ switches &= ~((uint64)FIRE << UL);
+ if (joy_buttons[BUT3+1])
+ switches &= ~(HYPER << UL);
- return switches;
+ return switches;
}
static uint64 keyboard_switches (void)
@@ -589,17 +646,66 @@ static uint64 keyboard_switches (void)
return switches;
}
+t_stat wcnsls_svc (UNIT *uptr)
+{
+ vid_refresh_window (cscope_display);
+ vid_draw_window (cscope_display, 0, 0, 512, 512, fade);
+ sim_activate_after (uptr, 33333);
+ return SCPE_OK;
+}
+
+t_stat
+wcnsls_reset (DEVICE *dptr)
+{
+ t_stat r;
+ if (sim_switches & SWMASK('P') || dptr->flags & DEV_DIS ||
+ (wcnsls_unit->flags & UNIT_CSCOPE) == 0) {
+ sim_cancel (wcnsls_unit);
+ if (cscope_display != NULL)
+ vid_close_window (cscope_display);
+ cscope_display = NULL;
+ } else if (cscope_display == NULL) {
+ r = vid_open_window (&cscope_display, dptr, "Color scope", 512, 512, 0);
+ if (r != SCPE_OK)
+ return r;
+ /* Allow time for window to open and data structures to settle. */
+ sim_os_sleep (1);
+ r = vid_set_alpha_mode (cscope_display, SIM_ALPHA_BLEND);
+ if (r != SCPE_OK)
+ return r;
+ sim_activate_abs (wcnsls_unit, 0);
+ cscope_init ();
+ }
+ return SCPE_OK;
+}
+
t_stat wcnsls_devio(uint32 dev, uint64 *data) {
switch (dev & 3) {
case CONO:
/* CONO WCNSLS,40 ;enable spacewar consoles */
+ sim_debug (DEBUG_CONO, &wcnsls_dev, "%06llo\n", *data);
+ dev420_cono = *data;
+ if (dev420_cono & CONO_RED)
+ cscope_r = (dev420_cono >> 12) & 017;
+ if (dev420_cono & CONO_GREEN)
+ cscope_g = (dev420_cono >> 6) & 017;
+ if (dev420_cono & CONO_BLUE)
+ cscope_b = dev420_cono & 017;
+ break;
+
+ case DATAO:
+ sim_debug (DEBUG_DATAIO, &wcnsls_dev, "DATAO %012llo\n", *data);
+ if (wcnsls_unit->flags & UNIT_CSCOPE)
+ cscope_plot((*data >> 9) & 0777, *data & 0777);
break;
case DATAI:
- if (wcnsls_unit->flags & UNIT_JOY) {
- *data = joystick_switches ();
- } else {
- *data = keyboard_switches ();
+ if (dev420_cono & CONO_SPCWAR) {
+ if (wcnsls_unit->flags & UNIT_JOY) {
+ *data = joystick_switches ();
+ } else {
+ *data = keyboard_switches ();
+ }
}
sim_debug(DEBUG_DATAIO, &wcnsls_dev, "WCNSLS %03o DATI %012llo PC=%06o\n",
@@ -648,39 +754,39 @@ const char *ocnsls_description (DEVICE *dptr)
static uint64 old_switches (void)
{
- uint64 switches = 0;
+ uint64 switches = 0;
- if (joy_axes[JOY0] > JOY_TRIG)
- switches |= OCCW;
- else if (joy_axes[JOY0] < -JOY_TRIG)
- switches |= OCW;
- if (joy_axes[JOY0+1] < -JOY_TRIG)
- switches |= FAST;
- if (joy_axes[JOY0+1] > JOY_TRIG)
- switches |= SLOW;
- if (joy_buttons[BUT0])
- switches |= OFIRE;
- if (joy_buttons[BUT0+1])
- switches |= OHYPER;
- if (joy_buttons[BUT0+2])
- switches |= BEACON;
+ if (joy_axes[JOY0] > JOY_TRIG)
+ switches |= OCCW;
+ else if (joy_axes[JOY0] < -JOY_TRIG)
+ switches |= OCW;
+ if (joy_axes[JOY0+1] < -JOY_TRIG)
+ switches |= FAST;
+ if (joy_axes[JOY0+1] > JOY_TRIG)
+ switches |= SLOW;
+ if (joy_buttons[BUT0])
+ switches |= OFIRE;
+ if (joy_buttons[BUT0+1])
+ switches |= OHYPER;
+ if (joy_buttons[BUT0+2])
+ switches |= BEACON;
- if (joy_axes[JOY1] > JOY_TRIG)
- switches |= OCCW << 18;
- else if (joy_axes[JOY1] < -JOY_TRIG)
- switches |= OCW << 18;
- if (joy_axes[JOY1+1] < -JOY_TRIG)
- switches |= FAST << 18;
- if (joy_axes[JOY1+1] > JOY_TRIG)
- switches |= SLOW << 18;
- if (joy_buttons[BUT1])
- switches |= OFIRE << 18;
- if (joy_buttons[BUT1+1])
- switches |= OHYPER << 18;
- if (joy_buttons[BUT1+2])
- switches |= BEACON << 18;
+ if (joy_axes[JOY1] > JOY_TRIG)
+ switches |= OCCW << 18;
+ else if (joy_axes[JOY1] < -JOY_TRIG)
+ switches |= OCW << 18;
+ if (joy_axes[JOY1+1] < -JOY_TRIG)
+ switches |= FAST << 18;
+ if (joy_axes[JOY1+1] > JOY_TRIG)
+ switches |= SLOW << 18;
+ if (joy_buttons[BUT1])
+ switches |= OFIRE << 18;
+ if (joy_buttons[BUT1+1])
+ switches |= OHYPER << 18;
+ if (joy_buttons[BUT1+2])
+ switches |= BEACON << 18;
- return switches;
+ return switches;
}
t_stat ocnsls_devio(uint32 dev, uint64 *data) {
diff --git a/PDP10/kx10_mt.c b/PDP10/kx10_mt.c
index 89c4198..f253811 100644
--- a/PDP10/kx10_mt.c
+++ b/PDP10/kx10_mt.c
@@ -533,7 +533,7 @@ t_stat mt_error(UNIT * uptr, t_stat r, DEVICE * dptr)
t_stat mt_srv(UNIT * uptr)
{
DEVICE *dptr = uptr->dptr;
- int unit = (uptr - dptr->units) & 7;
+ int unit;
int cmd = (uptr->CNTRL & FUNCTION) >> 9;
t_mtrlnt reclen;
t_stat r = SCPE_ARG; /* Force error if not set */
@@ -560,6 +560,7 @@ t_stat mt_srv(UNIT * uptr)
if (dptr == NULL)
dptr = find_dev_from_unit(uptr);
+ unit = (uptr - dptr->units) & 7;
switch(cmd) {
case NOP_IDLE:
sim_debug(DEBUG_DETAIL, dptr, "MT%o Idle\n", unit);
diff --git a/PDP10/kx10_sys.c b/PDP10/kx10_sys.c
index e5c3231..26c4b23 100644
--- a/PDP10/kx10_sys.c
+++ b/PDP10/kx10_sys.c
@@ -288,24 +288,20 @@ t_stat load_dmp (FILE *fileref)
uint64 data;
uint32 high = 0;
- while (fgets((char *)buffer, 80, fileref) != 0) {
- p = (char *)buffer;
- while (*p >= '0' && *p <= '7') {
- data = 0;
- while (*p >= '0' && *p <= '7') {
- data = (data << 3) + *p - '0';
- p++;
- }
- if (addr == 0135 && data != 0)
- high = (uint32)(data & RMASK);
- if (high != 0 && high == addr) {
- addr = 0400000;
- high = 0;
- }
- M[addr++] = data;
- if (*p == ' ' || *p == '\t')
- p++;
- }
+ while (fgets(&buffer[0], 80, fileref) != 0) {
+ data = 0;
+ p = &buffer[0];
+ if (*p >= '0' && *p <= '7') {
+ for (; *p >= '0' && *p <= '7'; p++)
+ data = (data << 3) + *p - '0';
+ if (addr == 0135 && data != 0)
+ high = (uint32)(data & RMASK);
+ if (high != 0 && high == addr) {
+ addr = 0400000;
+ high = 0;
+ }
+ M[addr++] = data;
+ }
}
return SCPE_OK;
}
diff --git a/Visual Studio Projects/PDP10-KL.vcproj b/Visual Studio Projects/PDP10-KL.vcproj
index a22ec22..bc53666 100644
--- a/Visual Studio Projects/PDP10-KL.vcproj
+++ b/Visual Studio Projects/PDP10-KL.vcproj
@@ -201,6 +201,10 @@
RelativePath="..\PDP10\ka10_pd.c"
>
+
+
diff --git a/scp.c b/scp.c
index 7ed77b0..d46585d 100644
--- a/scp.c
+++ b/scp.c
@@ -233,13 +233,9 @@
#include
#include
#if defined(_WIN32)
-#include
#include
#include
-#else
-#include
#endif
-#include
#include
#if defined(HAVE_DLOPEN) /* Dynamic Readline support */
@@ -451,6 +447,7 @@ void (*sim_vm_fprint_addr) (FILE *st, DEVICE *dptr, t_addr addr) = NULL;
t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char **tptr) = NULL;
t_value (*sim_vm_pc_value) (void) = NULL;
t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs) = NULL;
+void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val) = NULL;
t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason) = NULL;
const char *sim_vm_release = NULL;
const char *sim_vm_release_message = NULL;
@@ -3148,11 +3145,13 @@ DEVICE *tdptr;
CONST char *tptr;
char *namebuf;
char rangebuf[32];
+int side_effects = 0;
if (dptr->registers)
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
if (rptr->flags & REG_HIDDEN)
continue;
+ side_effects += ((rptr->flags & REG_DEPOSIT) != 0);
if (rptr->depth > 1)
sprintf (rangebuf, "[%d:%d]", 0, rptr->depth-1);
else
@@ -3172,8 +3171,11 @@ else {
namebuf = (char *)calloc (max_namelen + 1, sizeof (*namebuf));
fprintf (st, "\nThe %s device implements these registers:\n\n", dptr->name);
for (rptr = dptr->registers; rptr->name != NULL; rptr++) {
+ char note[2];
+
if (rptr->flags & REG_HIDDEN)
continue;
+ strlcpy (note, (side_effects != 0) ? ((rptr->flags & REG_DEPOSIT) ? "+" : " ") : "", sizeof (note));
if (rptr->depth <= 1)
sprintf (namebuf, "%*s", -((int)max_namelen), rptr->name);
else {
@@ -3181,16 +3183,22 @@ else {
sprintf (namebuf, "%s%*s", rptr->name, (int)(strlen(rptr->name))-((int)max_namelen), rangebuf);
}
if (all_unique) {
- fprintf (st, " %s %4d %s\n", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
+ fprintf (st, " %s %4d %s %s\n", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
continue;
}
trptr = find_reg_glob (rptr->name, &tptr, &tdptr);
if ((trptr == NULL) || (tdptr != dptr))
- fprintf (st, " %s %s %4d %s\n", dptr->name, namebuf, rptr->width, rptr->desc ? rptr->desc : "");
+ fprintf (st, " %s %s %4d %s %s\n", dptr->name, namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
else
- fprintf (st, " %*s %s %4d %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, rptr->desc ? rptr->desc : "");
+ fprintf (st, " %*s %s %4d %s %s\n", (int)strlen(dptr->name), "", namebuf, rptr->width, note, rptr->desc ? rptr->desc : "");
}
free (namebuf);
+ if (side_effects)
+ fprintf (st, "\n + Deposits to %s register%s will have some additional\n"
+ " side effects which can be suppressed if the deposit is\n"
+ " done with the -Z switch specified\n",
+ (side_effects == 1) ? "this" : "these",
+ (side_effects == 1) ? "" : "s");
}
}
@@ -3248,12 +3256,19 @@ t_bool found = FALSE;
t_bool deb_desc_available = FALSE;
char buf[CBUFSIZE], header[CBUFSIZE];
uint32 enabled_units = dptr->numunits;
-uint32 unit;
+char unit_spec[50];
+uint32 unit, found_unit = 0;
sprintf (header, "\n%s device SET commands:\n\n", dptr->name);
for (unit=0; unit < dptr->numunits; unit++)
if (dptr->units[unit].flags & UNIT_DIS)
--enabled_units;
+ else
+ found_unit = unit;
+if (enabled_units == 1)
+ snprintf (unit_spec, sizeof (unit_spec), "%s%u", sim_dname (dptr), found_unit);
+else
+ snprintf (unit_spec, sizeof (unit_spec), "%sn", sim_dname (dptr));
if (dptr->modifiers) {
for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) {
if (!MODMASK(mptr,MTAB_VDV) && MODMASK(mptr,MTAB_VUN) && (dptr->numunits != 1))
@@ -3299,34 +3314,33 @@ if ((dptr->flags & DEV_DEBUG) || (dptr->debflags)) {
fprintf (st, "%-30s\tDisables specific debugging for device %s\n", buf, sim_dname (dptr));
}
}
-if ((dptr->modifiers) && (dptr->units) && (enabled_units != 1)) {
+if ((dptr->modifiers) && (dptr->units)) { /* handle unit specific modifiers */
if (dptr->units->flags & UNIT_DISABLE) {
fprint_header (st, &found, header);
- sprintf (buf, "set %sn ENABLE", sim_dname (dptr));
- fprintf (st, "%-30s\tEnables unit %sn\n", buf, sim_dname (dptr));
- sprintf (buf, "set %sn DISABLE", sim_dname (dptr));
- fprintf (st, "%-30s\tDisables unit %sn\n", buf, sim_dname (dptr));
+ sprintf (buf, "set %s ENABLE", unit_spec);
+ fprintf (st, "%-30s\tEnables unit %s\n", buf, unit_spec);
+ sprintf (buf, "set %s DISABLE", unit_spec);
+ fprintf (st, "%-30s\tDisables unit %sn\n", buf, unit_spec);
}
if (((dptr->flags & DEV_DEBUG) || (dptr->debflags)) &&
((DEV_TYPE(dptr) == DEV_DISK) || (DEV_TYPE(dptr) == DEV_TAPE))) {
- sprintf (buf, "set %sn DEBUG", sim_dname (dptr));
- fprintf (st, "%-30s\tEnables debugging for device unit %sn\n", buf, sim_dname (dptr));
- sprintf (buf, "set %sn NODEBUG", sim_dname (dptr));
- fprintf (st, "%-30s\tDisables debugging for device unit %sn\n", buf, sim_dname (dptr));
+ sprintf (buf, "set %s DEBUG", unit_spec);
+ fprintf (st, "%-30s\tEnables debugging for device unit %s\n", buf, unit_spec);
+ sprintf (buf, "set %s NODEBUG", unit_spec);
+ fprintf (st, "%-30s\tDisables debugging for device unit %s\n", buf, unit_spec);
if (dptr->debflags) {
strcpy (buf, "");
- fprintf (st, "set %sn DEBUG=", sim_dname (dptr));
+ fprintf (st, "set %s DEBUG=", unit_spec);
for (dep = dptr->debflags; dep->name != NULL; dep++)
fprintf (st, "%s%s", ((dep == dptr->debflags) ? "" : ";"), dep->name);
fprintf (st, "\n");
- fprintf (st, "%-30s\tEnables specific debugging for device unit %sn\n", buf, sim_dname (dptr));
- fprintf (st, "set %sn NODEBUG=", sim_dname (dptr));
+ fprintf (st, "%-30s\tEnables specific debugging for device unit %s\n", buf, unit_spec);
+ fprintf (st, "set %s NODEBUG=", unit_spec);
for (dep = dptr->debflags; dep->name != NULL; dep++)
fprintf (st, "%s%s", ((dep == dptr->debflags) ? "" : ";"), dep->name);
fprintf (st, "\n");
- fprintf (st, "%-30s\tDisables specific debugging for device unit %sn\n", buf, sim_dname (dptr));
+ fprintf (st, "%-30s\tDisables specific debugging for device unit %s\n", buf, unit_spec);
}
-
}
for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) {
if ((!MODMASK(mptr,MTAB_VUN)) && MODMASK(mptr,MTAB_XTD))
@@ -3335,7 +3349,7 @@ if ((dptr->modifiers) && (dptr->units) && (enabled_units != 1)) {
continue; /* skip show only modifiers */
if (mptr->mstring) {
fprint_header (st, &found, header);
- sprintf (buf, "set %s%s %s%s", sim_dname (dptr), (dptr->numunits > 1) ? "n" : "0", mptr->mstring, (strchr(mptr->mstring, '=')) ? "" : (MODMASK(mptr,MTAB_VALR) ? "=val" : (MODMASK(mptr,MTAB_VALO) ? "{=val}": "")));
+ sprintf (buf, "set %s %s%s", unit_spec, mptr->mstring, (strchr(mptr->mstring, '=')) ? "" : (MODMASK(mptr,MTAB_VALR) ? "=val" : (MODMASK(mptr,MTAB_VALO) ? "{=val}": "")));
fprintf (st, "%-30s\t%s\n", buf, (strchr (mptr->mstring, '=')) ? ((strlen (buf) > 30) ? "" : mptr->help) : (mptr->help ? mptr->help : ""));
if ((strchr (mptr->mstring, '=')) && (strlen (buf) > 30))
fprintf (st, "%-30s\t%s\n", "", mptr->help);
@@ -3372,12 +3386,21 @@ MTAB *mptr;
t_bool found = FALSE;
char buf[CBUFSIZE], header[CBUFSIZE];
uint32 enabled_units = dptr->numunits;
-uint32 unit;
+char unit_spec[50];
+uint32 unit, found_unit = 0;
sprintf (header, "\n%s device SHOW commands:\n\n", dptr->name);
for (unit=0; unit < dptr->numunits; unit++)
if (dptr->units[unit].flags & UNIT_DIS)
--enabled_units;
+ else
+ found_unit = unit;
+if (enabled_units == 1)
+ snprintf (unit_spec, sizeof (unit_spec), "%s%u", sim_dname (dptr), found_unit);
+else
+ snprintf (unit_spec, sizeof (unit_spec), "%sn", sim_dname (dptr));
+snprintf (unit_spec, sizeof (unit_spec), "%s%s", sim_dname (dptr),
+ ((enabled_units == 1) && ((dptr->units[0].flags & UNIT_DIS) == 0)) ? "0" : "n");
if (dptr->modifiers) {
for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) {
if (!MODMASK(mptr,MTAB_VDV) && MODMASK(mptr,MTAB_VUN) && (dptr->numunits != 1))
@@ -3396,14 +3419,20 @@ if ((dptr->flags & DEV_DEBUG) || (dptr->debflags)) {
sprintf (buf, "show %s DEBUG", sim_dname (dptr));
fprintf (st, "%-30s\tDisplays debugging status for device %s\n", buf, sim_dname (dptr));
}
-if ((dptr->modifiers) && (dptr->units) && (enabled_units != 1)) {
+if (((dptr->flags & DEV_DEBUG) || (dptr->debflags)) &&
+ ((DEV_TYPE(dptr) == DEV_DISK) || (DEV_TYPE(dptr) == DEV_TAPE))) {
+ sprintf (buf, "show %s DEBUG", unit_spec);
+ fprintf (st, "%-30s\tDisplays debugging status for device unit %s\n", buf, unit_spec);
+ }
+
+if ((dptr->modifiers) && (dptr->units)) { /* handle unit specific modifiers */
for (mptr = dptr->modifiers; mptr->mask != 0; mptr++) {
if ((!MODMASK(mptr,MTAB_VUN)) && MODMASK(mptr,MTAB_XTD))
continue; /* skip device only modifiers */
if ((!mptr->disp) || (!mptr->pstring))
continue;
fprint_header (st, &found, header);
- sprintf (buf, "show %s%s %s%s", sim_dname (dptr), (dptr->numunits > 1) ? "n" : "0", mptr->pstring, MODMASK(mptr,MTAB_SHP) ? "=arg" : "");
+ sprintf (buf, "show %s %s%s", unit_spec, mptr->pstring, MODMASK(mptr,MTAB_SHP) ? "=arg" : "");
fprintf (st, "%-30s\t%s\n", buf, mptr->help ? mptr->help : "");
}
}
@@ -3840,10 +3869,10 @@ for (nargs = 0; nargs < 10; ) { /* extract arguments */
if (do_arg [0] == NULL) /* need at least 1 */
return SCPE_2FARG;
if ((strcasecmp (do_arg[0], "") != 0) &&
- ((fpin = fopen (do_arg[0], "r")) == NULL)) { /* file failed to open? */
+ ((fpin = sim_fopen (do_arg[0], "r")) == NULL)) { /* file failed to open? */
strlcpy (cbuf, do_arg[0], sizeof (cbuf)); /* try again with .sim extension */
strlcat (cbuf, ".sim", sizeof (cbuf));
- if ((fpin = fopen (cbuf, "r")) == NULL) { /* failed a second time? */
+ if ((fpin = sim_fopen (cbuf, "r")) == NULL) { /* failed a second time? */
if (flag == 0) /* cmd line file? */
fprintf (stderr, "Can't open file %s\n", do_arg[0]);
return SCPE_OPENERR; /* return failure */
@@ -4603,8 +4632,8 @@ if (sim_switches & SWMASK ('F')) { /* File Compare? */
filename2[strlen (filename2) - 1] = '\0';
setenv ("_FILE_COMPARE_DIFF_OFFSET", "", 1); /* Remove previous environment variable */
- f1 = fopen (filename1, "rb");
- f2 = fopen (filename2, "rb");
+ f1 = sim_fopen (filename1, "rb");
+ f2 = sim_fopen (filename2, "rb");
free (filename1);
free (filename2);
if ((f1 == NULL) && (f2 == NULL)) /* Both can't open? */
@@ -4827,7 +4856,7 @@ if (Exist || (*gbuf == '"') || (*gbuf == '\'')) { /* quoted string compari
result = !result;
}
else {
- FILE *f = fopen (gbuf, "r");
+ FILE *f = sim_fopen (gbuf, "r");
if (!f) {
if (((gbuf[0] == '"') || (gbuf[0] == '\'')) && /* quoted? */
@@ -4835,7 +4864,7 @@ if (Exist || (*gbuf == '"') || (*gbuf == '\'')) { /* quoted string compari
char *without_quotes = sim_filepath_parts (gbuf, "f");
if (without_quotes) {
- f = fopen (without_quotes, "r");
+ f = sim_fopen (without_quotes, "r");
free (without_quotes);
}
}
@@ -6837,7 +6866,7 @@ GET_SWITCHES (cptr); /* get switches */
gbuf[sizeof(gbuf)-1] = '\0';
strlcpy (gbuf, cptr, sizeof(gbuf));
sim_trim_endspc(gbuf);
-if (chdir(gbuf) != 0)
+if (sim_chdir(gbuf) != 0)
return sim_messagef(SCPE_IOERR, "Unable to directory change to: %s\n", gbuf);
return SCPE_OK;
}
@@ -6929,9 +6958,9 @@ if (*cptr == '\0')
else {
if ((WildName[strlen (WildName) - 1] == '/') ||
(WildName[strlen (WildName) - 1] == '\\'))
- WildName[strlen (WildName) - 1] = '\0';
+ strlcat (WildName, ".", sizeof (WildName));
}
-if ((!stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
+if ((!sim_stat (WildName, &filestat)) && (filestat.st_mode & S_IFDIR))
strlcat (WildName, "/*", sizeof (WildName));
r = sim_dir_scan (cptr, sim_dir_entry, &dir_state);
sim_dir_entry (NULL, NULL, 0, NULL, &dir_state); /* output summary */
@@ -7096,7 +7125,7 @@ sprintf (FullPath, "%s%s", directory, filename);
if ((dname[strlen (dname) - 1] == '/') || (dname[strlen (dname) - 1] == '\\'))
dname[strlen (dname) - 1] = '\0';
-if ((!stat (dname, &deststat)) && (deststat.st_mode & S_IFDIR)) {
+if ((!sim_stat (dname, &deststat)) && (deststat.st_mode & S_IFDIR)) {
const char *dslash = (strrchr (dname, '/') ? "/" : (strrchr (dname, '\\') ? "\\" : "/"));
dname[sizeof (dname) - 1] = '\0';
@@ -7161,12 +7190,12 @@ if (path[strlen (path) - 1] == '/') /* trim any trailing / from the path */
path[strlen (path) - 1] = '\0';
while ((c = strstr (path, "//")))
memmove (c, c + 1, strlen (c + 1) + 1); /* clean out any empty directories // */
-if ((!stat (path, &filestat)) && (filestat.st_mode & S_IFDIR))
+if ((!sim_stat (path, &filestat)) && (filestat.st_mode & S_IFDIR))
return sim_messagef (SCPE_OK, "directory %s already exists\n", path);
c = path;
while ((c = strchr (c, '/'))) {
*c = '\0';
- if (!stat (path, &filestat)) {
+ if (!sim_stat (path, &filestat)) {
if (filestat.st_mode & S_IFDIR) {
*c = '/'; /* restore / */
++c;
@@ -7174,24 +7203,12 @@ while ((c = strchr (c, '/'))) {
}
return sim_messagef (SCPE_ARG, "%s is not a directory\n", path);
}
- if (
-#if defined(_WIN32)
- mkdir (path)
-#else
- mkdir (path, 0777)
-#endif
- )
+ if (sim_mkdir (path))
return sim_messagef (SCPE_ARG, "Can't create directory: %s - %s\n", path, strerror (errno));
*c = '/'; /* restore / */
++c;
}
-if (
-#if defined(_WIN32)
- mkdir (path)
-#else
- mkdir (path, 0777)
-#endif
- )
+if (sim_mkdir (path))
return sim_messagef (SCPE_ARG, "Can't create directory: %s - %s\n", path, strerror (errno));
return SCPE_OK;
}
@@ -7201,7 +7218,7 @@ t_stat rmdir_cmd (int32 flg, CONST char *cptr)
GET_SWITCHES (cptr); /* get switches */
if ((!cptr) || (*cptr == '\0'))
return sim_messagef (SCPE_2FARG, "Must specify a directory\n");
-if (rmdir (cptr))
+if (sim_rmdir (cptr))
return sim_messagef (SCPE_ARG, "Can't remove directory: %s - %s\n", cptr, strerror (errno));
return SCPE_OK;
}
@@ -9420,6 +9437,11 @@ void put_rval_pcchk (REG *rptr, uint32 idx, t_value val, t_bool pc_chk)
size_t sz;
t_value mask;
uint32 *ptr;
+t_value prev_val;
+
+if ((!(sim_switches & SWMASK ('Z'))) &&
+ (rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
+ prev_val = get_rval (rptr, idx);
#define PUT_RVAL(sz,rp,id,v,m) \
*(((sz *) rp->loc) + id) = \
@@ -9478,6 +9500,9 @@ else PUT_RVAL (t_uint64, rptr, idx, val, mask);
#else
else PUT_RVAL (uint32, rptr, idx, val, mask);
#endif
+if ((!(sim_switches & SWMASK ('Z'))) &&
+ (rptr->flags & REG_DEPOSIT) && sim_vm_reg_update)
+ sim_vm_reg_update (rptr, idx, prev_val, val);
}
void put_rval (REG *rptr, uint32 idx, t_value val)
diff --git a/scp.h b/scp.h
index 5f423af..711a8ca 100644
--- a/scp.h
+++ b/scp.h
@@ -371,6 +371,7 @@ extern t_addr (*sim_vm_parse_addr) (DEVICE *dptr, CONST char *cptr, CONST char *
extern t_bool (*sim_vm_fprint_stopped) (FILE *st, t_stat reason);
extern t_value (*sim_vm_pc_value) (void);
extern t_bool (*sim_vm_is_subroutine_call) (t_addr **ret_addrs);
+extern void (*sim_vm_reg_update) (REG *rptr, uint32 idx, t_value prev_val, t_value new_val);
extern const char **sim_clock_precalibrate_commands;
extern int32 sim_vm_initial_ips; /* base estimate of simulated instructions per second */
extern const char *sim_vm_interval_units; /* Simulator can change this - default "instructions" */
diff --git a/sim_defs.h b/sim_defs.h
index 6beb214..dbc8c96 100644
--- a/sim_defs.h
+++ b/sim_defs.h
@@ -710,6 +710,7 @@ struct REG {
#define REG_VMIO 00400 /* use VM data print/parse */
#define REG_VMAD 01000 /* use VM addr print/parse */
#define REG_FIT 02000 /* fit access to size */
+#define REG_DEPOSIT 04000 /* call VM routine after update */
#define REG_HRO (REG_RO | REG_HIDDEN) /* hidden, read only */
#define REG_V_UF 16 /* device specific */
diff --git a/sim_fio.c b/sim_fio.c
index 4183370..fbd2b0e 100644
--- a/sim_fio.c
+++ b/sim_fio.c
@@ -248,19 +248,90 @@ if ((0 != fstat (fileno (fp), &statb)) ||
return TRUE;
}
+static void _sim_expand_homedir (const char *file, char *dest, size_t dest_size)
+{
+if (memcmp (file, "~/", 2) != 0)
+ strlcpy (dest, file, dest_size);
+else {
+ char *cptr = getenv("HOME");
+ char *cptr2;
+
+ if (cptr == NULL) {
+ cptr = getenv("HOMEPATH");
+ cptr2 = getenv("HOMEDRIVE");
+ }
+ else
+ cptr2 = NULL;
+ if (cptr && (dest_size > strlen (cptr) + strlen (file) + 3))
+ snprintf(dest, dest_size, "%s%s%s%s", cptr2 ? cptr2 : "", cptr, strchr (cptr, '/') ? "/" : "\\", file + 2);
+ else
+ strlcpy (dest, file, dest_size);
+ while ((strchr (dest, '\\') != NULL) && ((cptr = strchr (dest, '/')) != NULL))
+ *cptr = '\\';
+ }
+}
+
+#if defined(_WIN32)
+#include
+#include
+#include
+#else
+#include
+#endif
+
+int sim_stat (const char *fname, struct stat *stat_str)
+{
+char namebuf[PATH_MAX + 1];
+
+_sim_expand_homedir (fname, namebuf, sizeof (namebuf));
+return stat (namebuf, stat_str);
+}
+
+int sim_chdir(const char *path)
+{
+char pathbuf[PATH_MAX + 1];
+
+_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
+return chdir (pathbuf);
+}
+
+int sim_mkdir(const char *path)
+{
+char pathbuf[PATH_MAX + 1];
+
+_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
+#if defined(_WIN32)
+return mkdir (pathbuf);
+#else
+return mkdir (pathbuf, 0777);
+#endif
+}
+
+int sim_rmdir(const char *path)
+{
+char pathbuf[PATH_MAX + 1];
+
+_sim_expand_homedir (path, pathbuf, sizeof (pathbuf));
+return rmdir (pathbuf);
+}
+
+
/* OS-dependent routines */
/* Optimized file open */
FILE *sim_fopen (const char *file, const char *mode)
{
+char namebuf[PATH_MAX + 1];
+
+_sim_expand_homedir (file, namebuf, sizeof (namebuf));
#if defined (VMS)
-return fopen (file, mode, "ALQ=32", "DEQ=4096",
+return fopen (namebuf, mode, "ALQ=32", "DEQ=4096",
"MBF=6", "MBC=127", "FOP=cbt,tef", "ROP=rah,wbh", "CTX=stm");
#elif (defined (__linux) || defined (__linux__) || defined (__hpux) || defined (_AIX)) && !defined (DONT_DO_LARGEFILE)
-return fopen64 (file, mode);
+return fopen64 (namebuf, mode);
#else
-return fopen (file, mode);
+return fopen (namebuf, mode);
#endif
}
@@ -392,7 +463,11 @@ return szMsgBuffer;
t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing)
{
-if (CopyFileA (source_file, dest_file, !overwrite_existing))
+char sourcename[PATH_MAX + 1], destname[PATH_MAX + 1];
+
+_sim_expand_homedir (source_file, sourcename, sizeof (sourcename));
+_sim_expand_homedir (dest_file, destname, sizeof (destname));
+if (CopyFileA (sourcename, destname, !overwrite_existing))
return SCPE_OK;
return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, sim_get_os_error_text (GetLastError ()));
}
@@ -540,7 +615,7 @@ if (fOut)
if (st == SCPE_OK) {
struct stat statb;
- if (!stat (source_file, &statb)) {
+ if (!sim_stat (source_file, &statb)) {
struct utimbuf utim;
utim.actime = statb.st_atime;
@@ -762,7 +837,9 @@ char chr;
const char *p;
char filesizebuf[32] = "";
char filedatetimebuf[32] = "";
+char namebuf[PATH_MAX + 1];
+/* Remove quotes if they're present */
if (((*filepath == '\'') || (*filepath == '"')) &&
(filepath[strlen (filepath) - 1] == *filepath)) {
size_t temp_size = 1 + strlen (filepath);
@@ -774,6 +851,12 @@ if (((*filepath == '\'') || (*filepath == '"')) &&
tempfilepath[strlen (tempfilepath) - 1] = '\0';
filepath = tempfilepath;
}
+
+/* Expand ~/ home directory */
+_sim_expand_homedir (filepath, namebuf, sizeof (namebuf));
+filepath = namebuf;
+
+/* Check for full or current directory relative path */
if ((filepath[1] == ':') ||
(filepath[0] == '/') ||
(filepath[0] == '\\')){
@@ -785,7 +868,7 @@ if ((filepath[1] == ':') ||
}
strcpy (fullpath, filepath);
}
-else {
+else { /* Need to prepend current directory */
char dir[PATH_MAX+1] = "";
char *wd = sim_getcwd(dir, sizeof (dir));
@@ -837,7 +920,8 @@ if (ext == NULL)
tot_size = 0;
if (*parts == '\0') /* empty part specifier means strip only quotes */
tot_size = strlen (tempfilepath);
-if (strchr (parts, 't') || strchr (parts, 'z')) {
+if (strchr (parts, 't') || /* modification time or */
+ strchr (parts, 'z')) { /* or size requested? */
struct stat filestat;
struct tm *tm;
@@ -919,7 +1003,7 @@ WIN32_FIND_DATAA File;
struct stat filestat;
char WildName[PATH_MAX + 1];
-strlcpy (WildName, cptr, sizeof(WildName));
+_sim_expand_homedir (cptr, WildName, sizeof (WildName));
cptr = WildName;
sim_trim_endspc (WildName);
if ((hFind = FindFirstFileA (cptr, &File)) != INVALID_HANDLE_VALUE) {
@@ -982,7 +1066,7 @@ char DirName[PATH_MAX + 1], WholeName[PATH_MAX + 1], WildName[PATH_MAX + 1], Mat
memset (DirName, 0, sizeof(DirName));
memset (WholeName, 0, sizeof(WholeName));
memset (MatchName, 0, sizeof(MatchName));
-strlcpy (WildName, cptr, sizeof(WildName));
+_sim_expand_homedir (cptr, WildName, sizeof (WildName));
cptr = WildName;
sim_trim_endspc (WildName);
c = sim_filepath_parts (cptr, "f");
diff --git a/sim_fio.h b/sim_fio.h
index a632e5f..ba7c23a 100644
--- a/sim_fio.h
+++ b/sim_fio.h
@@ -37,6 +37,8 @@
extern "C" {
#endif
+#include
+
#define FLIP_SIZE (1 << 16) /* flip buf size */
#define fxread(a,b,c,d) sim_fread (a, b, c, d)
#define fxwrite(a,b,c,d) sim_fwrite (a, b, c, d)
@@ -70,6 +72,10 @@ uint32 sim_fsize_name (const char *fname);
t_offset sim_ftell (FILE *st);
t_offset sim_fsize_ex (FILE *fptr);
t_offset sim_fsize_name_ex (const char *fname);
+int sim_stat (const char *fname, struct stat *stat_str);
+int sim_chdir(const char *path);
+int sim_mkdir(const char *path);
+int sim_rmdir(const char *path);
t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing);
char *sim_filepath_parts (const char *pathname, const char *parts);
char *sim_getcwd (char *buf, size_t buf_size);
diff --git a/sim_video.c b/sim_video.c
index d750048..3026a18 100644
--- a/sim_video.c
+++ b/sim_video.c
@@ -370,6 +370,7 @@ t_bool vid_cursor_visible; /* cursor visibility sta
DEVICE *vid_dev;
t_bool vid_key_state[SDL_NUM_SCANCODES];
VID_DISPLAY *next;
+t_bool vid_blending;
};
SDL_Thread *vid_thread_handle = NULL; /* event thread handle */
@@ -448,6 +449,8 @@ if (vid_main_thread_handle == NULL) {
vid_beep_setup (400, 660);
+memset (&event, 0, sizeof (event));
+
while (1) {
int status = SDL_WaitEvent (&event);
if (status == 1) {
@@ -623,6 +626,7 @@ vptr->vid_width = width;
vptr->vid_height = height;
vptr->vid_mouse_captured = FALSE;
vptr->vid_cursor_visible = (vptr->vid_flags & SIM_VID_INPUTCAPTURED);
+vptr->vid_blending = FALSE;
if (!vid_active) {
vid_key_events.head = 0;
@@ -784,6 +788,11 @@ uint32 vid_map_rgb (uint8 r, uint8 g, uint8 b)
return vid_map_rgb_window (&vid_first, r, g, b);
}
+uint32 vid_map_rgba_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b, uint8 a)
+{
+return SDL_MapRGBA (vptr->vid_format, r, g, b, a);
+}
+
static SDL_Rect *vid_dst_last;
static uint32 *vid_data_last;
@@ -1572,11 +1581,15 @@ vid_stretch(vptr, &vid_dst);
sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "Video Update Event: \n");
if (sim_deb)
fflush (sim_deb);
-if (SDL_RenderClear (vptr->vid_renderer))
- sim_printf ("%s: Video Update Event: SDL_RenderClear error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
-if (SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, NULL, &vid_dst))
- sim_printf ("%s: Video Update Event: SDL_RenderCopy error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
-SDL_RenderPresent (vptr->vid_renderer);
+if (vptr->vid_blending)
+ SDL_RenderPresent (vptr->vid_renderer);
+else {
+ if (SDL_RenderClear (vptr->vid_renderer))
+ sim_printf ("%s: Video Update Event: SDL_RenderClear error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
+ if (SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, NULL, &vid_dst))
+ sim_printf ("%s: Video Update Event: SDL_RenderCopy error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
+ SDL_RenderPresent (vptr->vid_renderer);
+ }
}
void vid_update_cursor (VID_DISPLAY *vptr, SDL_Cursor *cursor, t_bool visible)
@@ -1618,8 +1631,13 @@ if (vid_dst == vid_dst_last) {
}
SDL_UnlockMutex (vptr->vid_draw_mutex);
-if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)))
- sim_printf ("%s: vid_draw_region() - SDL_UpdateTexture error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
+if (vptr->vid_blending) {
+ SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf));
+ SDL_RenderCopy (vptr->vid_renderer, vptr->vid_texture, vid_dst, vid_dst);
+ }
+else
+ if (SDL_UpdateTexture(vptr->vid_texture, vid_dst, buf, vid_dst->w*sizeof(*buf)))
+ sim_printf ("%s: vid_draw_region() - SDL_UpdateTexture error: %s\n", vid_dname(vptr->vid_dev), SDL_GetError());
free (vid_dst);
free (buf);
@@ -1686,6 +1704,36 @@ vid_active++;
return 1;
}
+t_stat vid_set_alpha_mode (VID_DISPLAY *vptr, int mode)
+{
+SDL_BlendMode x;
+switch (mode) {
+ case SIM_ALPHA_NONE:
+ vptr->vid_blending = FALSE;
+ x = SDL_BLENDMODE_NONE;
+ break;
+ case SIM_ALPHA_BLEND:
+ vptr->vid_blending = TRUE;
+ x = SDL_BLENDMODE_BLEND;
+ break;
+ case SIM_ALPHA_ADD:
+ vptr->vid_blending = TRUE;
+ x = SDL_BLENDMODE_ADD;
+ break;
+ case SIM_ALPHA_MOD:
+ vptr->vid_blending = TRUE;
+ x = SDL_BLENDMODE_MOD;
+ break;
+ default:
+ return SCPE_ARG;
+ }
+if (SDL_SetTextureBlendMode (vptr->vid_texture, x))
+ return SCPE_IERR;
+if (SDL_SetRenderDrawBlendMode (vptr->vid_renderer, x))
+ return SCPE_IERR;
+return SCPE_OK;
+}
+
static void vid_destroy (VID_DISPLAY *vptr)
{
VID_DISPLAY *parent;
@@ -1968,7 +2016,7 @@ if (0) while (SDL_PeepEvents (&event, 1, SDL_GETEVENT, SD
}
break;
case SDL_QUIT:
- sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE|SIM_VID_DBG_CURSOR, vptr->vid_dev, "vid_thread() - QUIT Event - %s\n", vid_quit_callback ? "Signaled" : "Ignored");
+ sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE|SIM_VID_DBG_CURSOR, vptr0->vid_dev, "vid_thread() - QUIT Event - %s\n", vid_quit_callback ? "Signaled" : "Ignored");
if (vid_quit_callback)
vid_quit_callback ();
break;
diff --git a/sim_video.h b/sim_video.h
index 6e9ebea..3127b45 100644
--- a/sim_video.h
+++ b/sim_video.h
@@ -157,6 +157,11 @@ extern "C" {
#define SIM_KEY_UNKNOWN 200
+#define SIM_ALPHA_NONE 1
+#define SIM_ALPHA_BLEND 2
+#define SIM_ALPHA_ADD 3
+#define SIM_ALPHA_MOD 4
+
typedef struct VID_DISPLAY VID_DISPLAY;
struct mouse_event {
@@ -214,12 +219,14 @@ t_stat vid_open_window (VID_DISPLAY **vptr, DEVICE *dptr, const char *title, uin
t_stat vid_close_window (VID_DISPLAY *vptr);
t_stat vid_close_all (void);
uint32 vid_map_rgb_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b);
+uint32 vid_map_rgba_window (VID_DISPLAY *vptr, uint8 r, uint8 g, uint8 b, uint8 a);
void vid_draw_window (VID_DISPLAY *vptr, int32 x, int32 y, int32 w, int32 h, uint32 *buf);
void vid_refresh_window (VID_DISPLAY *vptr);
t_stat vid_set_cursor_window (VID_DISPLAY *vptr, t_bool visible, uint32 width, uint32 height, uint8 *data, uint8 *mask, uint32 hot_x, uint32 hot_y);
t_bool vid_is_fullscreen_window (VID_DISPLAY *vptr);
t_stat vid_set_fullscreen_window (VID_DISPLAY *vptr, t_bool flag);
void vid_set_cursor_position_window (VID_DISPLAY *vptr, int32 x, int32 y); /* cursor position (set by calling code) */
+t_stat vid_set_alpha_mode (VID_DISPLAY *vptr, int mode);
/* A device simulator can optionally set the vid_display_kb_event_process
* routine pointer to the address of a routine.