From 43581c1739040f9ad1bca99bcafd487a12ac7648 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Thu, 8 Mar 2018 22:34:23 -0500 Subject: [PATCH] SCP: Updated to current version. --- display/display.c | 23 +++++++----- scp.c | 1 - scp.h | 1 + sim_disk.c | 95 +++++++++++++++++++++++++++++++++++------------ sim_ether.h | 7 +++- sim_fio.c | 16 +++++--- sim_fio.h | 1 + sim_rev.h | 2 +- sim_serial.c | 1 + sim_tmxr.c | 25 +++++++++++-- 10 files changed, 127 insertions(+), 45 deletions(-) diff --git a/display/display.c b/display/display.c index dcc0b82..65e6bf1 100644 --- a/display/display.c +++ b/display/display.c @@ -105,13 +105,19 @@ struct display { /* * original phosphor constants from Raphael Nabet's XMame 0.72.1 PDP-1 sim. - * not even sure Type30 really used P17 (guess by Daniel P. B. Smith) + * + * http://bitsavers.trailing-edge.com/components/rca/hb-3/1963_HB-3_CRT_Storage_Tube_and_Monoscope_Section.pdf + * pdf p374 says 16ADP7 used P7 phosphor. + * pdf pp28-32 describe P7 phosphor (spectra, buildup, persistence) + * + * https://www.youtube.com/watch?v=hZumwXS4fJo + * "3RP7A CRT - P7 Phosphor Persistence" shows colors/persistence */ -static struct phosphor p17[] = { +static struct phosphor p7[] = { {0.11, 0.11, 1.0, 0.5, 0.05}, /* fast blue */ {1.0, 1.0, 0.11, 0.5, 0.20} /* slow yellow/green */ }; -static struct color color_p17 = { p17, ELEMENTS(p17), 125000 }; +static struct color color_p7 = { p7, ELEMENTS(p7), 125000 }; /* green phosphor for VR14, VR17, VR20 */ static struct phosphor p29[] = {{0.0260, 1.0, 0.00121, 0.5, 0.025}}; @@ -137,10 +143,10 @@ static struct display displays[] = { * 12" tube, * maximum dot size ??? * 50us point plot time (20,000 points/sec) - * P17 Phosphor??? Two phosphor layers: + * P7 Phosphor??? Two phosphor layers: * fast blue (.05s half life), and slow green (.2s half life) */ - { DIS_TX0, "MIT TX-0", &color_p17, NULL, 512, 512 }, + { DIS_TX0, "MIT TX-0", &color_p7, NULL, 512, 512 }, /* @@ -152,12 +158,12 @@ static struct display displays[] = { * 16" tube, 14 3/8" square raster * maximum dot size .015" * 50us point plot time (20,000 points/sec) - * P17 Phosphor??? Two phosphor layers: + * P7 Phosphor??? Two phosphor layers: * fast blue (.05s half life), and slow green (.2s half life) * 360 lb * 7A at 115+-10V 60Hz */ - { DIS_TYPE30, "Type 30", &color_p17, NULL, 1024, 1024 }, + { DIS_TYPE30, "Type 30", &color_p7, NULL, 1024, 1024 }, /* * VR14 @@ -221,7 +227,7 @@ static struct display displays[] = { * 0,0 at lower left * 8 intensity levels */ - { DIS_TYPE340, "Type 340", &color_p17, NULL, 1024, 1024 } + { DIS_TYPE340, "Type 340", &color_p7, NULL, 1024, 1024 } }; /* @@ -1001,7 +1007,6 @@ unsigned long spacewar_switches = 0; void display_keydown(int k) { - /*printf("down '%c'\r\n", k); /**/ switch (k) { /* handle spacewar switches: see display.h for copious commentary */ #define SWSW(LC,UC,BIT,POS36,FUNC36) \ diff --git a/scp.c b/scp.c index ae40882..0d44d5c 100644 --- a/scp.c +++ b/scp.c @@ -474,7 +474,6 @@ typedef enum { SW_NUMBER /* Numeric Value */ } SWITCH_PARSE; SWITCH_PARSE get_switches (const char *cptr, int32 *sw_val, int32 *sw_number); -CONST char *get_sim_sw (CONST char *cptr); t_stat get_aval (t_addr addr, DEVICE *dptr, UNIT *uptr); t_value get_rval (REG *rptr, uint32 idx); void put_rval (REG *rptr, uint32 idx, t_value val); diff --git a/scp.h b/scp.h index c999c1a..faa9771 100644 --- a/scp.h +++ b/scp.h @@ -228,6 +228,7 @@ size_t sim_strlcpy (char *dst, const char *src, size_t size); #define strcasecmp(str1, str2) sim_strcasecmp ((str1), (str2)) #endif CONST char *get_sim_opt (int32 opt, CONST char *cptr, t_stat *st); +CONST char *get_sim_sw (CONST char *cptr); const char *put_switches (char *buf, size_t bufsize, uint32 sw); CONST char *get_glyph (const char *iptr, char *optr, char mchar); CONST char *get_glyph_nc (const char *iptr, char *optr, char mchar); diff --git a/sim_disk.c b/sim_disk.c index ae8f61d..0aaf9c9 100644 --- a/sim_disk.c +++ b/sim_disk.c @@ -92,6 +92,8 @@ struct disk_context { uint32 xfer_element_size; /* Disk Bus Transfer size (1 - byte, 2 - word, 4 - longword) */ uint32 storage_sector_size;/* Sector size of the containing storage */ uint32 removable; /* Removable device flag */ + uint32 is_cdrom; /* Host system CDROM Device */ + uint32 media_removed; /* Media not available flag */ uint32 auto_format; /* Format determined dynamically */ #if defined _WIN32 HANDLE disk_handle; /* OS specific Raw device handle */ @@ -282,7 +284,7 @@ static t_stat sim_os_disk_unload_raw (FILE *f); static t_bool sim_os_disk_isavailable_raw (FILE *f); static t_stat sim_os_disk_rdsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectsread, t_seccnt sects); static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *sectswritten, t_seccnt sects); -static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable); +static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom); static char *HostPathToVhdPath (const char *szHostPath, char *szVhdPath, size_t VhdPathSize); static char *VhdPathToHostPath (const char *szVhdPath, char *szHostPath, size_t HostPathSize); static t_offset get_filesystem_size (UNIT *uptr); @@ -383,6 +385,8 @@ return SCPE_OK; t_bool sim_disk_isavailable (UNIT *uptr) { +struct disk_context *ctx; + if (!(uptr->flags & UNIT_ATT)) /* attached? */ return FALSE; switch (DK_GET_FMT (uptr)) { /* case on format */ @@ -392,7 +396,28 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ return TRUE; break; case DKUF_F_RAW: /* Raw Physical Disk Access */ - return sim_os_disk_isavailable_raw (uptr->fileref); + ctx = (struct disk_context *)uptr->disk_ctx; + + if (sim_os_disk_isavailable_raw (uptr->fileref)) { + if (ctx->media_removed) { + int32 saved_switches = sim_switches; + int32 saved_quiet = sim_quiet; + char *path = (char *)malloc (1 + strlen (uptr->filename)); + + sim_switches = 0; + sim_quiet = 1; + strcpy (path, uptr->filename); + sim_disk_attach (uptr, path, ctx->sector_size, ctx->xfer_element_size, + FALSE, ctx->dbit, NULL, 0, 0); + sim_quiet = saved_quiet; + sim_switches = saved_switches; + free (path); + ctx->media_removed = 0; + } + } + else + ctx->media_removed = 1; + return !ctx->media_removed; break; default: return FALSE; @@ -797,11 +822,15 @@ return r; t_stat sim_disk_unload (UNIT *uptr) { +struct disk_context *ctx = (struct disk_context *)uptr->disk_ctx; + switch (DK_GET_FMT (uptr)) { /* case on format */ case DKUF_F_STD: /* Simh */ case DKUF_F_VHD: /* VHD format */ + ctx->media_removed = 1; return sim_disk_detach (uptr); case DKUF_F_RAW: /* Raw Physical Disk Access */ + ctx->media_removed = 1; return sim_os_disk_unload_raw (uptr->fileref); /* remove/eject disk */ break; default: @@ -1302,7 +1331,7 @@ char tbuf[4*CBUFSIZE]; FILE *(*open_function)(const char *filename, const char *mode) = sim_fopen; FILE *(*create_function)(const char *filename, t_offset desiredsize) = NULL; t_offset (*size_function)(FILE *file); -t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable) = NULL; +t_stat (*storage_function)(FILE *file, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) = NULL; t_bool created = FALSE, copied = FALSE; t_bool auto_format = FALSE; t_offset capac, filesystem_capac; @@ -1523,6 +1552,7 @@ ctx->capac_factor = ((dptr->dwidth / dptr->aincr) == 16) ? 2 : 1; /* save capaci ctx->xfer_element_size = (uint32)xfer_element_size; /* save xfer_element_size */ ctx->dptr = dptr; /* save DEVICE pointer */ ctx->dbit = dbit; /* save debug bit */ +ctx->media_removed = 0; /* default present */ sim_debug (ctx->dbit, ctx->dptr, "sim_disk_attach(unit=%d,filename='%s')\n", (int)(uptr-ctx->dptr->units), uptr->filename); ctx->auto_format = auto_format; /* save that we auto selected format */ ctx->storage_sector_size = (uint32)sector_size; /* Default */ @@ -1578,7 +1608,7 @@ uptr->pos = 0; /* Get Device attributes if they are available */ if (storage_function) - storage_function (uptr->fileref, &ctx->storage_sector_size, &ctx->removable); + storage_function (uptr->fileref, &ctx->storage_sector_size, &ctx->removable, &ctx->is_cdrom); if ((created) && (!copied)) { t_stat r = SCPE_OK; @@ -1592,7 +1622,7 @@ if ((created) && (!copied)) { 2) it allocates storage for the whole disk at creation time to avoid strange failures which may happen during simulator execution if the containing disk is full - 3) it leaves a Sinh Format disk at the intended size so it may + 3) it leaves a Simh Format disk at the intended size so it may subsequently be autosized with the correct size. */ if (secbuf == NULL) @@ -1954,8 +1984,12 @@ switch (DK_GET_FMT (uptr)) { /* case on format */ case DKUF_F_STD: /* SIMH format */ case DKUF_F_VHD: /* VHD format */ case DKUF_F_RAW: /* Raw Physical Disk Access */ +#if defined(_WIN32) + saved_errno = GetLastError (); +#endif perror (msg); - sim_printf ("%s %s: %s\n", sim_uname(uptr), msg, strerror(saved_errno)); + sim_printf ("%s %s: %s\n", sim_uname(uptr), msg, sim_get_os_error_text (saved_errno)); + break; default: ; } @@ -2256,6 +2290,7 @@ static FILE *sim_os_disk_open_raw (const char *rawdevicename, const char *openmo { HANDLE Handle; DWORD DesiredAccess = 0; +uint32 is_cdrom; if (strchr (openmode, 'r')) DesiredAccess |= GENERIC_READ; @@ -2274,14 +2309,27 @@ if (!memcmp ("\\.\\", rawdevicename, 3)) { strcpy (tmpname + 1, rawdevicename); Handle = CreateFileA (tmpname, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL); free (tmpname); - if (Handle != INVALID_HANDLE_VALUE) + if (Handle != INVALID_HANDLE_VALUE) { + if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) || + (DesiredAccess & GENERIC_WRITE) && is_cdrom) { + CloseHandle (Handle); + errno = EACCES; + return NULL; + } return (FILE *)Handle; + } } Handle = CreateFileA (rawdevicename, DesiredAccess, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS|FILE_FLAG_WRITE_THROUGH, NULL); if (Handle == INVALID_HANDLE_VALUE) { _set_errno_from_status (GetLastError ()); return NULL; } +if ((sim_os_disk_info_raw ((FILE *)Handle, NULL, NULL, &is_cdrom)) || + (DesiredAccess & GENERIC_WRITE) && is_cdrom) { + CloseHandle (Handle); + errno = EACCES; + return NULL; + } return (FILE *)Handle; } @@ -2364,7 +2412,7 @@ static t_stat sim_os_disk_unload_raw (FILE *Disk) DWORD BytesReturned; uint32 Removable = FALSE; -sim_os_disk_info_raw (Disk, NULL, &Removable); +sim_os_disk_info_raw (Disk, NULL, &Removable, NULL); if (Removable) { if (!DeviceIoControl((HANDLE)Disk, /* handle to disk */ IOCTL_STORAGE_EJECT_MEDIA, /* dwIoControlCode */ @@ -2390,7 +2438,7 @@ static t_bool sim_os_disk_isavailable_raw (FILE *Disk) DWORD BytesReturned; uint32 Removable = FALSE; -sim_os_disk_info_raw (Disk, NULL, &Removable); +sim_os_disk_info_raw (Disk, NULL, &Removable, NULL); if (Removable) { if (!DeviceIoControl((HANDLE)Disk, /* handle to disk */ IOCTL_STORAGE_CHECK_VERIFY, /* dwIoControlCode */ @@ -2408,26 +2456,27 @@ if (Removable) { return TRUE; } -static t_stat sim_os_disk_info_raw (FILE *Disk, uint32 *sector_size, uint32 *removable) +static t_stat sim_os_disk_info_raw (FILE *Disk, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) { DWORD IoctlReturnSize; STORAGE_DEVICE_NUMBER Device; ZeroMemory (&Device, sizeof (Device)); -if (DeviceIoControl((HANDLE)Disk, /* handle to volume */ - IOCTL_STORAGE_GET_DEVICE_NUMBER, /* dwIoControlCode */ - NULL, /* lpInBuffer */ - 0, /* nInBufferSize */ - (LPVOID) &Device, /* output buffer */ - (DWORD) sizeof(Device), /* size of output buffer */ - (LPDWORD) &IoctlReturnSize, /* number of bytes returned */ - (LPOVERLAPPED) NULL)) /* OVERLAPPED structure */ - sim_printf ("Device OK - Type: %s, Number: %d\n", _device_type_name (Device.DeviceType), (int)Device.DeviceNumber); +DeviceIoControl((HANDLE)Disk, /* handle to volume */ + IOCTL_STORAGE_GET_DEVICE_NUMBER, /* dwIoControlCode */ + NULL, /* lpInBuffer */ + 0, /* nInBufferSize */ + (LPVOID) &Device, /* output buffer */ + (DWORD) sizeof(Device), /* size of output buffer */ + (LPDWORD) &IoctlReturnSize, /* number of bytes returned */ + (LPOVERLAPPED) NULL); /* OVERLAPPED structure */ if (sector_size) *sector_size = 512; if (removable) *removable = 0; +if (is_cdrom) + *is_cdrom = (Device.DeviceType == FILE_DEVICE_CD_ROM) || (Device.DeviceType == FILE_DEVICE_DVD); #ifdef IOCTL_STORAGE_READ_CAPACITY if (1) { STORAGE_READ_CAPACITY S; @@ -2496,8 +2545,6 @@ if (1) { *removable = H.MediaRemovable; } #endif -if (removable && *removable) - sim_printf ("Removable Device\n"); return SCPE_OK; } @@ -2644,12 +2691,14 @@ if (sectswritten) return SCPE_OK; } -static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable) +static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) { if (sector_size) *sector_size = 512; if (removable) *removable = 0; +if (is_cdrom) + *is_cdrom = 0; return SCPE_OK; } @@ -2702,7 +2751,7 @@ static t_stat sim_os_disk_wrsect (UNIT *uptr, t_lba lba, uint8 *buf, t_seccnt *s return SCPE_NOFNC; } -static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable) +static t_stat sim_os_disk_info_raw (FILE *f, uint32 *sector_size, uint32 *removable, uint32 *is_cdrom) { return SCPE_NOFNC; } diff --git a/sim_ether.h b/sim_ether.h index 8fdded5..b331086 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -102,6 +102,11 @@ extern "C" { #define PCAP_READ_TIMEOUT 1 #endif +#include +#if defined(__struct_timespec_defined) && !defined(_TIMESPEC_DEFINED) +#define _TIMESPEC_DEFINED +#endif + /* set related values to have correct relationships */ #if defined (USE_READER_THREAD) #include @@ -113,8 +118,6 @@ extern "C" { #if (!defined (xBSD) && !defined(_WIN32) && !defined(VMS) && !defined(__CYGWIN__)) || defined (HAVE_TAP_NETWORK) || defined (HAVE_VDE_NETWORK) #define MUST_DO_SELECT 1 #endif -#else -#include #endif /* USE_READER_THREAD */ /* give priority to USE_NETWORK over USE_SHARED */ diff --git a/sim_fio.c b/sim_fio.c index d05e18f..6d7cb6e 100644 --- a/sim_fio.c +++ b/sim_fio.c @@ -375,8 +375,8 @@ return sim_fseeko (st, (t_offset)offset, whence); } #if defined(_WIN32) -static const char * -GetErrorText(DWORD dwError) +const char * +sim_get_os_error_text (int Error) { static char szMsgBuffer[2048]; DWORD dwStatus; @@ -384,13 +384,13 @@ DWORD dwStatus; dwStatus = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM| FORMAT_MESSAGE_IGNORE_INSERTS, // __in DWORD dwFlags, NULL, // __in_opt LPCVOID lpSource, - dwError, // __in DWORD dwMessageId, + Error, // __in DWORD dwMessageId, 0, // __in DWORD dwLanguageId, szMsgBuffer, // __out LPTSTR lpBuffer, sizeof (szMsgBuffer) -1, // __in DWORD nSize, NULL); // __in_opt va_list *Arguments if (0 == dwStatus) - snprintf(szMsgBuffer, sizeof(szMsgBuffer) - 1, "Error Code: 0x%lX", dwError); + snprintf(szMsgBuffer, sizeof(szMsgBuffer) - 1, "Error Code: 0x%X", Error); while (sim_isspace (szMsgBuffer[strlen (szMsgBuffer)-1])) szMsgBuffer[strlen (szMsgBuffer) - 1] = '\0'; return szMsgBuffer; @@ -400,7 +400,7 @@ t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool over { if (CopyFileA (source_file, dest_file, !overwrite_existing)) return SCPE_OK; -return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, GetErrorText (GetLastError ())); +return sim_messagef (SCPE_ARG, "Error Copying '%s' to '%s': %s\n", source_file, dest_file, sim_get_os_error_text (GetLastError ())); } #include @@ -471,6 +471,12 @@ return ftruncate(fileno(fptr), (off_t)size); #include #endif +const char * +sim_get_os_error_text (int Error) +{ +return strerror (Error); +} + t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing) { FILE *fIn = NULL, *fOut = NULL; diff --git a/sim_fio.h b/sim_fio.h index e372aba..530ed43 100644 --- a/sim_fio.h +++ b/sim_fio.h @@ -69,6 +69,7 @@ t_offset sim_fsize_name_ex (const char *fname); t_stat sim_copyfile (const char *source_file, const char *dest_file, t_bool overwrite_existing); void sim_buf_swap_data (void *bptr, size_t size, size_t count); void sim_buf_copy_swapped (void *dptr, const void *bptr, size_t size, size_t count); +const char *sim_get_os_error_text (int error); typedef struct SHMEM SHMEM; t_stat sim_shmem_open (const char *name, size_t size, SHMEM **shmem, void **addr); void sim_shmem_close (SHMEM *shmem); diff --git a/sim_rev.h b/sim_rev.h index 7eb068f..a929631 100644 --- a/sim_rev.h +++ b/sim_rev.h @@ -41,7 +41,7 @@ #endif #ifndef SIM_VERSION_MODE -#define SIM_VERSION_MODE "Beta" +#define SIM_VERSION_MODE "Current" #endif #if defined(SIM_NEED_GIT_COMMIT_ID) diff --git a/sim_serial.c b/sim_serial.c index 5b76713..b370b20 100644 --- a/sim_serial.c +++ b/sim_serial.c @@ -845,6 +845,7 @@ DWORD commerrors; COMSTAT cs; char *bptr; +memset (brk, 0, count); /* start with no break indicators */ if (!ClearCommError (port->hPort, &commerrors, &cs)) { /* get the comm error flags */ sim_error_serial ("ClearCommError", /* function failed; report unexpected error */ (int) GetLastError ()); diff --git a/sim_tmxr.c b/sim_tmxr.c index b93bf26..4897824 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -986,15 +986,29 @@ if (mp->last_poll_time == 0) { /* first poll initializa if (!uptr) /* Attached ? */ return -1; /* No connections are possinle! */ + uptr->dynflags |= UNIT_TM_POLL; /* Tag as polling unit */ + uptr->tmxr = (void *)mp; /* Connect UNIT to TMXR */ + if (mp->poll_interval == 0) /* Assure reasonable polling interval */ mp->poll_interval = TMXR_DEFAULT_CONNECT_POLL_INTERVAL; - if (!(uptr->dynflags & TMUF_NOASYNCH)) { /* if asynch not disabled */ + if (!(uptr->dynflags & TMUF_NOASYNCH)) /* if asynch not disabled */ sim_cancel (uptr); - } + for (i=0; i < mp->lines; i++) { + if (mp->ldsc[i].uptr) + mp->ldsc[i].uptr->dynflags |= UNIT_TM_POLL; /* Tag as polling unit */ + else + mp->ldsc[i].uptr = uptr; /* default line input polling to primary poll unit */ + if (mp->ldsc[i].o_uptr) + mp->ldsc[i].o_uptr->dynflags |= UNIT_TM_POLL;/* Tag as polling unit */ + else + mp->ldsc[i].o_uptr = uptr; /* default line output polling to primary poll unit */ if (!(mp->uptr->dynflags & TMUF_NOASYNCH)) { /* if asynch not disabled */ - sim_cancel (mp->ldsc[i].uptr); + if (mp->ldsc[i].uptr) + sim_cancel (mp->ldsc[i].uptr); + if (mp->ldsc[i].o_uptr) + sim_cancel (mp->ldsc[i].o_uptr); } } } @@ -1616,8 +1630,11 @@ t_stat tmxr_set_config_line (TMLN *lp, CONST char *config) t_stat r; tmxr_debug_trace_line (lp, "tmxr_set_config_line()"); -if (lp->serport) +if (lp->serport) { r = sim_config_serial (lp->serport, config); + if (r == SCPE_OK) + tmxr_set_line_speed (lp, config); + } else { lp->serconfig = (char *)realloc (lp->serconfig, 1 + strlen (config)); strcpy (lp->serconfig, config);