mirror of
https://github.com/rcornwell/sims.git
synced 2026-01-11 23:52:48 +00:00
SCP: Updated to current.
This commit is contained in:
parent
e4201d729a
commit
162b7eee94
302
sim_console.c
302
sim_console.c
@ -1,6 +1,6 @@
|
||||
/* sim_console.c: simulator console I/O library
|
||||
|
||||
Copyright (c) 1993-2014, Robert M Supnik
|
||||
Copyright (c) 1993-2022, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,6 +23,15 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
30-Nov-22 RMS Made definitions of sim_os_fd_isatty consistent (Dave Bryan)
|
||||
27-Sep-22 RMS Removed MacOS "Classic" and OS/2 support
|
||||
Added sim_ttisatty
|
||||
14-Jun-19 JDB Fixed argument passing in "sim_show_console"
|
||||
01-Mar-19 JDB SET CONSOLE LOG now closes prior log before opening
|
||||
27-Dec-18 JDB Added missing fall through comment in ControlHandler
|
||||
18-Mar-18 RMS Fixed deboff not to close stdout or stderr (Dave Bryan)
|
||||
31-Mar-15 RMS Backported parity feature from GitHub master
|
||||
10-Nov-14 JDB Added -N option to SET CONSOLE LOG and SET CONSOLE DEBUG
|
||||
02-Jan-14 RMS Added tab stop routines
|
||||
18-Mar-12 RMS Removed unused reference to sim_switches (Dave Bryan)
|
||||
07-Dec-11 MP Added sim_ttisatty to support reasonable behaviour (i.e.
|
||||
@ -117,6 +126,13 @@
|
||||
sim_set_noconsole_port Enable automatic WRU console polling
|
||||
sim_set_stable_registers_state Declare that all registers are always stable
|
||||
|
||||
sim_ttinit - called once to get initial terminal state
|
||||
sim_ttrun - called to put terminal into run state
|
||||
sim_ttcmd - called to return terminal to command state
|
||||
sim_ttclose - called once before the simulator exits
|
||||
sim_ttisatty - called to determine if running interactively
|
||||
sim_os_poll_kbd - poll for keyboard input
|
||||
sim_os_putchar - output character to console
|
||||
|
||||
The first group is OS-independent; the second group is OS-dependent.
|
||||
|
||||
@ -177,7 +193,7 @@ int32 sim_dbg_int_char = 0; /* SIGINT char under deb
|
||||
static t_bool sigint_message_issued = FALSE;
|
||||
int32 sim_brk_char = 000; /* break character */
|
||||
int32 sim_tt_pchar = 0x00002780;
|
||||
#if defined (_WIN32) || defined (__OS2__) || (defined (__MWERKS__) && defined (macintosh))
|
||||
#if defined (_WIN32)
|
||||
int32 sim_del_char = '\b'; /* delete character */
|
||||
#else
|
||||
int32 sim_del_char = 0177;
|
||||
@ -309,6 +325,10 @@ static t_stat sim_con_detach (UNIT *uptr)
|
||||
return sim_set_notelnet (0, NULL);
|
||||
}
|
||||
|
||||
/* Forward declaratations */
|
||||
|
||||
static t_stat sim_os_fd_isatty (int fd);
|
||||
|
||||
/* Set/show data structures */
|
||||
|
||||
static CTAB set_con_tab[] = {
|
||||
@ -3736,284 +3756,6 @@ if (ch != 0177) {
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* OS/2 routines, from Bruce Ray and Holger Veit */
|
||||
|
||||
#elif defined (__OS2__)
|
||||
|
||||
#include <conio.h>
|
||||
|
||||
static t_stat sim_os_ttinit (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttrun (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttcmd (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttclose (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_bool sim_os_fd_isatty (int fd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static t_stat sim_os_poll_kbd (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_poll_kbd()\n");
|
||||
|
||||
#if defined (__EMX__)
|
||||
switch (c = _read_kbd(0,0,0)) { /* EMX has _read_kbd */
|
||||
|
||||
case -1: /* no char*/
|
||||
return SCPE_OK;
|
||||
|
||||
case 0: /* char pending */
|
||||
c = _read_kbd(0,1,0);
|
||||
break;
|
||||
|
||||
default: /* got char */
|
||||
break;
|
||||
}
|
||||
#else
|
||||
if (!kbhit ())
|
||||
return SCPE_OK;
|
||||
c = getch();
|
||||
#endif
|
||||
if ((c & 0177) == sim_del_char)
|
||||
c = 0177;
|
||||
if ((c & 0177) == sim_int_char)
|
||||
return SCPE_STOP;
|
||||
if (sim_brk_char && ((c & 0177) == sim_brk_char))
|
||||
return SCPE_BREAK;
|
||||
return c | SCPE_KFLAG;
|
||||
}
|
||||
|
||||
static t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */
|
||||
{
|
||||
sim_os_ms_sleep (MIN(20,ms_timeout)); /* Wait a little */
|
||||
return TRUE; /* force a poll */
|
||||
}
|
||||
|
||||
static t_stat sim_os_putchar (int32 c)
|
||||
{
|
||||
if (c != 0177) {
|
||||
#if defined (__EMX__)
|
||||
putchar (c);
|
||||
#else
|
||||
putch (c);
|
||||
#endif
|
||||
fflush (stdout);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* Metrowerks CodeWarrior Macintosh routines, from Louis Chretien and
|
||||
Peter Schorn */
|
||||
|
||||
#elif defined (__MWERKS__) && defined (macintosh)
|
||||
|
||||
#include <console.h>
|
||||
#include <Mactypes.h>
|
||||
#include <string.h>
|
||||
#include <sioux.h>
|
||||
#include <unistd.h>
|
||||
#include <siouxglobals.h>
|
||||
#include <Traps.h>
|
||||
#include <LowMem.h>
|
||||
|
||||
/* function prototypes */
|
||||
|
||||
Boolean SIOUXIsAppWindow(WindowPtr window);
|
||||
void SIOUXDoMenuChoice(long menuValue);
|
||||
void SIOUXUpdateMenuItems(void);
|
||||
void SIOUXUpdateScrollbar(void);
|
||||
int ps_kbhit(void);
|
||||
int ps_getch(void);
|
||||
|
||||
extern pSIOUXWin SIOUXTextWindow;
|
||||
static CursHandle iBeamCursorH = NULL; /* contains the iBeamCursor */
|
||||
|
||||
static void updateCursor(void) {
|
||||
WindowPtr window;
|
||||
window = FrontWindow();
|
||||
if (SIOUXIsAppWindow(window)) {
|
||||
GrafPtr savePort;
|
||||
Point localMouse;
|
||||
GetPort(&savePort);
|
||||
SetPort(window);
|
||||
#if TARGET_API_MAC_CARBON
|
||||
GetGlobalMouse(&localMouse);
|
||||
#else
|
||||
localMouse = LMGetMouseLocation();
|
||||
#endif
|
||||
GlobalToLocal(&localMouse);
|
||||
if (PtInRect(localMouse, &(*SIOUXTextWindow->edit)->viewRect) && iBeamCursorH) {
|
||||
SetCursor(*iBeamCursorH);
|
||||
}
|
||||
else {
|
||||
SetCursor(&qd.arrow);
|
||||
}
|
||||
TEIdle(SIOUXTextWindow->edit);
|
||||
SetPort(savePort);
|
||||
}
|
||||
else {
|
||||
SetCursor(&qd.arrow);
|
||||
TEIdle(SIOUXTextWindow->edit);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int ps_kbhit(void) {
|
||||
EventRecord event;
|
||||
int c;
|
||||
updateCursor();
|
||||
SIOUXUpdateScrollbar();
|
||||
while (GetNextEvent(updateMask | osMask | mDownMask | mUpMask | activMask |
|
||||
highLevelEventMask | diskEvt, &event)) {
|
||||
SIOUXHandleOneEvent(&event);
|
||||
}
|
||||
if (SIOUXQuitting) {
|
||||
exit(1);
|
||||
}
|
||||
if (EventAvail(keyDownMask,&event)) {
|
||||
c = event.message&charCodeMask;
|
||||
if ((event.modifiers & cmdKey) && (c > 0x20)) {
|
||||
GetNextEvent(keyDownMask, &event);
|
||||
SIOUXHandleOneEvent(&event);
|
||||
if (SIOUXQuitting) {
|
||||
exit(1);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int ps_getch(void) {
|
||||
int c;
|
||||
EventRecord event;
|
||||
fflush(stdout);
|
||||
updateCursor();
|
||||
while(!GetNextEvent(keyDownMask,&event)) {
|
||||
if (GetNextEvent(updateMask | osMask | mDownMask | mUpMask | activMask |
|
||||
highLevelEventMask | diskEvt, &event)) {
|
||||
SIOUXUpdateScrollbar();
|
||||
SIOUXHandleOneEvent(&event);
|
||||
}
|
||||
}
|
||||
if (SIOUXQuitting) {
|
||||
exit(1);
|
||||
}
|
||||
c = event.message&charCodeMask;
|
||||
if ((event.modifiers & cmdKey) && (c > 0x20)) {
|
||||
SIOUXUpdateMenuItems();
|
||||
SIOUXDoMenuChoice(MenuKey(c));
|
||||
}
|
||||
if (SIOUXQuitting) {
|
||||
exit(1);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/* Note that this only works if the call to sim_ttinit comes before any output to the console */
|
||||
|
||||
static t_stat sim_os_ttinit (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_ttinit()\n");
|
||||
|
||||
/* this blank will later be replaced by the number of characters */
|
||||
char title[50] = " ";
|
||||
unsigned char ptitle[50];
|
||||
SIOUXSettings.autocloseonquit = TRUE;
|
||||
SIOUXSettings.asktosaveonclose = FALSE;
|
||||
SIOUXSettings.showstatusline = FALSE;
|
||||
SIOUXSettings.columns = 80;
|
||||
SIOUXSettings.rows = 40;
|
||||
SIOUXSettings.toppixel = 42;
|
||||
SIOUXSettings.leftpixel = 6;
|
||||
iBeamCursorH = GetCursor(iBeamCursor);
|
||||
strlcat(title, sim_name, sizeof(title));
|
||||
strlcat(title, " Simulator", sizeof(title));
|
||||
title[0] = strlen(title) - 1; /* Pascal string done */
|
||||
for (i = 0; i <= title[0]; i++) { /* copy to unsigned char */
|
||||
ptitle[i] = title[i];
|
||||
}
|
||||
SIOUXSetTitle(ptitle);
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttrun (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttcmd (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_stat sim_os_ttclose (void)
|
||||
{
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
static t_bool sim_os_fd_isatty (int fd)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static t_stat sim_os_poll_kbd (void)
|
||||
{
|
||||
int c;
|
||||
|
||||
sim_debug (DBG_TRC, &sim_con_telnet, "sim_os_poll_kbd()\n");
|
||||
|
||||
if (!ps_kbhit ())
|
||||
return SCPE_OK;
|
||||
c = ps_getch();
|
||||
if ((c & 0177) == sim_del_char)
|
||||
c = 0177;
|
||||
if ((c & 0177) == sim_int_char)
|
||||
return SCPE_STOP;
|
||||
if (sim_brk_char && ((c & 0177) == sim_brk_char))
|
||||
return SCPE_BREAK;
|
||||
return c | SCPE_KFLAG;
|
||||
}
|
||||
|
||||
static t_bool sim_os_poll_kbd_ready (int ms_timeout) /* Don't know how to do this on this platform */
|
||||
{
|
||||
sim_os_ms_sleep (MIN(20,ms_timeout)); /* Wait a little */
|
||||
return TRUE; /* force a poll */
|
||||
}
|
||||
|
||||
static t_stat sim_os_putchar (int32 c)
|
||||
{
|
||||
if (c != 0177) {
|
||||
putchar (c);
|
||||
fflush (stdout);
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
/* BSD UNIX routines */
|
||||
|
||||
#elif defined (BSDTTY)
|
||||
|
||||
#include <sgtty.h>
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/* sim_console.h: simulator console I/O library headers
|
||||
|
||||
Copyright (c) 1993-2014, Robert M Supnik
|
||||
Copyright (c) 1993-2022, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,6 +23,8 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-Sep-22 RMS Added sim_ttisatty
|
||||
14-Dec-14 JDB [4.0] Added sim_*_char externals
|
||||
02-Jan-14 RMS Added tab stop routines
|
||||
17-Jan-11 MP Added buffered line capabilities
|
||||
22-Jun-06 RMS Implemented SET/SHOW PCHAR
|
||||
|
||||
52
sim_defs.h
52
sim_defs.h
@ -23,6 +23,17 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
06-Jun-22 RMS Deprecated UNIT_TEXT, deleted UNIT_RAW
|
||||
10-Mar-22 JDB Modified REG macros to fix "stringizing" problem
|
||||
12-Nov-21 JDB Added UNIT_EXTEND dynamic flag
|
||||
17-Mar-21 JDB Added UNIT_PIPE dynamic flag
|
||||
16-Feb-21 JDB Added "stride" to REG to support arrays of structures
|
||||
Modified REG macros to initialize strides
|
||||
21-Jan-21 JDB Added "size" and "maxval" fields to the REG structure
|
||||
Modified REG macros to initialize access sizes
|
||||
09-Nov-20 RMS More V4.X compatibility hooks (Mark Pizzolato)
|
||||
26-Oct-19 RMS Removed MTAB_VAL definition
|
||||
23-Jun-17 RMS Added #include sim_rev.h (Mark Pizzolato)
|
||||
25-Sep-16 RMS Removed KBD_WAIT and friends
|
||||
08-Mar-16 RMS Added shutdown invisible switch
|
||||
24-Dec-14 JDB Added T_ADDR_FMT
|
||||
@ -93,7 +104,7 @@
|
||||
sim_devices[] array of pointers to simulated devices
|
||||
sim_PC pointer to saved PC register descriptor
|
||||
sim_interval simulator interval to next event
|
||||
sim_stop_messages[SCPE_BASE]
|
||||
sim_stop_messages[SCPE_BASE]
|
||||
array of pointers to stop messages
|
||||
sim_instr() instruction execution routine
|
||||
sim_load() binary loader routine
|
||||
@ -125,6 +136,9 @@ extern int sim_vax_snprintf(char *buf, size_t buf_size, const char *fmt, ...);
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <setjmp.h>
|
||||
|
||||
|
||||
#ifndef EXIT_FAILURE
|
||||
#define EXIT_FAILURE 1
|
||||
@ -152,7 +166,7 @@ extern int sim_vax_snprintf(char *buf, size_t buf_size, const char *fmt, ...);
|
||||
#define USE_REGEX 1
|
||||
#endif
|
||||
|
||||
#if (defined (__MWERKS__) && defined (macintosh)) || defined(__DECC)
|
||||
#if defined(__DECC)
|
||||
#define __FUNCTION__ __FILE__
|
||||
#endif
|
||||
|
||||
@ -207,7 +221,7 @@ typedef __int32 int32;
|
||||
typedef unsigned __int8 uint8;
|
||||
typedef unsigned __int16 uint16;
|
||||
typedef unsigned __int32 uint32;
|
||||
#else
|
||||
#else
|
||||
/* All modern/standard compiler environments */
|
||||
/* any other environment needa a special case above */
|
||||
#include <stdint.h>
|
||||
@ -316,7 +330,7 @@ typedef uint32 t_addr;
|
||||
#define SIM_INLINE inline
|
||||
#define SIM_NOINLINE __attribute__ ((noinline))
|
||||
#else
|
||||
#define SIM_INLINE
|
||||
#define SIM_INLINE
|
||||
#define SIM_NOINLINE
|
||||
#endif
|
||||
|
||||
@ -513,7 +527,7 @@ struct DEVICE {
|
||||
/* mem size routine */
|
||||
char *lname; /* logical name */
|
||||
t_stat (*help)(FILE *st, DEVICE *dptr,
|
||||
UNIT *uptr, int32 flag, const char *cptr);
|
||||
UNIT *uptr, int32 flag, const char *cptr);
|
||||
/* help */
|
||||
t_stat (*attach_help)(FILE *st, DEVICE *dptr,
|
||||
UNIT *uptr, int32 flag, const char *cptr);
|
||||
@ -647,8 +661,10 @@ struct UNIT {
|
||||
#define UNIT_WLK 0100000 /* hardware write lock */
|
||||
#define UNIT_WPRT (UNIT_WLK|UNIT_RO)/* write protect */
|
||||
|
||||
/* Unused/meaningless flags */
|
||||
#define UNIT_TEXT 0000000 /* text mode - no effect */
|
||||
/* Deleted or deprecated */
|
||||
|
||||
// #define UNIT_RAW 000000 /* raw mode */
|
||||
#define UNIT_TEXT 000000 /* text mode */
|
||||
|
||||
#define UNIT_UFMASK_31 (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF_31) - 1))
|
||||
#define UNIT_UFMASK (((1u << UNIT_V_RSV) - 1) & ~((1u << UNIT_V_UF) - 1))
|
||||
@ -892,10 +908,10 @@ struct MEMFILE {
|
||||
size_t pos; /* data used */
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
The following macros exist to help populate structure contents
|
||||
|
||||
They are dependent on the declaration order of the fields
|
||||
They are dependent on the declaration order of the fields
|
||||
of the structures they exist to populate.
|
||||
|
||||
*/
|
||||
@ -965,14 +981,14 @@ struct MEMFILE {
|
||||
This specifies a arrayed register whose elements are array[0].field,
|
||||
array[1].field, etc.
|
||||
|
||||
All above macro names from ORDATA through XRDATA have two additional
|
||||
precisely related macros. The first it the above name with D appended and
|
||||
has an additional parameter which is a quoted string describing the purpose
|
||||
of the register which is visible when displaying HELP about a device's
|
||||
All above macro names from ORDATA through XRDATA have two additional
|
||||
precisely related macros. The first it the above name with D appended and
|
||||
has an additional parameter which is a quoted string describing the purpose
|
||||
of the register which is visible when displaying HELP about a device's
|
||||
registers. The second related macro has the above name with DF appended
|
||||
and has two additional parameters. The first parameter is the register
|
||||
and has two additional parameters. The first parameter is the register
|
||||
description, and the second is the name of a BITFIELD array which describes
|
||||
the fields in the register's contents. This info is used to display the
|
||||
the fields in the register's contents. This info is used to display the
|
||||
register contents (via EXAMINE) along with the detailed bitfield data.
|
||||
For example:
|
||||
|
||||
@ -997,7 +1013,7 @@ struct MEMFILE {
|
||||
will occur before stringization, resulting in the wrong register name.
|
||||
|
||||
3. Additional REG initialization values may be supplied after a macro
|
||||
invocation. If present, these begin with the "flags" field which is,
|
||||
invocation. If present, these begin with the "flags" field which is,
|
||||
for the most part, not specified as a macro parameter.
|
||||
|
||||
4. The URDATA macro is obsolescent and present for backward-compatibility.
|
||||
@ -1014,8 +1030,8 @@ struct MEMFILE {
|
||||
#define _RegCheck(nm,loc,rdx,wd,off,dep,desc,flds,qptr,siz,elesiz,macro) \
|
||||
nm, (loc), (rdx), (wd), (off), (dep), (desc), (flds), (qptr), (siz), sizeof(*(loc)), (elesiz), #macro
|
||||
|
||||
/* Generic Register declaration for all fields.
|
||||
If the register structure is extended, this macro will be retained and a
|
||||
/* Generic Register declaration for all fields.
|
||||
If the register structure is extended, this macro will be retained and a
|
||||
new internal macro will be provided that populates the new register structure */
|
||||
#define REGDATA(nm,loc,rdx,wd,off,dep,desc,flds,fl,qptr,siz) \
|
||||
_RegCheck(#nm,&(loc),rdx,wd,off,dep,desc,flds,qptr,siz,sizeof((loc)),REGDATA),(fl)
|
||||
|
||||
@ -163,7 +163,7 @@ extern "C" {
|
||||
#define ETH_MIN_PACKET 60 /* minimum ethernet packet size */
|
||||
#define ETH_MAX_PACKET 1514 /* maximum ethernet packet size */
|
||||
#define ETH_MAX_JUMBO_FRAME 65536 /* maximum ethernet jumbo frame size (or Offload Segment Size) */
|
||||
#define ETH_MAX_DEVICE 20 /* maximum ethernet devices */
|
||||
#define ETH_MAX_DEVICE 40 /* maximum ethernet devices */
|
||||
#define ETH_CRC_SIZE 4 /* ethernet CRC size */
|
||||
#define ETH_FRAME_SIZE (ETH_MAX_PACKET+ETH_CRC_SIZE) /* ethernet maximum frame size */
|
||||
#define ETH_MIN_JUMBO_FRAME ETH_MAX_PACKET /* Threshold size for Jumbo Frame Processing */
|
||||
|
||||
15
sim_imd.c
15
sim_imd.c
@ -1,6 +1,6 @@
|
||||
/*************************************************************************
|
||||
* *
|
||||
* Copyright (c) 2007-2022 Howard M. Harte. *
|
||||
* Copyright (c) 2007-2023 Howard M. Harte. *
|
||||
* https://github.com/hharte *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining *
|
||||
@ -55,7 +55,12 @@ DISK_INFO *diskOpenEx(FILE *fileref, uint32 isVerbose, DEVICE *device, uint32 de
|
||||
{
|
||||
DISK_INFO *myDisk = NULL;
|
||||
|
||||
myDisk = (DISK_INFO *)malloc(sizeof(DISK_INFO));
|
||||
myDisk = (DISK_INFO*)calloc(1, sizeof(DISK_INFO));
|
||||
if (myDisk == NULL) {
|
||||
sim_printf("%s: %s(): memory allocation failure.\n", __FILE__, __FUNCTION__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
myDisk->file = fileref;
|
||||
myDisk->device = device;
|
||||
myDisk->debugmask = debugmask;
|
||||
@ -765,6 +770,12 @@ t_stat trackWrite(DISK_INFO *myDisk,
|
||||
*/
|
||||
dataLen = sectorLen + 1;
|
||||
sectorData = (uint8 *)malloc(dataLen);
|
||||
|
||||
if (sectorData == NULL) {
|
||||
sim_printf("%s: %s(): memory allocation failure.\n", __FILE__, __FUNCTION__);
|
||||
return SCPE_MEM;
|
||||
}
|
||||
|
||||
memset(sectorData, fillbyte, dataLen);
|
||||
sectorData[0] = SECT_RECORD_NORM;
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#define SIM_MAJOR 4
|
||||
#endif
|
||||
#ifndef SIM_MINOR
|
||||
#define SIM_MINOR 0
|
||||
#define SIM_MINOR 1
|
||||
#endif
|
||||
#ifndef SIM_PATCH
|
||||
#define SIM_PATCH 0
|
||||
|
||||
31
sim_tape.c
31
sim_tape.c
@ -2370,7 +2370,36 @@ return r;
|
||||
|
||||
Implementation notes:
|
||||
|
||||
1. Erase gaps are currently supported only in SIMH (MTUF_F_STD) tape format.
|
||||
1. Erase gaps are currently supported only in standard and extended SIMH
|
||||
tape formats.
|
||||
|
||||
2. Metadatum reads either succeed and return 1 or fail and return 0. If a
|
||||
read fails, and "ferror" returns false, then it must have read into the
|
||||
end of the file (only these three outcomes are possible).
|
||||
|
||||
3. The area scan is necessary for tape image integrity to ensure that a data
|
||||
record straddling the end of the erasure is truncated appropriately. The
|
||||
scan is guaranteed to succeed only if it begins at a valid metadatum. If
|
||||
it begins in the middle of a previously overwritten data record, then the
|
||||
scan will interpret old data values as tape formatting markers. The data
|
||||
record sanity checks attempt to recover from this situation, but it is
|
||||
still possible to corrupt valid data that follows an erasure of an
|
||||
invalid area (e.g., if the leading and trailing length words happen
|
||||
to match but actually represent previously recorded data rather than
|
||||
record metadata). If an application knows that the erased area will
|
||||
not contain valid formatting, the "sim_tape_erase" routine should be used
|
||||
instead, as it erases without first scanning the area.
|
||||
|
||||
4. Truncating an existing data record corresponds to overwriting part of a
|
||||
record on a real tape. Reading such a record on a real drive would
|
||||
produce CRC errors, due to the lost portion. In simulation, we could
|
||||
change a good record (Class 0) to a bad record (Class 8). However, this
|
||||
is not possible for private or reserved record classes, as that would
|
||||
change the classification (consider that a private class that had
|
||||
been ignored would not be once it had been truncated and changed to Class
|
||||
8). Given that there is no good general solution, we do not modify
|
||||
classes for truncated records, as reading a partially erased record is an
|
||||
"all bets are off" operation.
|
||||
*/
|
||||
|
||||
static t_stat tape_erase_fwd (UNIT *uptr, t_mtrlnt gap_size)
|
||||
|
||||
93
sim_timer.c
93
sim_timer.c
@ -1,6 +1,6 @@
|
||||
/* sim_timer.c: simulator timer library
|
||||
|
||||
Copyright (c) 1993-2010, Robert M Supnik
|
||||
Copyright (c) 1993-2022, Robert M Supnik
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,6 +23,11 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
27-Sep-22 RMS Removed OS/2 and Mac "Classic" support
|
||||
01-Feb-21 JDB Added cast for down-conversion
|
||||
22-May-17 RMS Hacked for V4.0 CONST compatibility
|
||||
23-Nov-15 RMS Fixed calibration lost path to reinitialize timer
|
||||
28-Mar-15 RMS Revised to use sim_printf
|
||||
21-Oct-11 MP Fixed throttling in several ways:
|
||||
- Sleep for the observed clock tick size while throttling
|
||||
- Recompute the throttling wait once every 10 seconds
|
||||
@ -536,92 +541,6 @@ return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined (__OS2__)
|
||||
|
||||
/* OS/2 routines, from Bruce Ray */
|
||||
|
||||
const t_bool rtc_avail = FALSE;
|
||||
|
||||
uint32 sim_os_msec (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sim_os_sleep (unsigned int sec)
|
||||
{
|
||||
}
|
||||
|
||||
uint32 sim_os_ms_sleep_init (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 sim_os_ms_sleep (unsigned int msec)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Metrowerks CodeWarrior Macintosh routines, from Ben Supnik */
|
||||
|
||||
#elif defined (__MWERKS__) && defined (macintosh)
|
||||
|
||||
#include <Timer.h>
|
||||
#include <Mactypes.h>
|
||||
#include <sioux.h>
|
||||
#include <unistd.h>
|
||||
#include <siouxglobals.h>
|
||||
#define NANOS_PER_MILLI 1000000
|
||||
#define MILLIS_PER_SEC 1000
|
||||
|
||||
const t_bool rtc_avail = TRUE;
|
||||
|
||||
uint32 sim_os_msec (void)
|
||||
{
|
||||
unsigned long long micros;
|
||||
UnsignedWide macMicros;
|
||||
unsigned long millis;
|
||||
|
||||
Microseconds (&macMicros);
|
||||
micros = *((unsigned long long *) &macMicros);
|
||||
millis = micros / 1000LL;
|
||||
return (uint32) millis;
|
||||
}
|
||||
|
||||
void sim_os_sleep (unsigned int sec)
|
||||
{
|
||||
sleep (sec);
|
||||
}
|
||||
|
||||
uint32 sim_os_ms_sleep_init (void)
|
||||
{
|
||||
return _compute_minimum_sleep ();
|
||||
}
|
||||
|
||||
uint32 sim_os_ms_sleep (unsigned int milliseconds)
|
||||
{
|
||||
uint32 stime = sim_os_msec ();
|
||||
struct timespec treq;
|
||||
|
||||
treq.tv_sec = milliseconds / MILLIS_PER_SEC;
|
||||
treq.tv_nsec = (milliseconds % MILLIS_PER_SEC) * NANOS_PER_MILLI;
|
||||
(void) nanosleep (&treq, NULL);
|
||||
return sim_os_msec () - stime;
|
||||
}
|
||||
|
||||
#if defined(NEED_CLOCK_GETTIME)
|
||||
int clock_gettime(int clk_id, struct timespec *tp)
|
||||
{
|
||||
struct timeval cur;
|
||||
|
||||
if (clk_id != CLOCK_REALTIME)
|
||||
return -1;
|
||||
gettimeofday (&cur, NULL);
|
||||
tp->tv_sec = cur.tv_sec;
|
||||
tp->tv_nsec = cur.tv_usec*1000;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
/* UNIX routines */
|
||||
|
||||
121
sim_video.c
121
sim_video.c
@ -313,17 +313,19 @@ static int SDL_SavePNG_RW(SDL_Surface *surface, SDL_RWops *dst, int freedst)
|
||||
|
||||
*/
|
||||
|
||||
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
||||
#define EVENT_CLOSE 2 /* close event for SDL */
|
||||
#define EVENT_CURSOR 3 /* new cursor for SDL */
|
||||
#define EVENT_WARP 4 /* warp mouse position for SDL */
|
||||
#define EVENT_DRAW 5 /* draw/blit region for SDL */
|
||||
#define EVENT_SHOW 6 /* show SDL capabilities */
|
||||
#define EVENT_OPEN 7 /* vid_open request */
|
||||
#define EVENT_EXIT 8 /* program exit */
|
||||
#define EVENT_SCREENSHOT 9 /* produce screenshot of video window */
|
||||
#define EVENT_BEEP 10 /* audio beep */
|
||||
#define MAX_EVENTS 20 /* max events in queue */
|
||||
#define EVENT_REDRAW 1 /* redraw event for SDL */
|
||||
#define EVENT_CLOSE 2 /* close event for SDL */
|
||||
#define EVENT_CURSOR 3 /* new cursor for SDL */
|
||||
#define EVENT_WARP 4 /* warp mouse position for SDL */
|
||||
#define EVENT_DRAW 5 /* draw/blit region for SDL */
|
||||
#define EVENT_SHOW 6 /* show SDL capabilities */
|
||||
#define EVENT_OPEN 7 /* vid_open request */
|
||||
#define EVENT_EXIT 8 /* program exit */
|
||||
#define EVENT_SCREENSHOT 9 /* produce screenshot of video window */
|
||||
#define EVENT_BEEP 10 /* audio beep */
|
||||
#define EVENT_FULLSCREEN 11 /* fullscreen */
|
||||
#define EVENT_SIZE 12 /* set window size */
|
||||
#define MAX_EVENTS 20 /* max events in queue */
|
||||
|
||||
typedef struct {
|
||||
SIM_KEY_EVENT events[MAX_EVENTS];
|
||||
@ -372,6 +374,7 @@ t_bool vid_key_state[SDL_NUM_SCANCODES];
|
||||
VID_DISPLAY *next;
|
||||
t_bool vid_blending;
|
||||
SDL_Rect *vid_dst_last;
|
||||
SDL_Rect vid_rect;
|
||||
uint32 *vid_data_last;
|
||||
};
|
||||
|
||||
@ -515,7 +518,7 @@ SDL_SetHint (SDL_HINT_RENDER_DRIVER, "software");
|
||||
SDL_SetHint (SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
|
||||
#endif
|
||||
|
||||
status = SDL_Init (SDL_INIT_VIDEO);
|
||||
status = SDL_Init (SDL_INIT_EVENTS);
|
||||
|
||||
if (status) {
|
||||
fprintf (stderr, "SDL Video subsystem can't initialize: %s\n", SDL_GetError ());
|
||||
@ -539,8 +542,10 @@ while (1) {
|
||||
if (event.type == SDL_USEREVENT) {
|
||||
if (event.user.code == EVENT_EXIT)
|
||||
break;
|
||||
if (event.user.code == EVENT_OPEN)
|
||||
if (event.user.code == EVENT_OPEN) {
|
||||
SDL_Init (SDL_INIT_VIDEO);
|
||||
vid_video_events ((VID_DISPLAY *)event.user.data1);
|
||||
}
|
||||
else {
|
||||
if (event.user.code == EVENT_SHOW)
|
||||
vid_show_video_event ();
|
||||
@ -1615,6 +1620,26 @@ if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||
}
|
||||
}
|
||||
|
||||
void vid_set_window_size (VID_DISPLAY *vptr, int32 w, int32 h)
|
||||
{
|
||||
SDL_Event user_event;
|
||||
|
||||
vptr->vid_rect.h = h;
|
||||
vptr->vid_rect.w = w;
|
||||
|
||||
user_event.type = SDL_USEREVENT;
|
||||
user_event.user.windowID = vptr->vid_windowID;
|
||||
user_event.user.code = EVENT_SIZE;
|
||||
user_event.user.data1 = NULL;
|
||||
user_event.user.data2 = NULL;
|
||||
#if defined (SDL_MAIN_AVAILABLE)
|
||||
while (SDL_PushEvent (&user_event) < 0)
|
||||
sim_os_ms_sleep (100);
|
||||
#else
|
||||
SDL_SetWindowSize(vptr->vid_window, w, h);
|
||||
#endif
|
||||
}
|
||||
|
||||
t_bool vid_is_fullscreen_window (VID_DISPLAY *vptr)
|
||||
{
|
||||
return SDL_GetWindowFlags (vptr->vid_window) & SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
@ -1627,10 +1652,22 @@ return vid_is_fullscreen_window (&vid_first);
|
||||
|
||||
t_stat vid_set_fullscreen_window (VID_DISPLAY *vptr, t_bool flag)
|
||||
{
|
||||
SDL_Event user_event;
|
||||
|
||||
user_event.type = SDL_USEREVENT;
|
||||
user_event.user.windowID = vptr->vid_windowID;
|
||||
user_event.user.code = EVENT_FULLSCREEN;
|
||||
user_event.user.data1 = (flag) ? vptr : NULL;
|
||||
user_event.user.data2 = NULL;
|
||||
#if defined (SDL_MAIN_AVAILABLE)
|
||||
while (SDL_PushEvent (&user_event) < 0)
|
||||
sim_os_ms_sleep (100);
|
||||
#else
|
||||
if (flag)
|
||||
SDL_SetWindowFullscreen (vptr->vid_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
else
|
||||
SDL_SetWindowFullscreen (vptr->vid_window, 0);
|
||||
#endif
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
@ -1659,6 +1696,12 @@ else {
|
||||
r->x = 0;
|
||||
r->y = (h - r->h) / 2;
|
||||
}
|
||||
if (vptr->vid_flags & SIM_VID_IGNORE_VBAR) {
|
||||
r->w = w;
|
||||
r->h = h;
|
||||
r->x = 0;
|
||||
r->y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void vid_update (VID_DISPLAY *vptr)
|
||||
@ -1769,6 +1812,11 @@ if (!vptr->vid_texture) {
|
||||
|
||||
vptr->vid_format = SDL_AllocFormat (SDL_PIXELFORMAT_ARGB8888);
|
||||
|
||||
if (vptr->vid_flags & SIM_VID_RESIZABLE) {
|
||||
SDL_SetWindowResizable(vptr->vid_window, SDL_TRUE);
|
||||
SDL_RenderSetIntegerScale(vptr->vid_renderer, SDL_TRUE);
|
||||
}
|
||||
|
||||
SDL_StopTextInput ();
|
||||
|
||||
vptr->vid_windowID = SDL_GetWindowID (vptr->vid_window);
|
||||
@ -2033,22 +2081,27 @@ while (vid_active) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
vid_update (vptr);
|
||||
break;
|
||||
default:
|
||||
sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "Did not handle window event: %d - %s\n", event.window.event, windoweventtypes[event.window.event]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_USEREVENT:
|
||||
/* There are 9 user events generated */
|
||||
/* EVENT_REDRAW to update the display */
|
||||
/* EVENT_DRAW to update a region in the display texture */
|
||||
/* EVENT_SHOW to display the current SDL video capabilities */
|
||||
/* EVENT_CURSOR to change the current cursor */
|
||||
/* EVENT_WARP to warp the cursor position */
|
||||
/* EVENT_OPEN to open a new window */
|
||||
/* EVENT_CLOSE to wake up this thread and let */
|
||||
/* it notice vid_active has changed */
|
||||
/* EVENT_SCREENSHOT to take a screenshot */
|
||||
/* EVENT_BEEP to emit a beep sound */
|
||||
/* There are 11 user events generated */
|
||||
/* EVENT_REDRAW to update the display */
|
||||
/* EVENT_DRAW to update a region in the display texture */
|
||||
/* EVENT_SHOW to display the current SDL video capabilities */
|
||||
/* EVENT_CURSOR to change the current cursor */
|
||||
/* EVENT_WARP to warp the cursor position */
|
||||
/* EVENT_OPEN to open a new window */
|
||||
/* EVENT_CLOSE to wake up this thread and let */
|
||||
/* it notice vid_active has changed */
|
||||
/* EVENT_SCREENSHOT to take a screenshot */
|
||||
/* EVENT_BEEP to emit a beep sound */
|
||||
/* EVENT_SIZE to change screen size */
|
||||
/* EVENT_FULLSCREEN to change fullscreen */
|
||||
while (vid_active && event.user.code) {
|
||||
/* Handle Beep first since it isn't a window oriented event */
|
||||
if (event.user.code == EVENT_BEEP) {
|
||||
@ -2059,7 +2112,7 @@ while (vid_active) {
|
||||
if (event.user.code != EVENT_OPEN) {
|
||||
vptr = vid_get_event_window (&event, event.user.windowID);
|
||||
if (vptr == NULL) {
|
||||
sim_debug (SIM_VID_DBG_VIDEO, vptr->vid_dev, "vid_thread() - Ignored event not bound to a window\n");
|
||||
sim_printf ("vid_thread() - Ignored event not bound to a window\n");
|
||||
event.user.code = 0; /* Mark as done */
|
||||
break;
|
||||
}
|
||||
@ -2104,6 +2157,17 @@ while (vid_active) {
|
||||
vid_screenshot_event ();
|
||||
event.user.code = 0; /* Mark as done */
|
||||
}
|
||||
if (event.user.code == EVENT_SIZE) {
|
||||
SDL_SetWindowSize (vptr->vid_window, vptr->vid_rect.w, vptr->vid_rect.h);
|
||||
event.user.code = 0; /* Mark as done */
|
||||
}
|
||||
if (event.user.code == EVENT_FULLSCREEN) {
|
||||
if (event.user.data1 != NULL)
|
||||
SDL_SetWindowFullscreen (vptr->vid_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
else
|
||||
SDL_SetWindowFullscreen (vptr->vid_window, 0);
|
||||
event.user.code = 0; /* Mark as done */
|
||||
}
|
||||
if (event.user.code == EVENT_BEEP) {
|
||||
vid_beep_event ();
|
||||
event.user.code = 0; /* Mark as done */
|
||||
@ -2341,6 +2405,8 @@ for (i = 0; i < SDL_GetNumRenderDrivers(); ++i) {
|
||||
if (vid_active) {
|
||||
SDL_RendererInfo info;
|
||||
|
||||
info.name = "";
|
||||
|
||||
for (vptr = &vid_first; vptr != NULL; vptr = vptr->next) {
|
||||
if (vptr->vid_active_window) {
|
||||
SDL_GetRendererInfo (vptr->vid_renderer, &info);
|
||||
@ -2820,6 +2886,11 @@ void vid_set_cursor_position_window (VID_DISPLAY *vptr, int32 x, int32 y)
|
||||
return;
|
||||
}
|
||||
|
||||
void vid_set_window_size (VID_DISPLAY *vptr, int32 w, int32 h)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const char *vid_key_name (uint32 key)
|
||||
{
|
||||
return "";
|
||||
|
||||
@ -189,6 +189,8 @@ typedef struct key_event SIM_KEY_EVENT;
|
||||
t_stat vid_open (DEVICE *dptr, const char *title, uint32 width, uint32 height, int flags);
|
||||
#define SIM_VID_INPUTCAPTURED 1 /* Mouse and Keyboard input captured (calling */
|
||||
/* code responsible for cursor display in video) */
|
||||
#define SIM_VID_IGNORE_VBAR 2 /* ignore video buffer aspect ratio */
|
||||
#define SIM_VID_RESIZABLE 4 /* video screen is resizable */
|
||||
typedef void (*VID_QUIT_CALLBACK)(void);
|
||||
t_stat vid_register_quit_callback (VID_QUIT_CALLBACK callback);
|
||||
typedef void (*VID_GAMEPAD_CALLBACK)(int, int, int);
|
||||
@ -214,6 +216,7 @@ t_stat vid_set_fullscreen (t_bool flag);
|
||||
|
||||
extern int vid_active;
|
||||
void vid_set_cursor_position (int32 x, int32 y); /* cursor position (set by calling code) */
|
||||
void vid_set_window_size (VID_DISPLAY *vptr, int32 x, int32 y); /* window size (set by calling code) */
|
||||
|
||||
t_stat vid_open_window (VID_DISPLAY **vptr, DEVICE *dptr, const char *title, uint32 width, uint32 height, int flags);
|
||||
t_stat vid_close_window (VID_DISPLAY *vptr);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user