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.