diff --git a/Ibm1130/ibm1130.ico b/Ibm1130/ibm1130.ico new file mode 100644 index 00000000..903171e4 Binary files /dev/null and b/Ibm1130/ibm1130.ico differ diff --git a/Ibm1130/ibm1130.mak b/Ibm1130/ibm1130.mak deleted file mode 100644 index 4651d698..00000000 --- a/Ibm1130/ibm1130.mak +++ /dev/null @@ -1,435 +0,0 @@ -# Microsoft Visual C++ Generated NMAKE File, Format Version 2.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -!IF "$(CFG)" == "" -CFG=Win32 Debug -!MESSAGE No configuration specified. Defaulting to Win32 Debug. -!ENDIF - -!IF "$(CFG)" != "Win32 Release" && "$(CFG)" != "Win32 Debug" -!MESSAGE Invalid configuration "$(CFG)" specified. -!MESSAGE You can specify a configuration when running NMAKE on this makefile -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "ibm1130.mak" CFG="Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE "Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE -!ERROR An invalid configuration is specified. -!ENDIF - -################################################################################ -# Begin Project -# PROP Target_Last_Scanned "Win32 Debug" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "WinRel" -# PROP BASE Intermediate_Dir "WinRel" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "WinRel" -# PROP Intermediate_Dir "WinRel" -OUTDIR=.\WinRel -INTDIR=.\WinRel - -ALL : $(OUTDIR)/ibm1130.exe $(OUTDIR)/ibm1130.bsc - -$(OUTDIR) : - if not exist $(OUTDIR)/nul mkdir $(OUTDIR) - -# ADD BASE CPP /nologo /W3 /GX /YX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /FR /c -# ADD CPP /nologo /W3 /GX /YX /O2 /I "c:\pdp11\supnik" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "GUI_SUPPORT" /U "VMS" /FR /c -CPP_PROJ=/nologo /W3 /GX /YX /O2 /I "c:\pdp11\supnik" /D "NDEBUG" /D "WIN32" /D\ - "_CONSOLE" /D "GUI_SUPPORT" /U "VMS" /FR$(INTDIR)/ /Fp$(OUTDIR)/"ibm1130.pch"\ - /Fo$(INTDIR)/ /c -CPP_OBJS=.\WinRel/ -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -RSC_PROJ=/l 0x409 /fo$(INTDIR)/"ibm1130.res" /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o$(OUTDIR)/"ibm1130.bsc" -BSC32_SBRS= \ - $(INTDIR)/ibm1130_cpu.sbr \ - $(INTDIR)/ibm1130_sys.sbr \ - $(INTDIR)/ibm1130_cr.sbr \ - $(INTDIR)/ibm1130_stddev.sbr \ - $(INTDIR)/ibm1130_disk.sbr \ - $(INTDIR)/ibm1130_gdu.sbr \ - $(INTDIR)/ibm1130_gui.sbr \ - $(INTDIR)/ibm1130_prt.sbr \ - $(INTDIR)/scp.sbr \ - $(INTDIR)/sim_tmxr.sbr \ - $(INTDIR)/sim_sock.sbr \ - $(INTDIR)/ibm1130_fmt.sbr \ - $(INTDIR)/sim_console.sbr \ - $(INTDIR)/sim_fio.sbr \ - $(INTDIR)/sim_timer.sbr \ - $(INTDIR)/ibm1130_ptrp.sbr - -$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib wsock32.lib shell32.lib /NOLOGO /SUBSYSTEM:console /MACHINE:I386 -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib\ - wsock32.lib shell32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:no\ - /PDB:$(OUTDIR)/"ibm1130.pdb" /MACHINE:I386 /OUT:$(OUTDIR)/"ibm1130.exe" -DEF_FILE= -LINK32_OBJS= \ - $(INTDIR)/ibm1130_cpu.obj \ - $(INTDIR)/ibm1130_sys.obj \ - $(INTDIR)/ibm1130_cr.obj \ - $(INTDIR)/ibm1130_stddev.obj \ - $(INTDIR)/ibm1130.res \ - $(INTDIR)/ibm1130_disk.obj \ - $(INTDIR)/ibm1130_gdu.obj \ - $(INTDIR)/ibm1130_gui.obj \ - $(INTDIR)/ibm1130_prt.obj \ - $(INTDIR)/scp.obj \ - $(INTDIR)/sim_tmxr.obj \ - $(INTDIR)/sim_sock.obj \ - $(INTDIR)/ibm1130_fmt.obj \ - $(INTDIR)/sim_console.obj \ - $(INTDIR)/sim_fio.obj \ - $(INTDIR)/sim_timer.obj \ - $(INTDIR)/ibm1130_ptrp.obj - -$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ELSEIF "$(CFG)" == "Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "WinDebug" -# PROP BASE Intermediate_Dir "WinDebug" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "WinDebug" -# PROP Intermediate_Dir "WinDebug" -OUTDIR=.\WinDebug -INTDIR=.\WinDebug - -ALL : $(OUTDIR)/ibm1130.exe $(OUTDIR)/ibm1130.bsc - -$(OUTDIR) : - if not exist $(OUTDIR)/nul mkdir $(OUTDIR) - -# ADD BASE CPP /nologo /W3 /GX /Zi /YX /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /FR /c -# ADD CPP /nologo /W3 /GX /Zi /YX /Od /I "c:\pdp11\supnik" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "GUI_SUPPORT" /U "VMS" /FR /c -CPP_PROJ=/nologo /W3 /GX /Zi /YX /Od /I "c:\pdp11\supnik" /D "_DEBUG" /D\ - "WIN32" /D "_CONSOLE" /D "GUI_SUPPORT" /U "VMS" /FR$(INTDIR)/\ - /Fp$(OUTDIR)/"ibm1130.pch" /Fo$(INTDIR)/ /Fd$(OUTDIR)/"ibm1130.pdb" /c -CPP_OBJS=.\WinDebug/ -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -RSC_PROJ=/l 0x409 /fo$(INTDIR)/"ibm1130.res" /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -BSC32_FLAGS=/nologo /o$(OUTDIR)/"ibm1130.bsc" -BSC32_SBRS= \ - $(INTDIR)/ibm1130_cpu.sbr \ - $(INTDIR)/ibm1130_sys.sbr \ - $(INTDIR)/ibm1130_cr.sbr \ - $(INTDIR)/ibm1130_stddev.sbr \ - $(INTDIR)/ibm1130_disk.sbr \ - $(INTDIR)/ibm1130_gdu.sbr \ - $(INTDIR)/ibm1130_gui.sbr \ - $(INTDIR)/ibm1130_prt.sbr \ - $(INTDIR)/scp.sbr \ - $(INTDIR)/sim_tmxr.sbr \ - $(INTDIR)/sim_sock.sbr \ - $(INTDIR)/ibm1130_fmt.sbr \ - $(INTDIR)/sim_console.sbr \ - $(INTDIR)/sim_fio.sbr \ - $(INTDIR)/sim_timer.sbr \ - $(INTDIR)/ibm1130_ptrp.sbr - -$(OUTDIR)/ibm1130.bsc : $(OUTDIR) $(BSC32_SBRS) - $(BSC32) @<< - $(BSC32_FLAGS) $(BSC32_SBRS) -<< - -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib wsock32.lib shell32.lib /NOLOGO /SUBSYSTEM:console /DEBUG /MACHINE:I386 -# SUBTRACT LINK32 /MAP -LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib comdlg32.lib advapi32.lib\ - wsock32.lib shell32.lib /NOLOGO /SUBSYSTEM:console /INCREMENTAL:yes\ - /PDB:$(OUTDIR)/"ibm1130.pdb" /DEBUG /MACHINE:I386 /OUT:$(OUTDIR)/"ibm1130.exe" -DEF_FILE= -LINK32_OBJS= \ - $(INTDIR)/ibm1130_cpu.obj \ - $(INTDIR)/ibm1130_sys.obj \ - $(INTDIR)/ibm1130_cr.obj \ - $(INTDIR)/ibm1130_stddev.obj \ - $(INTDIR)/ibm1130.res \ - $(INTDIR)/ibm1130_disk.obj \ - $(INTDIR)/ibm1130_gdu.obj \ - $(INTDIR)/ibm1130_gui.obj \ - $(INTDIR)/ibm1130_prt.obj \ - $(INTDIR)/scp.obj \ - $(INTDIR)/sim_tmxr.obj \ - $(INTDIR)/sim_sock.obj \ - $(INTDIR)/ibm1130_fmt.obj \ - $(INTDIR)/sim_console.obj \ - $(INTDIR)/sim_fio.obj \ - $(INTDIR)/sim_timer.obj \ - $(INTDIR)/ibm1130_ptrp.obj - -$(OUTDIR)/ibm1130.exe : $(OUTDIR) $(DEF_FILE) $(LINK32_OBJS) - $(LINK32) @<< - $(LINK32_FLAGS) $(LINK32_OBJS) -<< - -!ENDIF - -.c{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cpp{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -.cxx{$(CPP_OBJS)}.obj: - $(CPP) $(CPP_PROJ) $< - -################################################################################ -# Begin Group "Source Files" - -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_cpu.c -DEP_IBM11=\ - .\ibm1130_defs.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_cpu.obj : $(SOURCE) $(DEP_IBM11) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_sys.c -DEP_IBM113=\ - .\ibm1130_defs.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_sys.obj : $(SOURCE) $(DEP_IBM113) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_cr.c -DEP_IBM1130=\ - .\ibm1130_defs.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_cr.obj : $(SOURCE) $(DEP_IBM1130) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_stddev.c -DEP_IBM1130_=\ - .\ibm1130_defs.h\ - .\ibm1130_conout.h\ - .\ibm1130_conin.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_stddev.obj : $(SOURCE) $(DEP_IBM1130_) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130.rc -DEP_IBM1130_R=\ - .\1130consoleblank.bmp\ - .\hand.cur - -$(INTDIR)/ibm1130.res : $(SOURCE) $(DEP_IBM1130_R) $(INTDIR) - $(RSC) $(RSC_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_disk.c -DEP_IBM1130_D=\ - .\ibm1130_defs.h\ - .\dmsr2v12phases.h\ - .\dmsr2v12slet.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_disk.obj : $(SOURCE) $(DEP_IBM1130_D) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_gdu.c -DEP_IBM1130_G=\ - .\ibm1130_defs.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_gdu.obj : $(SOURCE) $(DEP_IBM1130_G) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_gui.c -DEP_IBM1130_GU=\ - .\ibm1130_defs.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_gui.obj : $(SOURCE) $(DEP_IBM1130_GU) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_prt.c -DEP_IBM1130_P=\ - .\ibm1130_defs.h\ - .\ibm1130_prtwheel.h\ - ..\sim_defs.h - -$(INTDIR)/ibm1130_prt.obj : $(SOURCE) $(DEP_IBM1130_P) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\scp.c -DEP_SCP_C=\ - ..\sim_defs.h\ - \pdp11\supnik\sim_rev.h\ - \pdp11\supnik\sim_sock.h\ - \pdp11\supnik\sim_tmxr.h\ - \MSVC20\INCLUDE\sys\TYPES.H - -$(INTDIR)/scp.obj : $(SOURCE) $(DEP_SCP_C) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\sim_tmxr.c -DEP_SIM_T=\ - ..\sim_defs.h\ - \pdp11\supnik\sim_sock.h\ - \pdp11\supnik\sim_tmxr.h\ - \MSVC20\INCLUDE\sys\TYPES.H - -$(INTDIR)/sim_tmxr.obj : $(SOURCE) $(DEP_SIM_T) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\sim_sock.c -DEP_SIM_S=\ - ..\sim_defs.h\ - \pdp11\supnik\sim_sock.h\ - \MSVC20\INCLUDE\sys\TYPES.H - -$(INTDIR)/sim_sock.obj : $(SOURCE) $(DEP_SIM_S) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_fmt.c - -$(INTDIR)/ibm1130_fmt.obj : $(SOURCE) $(INTDIR) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\sim_console.c -DEP_SIM_C=\ - ..\sim_defs.h\ - \pdp11\supnik\sim_sock.h\ - \pdp11\supnik\sim_tmxr.h\ - \pdp11\supnik\scp.h\ - \pdp11\supnik\sim_console.h\ - \pdp11\supnik\sim_timer.h\ - \pdp11\supnik\sim_fio.h\ - D:\PROGRA~1\MICROS~1\INCLUDE\WinSock2.h\ - \MSVC20\INCLUDE\sys\TYPES.H\ - D:\PROGRA~1\MICROS~1\INCLUDE\Qos.h\ - D:\WINDDK\2600\inc\wxp\guiddef.h - -$(INTDIR)/sim_console.obj : $(SOURCE) $(DEP_SIM_C) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\sim_fio.c -DEP_SIM_F=\ - ..\sim_defs.h\ - D:\PROGRA~1\MICROS~1\INCLUDE\BaseTsd.h\ - \pdp11\supnik\scp.h\ - \pdp11\supnik\sim_console.h\ - \pdp11\supnik\sim_timer.h\ - \pdp11\supnik\sim_fio.h - -$(INTDIR)/sim_fio.obj : $(SOURCE) $(DEP_SIM_F) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=\pdp11\supnik\sim_timer.c -DEP_SIM_TI=\ - ..\sim_defs.h\ - D:\PROGRA~1\MICROS~1\INCLUDE\BaseTsd.h\ - \pdp11\supnik\scp.h\ - \pdp11\supnik\sim_console.h\ - \pdp11\supnik\sim_timer.h\ - \pdp11\supnik\sim_fio.h - -$(INTDIR)/sim_timer.obj : $(SOURCE) $(DEP_SIM_TI) $(INTDIR) - $(CPP) $(CPP_PROJ) $(SOURCE) - -# End Source File -################################################################################ -# Begin Source File - -SOURCE=.\ibm1130_ptrp.c - -$(INTDIR)/ibm1130_ptrp.obj : $(SOURCE) $(INTDIR) - -# End Source File -# End Group -# End Project -################################################################################ diff --git a/Ibm1130/ibm1130.rc b/Ibm1130/ibm1130.rc index 47a56a67..a3e0b63a 100644 --- a/Ibm1130/ibm1130.rc +++ b/Ibm1130/ibm1130.rc @@ -1,4 +1,4 @@ -//Microsoft Visual C++ generated resource script. +// Microsoft Visual C++ generated resource script. // #include "ibm1130res.h" @@ -12,6 +12,14 @@ ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -19,24 +27,23 @@ // TEXTINCLUDE // -1 TEXTINCLUDE DISCARDABLE +1 TEXTINCLUDE BEGIN "ibm1130res.h\0" END -2 TEXTINCLUDE DISCARDABLE +2 TEXTINCLUDE BEGIN "#include \r\n" "\0" END -3 TEXTINCLUDE DISCARDABLE +3 TEXTINCLUDE BEGIN "\r\n" "\0" END -///////////////////////////////////////////////////////////////////////////// #endif // APSTUDIO_INVOKED @@ -45,20 +52,72 @@ END // Bitmap // -IDB_CONSOLE BITMAP MOVEABLE PURE "1130consoleblank.bmp" -FULL_1442 BITMAP MOVEABLE PURE "1442full.bmp" -EOF_1442 BITMAP MOVEABLE PURE "1442eof.bmp" -EMPTY_1442 BITMAP MOVEABLE PURE "1442empty.bmp" -MIDDLE_1442 BITMAP MOVEABLE PURE "1442middle.bmp" -FULL_1132 BITMAP MOVEABLE PURE "1132full.bmp" -EMPTY_1132 BITMAP MOVEABLE PURE "1132empty.bmp" +IDB_CONSOLE BITMAP "1130consoleblank.bmp" +FULL_1442 BITMAP "1442full.bmp" +EOF_1442 BITMAP "1442eof.bmp" +EMPTY_1442 BITMAP "1442empty.bmp" +MIDDLE_1442 BITMAP "1442middle.bmp" +FULL_1132 BITMAP "1132full.bmp" +EMPTY_1132 BITMAP "1132empty.bmp" ///////////////////////////////////////////////////////////////////////////// // // Cursor // -IDC_MYHAND CURSOR DISCARDABLE "HAND.CUR" +IDC_MYHAND CURSOR "HAND.CUR" + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +mainicon ICON "ibm1130.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,8,0,0 + PRODUCTVERSION 3,8,0,0 + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "IBM 1130 simulator. For more information see http://ibm1130.org. Program based on SIMH by Bob Supnik, http:/.simh.trailing-edge.com" + VALUE "FileDescription", "ibm1130 Application" + VALUE "FileVersion", "3, 8, 0, 0" + VALUE "InternalName", "ibm1130" + VALUE "LegalCopyright", "Copyright (C) 2012, Brian Knittel. Plotter support incorporates LIBGD Copyright © 1997-2008 Thomas Boutell, Pierre A. Joye and contributors, see file COPYING at www.libgd.org" + VALUE "OriginalFilename", "ibm1130.exe" + VALUE "ProductName", "ibm1130 Application" + VALUE "ProductVersion", "3, 8, 0, 0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// diff --git a/Ibm1130/ibm1130_cpu.c b/Ibm1130/ibm1130_cpu.c index 65094394..b0645fa2 100644 --- a/Ibm1130/ibm1130_cpu.c +++ b/Ibm1130/ibm1130_cpu.c @@ -22,6 +22,16 @@ Also commented out my echo command as it's now a standard simh command 27-Nov-05 BLK Added Arithmetic Factor Register support per Carl Claunch (GUI only) 06-Dec-06 BLK Moved CGI stuff out of ibm1130_cpu.c + 01-May-07 BLK Changed name of function xio_1142_card to xio_1442_card. Corrected list of + devices in xio_devs[] (used in debugging only). + 24-Mar-11 BLK Got the real IBM 1130 diagnostics (yay!). Fixed two errors detected by the CPU diagnostics: + -- was not resetting overflow bit after testing with BSC short form + (why did I think only the long form reset OV after testing?) + -- failed to detect numeric overflow in Divide instructions + Also fixed bug where simulator performed 2nd word fetch on Long mode instructions + on ops that don't have long mode, blowing out the SAR/SBR display that's important in the + IBM diagnostics. The simulator was decrementing the IAR after the incorrect fetch, so the + instructions worked correctly, but, the GUI display was wrong. >> To do: verify actual operands stored in ARF, need to get this from state diagrams in the schematic set Also: determine how many bits are actually stored in the IAR in a real 1130, by forcing wraparound @@ -91,6 +101,7 @@ opcode in MSBits F = format. 0 = short (1 word), 1 = long (2 word) instruction + (Not all operations have long versions. The bit is ignored for shifts, LDX, WAIT and invalid opcodes) T = Tag 00 = no index register (e.g. IAR relative) 01 = use index register 1 (e.g. core address 1 = M[1]) @@ -153,9 +164,6 @@ static int simh_status_to_stopcode (int status); /* hook pointers from scp.c */ void (*sim_vm_init) (void) = &sim_init; -extern char* (*sim_vm_read) (char *ptr, int32 size, FILE *stream); -extern void (*sim_vm_post) (t_bool from_scp); -extern CTAB *sim_vm_cmd; /* space to store extra simulator-specific commands */ #define MAX_EXTRA_COMMANDS 10 @@ -222,7 +230,7 @@ t_stat cpu_set_type (UNIT *uptr, int32 value, char *cptr, void *desc); void calc_ints (void); extern t_stat ts_wr (int32 data, int32 addr, int32 access); -extern UNIT cr_unit; +extern UNIT cr_unit, prt_unit[]; #ifdef ENABLE_BACKTRACE static void archive_backtrace(char *inst); @@ -261,9 +269,15 @@ static void trace_instruction (void); * ------------------------------------------------------------------------ */ #define UNIT_MSIZE (1 << (UNIT_V_UF + 7)) /* flag for memory size setting */ -#define UNIT_1800 (1 << (UNIT_V_UF + 0)) /* flag for 1800 mode */ +#define UNIT_1800 (1 << (UNIT_V_UF + 8)) /* flag for 1800 mode */ +#define UNIT_TRACE (3 << (UNIT_V_UF + 9)) /* debugging tracing mode bits */ -UNIT cpu_unit = { UDATA (&cpu_svc, UNIT_FIX | UNIT_BINK | UNIT_ATTABLE | UNIT_SEQ, INIMEMSIZE) }; +#define UNIT_TRACE_NONE 0 +#define UNIT_TRACE_IO (1 << (UNIT_V_UF+9)) +#define UNIT_TRACE_INSTR (2 << (UNIT_V_UF+9)) +#define UNIT_TRACE_BOTH (3 << (UNIT_V_UF+9)) + +UNIT cpu_unit = { UDATA (&cpu_svc, UNIT_FIX | UNIT_BINK | UNIT_ATTABLE | UNIT_SEQ | UNIT_TRACE_BOTH, INIMEMSIZE) }; REG cpu_reg[] = { { HRDATA (IAR, IAR, 32) }, @@ -300,14 +314,18 @@ REG cpu_reg[] = { }; MTAB cpu_mod[] = { - { UNIT_MSIZE, 4096, NULL, "4KW", &cpu_set_size}, - { UNIT_MSIZE, 8192, NULL, "8KW", &cpu_set_size}, - { UNIT_MSIZE, 16384, NULL, "16KW", &cpu_set_size}, - { UNIT_MSIZE, 32768, NULL, "32KW", &cpu_set_size}, + { UNIT_MSIZE, 4096, NULL, "4KW", &cpu_set_size}, + { UNIT_MSIZE, 8192, NULL, "8KW", &cpu_set_size}, + { UNIT_MSIZE, 16384, NULL, "16KW", &cpu_set_size}, + { UNIT_MSIZE, 32768, NULL, "32KW", &cpu_set_size}, #ifdef ENABLE_1800_SUPPORT - { UNIT_1800, 0, "1130", "1130", &cpu_set_type}, - { UNIT_1800, UNIT_1800, "1800", "1800", &cpu_set_type}, -#endif + { UNIT_1800, 0, "1130", "1130", &cpu_set_type}, + { UNIT_1800, UNIT_1800, "1800", "1800", &cpu_set_type}, +#endif + { UNIT_TRACE, UNIT_TRACE_NONE, "notrace", "NOTRACE", NULL}, + { UNIT_TRACE, UNIT_TRACE_IO, "traceIO", "TRACEIO", NULL}, + { UNIT_TRACE, UNIT_TRACE_INSTR, "traceInstr", "TRACEINSTR", NULL}, + { UNIT_TRACE, UNIT_TRACE_BOTH, "traceBoth", "TRACEBOTH", NULL}, { 0 } }; DEVICE cpu_dev = { @@ -433,7 +451,6 @@ void calc_ints (void) * ------------------------------------------------------------------------ */ #define INCREMENT_IAR IAR = (IAR + 1) & mem_mask -#define DECREMENT_IAR IAR = (IAR - 1) & mem_mask void bail (char *msg) { @@ -441,36 +458,53 @@ void bail (char *msg) exit(1); } -static void weirdop (char *msg, int offset) +static void weirdop (char *msg) { - printf("Weird opcode: %s at %04x\n", msg, IAR+offset); + printf("Weird opcode: %s at %04x\n", msg, IAR-1); } static char *xio_devs[] = { - "0?", "console", "1142card", "1134papertape", - "dsk0", "1627plot", "1132print", "switches", - "1231omr", "2501card", "comm", "b?", - "sys7", "d?", "e?", "f?", - "10?", "dsk1", "dsk2", "dsk3", - "dsk4", "dsk5", "dsk6", "dsk7+", - "18?", "2250disp", "2741attachment", "1b", - "1c?", "1d?", "1e?", "1f?" + "dev-00?", "console", "1442card", "1134ptape", + "dsk0", "1627plot", "1132print", "switches", + "1231omr", "2501card", "sca", "dev-0b?", + "sys7", "dev-0d?", "dev-0e?", "dev-0f?", + "dev-10?", "dsk1", "dsk2", "dsk3", + "dsk4", "1403prt", "dsk5", "2311drv2", + "dev-18?", "2250disp", "2741term", "dev-1b", + "dev-1c?", "dev-1d?", "dev-1e?", "dev-1f?" }; static char *xio_funcs[] = { - "0?", "write", "read", "sense_irq", + "func0?", "write", "read", "sense_irq", "control", "initw", "initr", "sense" }; t_stat sim_instr (void) { int32 i, eaddr, INDIR, IR, F, DSPLC, word2, oldval, newval, src, src2, dst, abit, xbit; - int32 iocc_addr, iocc_op, iocc_dev, iocc_func, iocc_mod; + int32 iocc_addr, iocc_op, iocc_dev, iocc_func, iocc_mod, result; char msg[50]; int cwincount = 0, status; static long ninstr = 0; static char *intlabel[] = {"INT0","INT1","INT2","INT3","INT4","INT5"}; + /* the F bit indicates a two-word instruction for most instructions except the ones marked FALSE below */ + static t_bool F_bit_used[] = { /* FALSE for those few instructions that don't have a long instr version */ + /*undef XIO SLx SRx LDS STS WAIT undef */ + FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, + /*BSI BSC undef undef LDX STX MDX undef */ + TRUE, TRUE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, + /*A AD S SD M D CPU dependent */ + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, + /*LD LDD STO STD AND OR EOR undef */ + TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE + }; + +#ifdef ENABLE_1800_SUPPORT + F_bit_used[0x16] = is_1800; /* these two are defined and do have long versions on the 1800 */ + F_bit_used[0x17] = is_1800; /* but are undefined on the 1130, so set these accordingly */ +#endif + if (cgi) /* give CGI hook function a chance to do something */ cgi_start(); @@ -581,7 +615,7 @@ t_stat sim_instr (void) } ninstr++; - if (cpu_unit.flags & UNIT_ATT) + if ((cpu_unit.flags & (UNIT_ATT|UNIT_TRACE_INSTR)) == (UNIT_ATT|UNIT_TRACE_INSTR)) trace_instruction(); /* log CPU details if logging is enabled */ prev_IAR = IAR; /* save IAR before incrementing it */ @@ -598,7 +632,7 @@ t_stat sim_instr (void) /* here I compute the usual effective address on the assumption that the instruction will need it. Some don't. */ - if (F) { /* long instruction, ASSUME it's valid (have to decrement IAR if not) */ + if (F && F_bit_used[OP]) { /* long instruction, except for a few that don't have a long mode, like WAIT */ INDIR = IR & 0x0080; /* indirect bit */ DSPLC = IR & 0x007F; /* displacement or modifier */ if (DSPLC & 0x0040) @@ -612,6 +646,8 @@ t_stat sim_instr (void) eaddr += ReadIndex(TAG); /* add index register value */ if (INDIR) /* if indirect addressing */ eaddr = ReadW(eaddr); /* pick up referenced address */ + + /* to do: the previous steps may lead to incorrect GUI SAR/SBR display if the instruction doesn't actually fetch anything. Check this. */ } else { /* short instruction, use displacement */ INDIR = 0; /* never indirect */ @@ -623,6 +659,8 @@ t_stat sim_instr (void) eaddr = ReadIndex(TAG) + DSPLC; /* add index register value */ else eaddr = IAR + DSPLC; /* otherwise relative to IAR after fetch */ + + /* to do: the previous steps may lead to incorrect GUI SAR/SBR display if the instruction doesn't actually fetch the index value. Check this. */ } switch (OP) { /* decode instruction */ @@ -634,16 +672,14 @@ t_stat sim_instr (void) iocc_func = (iocc_op >> 8) & 0x0007; iocc_mod = iocc_op & 0x00FF; - if (cpu_unit.flags & UNIT_ATT) - trace_io("* XIO %s %s mod %02x addr %04x", xio_funcs[iocc_func], xio_devs[iocc_dev], iocc_mod, iocc_addr); - -/* fprintf(stderr, "* XIO %s %s mod %02x addr %04x\n", xio_funcs[iocc_func], xio_devs[iocc_dev], iocc_mod, iocc_addr); */ + if ((cpu_unit.flags & (UNIT_ATT|UNIT_TRACE_IO)) == (UNIT_ATT|UNIT_TRACE_IO)) + trace_io("* XIO %s %s mod %02x addr %04x", xio_funcs[iocc_func], (iocc_func == XIO_SENSE_IRQ) ? "-" : xio_devs[iocc_dev], iocc_mod, iocc_addr); ACC = 0; /* ACC is destroyed, and default XIO_SENSE_DEV result is 0 */ switch (iocc_func) { case XIO_UNUSED: - sprintf(msg, "Unknown op %x on device %02x", iocc_func, iocc_dev); + sprintf(msg, "Unknown XIO op %x on device %02x (%s)", iocc_func, iocc_dev, xio_devs[iocc_dev]); xio_error(msg); break; @@ -656,8 +692,8 @@ t_stat sim_instr (void) case 0x01: /* console keyboard and printer */ xio_1131_console(iocc_addr, iocc_func, iocc_mod); break; - case 0x02: /* 1142 card reader/punch */ - xio_1142_card(iocc_addr, iocc_func, iocc_mod); + case 0x02: /* 1442 card reader/punch */ + xio_1442_card(iocc_addr, iocc_func, iocc_mod); break; case 0x03: /* 1134 paper tape reader/punch */ xio_1134_papertape(iocc_addr, iocc_func, iocc_mod); @@ -724,10 +760,8 @@ t_stat sim_instr (void) break; case 0x02: /* --- SLA,SLT,SLC,SLCA,NOP - Shift Left family --- */ - if (F) { - weirdop("Long Left Shift", -2); - DECREMENT_IAR; - } + if (F) + weirdop("Long Left Shift"); CCC = ((TAG == 0) ? DSPLC : ReadIndex(TAG)) & 0x003F; ARFSET(CCC); @@ -764,7 +798,7 @@ t_stat sim_instr (void) CCC--; } C = (CCC != 0); - WriteIndex(TAG, (ReadIndex(TAG) & 0xFF00) | CCC); /* put 6 bits back into low byte of index register */ + WriteIndex(TAG, ReadIndex(TAG) & 0xFF00 | CCC); /* put 6 bits back into low byte of index register */ break; } /* if TAG == 0, fall through and treat like normal shift SLT */ @@ -786,10 +820,8 @@ t_stat sim_instr (void) break; case 0x03: /* --- SRA, SRT, RTE - Shift Right family --- */ - if (F) { - weirdop("Long Right Shift", -2); - DECREMENT_IAR; - } + if (F) + weirdop("Long Right Shift"); CCC = ((TAG == 0) ? DSPLC : ReadIndex(TAG)) & 0x3F; ARFSET(CCC); @@ -810,8 +842,8 @@ t_stat sim_instr (void) while (CCC > 0) { xbit = (ACC & 0x0001) << 15; abit = (ACC & 0x8000); - ACC = ((ACC >> 1) & 0x7FFF) | abit; - EXT = ((EXT >> 1) & 0x7FFF) | xbit; + ACC = (ACC >> 1) & 0x7FFF | abit; + EXT = (EXT >> 1) & 0x7FFF | xbit; CCC--; } break; @@ -820,8 +852,8 @@ t_stat sim_instr (void) while (CCC > 0) { abit = (EXT & 0x0001) << 15; xbit = (ACC & 0x0001) << 15; - ACC = ((ACC >> 1) & 0x7FFF) | abit; - EXT = ((EXT >> 1) & 0x7FFF) | xbit; + ACC = (ACC >> 1) & 0x7FFF | abit; + EXT = (EXT >> 1) & 0x7FFF | xbit; CCC--; } break; @@ -833,10 +865,8 @@ t_stat sim_instr (void) break; case 0x04: /* --- LDS - Load Status --- */ - if (F) { /* never fetches second word? */ - weirdop("Long LDS", -2); - DECREMENT_IAR; - } + if (F) /* never fetches second word? */ + weirdop("Long LDS"); V = (DSPLC & 1); C = (DSPLC & 2) >> 1; @@ -854,11 +884,15 @@ t_stat sim_instr (void) break; case 0x06: /* --- WAIT --- */ +/* I am no longer doing the fetch if a long wait is encountered + * The 1130 diagnostics use WAIT instructions with the F bit set in some display error codes. + * (The wait instruction's opcode is displayed in the Storage Buffer Register on the console display, + * since the last thing fetched was the instruction) + */ wait_state = WAIT_OP; - if (F) { /* what happens if we use long format? */ - weirdop("Long WAIT", -2); - DECREMENT_IAR; /* assume it wouldn't have fetched 2nd word? */ - } + + SAR = prev_IAR; /* this is a hack; ensure that the SAR/SBR display shows the WAIT instruction fetch */ + SBR = IR; break; case 0x08: /* --- BSI - Branch and store IAR --- */ @@ -1023,10 +1057,20 @@ t_stat sim_instr (void) ARFSET(src2); - if (src2 == 0) + /* 24-Mar-11 - Failed IBM diagnostics because I was not checking for overflow here. Fixed. + * Have to check for special case of -maxint / -1 because Windows (at least) generates an exception + */ + if (src2 == 0) { V = 1; /* divide by zero just sets overflow, ACC & EXT are undefined */ + } + else if (src2 == -1 && src == 0x80000000) { + V = 1; /* another special case: max negative int / -1 also overflows */ + } else { - ACC = (src / src2) & 0xFFFF; + result = src / src2; /* compute dividend */ + if ((result > 32767) || (result < -32768)) + V = 1; /* if result does not fit into 16 bits, we have an overflow */ + ACC = result & 0xFFFF; EXT = (src % src2) & 0xFFFF; } break; @@ -1105,13 +1149,11 @@ t_stat sim_instr (void) /* case 0x07: */ /* case 0x0a: */ /* case 0x0b: */ -/* case 0x0e: */ /* case 0x0f: */ /* case 0x1f: */ wait_state = WAIT_INVALID_OP; - if (F) - DECREMENT_IAR; /* assume it wouldn't have fetched 2nd word? */ - + SAR = prev_IAR; /* this is a hack; ensure that the SAR/SBR display shows the WAIT instruction fetch */ + SBR = IR; break; } /* end instruction decode switch */ @@ -1164,6 +1206,7 @@ static int simh_status_to_stopcode (int status) * bsctest - perform standard set of condition tests. We return TRUE if any * of the condition bits specified in DSPLC test positive, FALSE if none are true. * If reset_V is TRUE, we reset the oVerflow flag after testing it. + * 24-Mar-11: no, we reset the oVerflow flag no matter what reset_V is * ------------------------------------------------------------------------ */ static t_bool bsctest (int32 DSPLC, t_bool reset_V) @@ -1171,7 +1214,8 @@ static t_bool bsctest (int32 DSPLC, t_bool reset_V) if (DSPLC & 0x01) { /* Overflow off (note inverted sense) */ if (! V) return TRUE; - else if (reset_V) /* reset after testing */ +// 24-Mar-11 - V is always reset when tested, in both the long and short forms of the instructions +// else if (reset_V) /* reset after testing */ V = 0; } @@ -1253,7 +1297,7 @@ t_stat cpu_reset (DEVICE *dptr) wait_state = 0; /* cancel wait */ wait_lamp = TRUE; /* but keep the wait lamp lit on the GUI */ - if (cpu_unit.flags & UNIT_ATT) { /* record reset in CPU log */ + if ((cpu_unit.flags & (UNIT_ATT|UNIT_TRACE_INSTR)) == (UNIT_ATT|UNIT_TRACE_INSTR)) { /* record reset in CPU log */ fseek(cpu_unit.fileref, 0, SEEK_END); fprintf(cpu_unit.fileref, "---RESET---" CRLF); } @@ -1451,7 +1495,7 @@ t_stat register_cmd (char *name, t_stat (*action)(int32 flag, char *ptr), int ar * echo_cmd - just echo the command line * ------------------------------------------------------------------------ */ -static t_stat echo_cmd (int flag, char *cptr) +static t_stat echo_cmd (int32 flag, char *cptr) { printf("%s\n", cptr); return SCPE_OK; @@ -1794,6 +1838,11 @@ static void trace_instruction (void) fputs(CRLF, cpu_unit.fileref); } +static void trace_common (FILE *fout) +{ + fprintf(fout, "[IAR %04x IPL %c] ", IAR, (ipl < 0) ? ' ' : ('0' + ipl)); +} + void trace_io (char *fmt, ...) { va_list args; @@ -1801,6 +1850,7 @@ void trace_io (char *fmt, ...) if ((cpu_unit.flags & UNIT_ATT) == 0) return; + trace_common(cpu_unit.fileref); va_start(args, fmt); /* get pointer to argument list */ vfprintf(cpu_unit.fileref, fmt, args); /* write errors to cpu log file */ va_end(args); @@ -1813,12 +1863,14 @@ void trace_both (char *fmt, ...) va_list args; if (cpu_unit.flags & UNIT_ATT) { + trace_common(cpu_unit.fileref); va_start(args, fmt); /* get pointer to argument list */ vfprintf(cpu_unit.fileref, fmt, args); va_end(args); fputs(CRLF, cpu_unit.fileref); } + trace_common(stdout); va_start(args, fmt); /* get pointer to argument list */ vfprintf(stdout, fmt, args); va_end(args); @@ -1830,17 +1882,32 @@ void trace_both (char *fmt, ...) void debug_print (char *fmt, ...) { va_list args; + FILE *fout = stdout; + t_bool binarymode = FALSE; + +#define DEBUG_TO_PRINTER + +#ifdef DEBUG_TO_PRINTER + if (prt_unit[0].fileref != NULL) { /* THIS IS TEMPORARY */ + fout = prt_unit[0].fileref; + binarymode = TRUE; + } +#endif va_start(args, fmt); - vprintf(fmt, args); + vfprintf(fout, fmt, args); if (cpu_unit.flags & UNIT_ATT) vfprintf(cpu_unit.fileref, fmt, args); va_end(args); if (strchr(fmt, '\n') == NULL) { /* be sure to emit a newline */ - putchar('\n'); + if (binarymode) + fputs(CRLF, fout); + else + putc('\n', fout); + if (cpu_unit.flags & UNIT_ATT) - putc('\n', cpu_unit.fileref); + fputs(CRLF, cpu_unit.fileref); } } diff --git a/Ibm1130/ibm1130_cr.c b/Ibm1130/ibm1130_cr.c index df9c19b3..3feeeff9 100644 --- a/Ibm1130/ibm1130_cr.c +++ b/Ibm1130/ibm1130_cr.c @@ -1,5 +1,6 @@ #include "ibm1130_defs.h" #include "ibm1130_fmt.h" +#include #ifdef _WIN32 # include /* Microsoft puts definition of mktemp into io.h rather than stdlib.h */ @@ -18,6 +19,16 @@ * This is not a supported product, but I welcome bug reports and fixes. * Mail to simh@ibm1130.org + * Update 2012-10-12 Added ability to specify tab expansion width in deck files + + * Update 2008-11-24 Made card reader attach always use read-only mode, so if file does not exist + it will not be created as an empty file. Fixed bug in BOOT CR (cold start from card) + that resulted in seeing cold card data again when next card was read. (This caused + the DMS load deck to fail, for instance). + + * Update 2007-05-01 Changed name of function xio_1142_card to xio_1442_card. + Took six years to notice the mistake. + * Update 2006-01-23 More fixes, in call to mktemp and in 2501 support, also thanks to Carl Claunch. @@ -60,25 +71,29 @@ The ATTACH CR command accepts several command-line switches - -q quiet mode, the simulator will not print the name of each file it opens - while processing deck files (which are discussed below). For example, + -q quiet mode, the simulator will not print the name of each file it opens + while processing deck files (which are discussed below). For example, - ATTACH -q @deckfile + ATTACH CR -q @deckfile - -l makes the simulator convert lower case letters in text decks - to the IBM lower-case Hollerith character codes. Normally, the simulator - converts lower case input to the uppercase Hollerith character codes. - (Lowercase codes are used in APL\1130 save decks). + -l makes the simulator convert lower case letters in text decks + to the IBM lower-case Hollerith character codes. Normally, the simulator + converts lower case input to the uppercase Hollerith character codes. + (Lowercase codes are used in APL\1130 save decks). - -d prints a lot of simulator debugging information + -d prints a lot of simulator debugging information - -f converts tabs in an ascii file to spaces according to Fortran column conventions - -a converts tabs in an ascii file to spaces according to 1130 Assembler column conventions - -t converts tabs in an ascii file to spaces, with tab settings every 8 columns - (See below for a discussion of tab formatting) + -f converts tabs in an ascii file to spaces according to Fortran column conventions + -a converts tabs in an ascii file to spaces according to 1130 Assembler column conventions + -t converts tabs in an ascii file to spaces, with tab settings every 8 columns + -# converts tabs in an ascii file to spaces, with tab settings every # columns + (See below for a discussion of tab formatting) - -p means that filename is a COM port connected to a physical card reader using - the CARDREAD interface (see http://ibm1130.org/sim/downloads) + -p means that filename is a COM port connected to a physical card reader using + the CARDREAD interface (see http://ibm1130.org/sim/downloads) + + NOTE: for the Card Reader (CR), the -r (readonly) switch is implied. If the file does + not exist, it will NOT be created. The ATTACH CP command accepts the -d switch. @@ -95,7 +110,7 @@ arguments to ibm1130, or to the "do" command if a "do" script is executing, if the attach command is constructed this way: - attach @deckfile %1 %2 %3 + attach CR @deckfile %1 %2 %3 This will pass the ibm1130 or do script arguments to attach, which will make them available in the deckfile. Then, for instance the line @@ -114,6 +129,7 @@ af forces 029 ascii conversion, and interprets tabs in Fortran mode aa forces 029 ascii conversion, and interprets tabs in 1130 Assembler mode at forces 029 ascii conversion, and interprets tabs with settings every 8 spaces + a# forces 029 ascii conversion, and interprets tabs with settings every # spaces If "a" or "b" mode is not specified, the device mode setting is used. In this case, if the mode is "auto", the simulator will select binary or 029 by inspecting each @@ -644,10 +660,12 @@ static CPCODE cardcode_026F[] = /* 026 fortran */ 0x0220, '\'', 0x8420, '.', 0x8220, ')', + 0x8220, '<', /* if ASCII has <, treat like ) */ 0x4420, '$', 0x4220, '*', 0x2420, ',', 0x2220, '(', + 0x2220, '%', /* if ASCII has %, treat like ) */ }; static CPCODE cardcode_026C[] = /* 026 commercial */ @@ -695,11 +713,13 @@ static CPCODE cardcode_026C[] = /* 026 commercial */ 0x0420, '=', 0x0220, '\'', 0x8420, '.', - 0x8220, ')', + 0x8220, '<', + 0x8220, ')', /* if ASCII has ), treat like < */ 0x4420, '$', 0x4220, '*', 0x2420, ',', - 0x2220, '(', + 0x2220, '%', + 0x2220, '(', /* if ASCII has (, treat like % */ }; extern int cgi; @@ -717,7 +737,8 @@ static int any_punched = 0; #define MAXARGS 10 /* max number of arguments to save */ static char list_save[MAXARGS][MAXARGLEN], *list_arg[MAXARGLEN]; static int list_nargs = 0; -static char* (*tab_proc)(char*) = NULL; /* tab reformatting routine */ +static char* (*tab_proc)(char* str, int width) = NULL; /* tab reformatting routine */ +static int tab_width = 8; static uint16 punchstation[80]; static uint16 readstation[80]; @@ -776,10 +797,12 @@ t_stat set_active_cr_code (int match) if (! lookup_codetable(match, &code, &ncode)) return SCPE_ARG; - memset(ascii_to_card, 0, sizeof(ascii_to_card)); + if (code != NULL) { /* if an ASCII mode was selected */ + memset(ascii_to_card, 0, sizeof(ascii_to_card)); - for (i = 0; i < ncode; i++) /* set ascii to card code table */ - ascii_to_card[code[i].ascii] = code[i].hollerith; + for (i = 0; i < ncode; i++) /* set ascii to card code table */ + ascii_to_card[code[i].ascii] = code[i].hollerith; + } return SCPE_OK; } @@ -938,19 +961,19 @@ t_stat load_cr_boot (int drvno, int switches) } /* quiet switch or CGI mode inhibit the boot remark */ if (((switches & SWMASK('Q')) == 0) && ! cgi) { /* 3.0-3, parenthesized & operation, per lint check */ - sprintf(msg, "Loaded %s cold start card\n", name); + sprintf(msg, "Loaded %s cold start card", name); #ifdef GUI_SUPPORT remark_cmd(msg); #else - printf("%s", msg); + printf("%s\n", msg); #endif } return SCPE_OK; } -t_stat cr_boot (int32 unitno, DEVICE *dptr) +t_stat cr_boot (int unitno, DEVICE *dptr) { t_stat rval; int i; @@ -962,7 +985,7 @@ t_stat cr_boot (int32 unitno, DEVICE *dptr) return load_cr_boot(-1, 0); if (GET_ACTCODE(cr_unit) != CODE_BINARY) { - printf("Can only boot from card reader when set to BINARY mode"); + printf("Can only boot from card reader when set to BINARY mode\n"); return SCPE_IOERR; } @@ -971,6 +994,11 @@ t_stat cr_boot (int32 unitno, DEVICE *dptr) feedcycle(TRUE, FALSE); + if (readstate != STATION_LOADED) { + printf("No cards in reader\n"); + return SCPE_IOERR; + } + /* if (fxread(buf, sizeof(buf[0]), 80, cr_unit.fileref) != 80) */ /* return SCPE_IOERR; */ @@ -979,6 +1007,7 @@ t_stat cr_boot (int32 unitno, DEVICE *dptr) for (i = 0; i < 80; i++) /* shift 12 bits into 16 */ WriteW(i, (readstation[i] & 0xF800) | ((readstation[i] & 0x0400) ? 0x00C0 : 0x0000) | ((readstation[i] & 0x03F0) >> 4)); + readstate = STATION_READ; /* the current card has been consumed */ return SCPE_OK; } @@ -1110,7 +1139,7 @@ again: /* jump here if we've loaded a new deck after emptying the previous one if (tab_proc != NULL) { /* apply tab editing, if specified */ buf[nread] = '\0'; /* .. be sure string is terminated */ - result = (*tab_proc)(buf); /* .. convert tabs spaces */ + result = (*tab_proc)(buf, tab_width); /* .. convert tabs spaces */ nread = strlen(result); /* .. set new read length */ } else @@ -1247,7 +1276,7 @@ static void checkdeck (void) static t_bool nextdeck (void) { - char buf[200], tmpbuf[200], *fname, *c, quote, *mode; + char buf[200], tmpbuf[200], *fname, *c, quote; int code; long fpos; @@ -1271,6 +1300,7 @@ static t_bool nextdeck (void) for (;;) { /* get a filename */ tab_proc = NULL; /* default: no tab editing */ + tab_width = 8; if (fgets(buf, sizeof(buf), deckfile) == NULL) break; /* oops, no more names */ @@ -1391,7 +1421,7 @@ static t_bool nextdeck (void) continue; } - mode = c = skipbl(c); /* skip to next token, which would be mode, if present */ + c = skipbl(c); /* skip to next token, which would be mode, if present */ switch (*c) { case 'b': @@ -1422,6 +1452,13 @@ static t_bool nextdeck (void) case 'T': tab_proc = EditToWhitespace; c++; + tab_width = 0; /* see if there is a digit after the 4 -- if so use it as tab expansion width */ + while (isdigit(*c)) + tab_width = tab_width*10 + *c++ - '0'; + + if (tab_width == 0) + tab_width = 8; + break; } } @@ -1430,10 +1467,10 @@ static t_bool nextdeck (void) code = guess_cr_code(); if (cpu_unit.flags & UNIT_ATT) - trace_io("(Opened %s deck %s%s)\n", (code == CODE_BINARY) ? "binary" : "text", fname, tab_proc ? (*tab_proc)(NULL) : ""); + trace_io("(Opened %s deck %s%s)\n", (code == CODE_BINARY) ? "binary" : "text", fname, tab_proc ? (*tab_proc)(NULL, tab_width) : ""); if (! (cr_unit.flags & UNIT_QUIET)) - printf( "(Opened %s deck %s%s)\n", (code == CODE_BINARY) ? "binary" : "text", fname, tab_proc ? (*tab_proc)(NULL) : ""); + printf( "(Opened %s deck %s%s)\n", (code == CODE_BINARY) ? "binary" : "text", fname, tab_proc ? (*tab_proc)(NULL, tab_width) : ""); break; } @@ -1510,7 +1547,7 @@ t_stat cr_rewind (void) static t_stat cr_attach (UNIT *uptr, char *cptr) { t_stat rval; - t_bool use_decklist; + t_bool use_decklist, old_quiet; char *c, *arg, quote; cr_detach(uptr); /* detach file and possibly deck file */ @@ -1518,8 +1555,11 @@ static t_stat cr_attach (UNIT *uptr, char *cptr) CLRBIT(uptr->flags, UNIT_SCRATCH|UNIT_QUIET|UNIT_DEBUG|UNIT_PHYSICAL|UNIT_LOWERCASE); /* set options */ tab_proc = NULL; + tab_width = 8; use_decklist = FALSE; + sim_switches |= SWMASK('R'); // the card reader is readonly. Don't create an empty file if file does not exist + if (sim_switches & SWMASK('D')) SETBIT(uptr->flags, UNIT_DEBUG); if (sim_switches & SWMASK('Q')) SETBIT(uptr->flags, UNIT_QUIET); if (sim_switches & SWMASK('L')) SETBIT(uptr->flags, UNIT_LOWERCASE); @@ -1589,8 +1629,14 @@ static t_stat cr_attach (UNIT *uptr, char *cptr) SETBIT(uptr->flags, UNIT_ATT); uptr->pos = 0; } - else if ((rval = attach_unit(uptr, cptr)) != SCPE_OK) { - return rval; + else { + old_quiet = sim_quiet; /* attach the file, but set sim_quiet so we don't get the "CR is read-only" message */ + sim_quiet = TRUE; + rval = attach_unit(uptr, cptr); + sim_quiet = old_quiet; + + if (rval != SCPE_OK) /* file did not exist */ + return rval; } if (use_decklist) { /* if we skipped the '@', store the actually-specified name */ @@ -1667,10 +1713,10 @@ static t_stat cp_detach (UNIT *uptr) return detach_unit(uptr); } -static void op_done (UNIT *u, t_bool issue_intr) +static void op_done (UNIT *u, char *opname, t_bool issue_intr) { if (u->flags & UNIT_DEBUG) - DEBUG_PRINT("!CR Op Complete, card %d", cr_count); + DEBUG_PRINT("!CR %s Op Complete, card %d%s", opname, cr_count, issue_intr ? ", interrupt" : ""); SET_OP(OP_IDLE); @@ -1704,7 +1750,7 @@ static t_stat cr_svc (UNIT *uptr) break; case OP_FEEDING: - op_done(&cr_unit, FALSE); + op_done(&cr_unit, "feed", FALSE); break; case OP_READING: @@ -1718,10 +1764,7 @@ static t_stat cr_svc (UNIT *uptr) M[(cr_addr + i) & mem_mask] = readstation[i]; readstate = STATION_READ; - if (cr_unit.flags & UNIT_DEBUG) - DEBUG_PRINT("!CR Op Complete, card %d", cr_count); - - op_done(&cr_unit, TRUE); + op_done(&cr_unit, "read", TRUE); } else if (++cr_unit.COLUMN < 80) { /* 1442 interrupts on each column... */ SETBIT(cr_dsw, CR_DSW_1442_READ_RESPONSE); @@ -1733,7 +1776,7 @@ static t_stat cr_svc (UNIT *uptr) } else { /* ... then issues op-complete */ readstate = STATION_READ; - op_done(&cr_unit, TRUE); + op_done(&cr_unit, "read", TRUE); } break; @@ -1745,7 +1788,7 @@ static t_stat cr_svc (UNIT *uptr) if (cp_unit.flags & UNIT_LASTPUNCH) { punchstate = STATION_PUNCHED; - op_done(&cp_unit, TRUE); + op_done(&cp_unit, "punch", TRUE); } else if (++cp_unit.COLUMN < 80) { SETBIT(cr_dsw, CR_DSW_1442_PUNCH_RESPONSE); @@ -1757,7 +1800,7 @@ static t_stat cr_svc (UNIT *uptr) } else { punchstate = STATION_PUNCHED; - op_done(&cp_unit, TRUE); + op_done(&cp_unit, "punch", TRUE); } break; } @@ -1853,7 +1896,7 @@ void xio_2501_card (int32 addr, int32 func, int32 modify) } } -void xio_1142_card (int32 addr, int32 func, int32 modify) +void xio_1442_card (int32 addr, int32 func, int32 modify) { char msg[80]; int ch; @@ -2579,8 +2622,7 @@ static t_stat pcr_svc (UNIT *uptr) break; case OP_READING: - if (pcr_nready >= 2) { /* if there is a whole column buffered, simulate column interrupt*/ - /* pcr_trigger_interrupt_0 - simulate a read response interrupt so OS will read queued column data */ + if (pcr_nready >= 2) { /* if there is a whole column buffered, simulate column interrupt/* pcr_trigger_interrupt_0 - simulate a read response interrupt so OS will read queued column data */ pcr_trigger_interrupt_0(); sim_activate(&cr_unit, cr_wait); /* keep checking frequently */ @@ -2588,7 +2630,7 @@ static t_stat pcr_svc (UNIT *uptr) else if (pcr_done) { pcr_done = FALSE; cr_count++; - op_done(&cr_unit, TRUE); + op_done(&cr_unit, "pcr read", TRUE); pcr_set_dsw_from_status(TRUE); } else @@ -2598,7 +2640,7 @@ static t_stat pcr_svc (UNIT *uptr) case OP_FEEDING: if (pcr_done) { cr_count++; - op_done(&cr_unit, FALSE); + op_done(&cr_unit, "pcr feed", FALSE); pcr_set_dsw_from_status(TRUE); } else diff --git a/Ibm1130/ibm1130_defs.h b/Ibm1130/ibm1130_defs.h index c25e2153..b32012de 100644 --- a/Ibm1130/ibm1130_defs.h +++ b/Ibm1130/ibm1130_defs.h @@ -137,6 +137,7 @@ void WriteW (int32 a, int32 d); #define STOP_BREAK 11 /* simulator break key pressed */ #define STOP_STEP 12 /* step count expired */ #define STOP_OTHER 13 /* other reason, probably error returned by sim_process_event() */ +#define STOP_PRINT_CHECK 14 /* stop due to printer check (used by CGI version) */ #define IORETURN(f,v) ((f)? (v): SCPE_OK) /* cond error return */ @@ -252,7 +253,7 @@ void WriteW (int32 a, int32 d); /* prototypes: xio handlers */ void xio_1131_console (int32 addr, int32 func, int32 modify); /* console keyboard and printer */ -void xio_1142_card (int32 addr, int32 func, int32 modify); /* standard card reader/punch */ +void xio_1442_card (int32 addr, int32 func, int32 modify); /* standard card reader/punch */ void xio_1134_papertape (int32 addr, int32 func, int32 modify); /* paper tape reader/punch */ void xio_disk (int32 addr, int32 func, int32 modify, int drv); /* internal CPU disk */ void xio_1627_plotter (int32 addr, int32 func, int32 modify); /* XY plotter */ diff --git a/Ibm1130/ibm1130_disk.c b/Ibm1130/ibm1130_disk.c index f74cbcc6..c6f3ebeb 100644 --- a/Ibm1130/ibm1130_disk.c +++ b/Ibm1130/ibm1130_disk.c @@ -34,7 +34,7 @@ commands may NOT be accurate. This should probably be fixed. */ #include "ibm1130_defs.h" -#include "memory.h" +#include #define TRACE_DMS_IO /* define to enable debug of DMS phase IO */ diff --git a/Ibm1130/ibm1130_fmt.c b/Ibm1130/ibm1130_fmt.c index 8178de89..d6ff70b1 100644 --- a/Ibm1130/ibm1130_fmt.c +++ b/Ibm1130/ibm1130_fmt.c @@ -72,18 +72,19 @@ #define MIN(a,b) ((a < b) ? a : b) #define AMSG " with Assembler Reformat" #define FMSG " with FORTRAN Reformat" +#define WMSG " with tab replacement" #define AFORMAT "%20.20s%-60.60s"," " #define ACOMMENTFMT "%20.20s%-60.60s"," " #define ABLANKLINE "%20.20s*"," " #define FFORMAT "%-5.5s %-74.74s" #define FCONTFMT "%-5.5s%-75.75s" -char gszLabel[6]; /* work area for label */ -char gszArg[MAXLINE]; /* .. argument */ -char gszOutput[MAXLINE]; /* .. output */ -short gaiAsmTabs[] = {7,12,15,20,25,30,35,40,45,52,0};/* tab stops for assembler */ - -short gaiPlainTabs[] = {9, 17, 25, 33, 41, 49, 57, 65, 73, 0};/* tab stops for just plain tabs */ +static char gszLabel[6]; /* work area for label */ +static char gszArg[MAXLINE]; /* .. argument */ +static char gszOutput[MAXLINE]; /* .. output */ +static short gaiAsmTabs[] = {7,12,15,20,25,30,35,40,45,52,0};/* tab stops for assembler */ +static short gaiPlainTabs[42]; /* tab stops for plain tabs. Settings will be made later. Max # positions when tabs are every 2 positions */ +static int giPlainTabWidth = 0; /* * helper routines @@ -163,7 +164,7 @@ char* pszX; /* work pointer */ * EditToAsm - convert tab-formatted text line to 1130 Assembler format */ -char *EditToAsm (char* p_pszEdit) /* convert line to 1130 assembler */ +char *EditToAsm (char* p_pszEdit, int width) /* convert line to 1130 assembler */ { char pszLine[MAXLINE]; /* source line */ char pszWork[WORKSZ]; /* work buffer */ @@ -174,11 +175,11 @@ size_t iI; /* work integer */ return AMSG; /* a. yes .. return display message */ if (*p_pszEdit == '!') /* leave lines starting with ! alone */ - return EditToWhitespace(p_pszEdit+1); + return EditToWhitespace(p_pszEdit+1, width); if (*p_pszEdit == '*') /* q. comment line? */ { /* a. yes.. */ - strncpy(pszWork, EditToWhitespace(p_pszEdit), MAXLINE); /* .. convert any tabs */ + strncpy(pszWork, EditToWhitespace(p_pszEdit, width), MAXLINE); /* .. convert any tabs */ sprintf(gszOutput, ACOMMENTFMT, pszWork); /* .. put the comment out there in the opcode column */ return gszOutput; /* .. and return it */ } @@ -229,7 +230,7 @@ size_t iI; /* work integer */ * (a la DEC Fortran) */ -char *EditToFortran(char* p_pszEdit) /* convert line to 1130 assembler */ +char *EditToFortran(char* p_pszEdit, int width) /* convert line to 1130 assembler */ { char pszLine[MAXLINE]; /* source line */ char* pszWork; /* work pointer */ @@ -244,7 +245,7 @@ int bContinue; /* true if continue */ if (*p_pszEdit == 'C' || *p_pszEdit == '*' || *p_pszEdit == '\0') /* q. comment or directive or blank line? */ { /* a. yes.. don't restructure */ - return EditToWhitespace(p_pszEdit); + return EditToWhitespace(p_pszEdit, width); } strncpy(pszLine, p_pszEdit, MAXLINE-1); /* copy the line local */ @@ -283,19 +284,33 @@ int bContinue; /* true if continue */ } /************************************************* - * EditToWhitespace - expand tabs at 8 space intervals. + * EditToWhitespace - expand tabs at n space intervals. */ -char* EditToWhitespace(char *p_pszEdit) +char* EditToWhitespace(char *p_pszEdit, int width) { int iI; /* work integer */ +int iPos; /* work integer for settings tab stops */ char pszLine[MAXLINE]; /* source line */ char pszWork[WORKSZ]; /* work buffer */ if (p_pszEdit == NULL) /* q. null request? */ - return AMSG; /* a. yes .. return display message */ + return WMSG; /* a. yes .. return display message */ strncpy(pszLine, p_pszEdit, MAXLINE-1); /* copy the line local */ + + if (width == 0) width = 8; /* default */ + + if ((width != giPlainTabWidth) && (width > 1) && (width < 30)) { + giPlainTabWidth = width; /* if width is different, and valid, rebuild tabstop array */ + iI = 0; /* output index */ + iPos = width + 1; /* first tab position */ + while (iPos < 80) { /* fill array up to but not including position 80 */ + gaiPlainTabs[iI++] = iPos; + iPos += width; + } + gaiPlainTabs[iI] = 0; /* mark end of array */ + } ExpandTabs(pszLine, pszWork, gaiPlainTabs); /* expand the tabs */ strncpy(gszOutput, pszWork, MAXLINE-1); /* copy the line back */ diff --git a/Ibm1130/ibm1130_fmt.h b/Ibm1130/ibm1130_fmt.h index 7232560b..89369d2a 100644 --- a/Ibm1130/ibm1130_fmt.h +++ b/Ibm1130/ibm1130_fmt.h @@ -12,6 +12,6 @@ /* ibm1130_asm.h: definition of routines in ibm1130_asm.c */ -char* EditToAsm(char*); /* convert edit format to 1130 assembler format */ -char* EditToFortran(char*); /* convert edit format to Fortran format */ -char* EditToWhitespace(char*); /* clean white space, tabstops every 8 positions */ +char* EditToAsm(char* str, int width); /* convert edit format to 1130 assembler format */ +char* EditToFortran(char* str, int width); /* convert edit format to Fortran format */ +char* EditToWhitespace(char* str, int width); /* clean white space, tabstops every 8 positions */ diff --git a/Ibm1130/ibm1130_gdu.c b/Ibm1130/ibm1130_gdu.c index 86d32c45..1bbd3e2d 100644 --- a/Ibm1130/ibm1130_gdu.c +++ b/Ibm1130/ibm1130_gdu.c @@ -151,6 +151,8 @@ static void EraseGDUScreen (void); void xio_2250_display (int32 addr, int32 func, int32 modify) { + if (cgi) return; /* ignore this device in CGI mode */ + switch (func) { case XIO_SENSE_DEV: ACC = (gdu_dsw & GDU_DSW_BUSY) ? GDU_DSW_BUSY : gdu_dsw; @@ -203,6 +205,8 @@ void xio_2250_display (int32 addr, int32 func, int32 modify) static t_stat gdu_reset (DEVICE *dptr) { + if (cgi) return SCPE_OK; /* ignore this device in CGI mode */ + halt_regeneration(); clear_interrupts(); set_indicators(0); @@ -250,15 +254,13 @@ static void start_regeneration (void) static void halt_regeneration (void) { - // halt_regeneration gets called at end of every refresh interation, so it should NOT black out the - // screen -- this is why it was flickering so badly. The lower level code (called on a timer) - // should check to see if GDU_DSW_BUSY is clear, and if it it still zero after several msec, - // only then should it black out the screen and call StopGDUUpdates. + // halt_regeneration gets called at end of every refresh interation, so it should NOT black out the + // screen -- this is why it was flickering so badly. The lower level code (called on a timer) + // should check to see if GDU_DSW_BUSY is clear, and if it it still zero after several msec, + // only then should it black out the screen and call StopGDUUpdates. if (gdu_dsw & GDU_DSW_BUSY) { -// StopGDUUpdates(); // let lower level code discover this during next refresh CLRBIT(gdu_dsw, GDU_DSW_BUSY); } -// EraseGDUScreen(); // let cessation of regeneration erase it (eventually) } static void notify_window_closed (void) @@ -677,6 +679,8 @@ static HPEN hRedPen = NULL; static HBRUSH hGrayBrush, hDarkBrush; static HPEN hBlackPen; static int halted = 0; // number of time intervals that GDU has been halted w/o a regeneration +static UINT idTimer = 0; +static t_bool painting = FALSE; static LRESULT APIENTRY GDUWndProc (HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam); static DWORD WINAPI GDUPump (LPVOID arg); @@ -685,6 +689,8 @@ static void destroy_GDU_window (void) if (hwGDU != NULL) SendMessage(hwGDU, WM_CLOSE, 0, 0); // cross thread call is OK +#ifdef XXXX + // let window closure do this if (hGDUPump != INVALID_HANDLE_VALUE) { // this is not the most graceful way to do it TerminateThread(hGDUPump, 0); hGDUPump = INVALID_HANDLE_VALUE; @@ -711,6 +717,7 @@ static void destroy_GDU_window (void) DeleteObject(hRedBrush); hRedBrush = NULL; } +#endif #ifdef DEBUG_LIGHTPEN if (hRedPen != NULL) { @@ -750,6 +757,13 @@ static void gdu_WM_CLOSE (HWND hWnd) static void gdu_WM_DESTROY (HWND hWnd) { + PostMessage(hWnd, WM_QUIT, 0, 0); + if (idTimer != 0) { + KillTimer(hwGDU, 1); + idTimer = 0; + halted = 10000; + painting = FALSE; + } notify_window_closed(); hwGDU = NULL; } @@ -868,17 +882,29 @@ static void gdu_WM_PAINT (HWND hWnd) { PAINTSTRUCT ps; HDC hDC; + int msec; + // code for display hDC = BeginPaint(hWnd, &ps); PaintImage(hDC, TRUE); EndPaint(hWnd, &ps); + + // set a timer so we keep doing it! + if (idTimer == 0) { + msec = (gdu_rate == 0) ? (1000 / DEFAULT_GDU_RATE) : 1000/gdu_rate; + idTimer = SetTimer(hwGDU, 1, msec, NULL); + } } // the window has been resized static void gdu_WM_SIZE (HWND hWnd, UINT state, int cx, int cy) { +#ifdef BLIT_MODE + InvalidateRect(hWnd, NULL, FALSE); // in blt mode, we'll paint a full black bitmap over the new screen size +#else InvalidateRect(hWnd, NULL, TRUE); +#endif } // tweak the sizing rectangle during a resize to guarantee a square window @@ -911,7 +937,7 @@ static void gdu_WM_TIMER (HWND hWnd, UINT id) { HDC hDC; - if (running) { // if CPU is running, update picture + if (painting) { // if GDU is running, update picture if ((gdu_dsw & GDU_DSW_BUSY) == 0) { // regeneration is not to occur if (++halted >= 4) { // stop the timer if four timer intervals go by with the display halted EraseGDUScreen(); // screen goes black due to cessation of refreshing @@ -981,26 +1007,15 @@ static void CheckGDUKeyboard (void) { } -static UINT idTimer = 0; - static void StartGDUUpdates (void) { - int msec; - - if (idTimer == 0) { - msec = (gdu_rate == 0) ? (1000 / DEFAULT_GDU_RATE) : 1000/gdu_rate; - idTimer = SetTimer(hwGDU, 1, msec, NULL); - } halted = 0; + painting = TRUE; } static void StopGDUUpdates (void) { - if (idTimer != 0) { - KillTimer(hwGDU, 1); - idTimer = 0; - halted = 10000; - } + painting = FALSE; } static void GetMouseCoordinates() @@ -1030,7 +1045,7 @@ static void GetMouseCoordinates() t_bool gdu_active (void) { - return gdu_dsw & GDU_DSW_BUSY; + return cgi ? 0 : (gdu_dsw & GDU_DSW_BUSY); } static void EraseGDUScreen (void) @@ -1103,6 +1118,8 @@ static DWORD WINAPI GDUPump (LPVOID arg) DispatchMessage(&msg); } + painting = FALSE; + if (hwGDU != NULL) { DestroyWindow(hwGDU); /* but if a quit message got posted, clean up */ hwGDU = NULL; diff --git a/Ibm1130/ibm1130_gui.c b/Ibm1130/ibm1130_gui.c index 0e32e3e5..c75cf562 100644 --- a/Ibm1130/ibm1130_gui.c +++ b/Ibm1130/ibm1130_gui.c @@ -28,6 +28,7 @@ * ------------------------------------------------------------------------ */ #include +#include #include #include "ibm1130_defs.h" @@ -92,10 +93,6 @@ DEVICE console_dev = { /* reset for the "console" display device */ -extern char *read_line (char *cptr, int size, FILE *stream); -extern DEVICE *find_unit (char *cptr, UNIT **uptr); -extern char *sim_prompt; - extern UNIT cr_unit; /* pointers to 1442 and 1132 (1403) printers */ extern UNIT prt_unit; diff --git a/Ibm1130/ibm1130_plot.c b/Ibm1130/ibm1130_plot.c index efa14401..208ad2a1 100644 --- a/Ibm1130/ibm1130_plot.c +++ b/Ibm1130/ibm1130_plot.c @@ -7,6 +7,7 @@ 2004.10.22 - Written. 2006.1.2 - Rewritten as plotter routine by Carl V Claunch + 2012.11.23 - added -d option in detach, which we'll use in the CGI simulator. BK. * (C) Copyright 2004, Brian Knittel. * You may freely use this program, but: it offered strictly on an AS-IS, AT YOUR OWN @@ -35,6 +36,7 @@ #else +#define NONDLL // I am linking statically to avoid some issues. #include "gd.h" /*************************************************************************************** @@ -45,31 +47,78 @@ * - sheet moveable in .01" steps, either direction * - switchable pen, in various colors and line widths * - * Simulator implementation will create a JPEG image corresponding to a - * landscape mode sheet of paper, the width of the carriage at 11". - * A diagram of more than 8" of paper travel will span printed pages - * in landscape mode. + * Notice that the WIDTH is 11" and the LENGTH can be anything up to 120'. And, the WIDTH + * was the plotter's Y direction, and the LENGTH was the plotter's X direction. + * + * The simulator creates a GIF image corresponding to a landscape mode sheet of paper. That is, + * the plotter's Y direction is the image's horizontal dimension, and the plotter's X direction + * is the image's vertical dimension. The WIDTH of the image is always 1100 pixels (11 inches at + * 100 dpi), and the LENGTH (height) of the image can be set. The default is 800 pixels (8 + * inches at 100 dpi). A diagram of more than 8" in length (X direction) will span more than + * one printed page in landscape mode. * * When an 'att plot' command is issued a file is created based on the - * default or currently set values of paper length, starting - * position of the pen in both X and Y axes, pen color and pen width. - * Based on the number of logical pages of paper, the command will create - * the proper size canvas internally and create the output JPEG file. + * default or currently set values of paper length, pen position, pen color and pen width. * - * When a 'det plot' command is issued, the plotter image will be converted - * into the file that was specified during the attach process. The - * image is not viewable until this point, unless an examine plot is - * issued which will dump the current state of the paper into the file. + * When a 'det plot' command is issued, the plotter image will be + * written to the GIF that was created during the attach process. The + * image is not viewable until this point. (You could implement an EXAMINE PLOT command + * of some sort to write out an intermediate version of the image, but this is not currently + * implemented). * * The 'set plot' command can set pen width, paper length, pen color, - * current carriage X and Y coordinates. Paper length can be set + * current carriage X and Y coordinates, as discussed below. Paper length can be set * to alter the default of 800 (8"); changes are ignored until * the next 'attach' command. The current carriage x and y positions * can be set at any time and will go into effect immediately, just * as the pen color and pen width can be altered on the fly. * - * NOTE: requires gd library and definition of ENABLE_PLOT_SUPPORT in makefile or Visual C configuration - * gd is not included in the main simh and ibm1130.org distributions at the present time. + * NOTE: requires the libgd library and definition of ENABLE_PLOT_SUPPORT in makefile or Visual C configuration + * gd source is not included in the main simh and ibm1130.org source distributions at the present time due to + * licensing issues. + * + * NOTE: On Windows, you need to either: + * + compile both LIBGD and SIMH to use the static C runtime libraries, compile + * LIBGD to a static library, and link LIBGD into ibm1130.exe (which is + * what we do at IBM1130.org, so that gd is built into the version of ibm1130.exe + * we distribute), or, + * + Compile both LIBGD and IBM1130 to use the DLL version of the C runtime, and compile + * GD to either a static library or a DLL, but, static is easier since you don't + * need to copy LIBGD.DLL along with ibm1130.exe + * + * SIMH commands: + * + * attach [-w] plot filename.gif + * Creates file filename.gif and attaches the plotter device to it. + * The file is empty at this point. The pen is raised. If the -w option is specified, and the + * simulator does not draw on the plotter between attach and detach, the gif file will be deleted + * on detach. (This is useful for the the cgi version of the simulator). + * + * detach plot filename.gif + * Detach the plot device. The gif data is written at this point, not before. + * If the -w flag was used on attach, and there was no plot activity, the gif file will be deleted. + * + * set plot black | red | blue | green | yellow | purple | lgrey | grey + * Sets the pen to the named color. Default is black. + * + * set plot 1.0 | 2.0 | 3.0 | 4.0 + * Sets the pen thickness to the specified number of hundredths of an inch. Default is 1.0 + * + * set plot penup | pendown + * Moves the pen up or down (onto the paper). + * + * set plot length NNN + * Sets the plot length (plotter X direction, GIF vertical dimension) to the NNN hundredths of + * an inch. Default is 800. The plot width (plotter Y direction, GIF horizontal dimension) is always + * 1100 (11 inches). NOTE: Changing this setting has no affect on the current plot. It takes affect at + * the next "attach plot" command. + * + * set plot xpos NNN + * set plot ypos NNN + * Sets the pen x or y position to NNN hundredths of an inch. + * + * (You cannot manually create a plot by issuing set plot pendown, xpos and ypos commands. The xpos and ypos + * settings only change the starting point for the simulated program). ***************************************************************************************/ #define PLOT1627_DSW_OP_COMPLETE 0x8000 @@ -78,7 +127,7 @@ #define IS_ONLINE(u) (((u)->flags & (UNIT_ATT|UNIT_DIS)) == UNIT_ATT) #define IS_DEBUG ((plot_unit->flags & UNIT_DEBUG) == UNIT_DEBUG) -#define IS_PENDOWN ((plot_unit->flags & UNIT_PEN) == UNIT_PEN) +#define IS_PENDOWN ((plot_unit->flags & UNIT_PEN) != 0) static t_stat plot_svc (UNIT *uptr); /* activity routine */ static t_stat plot_reset (DEVICE *dptr); /* reset of 1130 */ @@ -103,7 +152,7 @@ static int32 plot_ymax = 1099; /* right edge of carriage */ #define PEN_DOWN 0x80000000 #define PEN_UP 0x00000000 -static int32 plot_pen = PEN_UP; /* current pen position */ +static int32 plot_pen = PEN_UP; /* current pen position. This duplicates the device flag PLOT_PEN. Makes the show dev plot command nicer. */ static int black_pen; /* holds color black */ static int blue_pen; /* holds color blue */ @@ -116,8 +165,10 @@ static int grey_pen; /* holds grey */ static int white_background; /* holds white of paper roll */ static int plot_pwidth; /* set and display variable */ static int plot_pcolor; /* set and display variable */ -static int need_update = 0; /* flag to force and update_pen() */ -static gdImagePtr image; /* pointer to our canvas */ +static int need_update = FALSE; /* flag to force and update_pen() */ +static int plot_used = FALSE; /* flag set to true if anything was actually plotted between attach and detach */ +static int delete_if_unused = FALSE; /* if TRUE and no plotter activity was seen, delete file on detach. This flag is set by -w option on attach command. */ +static gdImagePtr image = NULL; /* pointer to our canvas */ #define UNIT_V_COLOR (UNIT_V_UF + 0) /* color of selected pen - 3 bits */ #define UNIT_V_WIDTH (UNIT_V_UF + 3) /* width of pen - two bits */ @@ -140,8 +191,8 @@ static gdImagePtr image; /* pointer to our canvas */ #define PEN_LTGREY (6u << UNIT_V_COLOR) #define PEN_GREY (7u << UNIT_V_COLOR) -#define SET_COLOR(op) {plot_unit[0].flags &= ~UNIT_COLOR; plot_unit[0].flags |= (op);} -#define GET_COLOR (plot_unit[0].flags & UNIT_COLOR) +#define SET_COLOR(op) (plot_unit[0].flags = (plot_unit[0].flags & ~UNIT_COLOR) | (op)) +#define GET_COLOR (plot_unit[0].flags & UNIT_COLOR) #define BLACK 0,0,0 #define BLUE 0,0,255 @@ -159,7 +210,7 @@ static gdImagePtr image; /* pointer to our canvas */ #define PEN_QUAD (3u << UNIT_V_WIDTH) #define GET_WIDTH() (plot_unit[0].flags & UNIT_WIDTH) -#define SET_WIDTH(cd) {plot_unit[0].flags &= ~UNIT_WIDTH; un.flags |= (cd);} +#define SET_WIDTH(cd) (plot_unit[0].flags = (plot_unit[0].flags & ~UNIT_WIDTH) | (cd)) UNIT plot_unit[] = { { UDATA (&plot_svc, UNIT_ATTABLE, 0) }, @@ -167,10 +218,10 @@ UNIT plot_unit[] = { REG plot_reg[] = { { HRDATA (DSW, plot_dsw, 16) }, /* device status word */ - { DRDATA (WTIME, plot_wait, 24), PV_LEFT }, /* plotter movement wait */ + { DRDATA (WTIME, plot_wait, 24), PV_LEFT }, /* plotter movement wait */ { DRDATA (Xpos, plot_xpos, 32), PV_LEFT }, /* Current X Position*/ { DRDATA (Ypos, plot_ypos, 32), PV_LEFT }, /* Current Y Position*/ - { FLDATA (PenDown, plot_pen, 0)}, /* Current pen position - 1 = down */ + { FLDATA (PenDown, plot_pen, 0)}, /* Current pen position: 1 = down */ { DRDATA (PaperSize, plot_xmax, 32), PV_LEFT }, /* Length of paper in inches */ { NULL } }; @@ -211,9 +262,10 @@ DEVICE plot_dev = { /* xio_1627_plotter - XIO command interpreter for the 1627 plotter model 1 */ -void xio_1627_plotter (iocc_addr, iocc_func, iocc_mod) +void xio_1627_plotter (int32 iocc_addr, int32 iocc_func, int32 iocc_mod) { char msg[80]; + int16 v; if (! IS_ONLINE(plot_unit) ) { SETBIT(plot_dsw, PLOT1627_DSW_NOT_READY); /* set not ready */ @@ -246,7 +298,44 @@ void xio_1627_plotter (iocc_addr, iocc_func, iocc_mod) break; case XIO_CONTROL: /* control XIO */ - xio_error("Control XIO not supported by 1627 plotter"); + // xio_error("Control XIO not supported by 1627 plotter"); + // Well, not on a real 1130. But on our simulator, let's use XIO_CONTROL to + // allow programmatic control of the pen. Nifty, eh? + // + // Functions: XIO_CONTROL 0 clr - sets pen color (0=black, 1=red, 2=blue, 3=green, 4=yellow, 5=purple, 6=ltgrey, 7=grey) + // XIO_CONTRLL 1 wid - sets pen width (1..4) + // XIO_CONTROL 2 xpos - sets pen xpos + // XIO_CONTROL 3 ypos - sets pen ypos + + v = (int16) iocc_addr; /* get signed 16 bit value passed in addr arg */ + switch (iocc_mod) { + case 0: /* set pen color */ + if (BETWEEN(v,0,7)) { + SET_COLOR(v << UNIT_V_COLOR); + update_pen(); + } + break; + + case 1: /* set pen width 1..4*/ + if (BETWEEN(v,1,4)) { + SET_WIDTH((v-1) << UNIT_V_WIDTH); + update_pen(); + } + break; + + case 2: /* set xpos. (Programmatic xpos and ypos are probably not that valuable) */ + plot_xpos = v; /* Note that it's possible to move the pen way off the paper */ + break; + + case 3: /* set ypos. Clip to valid range! */ + if (v <= 0) + plot_ypos = 0; + else if (v > plot_ymax) + plot_ypos = plot_ymax; + else + plot_ypos = v; + break; + } break; default: @@ -274,8 +363,14 @@ static t_stat plot_svc (UNIT *uptr) static t_stat plot_reset (DEVICE *dptr) { - char * buf; - int32 size; +#ifdef NONDLL + static int show_notice = FALSE; + + if (show_notice && ! cgi) { + printf("Plotter support included. Please see www.libgd.org for libgd copyright information.\n"); + show_notice = FALSE; + } +#endif sim_cancel(plot_unit); @@ -296,18 +391,13 @@ static t_stat plot_attach (UNIT *uptr, char *cptr) { t_stat result; - CLRBIT(uptr->flags, UNIT_DEBUG); + SETBIT(plot_dsw, PLOT1627_DSW_NOT_READY); /* assume failure */ + + CLRBIT(uptr->flags, UNIT_DEBUG); if (sim_switches & SWMASK('D')) SETBIT(uptr->flags, UNIT_DEBUG); - /* get the output file by using regular attach routine */ - result = attach_unit(uptr, cptr); - - if (result != SCPE_OK) { - if (IS_DEBUG) printf("problem attaching file\n"); - return result; - } - - SETBIT(plot_dsw, PLOT1627_DSW_NOT_READY); /* assume failure */ + if (cptr == NULL || ! *cptr) /* filename must be passed */ + return SCPE_ARG; /* set up our canvas at the desired size */ image = gdImageCreate(plot_ymax+1,plot_xmax+1); /* create our canvas */ @@ -316,7 +406,21 @@ static t_stat plot_attach (UNIT *uptr, char *cptr) return SCPE_MEM; } + delete_if_unused = (sim_switches & SWMASK('W')) != 0; + + remove(cptr); /* delete file if it already exists. Otherwise, attach_unit() would open r+w */ + /* get the output file by using regular attach routine */ + result = attach_unit(uptr, cptr); + + if (result != SCPE_OK) { + if (IS_DEBUG) printf("problem attaching file\n"); + gdImageDestroy(image); /* free up the canvas memory */ + image = NULL; + return result; + } + /* set up the basic colors after image created */ + /* (by the way, these calls don't allocate any memory in or out of the image buffer. They just populate its "colors-used" table */ white_background = gdImageColorAllocate(image,WHITE); /* white is background */ black_pen = gdImageColorAllocate(image,BLACK); /* load up black color */ blue_pen = gdImageColorAllocate(image,BLUE); /* load up blue color */ @@ -336,19 +440,22 @@ static t_stat plot_attach (UNIT *uptr, char *cptr) CLRBIT(plot_dsw, PLOT1627_DSW_NOT_READY); /* we're in business */ - update_pen(); /* routine to ensure pen is okay */ + plot_pen = PEN_UP; + CLRBIT(plot_unit->flags, UNIT_PEN); + update_pen(); /* routine to ensure pen is okay */ + plot_used = FALSE; /* plotter page is blank */ return SCPE_OK; } /* pen updating routine, called at attach and whenever we reset the values */ -void update_pen (void) +static void update_pen (void) { int color; int width; - if (!IS_ONLINE(plot_unit)) return; /* only do this if attached */ + if (! IS_ONLINE(plot_unit)) return; /* only do this if attached */ /* pick up latest color as active pen */ color = GET_COLOR; @@ -430,39 +537,69 @@ void update_pen (void) } /* plot_detach - detach file from simulated plotter */ + static t_stat plot_detach (UNIT *uptr) { - char * buf; - int32 size; + char * buf, * fname; + int32 size, result, saveit; FILE * fp; - int32 result; + t_stat rval = SCPE_OK; /* return value */ SETBIT(plot_dsw, PLOT1627_DSW_NOT_READY); - /* copy images to files, close files, set device to detached, free gd memory */ + if (! (uptr->flags & UNIT_ATT)) /* not currently attached; don't proceed */ + return SCPE_OK; - buf = gdImageGifPtr(image,&size); - if (! buf) { - if (IS_DEBUG) printf("failure creating GIF in-memory\n"); - return SCPE_MEM; + /* if -w flag was passed on attach: save file if there was plotter activity, otherwise delete it */ + /* if -w flag was not passed on attached, always save the file */ + saveit = (plot_used || ! delete_if_unused) && (image != NULL); + + if (saveit) { /* copy images to files, close files, set device to detached, free gd memory */ + if ((buf = gdImageGifPtr(image,&size)) == NULL) { + if (IS_DEBUG) printf("failure creating GIF in-memory\n"); + return SCPE_MEM; + } + + fp = uptr->fileref; /* get file attached to unit */ + + if (fseek(fp,0,SEEK_SET) == 0) { /* first we reset to begin of file */ + if (IS_DEBUG) printf("wrote out GIF to file\n"); + result = fwrite(buf,1,size,fp); /* write out our image to the file */ + } + else + result = 0; /* make it look like the write failed so we return error status */ + + gdFree(buf); /* free up the memory of GIF format */ + } + else { /* make a copy of the filename so we can delete it after detach */ + if ((fname = malloc(strlen(uptr->filename)+1)) != NULL) + strcpy(fname, uptr->filename); + } + + if (image != NULL) { + gdImageDestroy(image); /* free up the canvas memory */ + image = NULL; + } + + rval = detach_unit(uptr); /* have simh close the file */ + + if (saveit) { /* if we wrote the file, check that write was OK */ + if (result != size) { /* report error writing file */ + if (IS_DEBUG) printf("error in write of image file\n"); + rval = SCPE_IOERR; + } } + else { /* if we did not write the file, delete the file */ + if (fname == NULL) { + rval = SCPE_MEM; /* we previously failed to allocate a copy of the filename (this will never happen) */ + } + else { + remove(fname); /* remove the file and free the copy of the filename */ + free(fname); + } + } - fp = uptr->fileref; /* get file attached to unit */ - - if (! fseek(fp,0,SEEK_SET)) { /* first we reset to begin of file */ - if (IS_DEBUG) printf("wrote out GIF to file\n"); - result = fwrite(buf,1,size,fp); /* write out our image to the file */ - } - - gdFree(buf); /* free up the memory of GIF format */ - gdImageDestroy(image); /* free up the canvas memory */ - - if (result != size) { /* some problem writing it */ - if (IS_DEBUG) printf("error in write of image file\n"); - return SCPE_IOERR; - } - - return detach_unit(uptr); /* have simh close the file */ + return rval; } /* process_cmd - implement the drawing actions of the plotter */ @@ -474,7 +611,7 @@ static void process_cmd (void) /* first see if we set any changes to pen or position, do an update */ if (need_update) { update_pen(); - need_update = 0; + need_update = FALSE; } /* will move pen one step or flip pen up or down */ @@ -484,49 +621,49 @@ static void process_cmd (void) switch (plot_cmd) { case 1: /* raise pen command */ plot_pen = PEN_UP; - plot_unit->flags = plot_unit->flags & (~UNIT_PEN); + CLRBIT(plot_unit->flags, UNIT_PEN); return; break; case 2: /* +Y command */ - plot_ypos = plot_ypos + 1; + ++plot_ypos; break; case 4: /* -Y command */ - plot_ypos = plot_ypos - 1; + --plot_ypos; break; case 8: /* -X command */ - plot_xpos = plot_xpos - 1; + --plot_xpos; break; case 10: /* -X +Y command */ - plot_xpos = plot_xpos - 1; - plot_ypos = plot_ypos + 1; + --plot_xpos; + ++plot_ypos; break; case 12: /* -X -Y command */ - plot_xpos = plot_xpos - 1; - plot_ypos = plot_ypos - 1; + --plot_xpos; + --plot_ypos; break; case 16: /* +X command */ - plot_xpos = plot_xpos + 1; + ++plot_xpos; break; case 18: /* +X +Y command */ - plot_xpos = plot_xpos + 1; - plot_ypos = plot_ypos + 1; + ++plot_xpos; + ++plot_ypos; break; case 20: /* +X -Y pen command */ - plot_xpos = plot_xpos + 1; - plot_ypos = plot_ypos - 1; + ++plot_xpos; + --plot_ypos; break; case 32: /* lower pen command */ plot_pen = PEN_DOWN; - plot_unit->flags = plot_unit->flags | UNIT_PEN; + SETBIT(plot_unit->flags, UNIT_PEN); return; break; @@ -536,19 +673,36 @@ static void process_cmd (void) break; } - /* check to see if carriage has moved off any edge */ - if ((plot_xpos > (plot_xmax+1)) || (plot_ypos > (plot_ymax+1)) || - (plot_xpos < 0) || (plot_ypos < 0)) { + /* On the real plotter, y motions were physically restricted at the ends of travel. + * We simulate this by clipping the plot_ypos value. Three +y movements at the right + * end of travel followed by three -y movements will back up 3 positions, just as it would have on + * the physical plotter. Without clipping, the pen would end up where it started, which + * is incorrect. (Hopefully, good 1130 plotting software would never make this happen anyhow!) + */ + + if (plot_ypos < 0) + plot_ypos = 0; + else if (plot_ypos > plot_ymax) + plot_ypos = plot_ymax; + + /* We do allow X overtravel though, as the drum simply turned past the end of the paper. Three +x + * movements past the end of the paper followed by three -x movements would put the pen back at the + * edge of the paper. + */ + + if ((plot_xpos < 0) || (plot_xpos > plot_xmax)) { /* if so, ignore as 1627 has no way of signalling error */ if (IS_DEBUG) printf( "attempted to move carriage off paper edge %d %d for command %d\n", plot_xpos,plot_ypos,plot_cmd); - return; + + return; // no drawing takes place if the pen is off of the paper! } /* only draw a line if the pen was down during the movement command */ if (plot_pen) { - gdImageLine(image, plot_ymax-plot_ypos, plot_xmax-plot_xpos, plot_ymax-oldy, plot_xmax-oldx, gdAntiAliased); + gdImageLine(image, plot_ymax-plot_ypos, plot_xmax-plot_xpos, plot_ymax-oldy, plot_xmax-oldx, gdAntiAliased); + plot_used = TRUE; /* remember that we drew something */ /* semantics are 0,0 point is lower right */ } @@ -564,6 +718,11 @@ static t_stat plot_set_length (UNIT *uptr, int32 set, char *ptr, void *desc) #define LONGEST_ROLL 1440000 /* longest is 120', 14400", 1,440,000 .01"s */ + if (ptr == NULL) { /* check for missing argument */ + printf("Command format is: set plot length=nnn\n"); + return SCPE_ARG; + } + val = strtotv (ptr, &cptr, (uint32) 10); /* sim routine to get value */ if ((val < 1) | (val >= LONGEST_ROLL)) { /* check valid range */ if (IS_DEBUG) printf("setting paper more than 120' or less than 1 inch\n"); @@ -626,8 +785,9 @@ static t_stat plot_show_nl(FILE *fp, UNIT *uptr, int32 val, void *descrip) static t_stat plot_validate_change (UNIT *uptr, int32 set, char *ptr, void *desc) { - need_update = 1; + need_update = TRUE; return SCPE_OK; } #endif /* ENABLE_PLOT_SUPPORT */ + diff --git a/Ibm1130/ibm1130_prt.c b/Ibm1130/ibm1130_prt.c index 21aaa140..f6a50fde 100644 --- a/Ibm1130/ibm1130_prt.c +++ b/Ibm1130/ibm1130_prt.c @@ -112,6 +112,7 @@ static t_bool formfed = FALSE; /* last line printed was a formfeed */ #define UNIT_V_RINGCHECK (UNIT_V_UF + 8) #define UNIT_V_SYNCCHECK (UNIT_V_UF + 9) #define UNIT_V_PHYSICAL_PTR (UNIT_V_UF + 10) /* this appears in ibm1130_gui as well */ +#define UNIT_V_TRACE (UNIT_V_UF + 11) #define UNIT_FORMCHECK (1u << UNIT_V_FORMCHECK) #define UNIT_DATACHECK (1u << UNIT_V_DATACHECK) @@ -124,6 +125,7 @@ static t_bool formfed = FALSE; /* last line printed was a formfeed */ #define UNIT_RINGCHECK (1u << UNIT_V_RINGCHECK) #define UNIT_SYNCCHECK (1u << UNIT_V_SYNCCHECK) #define UNIT_PHYSICAL_PTR (1u << UNIT_V_PHYSICAL_PTR) +#define UNIT_TRACE (1u << UNIT_V_TRACE) UNIT prt_unit[] = { { UDATA (&prt_svc, UNIT_ATTABLE, 0) }, @@ -132,6 +134,7 @@ UNIT prt_unit[] = { #define IS_1403(uptr) (uptr->flags & UNIT_1403) /* model test */ #define IS_1132(uptr) ((uptr->flags & UNIT_1403) == 0) /* model test */ #define IS_PHYSICAL(uptr) (uptr->flags & UNIT_PHYSICAL_PTR) +#define DO_TRACE(uptr) (uptr->flags & UNIT_TRACE) /* Parameter in the unit descriptor (1132 printer) */ @@ -149,8 +152,10 @@ REG prt_reg[] = { { NULL } }; MTAB prt_mod[] = { - { UNIT_1403, 0, "1132", "1132", NULL }, /* model option */ - { UNIT_1403, UNIT_1403, "1403", "1403", NULL }, + { UNIT_1403, 0, "1132", "1132", NULL }, /* model option */ + { UNIT_1403, UNIT_1403, "1403", "1403", NULL }, + { UNIT_TRACE, UNIT_TRACE, "TRACE", "TRACE", NULL }, + { UNIT_TRACE, 0, "NOTRACE", "NOTRACE", NULL }, { 0 } }; DEVICE prt_dev = { @@ -348,7 +353,7 @@ static void mytrace (int start, char *what) char *where; if ((where = saywhere(prev_IAR)) == NULL) where = "?"; - trace_io("%s %s at %04x: %s\n", start ? "start" : "stop", what, prev_IAR, where); + trace_io("%s %s at %04x: %s", start ? "start" : "stop", what, prev_IAR, where); } /* xio_1132_printer - XIO command interpreter for the 1132 printer */ @@ -372,32 +377,33 @@ void xio_1132_printer (int32 iocc_addr, int32 func, int32 modify) CLRBIT(PRT_DSW, PRT1132_DSW_READ_EMITTER_RESPONSE | PRT1132_DSW_SKIP_RESPONSE | PRT1132_DSW_SPACE_RESPONSE); CLRBIT(ILSW[1], ILSW_1_1132_PRINTER); } + trace_io("* Printer DSW %04x mod %x", ACC, modify); break; case XIO_CONTROL: if (modify & PRT_CMD_START_PRINTER) { SETBIT(uptr->flags, UNIT_PRINTING); -/* mytrace(1, "printing"); */ + if (DO_TRACE(uptr)) mytrace(1, "printing"); } if (modify & PRT_CMD_STOP_PRINTER) { CLRBIT(uptr->flags, UNIT_PRINTING); -/* mytrace(0, "printing"); */ + if (DO_TRACE(uptr)) mytrace(0, "printing"); } if (modify & PRT_CMD_START_CARRIAGE) { SETBIT(uptr->flags, UNIT_SKIPPING); -/* mytrace(1, "skipping"); */ + if (DO_TRACE(uptr)) mytrace(1, "skipping"); } if (modify & PRT_CMD_STOP_CARRIAGE) { CLRBIT(uptr->flags, UNIT_SKIPPING); -/* mytrace(0, "skipping"); */ + if (DO_TRACE(uptr)) mytrace(0, "skipping"); } if (modify & PRT_CMD_SPACE) { SETBIT(uptr->flags, UNIT_SPACING); -/* mytrace(1, "space"); */ + if (DO_TRACE(uptr)) mytrace(1, "space"); } sim_cancel(uptr); @@ -437,6 +443,7 @@ static t_stat prt_svc (UNIT *uptr) static t_stat prt1132_svc (UNIT *uptr) { if (PRT_DSW & PRT1132_DSW_NOT_READY) { /* cancel operation if printer went offline */ + if (DO_TRACE(uptr)) trace_io("1132 form check"); SETBIT(uptr->flags, UNIT_FORMCHECK); SET_ACTION(uptr, 0); forms_check(TRUE); /* and turn on forms check lamp */ @@ -467,9 +474,15 @@ static t_stat prt1132_svc (UNIT *uptr) if (uptr->flags & UNIT_PRINTING) { if (! save_1132_prt_line(codewheel1132[prt_nchar].ascii)) { /* save previous printed line */ + trace_io("* Print check -- buffer not set in time"); SETBIT(uptr->flags, UNIT_DATACHECK); /* buffer wasn't set in time */ SET_ACTION(uptr, 0); print_check(TRUE); /* and turn on forms check lamp */ + +/* if (running) + reason = STOP_IMMEDIATE; // halt on check +*/ + return SCPE_OK; } @@ -583,6 +596,7 @@ static t_stat prt1403_svc(UNIT *uptr) { if (PRT_DSW & PRT1403_DSW_NOT_READY) { /* cancel operation if printer went offline */ SET_ACTION(uptr, 0); + if (DO_TRACE(uptr)) trace_io("1403 form check"); forms_check(TRUE); /* and turn on forms check lamp */ } else if (uptr->flags & UNIT_TRANSFERRING) { /* end of transfer */ @@ -635,7 +649,7 @@ static t_stat prt1403_svc(UNIT *uptr) /* delete_cmd - SCP command to delete a file */ -static t_stat delete_cmd (int32 flag, char *cptr) +static t_stat delete_cmd (int flag, char *cptr) { char gbuf[CBUFSIZE]; int status; diff --git a/Ibm1130/ibm1130_stddev.c b/Ibm1130/ibm1130_stddev.c index ba268668..8e4f38bb 100644 --- a/Ibm1130/ibm1130_stddev.c +++ b/Ibm1130/ibm1130_stddev.c @@ -363,7 +363,7 @@ static t_stat tti_svc (UNIT *uptr) if ((tti_unit.flags & CSET_MASK) == CSET_ASCII) temp = conin_map[temp] & 0xFF; /* perform input translation */ - if (temp == IRQ_KEY) { /* INT REQ (interrupt request) key */ + if (temp == IRQ_KEY) { /* INT REQ (interrupt request) key -- process this even if no keyboard input request pending */ SETBIT(tti_dsw, TT_DSW_INTERRUPT_REQUEST); /* queue interrupt */ SETBIT(ILSW[4], ILSW_4_CONSOLE); calc_ints(); @@ -388,16 +388,17 @@ static t_stat tti_svc (UNIT *uptr) return SCPE_OK; } - + // keyboard is locked or no active input request? if ((tti_unit.flags & KEYBOARD_LOCKED) || ! (tti_dsw & TT_DSW_KEYBOARD_BUSY)) { SendBeep(); + calc_ints(); return SCPE_OK; } if ((tti_unit.flags & CSET_MASK) == CSET_ASCII) temp = ascii_to_conin[temp]; - if (temp == 0) { /* ignore invalid characters */ + if (temp == 0) { /* ignore invalid characters (no mapping to 1130 input code) */ SendBeep(); calc_ints(); return SCPE_OK; diff --git a/Ibm1130/ibm1130_sys.c b/Ibm1130/ibm1130_sys.c index 2fefc52c..911149a4 100644 --- a/Ibm1130/ibm1130_sys.c +++ b/Ibm1130/ibm1130_sys.c @@ -35,6 +35,7 @@ extern DEVICE gdu_dev, console_dev, plot_dev; extern UNIT cpu_unit; extern REG cpu_reg[]; extern int32 saved_PC; +extern t_bool is_1800; /* SCP data structures and interface routines @@ -290,12 +291,10 @@ static int ebcdic_to_ascii (int ch) t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) { - int32 cflag, ch, OP, F, TAG, INDIR, DSPLC, IR, eaddr; + int32 ch, OP, F, TAG, INDIR, DSPLC, IR, eaddr; char *mnem, tst[12]; - cflag = (uptr == NULL) || (uptr == &cpu_unit); - -/* if (sw & SWMASK ('A')) { // ASCII? not useful +/* if (sw & SWMASK ('A')) { // ASCII? not useful fprintf (of, (c1 < 040)? "<%03o>": "%c", c1); return SCPE_OK; } @@ -348,6 +347,13 @@ t_stat fprint_sym (FILE *of, t_addr addr, t_value *val, UNIT *uptr, int32 sw) } mnem = opcode[OP]; /* get mnemonic */ + if (is_1800) { /* these two are defined on the 1800 but undefined on the 1130 */ + if (OP == 0x16) + mnem = "CMP "; + else if (OP == 0x17) + mnem = "DCMP"; + } + if (OP == 0x02) { /* left shifts are special */ mnem = lsopcode[(DSPLC >> 6) & 0x0003]; DSPLC &= 0x003F; @@ -459,7 +465,7 @@ int strnicmp (const char *a, const char *b, size_t n) { int ca, cb; - if (n == 0) return 0; /* zero length compare is equal */ + if (n == 0) return 0; /* zero length compare is equal */ for (;;) { if ((ca = *a) == 0) /* get character, stop on null terminator */ diff --git a/Ibm1130/ibm1130res.h b/Ibm1130/ibm1130res.h index d84a46ee..0d0d9d49 100644 --- a/Ibm1130/ibm1130res.h +++ b/Ibm1130/ibm1130res.h @@ -4,12 +4,13 @@ // #define IDB_CONSOLE 101 #define IDC_MYHAND 102 +#define IDI_ICON1 103 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_RESOURCE_VALUE 104 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1000 #define _APS_NEXT_SYMED_VALUE 101 diff --git a/Ibm1130/makefile b/Ibm1130/makefile deleted file mode 100644 index 647d0537..00000000 --- a/Ibm1130/makefile +++ /dev/null @@ -1,74 +0,0 @@ -# (This makefile is for operating systems other than Windows, -# or compilers other than Microsoft's. For MS builds, use the -# .mak files found in this directory and the utils directory). -# -# If you are building the emulator and utilities as part of -# the SIMH package, please: -# -# Be sure that you there are NO copies of scp.c, scp_tty.c, -# sim_sock.c, sim_tmxr.c, sim_rev.h, sim_defs.h, sim_sock.h and -# sim_tmxr.h in the ibm1130 subdirectory. Delete them if there -# are. -# -# Do not use this makefile with "make all" or "make ibm1130". -# Use the SIMH build files instead. -# -# If and when you download updates for this simulator from -# www.ibm1130.org, get ibm1130code.zip and ibm1130software.zip -# separately. -# -# If you have downloaded the emulator independently of SIMH (e.g, from -# www.ibm1130.org), please: -# -# Be sure that you DO have copies of scp.c, scp_tty.c, sim_sock.c, -# sim_tmxr.c, sim_rev.h, sim_defs.h, sim_sock.h and sim_tmxr.h -# in this folder. -# -# Use this file to make the emulator. -# -# If and when you download updates for this simulator from -# www.ibm1130.org, get ibm1130.zip. When you expand it, -# also expand ibm1130sofware.zip, which is inside. -# -# In either case, if you want to build DMS or work with assembly -# language programs outside of DMS, you'll want to make the utilities -# by cd'ing to the utils directory and running make there. - -# CC Command -# -# Note: -O2 is sometimes broken in GCC when setjump/longjump is being -# used. Try -O2 only with released simulators. -# -CC = gcc -O0 -lm -I . -#CC = gcc -O2 -g -lm -I . - - -# -# Common Libraries -# -BIN = -SIM = scp.c sim_console.c sim_fio.c sim_sock.c sim_timer.c sim_tmxr.c scp_tty.c -SIM_INC = scp.h sim_console.h sim_defs.h sim_fio.h sim_rev.h sim_sock.h sim_timer.h sim_tmxr.h - -# -# Emulator source files and compile time options -# - -ibm1130D = ./ -ibm1130 = ${ibm1130D}ibm1130_sys.c ${ibm1130D}ibm1130_cpu.c \ - ${ibm1130D}ibm1130_cr.c ${ibm1130D}ibm1130_disk.c \ - ${ibm1130D}ibm1130_stddev.c ${ibm1130D}ibm1130_gdu.c \ - ${ibm1130D}ibm1130_gui.c ${ibm1130D}ibm1130_prt.c \ - ${ibm1130D}ibm1130_ptrp.c ${ibm1130D}ibm1130_fmt.c - -ibm1130_INC = ibm1130res.h ibm1130_conin.h ibm1130_conout.h \ - ibm1130_defs.h ibm1130_prtwheel.h ibm1130_fmt.h \ - dmsr2v12phases.h dmsr2v12slet.h - -# -# Build the emulator -# - -${BIN}ibm1130 : ${ibm1130} ${SIM} ${ibm1130_INC} ${SIM_INC} - ${CC} ${ibm1130} ${SIM} -o $@ - diff --git a/Ibm1130/readme1130.txt b/Ibm1130/readme1130.txt index d2b5da29..e2b85ae8 100644 --- a/Ibm1130/readme1130.txt +++ b/Ibm1130/readme1130.txt @@ -1,5 +1,13 @@ Here's the 1130 simulator as it stands now. +Status: 25Oct2012 + + * Added plotter and 2250 GDU support (though, we don't + have the 2250 support library) + + * Numerous fixes, especially the error in compiling + the FORTRAN sqrt() function under extended precision. + Status: 22Jul2003 * Added support for APL\1130 output translations diff --git a/Visual Studio Projects/IBM1130.vcproj b/Visual Studio Projects/IBM1130.vcproj index 8c7f45c1..2ff19704 100644 --- a/Visual Studio Projects/IBM1130.vcproj +++ b/Visual Studio Projects/IBM1130.vcproj @@ -27,7 +27,7 @@ + + @@ -367,6 +371,46 @@ Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" > + + + + + + + + + + + + + + + + + + + + diff --git a/makefile b/makefile index f399e295..4d2b4e27 100644 --- a/makefile +++ b/makefile @@ -754,6 +754,9 @@ IBM1130 = ${IBM1130D}/ibm1130_cpu.c ${IBM1130D}/ibm1130_cr.c \ ${IBM1130D}/ibm1130_plot.c ${IBM1130D}/ibm1130_sca.c \ ${IBM1130D}/ibm1130_t2741.c IBM1130_OPT = -I ${IBM1130D} +ifneq ($(WIN32),) +IBM1130_OPT += -DGUI_SUPPORT -lgdi32 +endif ID16D = Interdata @@ -1038,7 +1041,13 @@ ibm1130 : ${BIN}ibm1130${EXE} ${BIN}ibm1130${EXE} : ${IBM1130} ${MKDIRBIN} +ifneq ($(WIN32),) + windres ${IBM1130D}/ibm1130.rc $(BIN)ibm1130.o + ${CC} ${IBM1130} ${SIM} ${IBM1130_OPT} $(BIN)ibm1130.o $(CC_OUTSPEC) ${LDFLAGS} + del BIN\ibm1130.o +else ${CC} ${IBM1130} ${SIM} ${IBM1130_OPT} $(CC_OUTSPEC) ${LDFLAGS} +endif s3 : ${BIN}s3${EXE} diff --git a/scp.h b/scp.h index 6c573ee1..d5f773fc 100644 --- a/scp.h +++ b/scp.h @@ -115,6 +115,7 @@ char *get_range (DEVICE *dptr, char *cptr, t_addr *lo, t_addr *hi, uint32 rdx, t_addr max, char term); t_value strtotv (const char *cptr, char **endptr, uint32 radix); t_stat fprint_val (FILE *stream, t_value val, uint32 rdx, uint32 wid, uint32 fmt); +char *read_line (char *cptr, int32 size, FILE *stream); void fprint_reg_help (FILE *st, DEVICE *dptr); void fprint_set_help (FILE *st, DEVICE *dptr); void fprint_show_help (FILE *st, DEVICE *dptr); @@ -163,6 +164,7 @@ extern FILE *sim_deb; /* debug file */ extern FILEREF *sim_deb_ref; /* debug file file reference */ extern UNIT *sim_clock_queue; extern int32 sim_is_running; +extern char *sim_prompt; /* prompt string */ extern volatile int32 stop_cpu; extern uint32 sim_brk_types; /* breakpoint info */ extern uint32 sim_brk_dflt;