diff --git a/CP_48G3.BMP b/CP_48G3.BMP index 56e6045..0d12215 100644 Binary files a/CP_48G3.BMP and b/CP_48G3.BMP differ diff --git a/CP_48S3.BMP b/CP_48S3.BMP index 2a2827d..b41cca6 100644 Binary files a/CP_48S3.BMP and b/CP_48S3.BMP differ diff --git a/EMU48.EXE b/EMU48.EXE index b483462..faa28da 100755 Binary files a/EMU48.EXE and b/EMU48.EXE differ diff --git a/EMU48.TXT b/EMU48.TXT index 3c52496..4a38c7a 100644 --- a/EMU48.TXT +++ b/EMU48.TXT @@ -2,7 +2,7 @@ Emu48 - A freeware HP38/39/40/48/49 Emulator - for Windows 9x, ME, NT, 2000 and XP + for Windows 9x, ME, NT, 2000, XP and Vista @@ -19,18 +19,18 @@ recompile the sources to run Emu48 with Windows NT on a DEC Alpha. **************** Emu48 is distributed in 1 archive: -- Emu48-1_35.zip All files and sources +- Emu48v14xSetup.zip All files and sources -To install Emu48, just unzip Emu48-1_35.zip into an empty directory. When you -first run Emu48, it will detect the directory in which you installed it, and -will write its configuration to a file named Emu48.ini in your Windows -directory. If you move the Emu48 directory to another place you have to change -the directory path inside the Emu48.ini file manually or have to delete the -Emu48.ini file. +To install Emu48, just start the executable file inside the Emu48v14xSetup.zip +archive. The installer will guide you through the installation. When you first +run Emu48, it will detect the directory in which you installed it, and will +write its configuration to a file named Emu48.ini in your Windows directory. If +you move the Emu48 directory to another place you have to change the directory +path inside the Emu48.ini file manually or have to delete the Emu48.ini file. -You can also update your current version with the Unofficial Service Packs: -- E48BP3x.ZIP New EXE-File -- E48SP3x.ZIP Sources of the Service Pack +You can also update your current version with the Service Packs: +- E48BP4x.ZIP New EXE-File +- E48SP4x.ZIP Sources of the Service Pack Replace the original EXE file please. @@ -210,10 +210,15 @@ If you use RAM cards greater than 128 KB in a HP48SX, you can only see the first bug when using a 4MB RAM card. You always get the message "Warning: Invalid Card Data" at startup and Port 33 is unaccessible. This is not a bug of the emulator! -When you have created this file, run Emu48, and use the Close menu item to close -the calculator state. Now select File/Settings. In the "Port 2" text area, type -the name of the file you created (if you don't include a path, it will be -searched for in Emu48's directory). +When you have created this file, run Emu48, and call File/Settings. In the "Port +2" text area, type the name of the file you created (if you don't include a +path, it will be searched for in Emu48's directory) or press the "..." button +for the file browser. If this field is disabled you have chosen the Port 2 file +over the 2nd command line argument, so change the name there please. + +The "Port 2 is Writeable" check box represents the actual read/write state of +the Port 2 file. Changing the state will also change the state for the +calculator by modifying the Read-Only attribute of the file. You can also tick the check box "Port 2 Is Shared". When the box is cleared, only the first instance of Emu48 will allow you to use the RAM card in Port 2. @@ -223,6 +228,13 @@ RAM card in Port 2 will be write-protected. Thus you can transfer files very easily between two calculators. This RAM card is used by both S/SX and G/GX types. +Please remember, all port configuration changes mostly behave like on the +original calculator. This means when you do this changes with the emulated +calculator on, it's the same like when you do this with a real calculator on. In +many times, this depends on the current state of the calculator, this will work +without any problems by doing an automatically calculator warmstart. But for the +most secure way, switch off the emulated calculator first, please! + *********************** * FLASH ROM EMULATION * @@ -361,20 +373,29 @@ address #40000 (128 * 1024 * 2). The "Copy Data" button copies the selected disassembler lines to the PC clipboard. + ************ + * DEBUGGER * + ************ + +Emu48 has an integrated Saturn assembler debugger inside. For further +information read the separated "Debugger.txt" documentation please. + + ************** * DDE SERVER * ************** I implemented a DDE server in Emu48 to transmit data from and to the HP stack with DDE. You have the same restrictions like with the commands "Load object..." -and "Save Object...", that a running program may corrupt memory. Take care to -transmit data only after the acknowledge of the last DDE transaction. +and "Save Object...", that a running program may corrupt memory. In difference +you can choose the stack level for the transfer in the DDE item field. Take care +to transmit data only after the acknowledge of the last DDE transaction. Technical data: Servername: Emu48 Topicname: Stack -Item: - (ignored, must be a nonzero string) +Item: 1 (stack level) Clipboardformat: "CF_HPOBJ" (user defined) The DDE commands CONNECT, POKE and REQUEST are supported. @@ -401,22 +422,21 @@ to get more information please. * SUPPORT * *********** -We cannot provide any individual support for Emu48. All informations about Emu48 -will be on the Emu48 Official Homepage on the Web: - - http://www.epita.fr/~sebc/Emu48/index.html - -or on the Emu48 FAQ at +We cannot provide any individual support for Emu48. Information about Emu48 will +be on the Emu48 Homepage or on the Emu48 FAQ at http://privat.swol.de/ChristophGiesselink/index.htm +It's also a good idea to look at the Usenet forum comp.sys.hp48. Emu48 topics +have discussed there in different threads for years now. + *************** * LEGAL STUFF * *************** Emu48 - An HP38/39/40/48/49 Emulator -Copyright (C) 2005 Sebastien Carlier & Christoph Gießelink +Copyright (C) 2007 Sebastien Carlier & Christoph Gießelink This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -445,9 +465,6 @@ Paper Mail: E-Mail: sebc@epita.fr -Homepage: - http://www.epita.fr/~sebc/Emu48/index.html - Paper Mail: Christoph Giesselink diff --git a/Emu48.url b/Emu48.url index 352cc16..2ccd2f4 100644 --- a/Emu48.url +++ b/Emu48.url @@ -1,2 +1,2 @@ [InternetShortcut] -URL=http://privat.swol.de/ChristophGiesselink/ +URL=http://hp.giesselink.com/ diff --git a/KML_20.DOC b/KML_20.DOC index b374c48..1bc0c1d 100644 --- a/KML_20.DOC +++ b/KML_20.DOC @@ -12,14 +12,14 @@ Global\tab Page 2\par Background\tab Page 5\par \lang1036 LCD\tab Page 6\par -Digit\tab Page 8\par +Digit\tab Page 9\par \lang1040 Annunciator\tab Page 10\par Button\tab Page 11\par \lang1036 OutIn Codes\tab Page 13\par Scancode\tab Page 21\par -\lang1033 Conclusion\b\fs28\tab\b0\fs24 Page 22\par +Conclusion\b\fs28\tab\b0\fs24 Page 23\par \pard\nowidctlpar\b\fs28\par -Basics\b0\par +\lang1033 Basics\b0\par \fs24\par \pard\nowidctlpar\qj\tab A KML script file is a text file that the emulators use to set its screen layout and keyboard layout. A custom bitmap file can be created to be the \ldblquote faceplate\rdblquote of the calculator. KML defines the size and position of the screen, buttons, annunciators, and the Emu48 window. The \ldblquote #\rdblquote character can be used to add remarks to a line. The following sections describe each main block of the KML script.\par \pard\nowidctlpar\par @@ -102,9 +102,9 @@ Emu42:\par \pard\nowidctlpar Example:\par \f1\fs16\tab Rom \ldblquote ROM.48G\rdblquote\par \f0\fs24\par -\pard\nowidctlpar\qj\page Patch is the name of a ROM patch file. \cf1 Any file with correct syntax can be used as a patch file. Multiple Patch lines can be used, and all files will be loaded in the order in which they are declared. Important: They MUST appear after the Rom command.\par +\pard\nowidctlpar\qj Patch is the name of a ROM patch file. \cf1 Any file with correct syntax can be used as a patch file. Multiple Patch lines can be used, and all files will be loaded in the order in which they are declared. Important: They \ul must\ulnone appear after the Rom command.\par \cf0 Example:\par -\pard\nowidctlpar\f1\fs16\tab Patch \ldblquote BEEP.EXT\rdblquote\par +\pard\nowidctlpar\f1\fs16\tab Patch \ldblquote BEEP.48\rdblquote\par \pard\nowidctlpar\qj\f0\fs24\par Bitmap is the bitmap file that will be the \ldblquote faceplate\rdblquote\par \pard\nowidctlpar Example:\par @@ -112,7 +112,7 @@ Bitmap is the bitmap file that will be the \ldblquote faceplate\rdblquote\par \pard\nowidctlpar\qj\f0\fs24\par Print will display a string when the KML file is loaded. You can have as many of these as necessary. They are more effective if you put them before the other settings.\par \pard\nowidctlpar Example:\par -\f1\fs16\tab Print \ldblquote My homepage is at http://www.gulftel.com/~pattersc/emu48/\rdblquote\par +\f1\fs16\tab Print \ldblquote My homepage is at http://privat.swol.de/ChristophGiesselink/\rdblquote\par \pard\nowidctlpar\qj\f0\fs24\par Debug sets the emulator to return an information message box telling the scancode number of the keyboard key pressed when the scancode number isn\rquote t defined. Valid entries are 0 or 1. One is on and Zero is off.\par \pard\nowidctlpar Example:\par @@ -143,10 +143,14 @@ End\par \pard\nowidctlpar Example:\par \f1\fs16\tab Vga 1\par \f0\fs24\par -\pard\nowidctlpar\qj Topbar is a special command only for the Pocket PC versions of Emu32, Emu42 and Emu48 to enable/disable the topbar of the screen. Valid entries are 0 or 1. One is enabled and Zero is disabled.\par +\pard\nowidctlpar\qj Topbar is a special command only for the Pocket PC versions of Emu32, Emu42 and Emu48 to enable/disable the top bar of the screen. Valid entries are 0 or 1. One is enabled and Zero is disabled.\par \pard\nowidctlpar Example:\par \f1\fs16\tab Topbar 0\par \f0\fs24\par +\pard\nowidctlpar\qj Menubar is a special command only for the Pocket PC versions of Emu32, Emu42 and Emu48 to enable/disable the menu bar of the screen. If the menu bar is disabled you can get the menu over the context menu gesture on a display area isn\rquote t covered by virtual key buttons. Valid entries are 0 or 1. One is enabled and Zero is disabled.\par +\pard\nowidctlpar Example:\par +\f1\fs16\tab Menubar 0\par +\f0\fs24\par \b\fs28\page LCD\par \fs24\par \b0\tab This section set the size, position and contrast setting of the LCD screen.\b\par @@ -180,7 +184,7 @@ unused number at background colors = transparent\par 32-63 = background colors (Pixel off), 32 corresponds to 0, 33 to 1, \'85\par unused number at background colors = use color defined by setting 0\par \pard\nowidctlpar\qj\par -You should include one line for every foreground color setting. But the calculator Rom bounds the contrast setting with the keyboard to useful values. The HP48S/SX Rom use values between 3 and 19, the HP48G/GX Rom use values between 9 and 24. Remember this when you write the color table please. The other three integers are the RGB numbers (Red, Green, Blue). The RGB numbers range from 0 to 255. The background color number for the corresponding foreground color is always calculated by adding the first background number setting to the color value. If the background color for the contrast setting isn't defined, color 0 is used by the emulators Emu28, Emu42 and Emu48 and transparent mode by Emu32.\par +You should include one line for every foreground color setting. The other three integers are the RGB numbers (Red, Green, Blue). The RGB numbers range from 0 to 255. The background color number for the corresponding foreground color is always calculated by adding the first background number setting to the color value. If the background color for the contrast setting isn't defined, color 0 is used by the emulators Emu28, Emu42 and Emu48 and transparent mode by Emu10 and Emu32.\par \pard\nowidctlpar Example:\par \f1\fs16\tab Color 0 255 255 255\par \tab Color 1 220 220 220\par @@ -188,7 +192,40 @@ You should include one line for every foreground color setting. But the calculat \tab Color 30 10 10 10\par \tab Color 31 0 0 0\par \tab Color 32 255 255 255\tab # optional background color for contrast setting\par -\f0\fs24\par +\pard\nowidctlpar\qj\f0\fs24\par +\page But the calculator Rom bounds the contrast setting with the keyboard to useful values for each calculator model. The easiest way to generate reasonable contrast settings is to put the calculator to lowest possible darkness value by keyboard and enter the corresponding RGB values to your KML script at the lowest possible setting by ROM (background = pixel off color, foreground = near to background color). In the next step put the calculator to highest possible darkness value by keyboard and enter the corresponding RGB values to your KML script at the highest possible setting by ROM (background = pixel on color, foreground = near to background color). Next important point is the darkness reset value of the Rom because this should be the point of best contrast between fore- and background color. So in the first range between lowest darkness and reset point, use the pixel off color for all background colors and calculated RGB values by a nearly equal distance algorithm for each color part for the foreground colors. For the second range between reset point and highest darkness use the foreground pixel color of the reset point for all foreground colors and calculated RGB values by a nearly equal distance algorithm for each color part for the background colors.\par +\par +The contrast settings outside these areas (accessible by hardware so it\rquote s not useless) can be calculated by the distance between each color channel with saturation to no contrast at pixel off on one side, and pixel on the other side.\par +\par +Contrast setting for each calculator model:\par +\par +\trowd\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl\cell Emulator\cell Range\cell Reset\cell\lang1031 Min\cell Max\cell\row +\trowd\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrt\brdrw15\brdrs\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl HP10B\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\cell\row +\trowd\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl HP14B\cell Emu32\cell 0-15\cell 6\cell 0\cell 15\cell\row +\intbl HP17B\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row +\intbl HP17BII\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row +\intbl HP19BII\cell Emu42\cell\lang1033 0-31\cell 22\cell 16\cell 31\cell\row +\intbl HP20S\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\cell\row +\intbl HP21S\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\cell\row +\intbl HP27S\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row +\intbl HP28C\cell Emu28\cell 0-31\cell 26\cell 20\cell 31\cell\row +\intbl HP28S\cell Emu42\cell 0-31\cell 22\cell 16\cell 31\cell\row +\intbl HP32SII\cell Emu32\cell 0-15\cell 6\cell 0\cell 15\cell\row +\intbl HP38G\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row +\intbl HP39G\cell Emu48\cell 0-31\cell 12\cell 9\cell 24\cell\row +\intbl HP40G\cell Emu48\cell 0-31\cell 12\cell 9\cell 24\cell\row +\intbl HP42S\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row +\intbl HP48SX\cell Emu48\cell 0-31\cell 11\cell 3\cell 19\cell\row +\intbl HP48GX\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row +\trowd\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10 \trbrdrl\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrb\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl HP49G\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row +\pard\nowidctlpar\qj\par +Range\tab : hardware range (accessible by assembler)\par +Reset\tab : contrast value after calculator reset\par +Min\tab : min. adjustable contrast value by keyboard\par +Max\tab : max. adjustable contrast value by keyboard\par +\par +\pard\nowidctlpar On Emu28 and Emu42 the contrast setting of the annunciators depend on the current main display contrast setting and the contrast setting of each annunciator. In normal operation the annunciator color of an on annunciator is exactly the pixel on color of the current contrast. Modifying the annunciator contrast from the default setting will choose a color below or above the current pixel on contrast setting. To avoid any misbehaviors fill the complete display color table of the emulator with reasonable values please.\par +\par \pard\nowidctlpar\qj Vertical is a special command only for the Pocket PC versions of Emu42 and Emu48 to rotate the display by 90\u730? clock or anticlockwise to allow skins in landscape mode. Valid entries are 0 for portrait, 1 for anticlockwise and 2 for clockwise rotated landscape mode. The default setting is portrait mode.\par \pard\nowidctlpar Example:\par \f1\fs16\tab Vertical 1\par @@ -197,7 +234,6 @@ You should include one line for every foreground color setting. But the calculat \fs24\par \pard\nowidctlpar\qj\b0\tab This section is only valid for Emu10 and Emu32 and describes the (alpha-) numeric part of the LCD screen.Emu10 and Emu32 use different methods for creating a numeric value.\b\par \pard\nowidctlpar\b0\par -\par \lang1031\f1\fs16 Digit\par \tab Offset INTEGER INTEGER\par \tab\lang1033 Size INTEGER INTEGER\par @@ -205,7 +241,6 @@ You should include one line for every foreground color setting. But the calculat \tab Bitmap STRING\par End\par \f0\fs24\par -\par Emu10:\par \pard\nowidctlpar\qj The low-end Pioneer series use a classic 7 segment LCD. With the first nine annunciators (segments \lquote a\rquote to \lquote g\rquote , \lquote dp\rquote and \lquote cm\rquote ) one digit is described.\par \pard\nowidctlpar\par @@ -226,10 +261,6 @@ Size is the size of one pixel in the LCD screen. Width Height.\par Example:\par \f1\fs16\tab Size 3 4\tab\tab # size of LCD pixel\par \f0\fs24\par -Size is the Size of the annunciator in pixels. Width Height.\par -Example:\par -\f1\fs16\tab Size 16 11\par -\f0\fs24\par Offset is the position of the first digit inside the display area.\par Example:\par \f1\fs16\tab Offset 17 13\tab\tab # position of 1st digit\par @@ -360,7 +391,7 @@ Example:\par \trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\cf1\b\fs20 OutIn\cell\b0\cell\cell\cell\cell\cell\row \trowd\trgaph30\trleft-30\cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\b\fs16\cell\b0\cell\cell\cell\cell\cell\row \trowd\trgaph30\trleft-30\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf2\b\fs24 N\cell I/YR\cell PV\cell PMT\cell\lang1040 FV\cell SUM+\cell\row -\trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 16\cell 1 16\cell 2 16\cell 5 15\cell 4 16\cell 3 16\cell\row +\trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 16\cell 1 16\cell 2 16\cell 5 16\cell 4 16\cell 3 16\cell\row \trowd\trgaph30\trleft-30\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf2\b\fs24 STO\cell RCL\cell\lang1036 CST\cell PRC\cell MAR\cell\lang1033 STAT\cell\row \trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 1\cell 1 1\cell 2 1\cell 5 1\cell 4 1\cell 3 1\cell\row \trowd\trgaph30\trleft-30\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs \cellx1986\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf2\b\fs24 INPUT\cell +/-\cell (\cell )\cell <-\cell\row @@ -372,7 +403,7 @@ Example:\par \trowd\trgaph30\trleft-30\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf2\b\fs24 SHIFT\cell\cell\lang1036 1\cell 2\cell 3\cell -\cell\row \trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 32\cell\cell 2 32\cell 5 32\cell 4 32\cell 3 32\cell\row \trowd\trgaph30\trleft-30\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrt\brdrw30\brdrs\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf2\b\fs24 C\cell\cell 0\cell .\cell =\cell +\cell\row -\trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 32768\cell\cell 2 64\cell 5 54\cell 4 64\cell 3 64\cell\row +\trowd\trgaph30\trleft-30\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\cf1\b0\fs20 0 32768\cell\cell 2 64\cell 5 64\cell 4 64\cell 3 64\cell\row \pard\nowidctlpar\cf0\f0\fs24\par \pard\nowidctlpar\qj\b\fs28\page OutIn Codes HP17B / HP17BII\par \pard\nowidctlpar\par diff --git a/Macro/Mac2txt.exe b/Macro/Mac2txt.exe index f21f06f..8b25e8e 100755 Binary files a/Macro/Mac2txt.exe and b/Macro/Mac2txt.exe differ diff --git a/Macro/Mac2txt.txt b/Macro/Mac2txt.txt index c52326d..909acb2 100644 --- a/Macro/Mac2txt.txt +++ b/Macro/Mac2txt.txt @@ -1,5 +1,5 @@ Mac2Txt - Keyboard Macro to Text File Converter -11/09/04 (c) by Christoph Gießelink, c dot giesselink at gmx dot de +04/11/07 (c) by Christoph Gießelink, c dot giesselink at gmx dot de *********** @@ -45,7 +45,7 @@ using the default time of the keyboard macro settings in macro replay mode. So it's a good idea to use "T 0" if you want to have no delay. In the other case, if you don't want to switch between 'Real' and 'Manual' Replay speed and want to have always 'Manual' speed it's a good idea to remove all time information in -the text file. The "T" command is alway ignored on 'Manual' Replay speed. +the text file. The "T" command is always ignored on 'Manual' Replay speed. Example @@ -116,6 +116,6 @@ destination immediately! *************** Mac2Txt - Keyboard Macro to Text File Converter -Copyright (c) 2004 Christoph Gießelink +Copyright (c) 2007 Christoph Gießelink This program is freeware. Use it at your own risk. diff --git a/MkShared.exe b/MkShared.exe index 9e3e116..6662fba 100755 Binary files a/MkShared.exe and b/MkShared.exe differ diff --git a/PROBLEMS.TXT b/PROBLEMS.TXT index b44af79..d50cc8c 100644 --- a/PROBLEMS.TXT +++ b/PROBLEMS.TXT @@ -1,15 +1,15 @@ -Known bugs and restrictions of Emu48 V1.42 +Known bugs and restrictions of Emu48 V1.44 ------------------------------------------ - the following I/O bits aren't emulated (incomplete) DTEST (0x102) [VDIG LID TRIM] DSPCTL (0x103) [LRT LRTD LRTC BIN] - LPD (0x108) [LB2 LB1 LB0 VLBI] - LPE (0x109) [ELBI EVLBI GRST RST] + LPD (0x108) [LB2 LB1] + LPE (0x109) [GRST RST] CMODE (0x10A) Mode register IOC (0x110) [ERBZ] RCS (0x111) [RX RER RBZ] - SRQ1 (0x118) [ISQR VSRQ] + SRQ1 (0x118) [ISQR] SRQ2 (0x119) [LSRQ] IRC (0x11A) [IRI EIRU EIRI IRE] LCR (0x11C) [LED ELBE LBZ LBF] @@ -53,4 +53,4 @@ Known bugs and restrictions of Emu48 V1.42 - quitting the emulator while programming the flash isn't allowed, because the content of flash state machine isn't saved so far -08/22/06 (c) by Christoph Gießelink, c dot giesselink at gmx dot de +05/22/07 (c) by Christoph Gießelink, c dot giesselink at gmx dot de diff --git a/Sources/Emu48/CHANGES.TXT b/Sources/Emu48/CHANGES.TXT index e9f0fe4..3e72d9b 100644 --- a/Sources/Emu48/CHANGES.TXT +++ b/Sources/Emu48/CHANGES.TXT @@ -1,3 +1,272 @@ +Service Pack 44 for Emu48 Version 1.0 + +DEBUGGER.C +- added new function OnSetCursor(), message handler for + "Activation Follows Mouse" implementation +- changed function Debugger(), added "Always On Top" and + "Activation Follows Mouse" handling +- bugfix in function OnToolDebug(), argument for owner window handle + was wrong, but over the years I has liked this debugger dialog + behavior so I put in the correct argument for this behavior + +DISASM.C +- disabled automatic inline code +- fixed source file formatting error +- changed function append_field(), defined as inline code +- changed function append_r_addr(), code optimization + +DISPLAY.C +- changed function ResizeWindow(), added "Always on top" feature + +EMU48.C +- removed definition of MAXPORTS +- removed global variable bClassicCursor +- added function ForceForegroundWindow() forcing window to + foreground +- changed function SetCommList(), don't try all possible COM ports + any more, get current serial device list from registry + "HKLM\Hardware\\DeviceMap\\SerialComm" and fill both combo boxes + at one loop for speed up scanning +- changed function SettingsProc(), added "Always On Top" and + "Activation Follows Mouse" checkbox handling, adjusted to new CRC + handling of port2 and adjusted to new prototype of function + SetCommList() +- bugfix in function OnFileNew(), function SaveBackup() was called + when emulator engine was running -> this may caused inconsistent + backup data +- changed function OnMouseMove(), added "Activation follows mouse" + feature +- added function OnNcMouseMove() for "Activation follows mouse" + feature in non client area +- changed function MainWndProc(), added WM_NCMOUSEMOVE message + handler +- bugfix in function WinMain(), moved additional DDE stuff just + behind DDE server initialization, added StartupBackup handling, + adjusted length for cutted filenames preventing negative values + and call ShowWindow() before asking for a new document preventing + a KML script dialog without a parent window + +EMU48.H +- removed declaration of bClassicCursor +- extern declaration of global variables and functions +- changed function prototypes + +EMU48.RC +- added item "Always On Top" and "Activation Follows Mouse" in + settings dialog +- cosmetic changes in dialog IDD_CHOOSEKML to improve WinXP style +- changed version + +FILES.C +- added global variables holding the patched ROM checksum and the + port2 CRC +- changed function GetCutPathName(), better support for UNC names +- changed function SetWindowPathTitle(), adjusted length for cutted + filename +- changed function CrcRom(), change function prototype, added + unpacked data check and made function public +- bugfix in function CrcRom(), hadn't detected address content + changes at addresses ending with a 0x2 and 0x3 because only lower + 16 bit of checksum was used -> modified function cause a warmstart + because of new checksum +- changed function MapRom(), removed check for packed ROM image -> + a more complete check is implemented in InitKML() now +- changed function UnmapRom(), added reset of ROM checksum variable +- changed function CrcPort2(), change function prototype and added + unpacked data check +- changed function MapPort2(), added CRC calculation with saving + result in global variable and added unpacked data check +- changed function UnmapPort2(), added reset of port2 CRC variable +- new function IsDataPacked() for unpacked data check +- changed function OpenDocument(), use ROM checksum made in + InitKML() and port2 CRC made in MapPort2() and added checks for + packed memory data +- changed function SaveDocument(), changed document signature to + "Emu48 Document\xFE" without the calculator model dependent + variations and adjusted implementation to new prototypes of + CrcRom() and CrcPort2() +- changed function SaveBackup(), added assertion for checking + emulator engine state +- bugfix in function GetSaveAsFilename(), removed "Win48 Document" + from filter list because Emu48 cannot create such a document +- changed function WriteStack(), adjusted to new prototype of + function RPL_ObjectSize() and added new error state for bad + objects +- changed function LoadObject(), added error message for bad objects + +KML.C +- bugfix in function KillKML(), class member variable wasn't reset +- changed function MouseMovesTo(), removed bClassicCursor switch + for using arrow cursor over button +- changed function InitKML(), added full check for unpacked ROM + image and build checksum of patched ROM + +OPCODES.C +- changed function o83n(), o88n() and o89n(), speed optimization + +OPS.H +- changed function Tbit0(), Tbit1(), Ta(), Tb(), Tae() and Tbe(), + speed optimization + +PCH.H +- added include stddef.h +- restricted DWORD_PTR type definition for MSVC6.0 and earlier + +RESOURCE.H +- added some definitions + +RPL.C +- bugfix in RPL_ObjectSize(), changed function prototype for adding + buffer size parameter preventing reading outside buffer area when + decoding bad objects + +SERIAL.C +- changed function CommOpen(), increased buffer size for device name + +SETTINGS.C +- changed function ReadSettings() and WriteSettings(), added item + "StartupBackup" in section [Files] and item "ActFollowsMouse" and + "AlwaysOnTop" in section [Emulator], removed item "ClassicCursor" + from [KML] section in the INI-File + + +Service Pack 43 for Emu48 Version 1.0 + +DDESERV.C +- removed warnings when compiling under VS2005 +- changed function DdeCallback(), case XTYP_POKE and XTYP_REQUEST + now decode the item name for the stack level + +DEBUGGER.C +- removed warnings when compiling under VS2005 + +DISASM.C +- bugfix in function disasm_8(), the ?HS=0 n opcode showed always as + ?=0 opcode + +DISPLAY.C +- changed function StopDisplayGray() and StopDisplayBW(), adjusted + to new prototype of ReadIO() + +EMU48.C +- removed warnings when compiling under VS2005 +- moved CF_HPOBJ definition to EMU48.H +- replaced function IsPort2Writeable() with IsFileWriteable() +- bugfix in function SettingsProc(), in case IDC_PORT2LOAD an update + of the port2 writeable checkbox was missing, in case IDOK a + changed port2 writeable checkbox made a warmstart even if there's + no port2 filename, changed behavior of port2 area if port2 + filename is given by the command line argument: show actual port2 + file in disabled port2 filename edit field now, also changes of + the port2 shared and writeable checkboxes have affect now +- changed function OnFileClose(), removed call of KillKML() because + will be done in ResetDocument() + +EMU48.DSP +- added lowbat.c sources + +EMU48.H +- added CF_HPOBJ definition from EMU48.C +- changed function prototypes +- extern declaration of global functions + +EMU48.RC +- replaced CREATEPROCESS_MANIFEST_RESOURCE_ID definition in manifest + declaration by 1 +- changed version and copyright + +ENGINE.C +- changed function WorkerThread(), added control of battery + measurement thread + +EXTERNAL.C +- changed function BeepWave(), removed VS2005 warning +- changed function BeepWin9x(), disabled implementation for x64 + architecture + +FILES.C +- changed function PatchNibble(), added saving state that ROM + address is patched +- bugfix in function UpdatePatches(), the function maybe called for + patching the ROM when it's already patched, in this case the patch + restore list was overwritten with the patched data +- changed function PatchRom(), removed VS2005 warning +- changed function MapPort2(), improved checking for valid size +- bugfix in function GetLoadObjectFilename(), removed call of + HeapFree() which was a remainder of the implementation prior to + SP42 +- changed function WriteStack(), added stack level argument +- changed function LoadObject(), adjusted call of WriteStack() to + new function prototype + +KEYBOARD.C +- bugfix in function ScanKeyboard(), if keyboard reading wasn't + active a released ON key wasn't cleared in the "in" register + +KEYMACRO.C +- removed warnings when compiling under VS2005 +- changed function OnToolMacroNew(), minor optimization writing + macro file header + +KML.C +- removed warnings when compiling under VS2005 +- changed function DisplayChooseKml(), changed return type of dialog + box +- changed function ParseLine(), change typecast of szLexString from + DWORD to DWORD_PTR +- bugfix in function TransparentCircle(), there was no radius value + check for preventing division by 0 and color low adjust value + wasn't reached because of wrong color offset divisor -> adjusted + LOWADJ definition to get similar output to buggy earlier version + +KML.H +- changed variable type of nParam[] element of KmlLine structure + because element is also used as pointer + +LOWBAT.C +- new module with battery measurement + +MOPS.C +- changed function Npeek() and Nread(), adjusted to new prototype of + ReadIO() +- changed prototype of function ReadIO(), added update argument +- bugfix in function ReadIO(), the LPE (0x109), RBR LSB (0x114) and + RBR MSB (0x115) register access had to differ between peek and + read mode and added implementation of the LB0 and VLBI bits in the + LPD (0x108) and implementation of the ELBI and EVLBI bits in the + LPE (0x109) register + +OPCODES.C +- bugfix in function o807(), Chipset.in register must be refreshed + before checking for a pressed key + +PCH.H +- added _CRT_SECURE_NO_DEPRECATE definition +- added DWORD_PTR type definition + +RESOURCE.H +- removed CREATEPROCESS_MANIFEST_RESOURCE_ID and RT_MANIFEST + definition + +RPL.C +- added definition of EDITLINE +- added function RPL_Depth() returning stack depth +- changed function RPL_Pick(), added check of stack depth +- changed function RPL_Push(), new implementation with stack level + argument + +STACK.C +- adjusted calls of RPL_Push() to new function prototype +- changed function RPL_SetBcd(), removed compiler warning +- bugfix in function OnStackPaste(), case "any other format" must be + treated as string and not as binary object + +TIMER.C +- removed warnings when compiling under VS2005 +- changed function CalcT2(), in the case of a pending timer2 + interrupt return always the timer2 value 0xFFFFFFFF + + Service Pack 42 for Emu48 Version 1.0 EMU48.C @@ -267,7 +536,7 @@ SETTINGS.C "WaveBeep" and "WaveVolume" in section [Emulator] in the INI-File STACK.C -- new modul with the message handler functions OnStackCopy() and +- new module with the message handler functions OnStackCopy() and OnStackPaste() prior located in EMU48.C - changed function OnStackCopy() and OnStackPaste(), they can now also copy real numbers from and to the clipboard @@ -457,7 +726,7 @@ KEYBOARD.C too big out codes on Chipset.Keyboard_Row array KEYMACRO.C -- new modul supporting keyboard macro functions +- new module supporting keyboard macro functions KML.C - added function ReloadButtons(), update internal button state from @@ -584,7 +853,7 @@ TIMER.C Service Pack 34 for Emu48 Version 1.0 CURSOR.C -- new modul to create a hand cursor +- new module to create a hand cursor DEBUGGER.C - bugfix in function NewValue(), EnterAddr(), EnterBreakpoint(), @@ -1931,7 +2200,7 @@ FILES.C flash memory structure I28F160.C -- new modul with I28F160 flash memory implementation +- new module with I28F160 flash memory implementation I28F160.H - header file for flash memory implementation @@ -2188,7 +2457,7 @@ SERIAL.H - renamed to IO.H SETTINGS.C -- new modul to handle the INI file +- new module to handle the INI file TIMER.C - removed timer I/O definitions, replaced by include file IO.H @@ -2215,7 +2484,7 @@ DDESERV.C - added different files headers for HP48/49 DEBUGGER.C -- new modul for debugger routines +- new module for debugger routines DEBUGGER.H - header file for debugger part @@ -2331,10 +2600,10 @@ ENGINE.C - made function AdjKeySpeed() public - replaced opcode handling include files by a function call, decoder now works with tables instead of case switching -- deleted unused code parts in modul +- deleted unused code parts in module FETCH.C -- new modul with opcode dispatcher +- new module with opcode dispatcher FETCH.H - file deleted, replaced by FETCH.C @@ -2344,7 +2613,7 @@ FILES.C interpreter failed on lower case hex digits in arguments OPCODES.C -- new modul with opcode implementation +- new module with opcode implementation OPCODES.H - file content changed, replaced by OPCODES.C @@ -2722,7 +2991,7 @@ TIMER.C Service Pack 7 for Emu48 Version 1.0 DISASM.C -- new modul with disassembler +- new module with disassembler DISPLAY.C - bugfixes in function UpdateDisplayPointers(), next line offset was @@ -2846,7 +3115,7 @@ OPCODES.H - update field select table in "EXTENSION opcode o81B1" TIMER.C -- moved static lFreq variable to modul EMU48.C +- moved static lFreq variable to module EMU48.C Service Pack 5a for Emu48 Version 1.0 @@ -2886,7 +3155,7 @@ FILES.C MOPS.C - bugfix in MapP0(), data offset was wrong - bugfix in MapP1(), data offset was wrong -- bugfix in MapP2(), data offset was wrong and real size of modul +- bugfix in MapP2(), data offset was wrong and real size of module was zero - bugfix in MapBS(), wrong pointer in mirrored data page - bugfix in MapROM(), wrong pointer in mirrored data page @@ -2954,7 +3223,7 @@ TIMER.C Service Pack 3 for Emu48 Version 1.0 DDESERV.C -- new modul for DDE communication +- new module for DDE communication EMU48.C - init DDE callback function and name service @@ -2994,7 +3263,7 @@ RESOURCE.H - added IDC_WIRE and IDC_IR SERIAL.C -- new modul for serial support +- new module for serial support SERIAL.H - new header with serial definitions diff --git a/Sources/Emu48/DDESERV.C b/Sources/Emu48/DDESERV.C index 61fdc16..f6913b2 100644 --- a/Sources/Emu48/DDESERV.C +++ b/Sources/Emu48/DDESERV.C @@ -14,10 +14,11 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, HSZ hsz1,HSZ hsz2,HDDEDATA hData, DWORD dwData1,DWORD dwData2) { - TCHAR szBuffer[32]; + TCHAR *psz,szBuffer[32]; HDDEDATA hReturn; LPBYTE lpData,lpHeader; DWORD dwAddress,dwSize,dwLoop,dwIndex; + UINT nStkLvl; BOOL bSuccess; // disable stack loading items on HP38G, HP39/40G @@ -26,17 +27,25 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, switch (iType) { case XTYP_CONNECT: + // get service name DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0); if (0 != lstrcmp(szBuffer,szAppName)) return (HDDEDATA) FALSE; + // get topic name DdeQueryString(idDdeInst,hsz1,szBuffer,ARRAYSIZEOF(szBuffer),0); - return (HDDEDATA) (0==lstrcmp(szBuffer,szTopic)); + return (HDDEDATA) (INT_PTR) (0 == lstrcmp(szBuffer,szTopic)); case XTYP_POKE: // quit on models without stack or illegal data format or not in running state if (!bStackEnable || iFmt != uCF_HpObj || nState != SM_RUN) return (HDDEDATA) DDE_FNOTPROCESSED; + // get item name + DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0); + nStkLvl = _tcstoul(szBuffer,&psz,10); + if (*psz != 0 || nStkLvl < 1) // invalid number format + return (HDDEDATA) DDE_FNOTPROCESSED; + DdeAccessData(hData,&dwSize); // fetch data size DdeUnaccessData(hData); @@ -69,7 +78,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, if (dwIndex <= dwSize - sizeof(DWORD)) dwSize = dwIndex; dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD)); - bSuccess = (WriteStack(lpData,dwSize) == S_ERR_NO); + bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO); HeapFree(hHeap,0,lpData); // free memory SwitchToState(SM_RUN); // run state @@ -98,13 +107,19 @@ cancel: if (!bStackEnable || iFmt != uCF_HpObj || nState != SM_RUN) return NULL; + // get item name + DdeQueryString(idDdeInst,hsz2,szBuffer,ARRAYSIZEOF(szBuffer),0); + nStkLvl = _tcstoul(szBuffer,&psz,10); + if (*psz != 0 || nStkLvl < 1) // invalid number format + return NULL; + if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state return NULL; while (nState!=nNextState) Sleep(0); _ASSERT(nState==SM_SLEEP); - dwAddress = RPL_Pick(1); // pick address of level1 object + dwAddress = RPL_Pick(nStkLvl); // pick address of stack level "item" object if (dwAddress == 0) { SwitchToState(SM_RUN); // run state @@ -115,7 +130,7 @@ cancel: lpHeader = (Chipset.type != 'X') ? BINARYHEADER48 : BINARYHEADER49; // length of binary header - dwIndex = strlen(lpHeader); + dwIndex = (DWORD) strlen(lpHeader); // size of objectsize + header + object dwSize += dwIndex + sizeof(DWORD); diff --git a/Sources/Emu48/DEBUGGER.C b/Sources/Emu48/DEBUGGER.C index 0e3d948..f37c4da 100644 --- a/Sources/Emu48/DEBUGGER.C +++ b/Sources/Emu48/DEBUGGER.C @@ -171,15 +171,14 @@ static BOOL bRegUpdate[REG_SIZE]; // register update table static HBITMAP hBmpCheckBox; // checked and unchecked bitmap // function prototypes -static BOOL OnMemFind(HWND hDlg); -static BOOL OnProfile(HWND hDlg); -static INT OnNewValue(LPTSTR lpszValue); -static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue); -static BOOL OnEditBreakpoint(HWND hDlg); -static BOOL OnInfoIntr(HWND hDlg); -static BOOL OnInfoWoRegister(HWND hDlg); - -static VOID UpdateProfileWnd(HWND hDlg); +static BOOL OnMemFind(HWND hDlg); +static BOOL OnProfile(HWND hDlg); +static INT_PTR OnNewValue(LPTSTR lpszValue); +static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue); +static BOOL OnEditBreakpoint(HWND hDlg); +static BOOL OnInfoIntr(HWND hDlg); +static BOOL OnInfoWoRegister(HWND hDlg); +static VOID UpdateProfileWnd(HWND hDlg); //################ //# @@ -514,7 +513,7 @@ static VOID UpdateCodeWnd(HWND hDlg) HWND hWnd = GetDlgItem(hDlg,IDC_DEBUG_CODE); - j = SendMessage(hWnd,LB_GETCOUNT,0,0); // no. of items in table + j = (INT) SendMessage(hWnd,LB_GETCOUNT,0,0); // no. of items in table // seach for actual address in code area for (i = 0; i < j; ++i) @@ -670,14 +669,14 @@ static VOID UpdateStackWnd(HWND hDlg) HWND hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); SendMessage(hWnd,WM_SETREDRAW,FALSE,0); - nPos = SendMessage(hWnd,LB_GETTOPINDEX,0,0); + nPos = (LONG) SendMessage(hWnd,LB_GETTOPINDEX,0,0); SendMessage(hWnd,LB_RESETCONTENT,0,0); for (i = 1; i <= ARRAYSIZEOF(Chipset.rstk); ++i) { INT j; wsprintf(szBuffer,_T("%d: %05X"), i, Chipset.rstk[(Chipset.rstkp-i)&7]); - j = SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); + j = (INT) SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); SendMessage(hWnd,LB_SETITEMDATA,j,Chipset.rstk[(Chipset.rstkp-i)&7]); } SendMessage(hWnd,LB_SETTOPINDEX,nPos,0); @@ -823,7 +822,7 @@ static BOOL OnKeyF2(HWND hDlg) LONG i; hWnd = GetDlgItem(hDlg,IDC_DEBUG_CODE); - i = SendMessage(hWnd,LB_GETCURSEL,0,0); // get selected item + i = (LONG) SendMessage(hWnd,LB_GETCURSEL,0,0); // get selected item ToggleBreakpoint(dwAdrLine[i]); // toggle breakpoint at address // update region of toggled item SendMessage(hWnd,LB_GETITEMRECT,i,(LPARAM)&rc); @@ -845,7 +844,7 @@ static BOOL OnKeyF5(HWND hDlg) DisableMenuKeys(hDlg); // disable menu keys hWnd = GetDlgItem(hDlg,IDC_DEBUG_CODE); - nPos = SendMessage(hWnd,LB_GETCURSEL,0,0); + nPos = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); // clear "->" in code window for (i = 0; i < MAXCODELINES; ++i) @@ -855,7 +854,7 @@ static BOOL OnKeyF5(HWND hDlg) { szBuf[5] = szBuf[6] = _T(' '); SendMessage(hWnd,LB_DELETESTRING,i,0); - SendMessage(hWnd,LB_INSERTSTRING,i,(LPARAM)(LPTSTR)szBuf); + SendMessage(hWnd,LB_INSERTSTRING,i,(LPARAM) szBuf); break; } } @@ -877,7 +876,7 @@ static BOOL OnKeyF6(HWND hDlg) if (nDbgState != DBG_RUN) // emulation stopped { // get address of selected item - INT nPos = SendDlgItemMessage(hDlg,IDC_DEBUG_CODE,LB_GETCURSEL,0,0); + INT nPos = (INT) SendDlgItemMessage(hDlg,IDC_DEBUG_CODE,LB_GETCURSEL,0,0); dwDbgStopPC = dwAdrLine[nPos]; OnKeyF5(hDlg); // run emulation @@ -1094,7 +1093,7 @@ static BOOL OnStackPush(HWND hDlg) hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); - i = SendMessage(hWnd,LB_GETCURSEL,0,0); + i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); if (LB_ERR == i) return TRUE; // no selection if (IDOK != OnNewValue(szBuffer)) // canceled function @@ -1126,7 +1125,7 @@ static BOOL OnStackPop(HWND hDlg) hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); - i = SendMessage(hWnd,LB_GETCURSEL,0,0); + i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); if (LB_ERR == i) return TRUE; // no selection // pop stack element @@ -1153,7 +1152,7 @@ static BOOL OnStackModify(HWND hDlg) hWnd = GetDlgItem(hDlg,IDC_DEBUG_STACK); - i = SendMessage(hWnd,LB_GETCURSEL,0,0); + i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); if (LB_ERR == i) return TRUE; // no selection SendMessage(hWnd,LB_GETTEXT,i,(LPARAM) szBuffer); @@ -1307,8 +1306,8 @@ static BOOL OnDblClick(HWND hWnd, WORD wId) if (wId == IDC_DEBUG_STACK) // stack list box { // get cpu address of selected item - i = SendMessage(hWnd,LB_GETCURSEL,0,0); - dwAddress = SendMessage(hWnd,LB_GETITEMDATA,i,0); + i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0); + dwAddress = (DWORD) SendMessage(hWnd,LB_GETITEMDATA,i,0); // show code of this address ViewCodeWnd(GetDlgItem(GetParent(hWnd),IDC_DEBUG_CODE),dwAddress); @@ -1325,7 +1324,7 @@ static BOOL OnDblClick(HWND hWnd, WORD wId) // calculate address of byte dwAddress = i * 2; - i = SendMessage(hWnd,LB_GETCARETINDEX,0,0); + i = (INT) SendMessage(hWnd,LB_GETCARETINDEX,0,0); dwAddress += MAXMEMITEMS * i + dwAdrMem; // enter new value @@ -1375,6 +1374,19 @@ static VOID OnContextMenu(HWND hDlg, LPARAM lParam, WPARAM wParam) return; } +// +// mouse setting for capturing window +// +static BOOL OnSetCursor(HWND hDlg) +{ + // debugger not active but cursor is over debugger window + if (bActFollowsMouse && GetActiveWindow() != hDlg) + { + ForceForegroundWindow(hDlg); // force debugger window to foreground + } + return FALSE; +} + //################ //# //# Dialog handler @@ -1503,7 +1515,7 @@ static __inline BOOL OnDrawCodeWnd(LPDRAWITEMSTRUCT lpdis) return TRUE; // get item text - SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LONG)(LPTSTR)szBuf); + SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM) szBuf); // check for codebreakpoint bBrk = CheckBreakpoint(dwAdrLine[lpdis->itemID],1,BP_EXEC); @@ -1697,7 +1709,7 @@ quit: return hWndToolbar; } -static BOOL CALLBACK Debugger(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HMENU hMenuMainCode,hMenuMainMem,hMenuMainStack; @@ -1711,6 +1723,7 @@ static BOOL CALLBACK Debugger(HWND hDlg, UINT message, DWORD wParam, LONG lParam { case WM_INITDIALOG: SetWindowLocation(hDlg,nDbgPosX,nDbgPosY); + if (bAlwaysOnTop) SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); SendMessage(hDlg,WM_SETICON,ICON_BIG,(LPARAM) LoadIcon(hApp,MAKEINTRESOURCE(IDI_EMU48))); hWndToolbar = CreateToolbar(hDlg); // add toolbar CheckMenuItem(GetMenu(hDlg),ID_BREAKPOINTS_NOP3, bDbgNOP3 ? MF_CHECKED : MF_UNCHECKED); @@ -1811,7 +1824,7 @@ static BOOL CALLBACK Debugger(HWND hDlg, UINT message, DWORD wParam, LONG lParam return OnDblClick((HWND) lParam, LOWORD(wParam)); case LBN_SETFOCUS: - i = SendMessage((HWND) lParam,LB_GETCARETINDEX,0,0); + i = (INT) SendMessage((HWND) lParam,LB_GETCARETINDEX,0,0); SendMessage((HWND) lParam,LB_SETCURSEL,i,0); return TRUE; @@ -1915,13 +1928,16 @@ static BOOL CALLBACK Debugger(HWND hDlg, UINT message, DWORD wParam, LONG lParam OnContextMenu(hDlg, lParam, wParam); break; + case WM_SETCURSOR: + return OnSetCursor(hDlg); + case WM_CTLCOLORSTATIC: // register color highlighting // highlight text? if (OnCtlColorStatic((HWND) lParam)) { SetTextColor((HDC) wParam, COLOR_RED); SetBkColor((HDC) wParam, GetSysColor(COLOR_BTNFACE)); - return (BOOL) GetStockObject(NULL_BRUSH); // transparent brush + return (INT_PTR) GetStockObject(NULL_BRUSH); // transparent brush } break; @@ -1960,9 +1976,9 @@ static BOOL CALLBACK Debugger(HWND hDlg, UINT message, DWORD wParam, LONG lParam return FALSE; } -LRESULT OnToolDebug() // debugger dialogbox call +LRESULT OnToolDebug(VOID) // debugger dialogbox call { - if ((hDlgDebug = CreateDialog(hApp,MAKEINTRESOURCE(IDD_DEBUG),GetParent(hWnd), + if ((hDlgDebug = CreateDialog(hApp,MAKEINTRESOURCE(IDD_DEBUG),NULL, (DLGPROC)Debugger)) == NULL) AbortMessage(_T("Debugger Dialog Box Creation Error !")); return 0; @@ -2090,7 +2106,7 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast) // // enter find dialog // -static BOOL CALLBACK Find(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK Find(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static DWORD dwAddrEntry; static BOOL bASCII = FALSE; @@ -2163,7 +2179,7 @@ static VOID UpdateProfileWnd(HWND hDlg) lVar = *(QWORD *)&Chipset.cycles - *(QWORD *)&OldChipset.cycles; // cycle counts - _stprintf(szBuffer,_T("%I64u"),lVar); + _sntprintf(szBuffer,ARRAYSIZEOF(szBuffer),_T("%I64u"),lVar); SetDlgItemText(hDlg,IDC_PROFILE_LASTCYCLES,szBuffer); // CPU frequency @@ -2183,7 +2199,7 @@ static VOID UpdateProfileWnd(HWND hDlg) lVar = (2 * lVar + dwFreq) / (2 * dwFreq); _ASSERT(i < ARRAYSIZEOF(pcUnit)); - _stprintf(szBuffer,_T("%I64u %s"),lVar,pcUnit[i]); + _sntprintf(szBuffer,ARRAYSIZEOF(szBuffer),_T("%I64u %s"),lVar,pcUnit[i]); SetDlgItemText(hDlg,IDC_PROFILE_LASTTIME,szBuffer); return; #undef SX_CLK @@ -2194,7 +2210,7 @@ static VOID UpdateProfileWnd(HWND hDlg) // // enter profile dialog // -static BOOL CALLBACK Profile(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK Profile(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -2241,7 +2257,7 @@ static BOOL OnProfile(HWND hDlg) // // enter new value dialog // -static BOOL CALLBACK NewValue(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK NewValue(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static LPTSTR lpszBuffer; // handle of buffer static int nBufferlen; // length of buffer @@ -2287,9 +2303,9 @@ static BOOL CALLBACK NewValue(HWND hDlg, UINT message, DWORD wParam, LONG lParam UNREFERENCED_PARAMETER(wParam); } -static INT OnNewValue(LPTSTR lpszValue) +static INT_PTR OnNewValue(LPTSTR lpszValue) { - INT nResult; + INT_PTR nResult; if ((nResult = DialogBoxParam(hApp, MAKEINTRESOURCE(IDD_NEWVALUE), @@ -2311,7 +2327,7 @@ static INT OnNewValue(LPTSTR lpszValue) // // enter goto address dialog // -static BOOL CALLBACK EnterAddr(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK EnterAddr(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static DWORD *dwAddress; @@ -2368,7 +2384,7 @@ static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue) // // enter breakpoint dialog // -static BOOL CALLBACK EnterBreakpoint(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static BP_T *sBp; @@ -2459,7 +2475,7 @@ static __inline BOOL OnDrawBreakWnd(LPDRAWITEMSTRUCT lpdis) crBkColor = SetBkColor(lpdis->hDC,crBkColor); crTextColor = SetTextColor(lpdis->hDC,crTextColor); - SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LONG)(LPTSTR)szBuf); + SendMessage(lpdis->hwndItem,LB_GETTEXT,lpdis->itemID,(LPARAM) szBuf); ExtTextOut(lpdis->hDC,(int)(lpdis->rcItem.left)+17,(int)(lpdis->rcItem.top), ETO_OPAQUE,(LPRECT)&lpdis->rcItem,szBuf,lstrlen(szBuf),NULL); @@ -2467,7 +2483,7 @@ static __inline BOOL OnDrawBreakWnd(LPDRAWITEMSTRUCT lpdis) SetTextColor(lpdis->hDC,crTextColor); // draw checkbox - i = SendMessage(lpdis->hwndItem,LB_GETITEMDATA,lpdis->itemID,0); + i = (INT) SendMessage(lpdis->hwndItem,LB_GETITEMDATA,lpdis->itemID,0); hdcMem = CreateCompatibleDC(lpdis->hDC); _ASSERT(hBmpCheckBox); hBmpOld = SelectObject(hdcMem,hBmpCheckBox); @@ -2493,7 +2509,7 @@ static BOOL ToggleBreakpointItem(HWND hWnd, INT nItem) RECT rc; // get breakpoint number - INT i = SendMessage(hWnd,LB_GETITEMDATA,nItem,0); + INT i = (INT) SendMessage(hWnd,LB_GETITEMDATA,nItem,0); sBreakpoint[i].bEnable = !sBreakpoint[i].bEnable; // update region of toggled item @@ -2532,7 +2548,7 @@ static VOID DrawBreakpoint(HWND hWnd, INT i) _ASSERT(0); } wsprintf(szBuffer,_T("%05X (%s)"),sBreakpoint[i].dwAddr,szText); - nItem = SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); + nItem = (INT) SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); SendMessage(hWnd,LB_SETITEMDATA,nItem,i); return; } @@ -2540,7 +2556,7 @@ static VOID DrawBreakpoint(HWND hWnd, INT i) // // enter edit breakpoint dialog // -static BOOL CALLBACK EditBreakpoint(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { TEXTMETRIC tm; @@ -2581,7 +2597,7 @@ static BOOL CALLBACK EditBreakpoint(HWND hDlg, UINT message, DWORD wParam, LONG case LBN_DBLCLK: if (LOWORD(wParam) == IDC_BREAKEDIT_WND) { - if ((nItem = SendMessage(hWnd,LB_GETCURSEL,0,0)) == LB_ERR) + if ((nItem = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0)) == LB_ERR) return FALSE; return ToggleBreakpointItem(hWnd,nItem); @@ -2650,14 +2666,14 @@ static BOOL CALLBACK EditBreakpoint(HWND hDlg, UINT message, DWORD wParam, LONG INT j; // get breakpoint index - i = SendMessage(hWnd,LB_GETITEMDATA,nItem,0); + i = (INT) SendMessage(hWnd,LB_GETITEMDATA,nItem,0); SendMessage(hWnd,LB_DELETESTRING,nItem,0); --wBreakpointCount; // update remaining list box references for (j = 0; j < wBreakpointCount; ++j) { - INT k = SendMessage(hWnd,LB_GETITEMDATA,j,0); + INT k = (INT) SendMessage(hWnd,LB_GETITEMDATA,j,0); if (k > i) SendMessage(hWnd,LB_SETITEMDATA,j,k-1); } @@ -2733,7 +2749,7 @@ static BOOL OnEditBreakpoint(HWND hDlg) // // view last instructions // -static BOOL CALLBACK InfoIntr(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK InfoIntr(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hWnd; TCHAR szBuffer[64]; @@ -2757,7 +2773,7 @@ static BOOL CALLBACK InfoIntr(HWND hDlg, UINT message, DWORD wParam, LONG lParam { j = wsprintf(szBuffer,_T("%05lX "),pdwInstrArray[i]); disassemble(pdwInstrArray[i],&szBuffer[j],VIEW_SHORT); - lIndex = SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); + lIndex = (LONG) SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szBuffer); } SendMessage(hWnd,WM_SETREDRAW,TRUE,0); SendMessage(hWnd,LB_SETCARETINDEX,lIndex,TRUE); diff --git a/Sources/Emu48/DISASM.C b/Sources/Emu48/DISASM.C index c67717f..1e87fe2 100644 --- a/Sources/Emu48/DISASM.C +++ b/Sources/Emu48/DISASM.C @@ -10,6 +10,8 @@ #include "pch.h" #include "Emu48.h" +#pragma inline_depth(0) + #define TAB_SKIP 8 BOOL disassembler_mode = HP_MNEMONICS; @@ -209,7 +211,7 @@ static LPCTSTR hst_bits[8] = /* * Class Mnemonics */ - _T("xm"), _T("sb"), _T("sr"), _T("mp"), + _T("xm"), _T("sb"), _T("sr"), _T("mp") }; @@ -317,7 +319,7 @@ static LPTSTR append_tab (LPTSTR buf) return p; } -static LPTSTR append_field (LPTSTR buf, BYTE fn) +static __inline LPTSTR append_field (LPTSTR buf, BYTE fn) { return append_str (buf, field_tbl[fn + 16 * disassembler_mode]); } @@ -371,47 +373,25 @@ static LPTSTR append_addr (LPTSTR buf, DWORD addr) return buf; } -static LPTSTR append_r_addr (LPTSTR buf, DWORD * pc, long disp, int n, int offset) +static LPTSTR append_r_addr (LPTSTR buf, DWORD *pc, long disp, int n, int offset) { long sign; sign = 1 << (n * 4 - 1); - if (disp & sign) - disp |= ~(sign - 1); + if (disp & sign) // negative value? + disp |= ~(sign - 1); // expand it to long *pc += disp; - - switch (disassembler_mode) + if (disp < 0) { - case HP_MNEMONICS: - if (disp < 0) - { - buf = append_str(buf, _T("-")); - disp = -disp - offset; - } - else - { - buf = append_str(buf, _T("+")); - disp += offset; - } - buf = append_addr(buf, disp); - break; - case CLASS_MNEMONICS: - if (disp < 0) - { - buf = append_str(buf, _T("-")); - disp = -disp - offset; - } - else - { - buf = append_str(buf, _T("+")); - disp += offset; - } - buf = append_addr(buf, disp); - break; - default: - buf = append_str (buf, _T("Unknown disassembler mode")); - break; + buf = append_str(buf, _T("-")); + disp = -disp - offset; } + else + { + buf = append_str(buf, _T("+")); + disp += offset; + } + buf = append_addr(buf, disp); return buf; } @@ -435,8 +415,8 @@ static LPTSTR append_pc_comment (LPTSTR buf, DWORD pc, BOOL view) p = append_addr (p, pc); break; default: - p = append_str (p, _T("Unknown disassembler mode")); - break; + p = append_str (p, _T("Unknown disassembler mode")); + break; } } else // output of address in brackets @@ -1184,10 +1164,20 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out, BOOL view) switch (disassembler_mode) { case HP_MNEMONICS: - p = append_str (out, _T("?")); - p = append_hst_bits (p, n); - p = append_str (p, _T("=0")); - p = append_tab (out); + if (n != 1 && n != 2 && n != 4 && n != 8) + { + p = append_str (out, _T("?HS=0")); + p = append_tab (out); + wsprintf (buf, _T("%d, "), n); + p = append_str (p, buf); + } + else + { + p = append_str (out, _T("?")); + p = append_hst_bits (p, n); + p = append_str (p, _T("=0")); + p = append_tab (out); + } if (disp != 0) { p = append_str (p, _T("GOYES ")); @@ -1894,9 +1884,9 @@ DWORD disassemble (DWORD addr, LPTSTR out, BOOL view) { wsprintf (buf, p, hp_reg_1_af[n], hp_reg_2_af[n]); } - p = append_str (out, buf); - p = append_tab (out); - p = append_field (p, fn); + p = append_str (out, buf); + p = append_tab (out); + p = append_field (p, fn); break; case CLASS_MNEMONICS: @@ -1924,4 +1914,3 @@ DWORD disassemble (DWORD addr, LPTSTR out, BOOL view) return addr; } - diff --git a/Sources/Emu48/DISPLAY.C b/Sources/Emu48/DISPLAY.C index a04c2d0..a0b8806 100644 --- a/Sources/Emu48/DISPLAY.C +++ b/Sources/Emu48/DISPLAY.C @@ -833,16 +833,16 @@ VOID ResizeWindow(VOID) rectWindow.right = nBackgroundW; rectWindow.bottom = nBackgroundH; AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); - SetWindowPos (hWnd, (HWND)NULL, 0, 0, + SetWindowPos(hWnd, bAlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, - SWP_NOMOVE | SWP_NOZORDER); + SWP_NOMOVE); GetClientRect(hWnd, &rectClient); AdjustWindowRect(&rectClient, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); if (rectClient.bottom < rectWindow.bottom) { rectWindow.bottom += (rectWindow.bottom - rectClient.bottom); - SetWindowPos (hWnd, (HWND)NULL, 0, 0, + SetWindowPos (hWnd, NULL, 0, 0, rectWindow.right - rectWindow.left, rectWindow.bottom - rectWindow.top, SWP_NOMOVE | SWP_NOZORDER); @@ -920,7 +920,7 @@ static VOID StartDisplayGray(BYTE byInitial) static VOID StopDisplayGray(VOID) { BYTE a[2]; - ReadIO(a,LINECOUNT,2); // update VBL at display off time + ReadIO(a,LINECOUNT,2,TRUE); // update VBL at display off time if (uLcdTimerId == 0) // timer stopped return; // -> quit @@ -970,6 +970,6 @@ static VOID StartDisplayBW(BYTE byInitial) static VOID StopDisplayBW(VOID) { BYTE a[2]; - ReadIO(a,LINECOUNT,2); // update VBL at display off time + ReadIO(a,LINECOUNT,2,TRUE); // update VBL at display off time return; } diff --git a/Sources/Emu48/EMU48.C b/Sources/Emu48/EMU48.C index e72c59e..b58516a 100644 --- a/Sources/Emu48/EMU48.C +++ b/Sources/Emu48/EMU48.C @@ -13,17 +13,14 @@ #include "kml.h" #include "debugger.h" -#define VERSION "1.42" -#define CF_HPOBJ "CF_HPOBJ" // clipboard format for DDE - -#define MAXPORTS 256 // number of COM ports +#define VERSION "1.44" // #define MONOCHROME // CF_BITMAP clipboard format #ifdef _DEBUG -LPTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug"); +LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug"); #else -LPTSTR szNoTitle = _T("Emu48 ")_T(VERSION); +LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION); #endif LPTSTR szAppName = _T("Emu48"); // application name for DDE server LPTSTR szTopic = _T("Stack"); // topic for DDE server @@ -77,12 +74,15 @@ HPALETTE hPalette = NULL; HPALETTE hOldPalette = NULL; // old palette of hWindowDC HCURSOR hCursorArrow = NULL; HCURSOR hCursorHand = NULL; -BOOL bClassicCursor = FALSE; // use hand instead of arrow cursor BOOL bAutoSave = FALSE; BOOL bAutoSaveOnExit = TRUE; BOOL bSaveDefConfirm = TRUE; // yes +BOOL bStartupBackup = FALSE; BOOL bAlwaysDisplayLog = TRUE; BOOL bLoadObjectWarning = TRUE; +BOOL bAlwaysOnTop = FALSE; // emulator window always on top +BOOL bActFollowsMouse = FALSE; // emulator window activation follows mouse + //################ @@ -147,6 +147,18 @@ VOID UpdateWindowStatus(VOID) return; } +VOID ForceForegroundWindow(HWND hWnd) +{ + // force window to foreground + DWORD dwEmuThreadID = GetCurrentThreadId(); + DWORD dwActThreadID = GetWindowThreadProcessId(GetForegroundWindow(),NULL); + + AttachThreadInput(dwEmuThreadID,dwActThreadID,TRUE); + SetForegroundWindow(hWnd); + AttachThreadInput(dwEmuThreadID,dwActThreadID,FALSE); + return; +} + //################ @@ -161,7 +173,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar LPINT lpnCount; // get number of selections - if ((i = SendMessage(hWnd,LB_GETSELCOUNT,0,0)) == 0) + if ((i = (LONG) SendMessage(hWnd,LB_GETSELCOUNT,0,0)) == 0) return; // no items selected if ((lpnCount = HeapAlloc(hHeap,0,i * sizeof(INT))) != NULL) @@ -171,11 +183,11 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar LONG j,lMem = 0; // get indexes of selected items - i = SendMessage(hWnd,LB_GETSELITEMS,i,(LPARAM) lpnCount); + i = (LONG) SendMessage(hWnd,LB_GETSELITEMS,i,(LPARAM) lpnCount); for (j = 0;j < i;++j) // scan all selected items { // calculate total amount of characters - lMem += SendMessage(hWnd,LB_GETTEXTLEN,lpnCount[j],0) + 2; + lMem += (LONG) SendMessage(hWnd,LB_GETTEXTLEN,lpnCount[j],0) + 2; } // allocate clipboard data if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,(lMem + 1) * sizeof(*lpszData))) != NULL) @@ -222,57 +234,103 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar //# //################ -// get R/W state of port2 file -static BOOL IsPort2Writeable(VOID) +// get R/W state of file +static BOOL IsFileWriteable(LPCTSTR szFilename) { DWORD dwFileAtt; BOOL bWriteable = FALSE; SetCurrentDirectory(szEmuDirectory); - dwFileAtt = GetFileAttributes(szPort2Filename); + dwFileAtt = GetFileAttributes(szFilename); if (dwFileAtt != 0xFFFFFFFF) bWriteable = ((dwFileAtt & FILE_ATTRIBUTE_READONLY) == 0); SetCurrentDirectory(szCurrentDirectory); return bWriteable; } -// set listfield for serial combobox -static VOID SetCommList(HWND hDlg,int nIDDlgItem,LPCTSTR szSetting) +// set listfield for serial combo boxes +static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting) { - HANDLE hComm; - BOOL bAdd; - WORD wCount, wIndex = 1; - TCHAR szBuffer[16]; + WPARAM wSelectWire,wSelectIr; + HKEY hKey; - WPARAM wSelect = 0; // set select to disabled - SendDlgItemMessage(hDlg,nIDDlgItem,CB_ADDSTRING,0,(LPARAM) _T(NO_SERIAL)); + wSelectWire = wSelectIr = 0; // set selections to disabled + SendDlgItemMessage(hDlg,IDC_WIRE,CB_ADDSTRING,0,(LPARAM) _T(NO_SERIAL)); + SendDlgItemMessage(hDlg,IDC_IR ,CB_ADDSTRING,0,(LPARAM) _T(NO_SERIAL)); - for (wCount = 1;wCount <= MAXPORTS;++wCount) + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, + _T("Hardware\\DeviceMap\\SerialComm"), + 0, + KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, + &hKey) == ERROR_SUCCESS) { - wsprintf(szBuffer,_T("\\\\.\\COM%u"),wCount); - if ((bAdd = (lstrcmp(&szBuffer[4],szSetting) == 0))) - wSelect = wIndex; + HANDLE hComm; + TCHAR szBuffer[256],cKey[256],cData[256]; + DWORD dwKeySize,dwDataSize; + WPARAM wSelIndexWire,wSelIndexIr; + BOOL bAddWire,bAddIr; + DWORD dwType,dwEnumVal; + LONG lRet; - // test if COM port is valid - hComm = CreateFile(szBuffer,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); - if(hComm != INVALID_HANDLE_VALUE) - { - VERIFY(CloseHandle(hComm)); - bAdd = TRUE; - } + wSelIndexWire = wSelIndexIr = 1; // preset selector - if (bAdd) // add item to combobox + dwEnumVal = 0; + do { - SendDlgItemMessage(hDlg,nIDDlgItem,CB_ADDSTRING,0,(LPARAM) &szBuffer[4]); - ++wIndex; + dwKeySize = ARRAYSIZEOF(cKey); // init return buffer sizes + dwDataSize = sizeof(cData); + + lRet = RegEnumValue(hKey,dwEnumVal++, + cKey,&dwKeySize, + NULL,&dwType, + (LPBYTE) cData,&dwDataSize); + + if (lRet == ERROR_SUCCESS && dwType == REG_SZ) + { + wsprintf(szBuffer,_T("\\\\.\\%s"),cData); + if ((bAddWire = (lstrcmp(&szBuffer[4],szWireSetting) == 0))) + wSelectWire = wSelIndexWire; + if ((bAddIr = (lstrcmp(&szBuffer[4],szIrSetting) == 0))) + wSelectIr = wSelIndexIr; + + // test if COM port is valid + hComm = CreateFile(szBuffer,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); + if(hComm != INVALID_HANDLE_VALUE) + { + VERIFY(CloseHandle(hComm)); + bAddWire = bAddIr = TRUE; + } + + if (bAddWire) // add item to wire combobox + { + SendDlgItemMessage(hDlg,IDC_WIRE,CB_ADDSTRING,0,(LPARAM) &szBuffer[4]); + ++wSelIndexWire; + } + if (bAddIr) // add item to ir combobox + { + SendDlgItemMessage(hDlg,IDC_IR,CB_ADDSTRING,0,(LPARAM) &szBuffer[4]); + ++wSelIndexIr; + } + } } + while (lRet == ERROR_SUCCESS); + _ASSERT(lRet == ERROR_NO_MORE_ITEMS); + RegCloseKey(hKey); } - SendDlgItemMessage(hDlg,nIDDlgItem,CB_SETCURSEL,wSelect,0L); + + // set cursors + SendDlgItemMessage(hDlg,IDC_WIRE,CB_SETCURSEL,wSelectWire,0L); + SendDlgItemMessage(hDlg,IDC_IR ,CB_SETCURSEL,wSelectIr ,0L); + return; } -static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { + HWND hWndInsertAfter; + + LPCTSTR szActPort2Filename = _T(""); + BOOL bPort2CfgChange = FALSE; BOOL bPort2AttChange = FALSE; @@ -281,11 +339,13 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP case WM_INITDIALOG: // init speed checkbox CheckDlgButton(hDlg,IDC_REALSPEED,bRealSpeed); + CheckDlgButton(hDlg,IDC_GRAYSCALE,bGrayscale); + CheckDlgButton(hDlg,IDC_ALWAYSONTOP,bAlwaysOnTop); + CheckDlgButton(hDlg,IDC_ACTFOLLOWSMOUSE,bActFollowsMouse); CheckDlgButton(hDlg,IDC_AUTOSAVE,bAutoSave); CheckDlgButton(hDlg,IDC_AUTOSAVEONEXIT,bAutoSaveOnExit); CheckDlgButton(hDlg,IDC_OBJECTLOADWARNING,bLoadObjectWarning); CheckDlgButton(hDlg,IDC_ALWAYSDISPLOG,bAlwaysDisplayLog); - CheckDlgButton(hDlg,IDC_GRAYSCALE,bGrayscale); // set disassebler mode CheckDlgButton(hDlg,(disassembler_mode == HP_MNEMONICS) ? IDC_DISASM_HP : IDC_DISASM_CLASS,BST_CHECKED); @@ -300,8 +360,7 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),bWaveBeep); // set combobox parameter - SetCommList(hDlg,IDC_WIRE,szSerialWire); - SetCommList(hDlg,IDC_IR,szSerialIr); + SetCommList(hDlg,szSerialWire,szSerialIr); if (bCommInit) // disable when port open { EnableWindow(GetDlgItem(hDlg,IDC_WIRE),FALSE); @@ -314,10 +373,22 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP // init port1 enable checkbox CheckDlgButton(hDlg,IDC_PORT1EN,(Chipset.cards_status & PORT1_PRESENT) != 0); CheckDlgButton(hDlg,IDC_PORT1WR,(Chipset.cards_status & PORT1_WRITE) != 0); + + if (nArgc < 3) // port2 filename from Emu48.ini file + { + szActPort2Filename = szPort2Filename; + } + else // port2 filename given from command line + { + szActPort2Filename = ppArgv[2]; + EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE); + EnableWindow(GetDlgItem(hDlg,IDC_PORT2LOAD),FALSE); + } + // init port2 shared and writeable checkbox and set port2 filename CheckDlgButton(hDlg,IDC_PORT2ISSHARED,bPort2IsShared); - CheckDlgButton(hDlg,IDC_PORT2WR,IsPort2Writeable()); - SetDlgItemText(hDlg,IDC_PORT2,szPort2Filename); + CheckDlgButton(hDlg,IDC_PORT2WR,IsFileWriteable(szActPort2Filename)); + SetDlgItemText(hDlg,IDC_PORT2,szActPort2Filename); if (nState == SM_INVALID) // Invalid State { EnableWindow(GetDlgItem(hDlg,IDC_PORT1EN),FALSE); @@ -364,6 +435,9 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP lstrcpy(szBufferFilename,lpFilePart); } SetDlgItemText(hDlg,IDC_PORT2,szBufferFilename); + + // adjust R/W checkbox + CheckDlgButton(hDlg,IDC_PORT2WR,IsFileWriteable(szBufferFilename)); } return TRUE; case IDOK: @@ -398,26 +472,31 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP if(cCurrentRomType=='S' || cCurrentRomType=='G' || cCurrentRomType==0) { TCHAR szFilename[MAX_PATH]; - BOOL bPortShared; + BOOL bOldPort2IsShared = bPort2IsShared; + + szActPort2Filename = (nArgc < 3) ? szPort2Filename : ppArgv[2]; // shared port - bPortShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED); - if (bPort2IsShared != bPortShared) + bPort2IsShared = IsDlgButtonChecked(hDlg,IDC_PORT2ISSHARED); + if (bPort2IsShared != bOldPort2IsShared) { - bPort2IsShared = bPortShared; bPort2CfgChange = TRUE; // slot2 configuration changed } - // get current filename and notify difference - GetDlgItemText(hDlg,IDC_PORT2,szFilename,ARRAYSIZEOF(szFilename)); - if (lstrcmp(szPort2Filename,szFilename) != 0) + if (nArgc < 3) // port2 filename from Emu48.ini file { - lstrcpyn(szPort2Filename,szFilename,ARRAYSIZEOF(szPort2Filename)); - bPort2CfgChange = TRUE; // slot2 configuration changed + // get current filename and notify difference + GetDlgItemText(hDlg,IDC_PORT2,szFilename,ARRAYSIZEOF(szFilename)); + if (lstrcmp(szPort2Filename,szFilename) != 0) + { + lstrcpyn(szPort2Filename,szFilename,ARRAYSIZEOF(szPort2Filename)); + bPort2CfgChange = TRUE; // slot2 configuration changed + } } // R/W port - if (IsDlgButtonChecked(hDlg,IDC_PORT2WR) != (UINT) IsPort2Writeable()) + if ( *szActPort2Filename != 0 + && (BOOL) IsDlgButtonChecked(hDlg,IDC_PORT2WR) != IsFileWriteable(szActPort2Filename)) { bPort2AttChange = TRUE; // slot2 file R/W attribute changed bPort2CfgChange = TRUE; // slot2 configuration changed @@ -425,10 +504,12 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP } // get speed checkbox value bRealSpeed = IsDlgButtonChecked(hDlg,IDC_REALSPEED); - bAutoSave = IsDlgButtonChecked(hDlg, IDC_AUTOSAVE); - bAutoSaveOnExit = IsDlgButtonChecked(hDlg, IDC_AUTOSAVEONEXIT); - bLoadObjectWarning = IsDlgButtonChecked(hDlg, IDC_OBJECTLOADWARNING); - bAlwaysDisplayLog = IsDlgButtonChecked(hDlg, IDC_ALWAYSDISPLOG); + bAlwaysOnTop = IsDlgButtonChecked(hDlg,IDC_ALWAYSONTOP); + bActFollowsMouse = IsDlgButtonChecked(hDlg,IDC_ACTFOLLOWSMOUSE); + bAutoSave = IsDlgButtonChecked(hDlg,IDC_AUTOSAVE); + bAutoSaveOnExit = IsDlgButtonChecked(hDlg,IDC_AUTOSAVEONEXIT); + bLoadObjectWarning = IsDlgButtonChecked(hDlg,IDC_OBJECTLOADWARNING); + bAlwaysDisplayLog = IsDlgButtonChecked(hDlg,IDC_ALWAYSDISPLOG); SetSpeed(bRealSpeed); // set speed // LCD grayscale checkbox has been changed if (bGrayscale != (BOOL) IsDlgButtonChecked(hDlg,IDC_GRAYSCALE)) @@ -448,7 +529,7 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP DWORD dwFileAtt; SetCurrentDirectory(szEmuDirectory); - dwFileAtt = GetFileAttributes(szPort2Filename); + dwFileAtt = GetFileAttributes(szActPort2Filename); if (dwFileAtt != 0xFFFFFFFF) { if (IsDlgButtonChecked(hDlg,IDC_PORT2WR)) @@ -456,17 +537,17 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP else dwFileAtt |= FILE_ATTRIBUTE_READONLY; - SetFileAttributes(szPort2Filename,dwFileAtt); + SetFileAttributes(szActPort2Filename,dwFileAtt); } SetCurrentDirectory(szCurrentDirectory); } if (cCurrentRomType) // ROM defined { - // use 2nd command line argument if defined - MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]); + MapPort2(szActPort2Filename); + // port2 changed and card detection enabled - if ( (bPort2AttChange || Chipset.wPort2Crc != CrcPort2()) + if ( (bPort2AttChange || Chipset.wPort2Crc != wPort2Crc) && (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0 ) { @@ -476,19 +557,26 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP bInterrupt = TRUE; } // save fingerprint of port2 - Chipset.wPort2Crc = CrcPort2(); + Chipset.wPort2Crc = wPort2Crc; } SwitchToState(nOldState); } // set disassembler mode disassembler_mode = IsDlgButtonChecked(hDlg,IDC_DISASM_HP) ? HP_MNEMONICS : CLASS_MNEMONICS; // set sound data - dwWaveVol = SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_GETPOS,0,0); + dwWaveVol = (DWORD) SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_GETPOS,0,0); bWaveBeep = IsDlgButtonChecked(hDlg,IDC_SOUND_WAVE); // set combobox parameter GetDlgItemText(hDlg,IDC_WIRE,szSerialWire,ARRAYSIZEOF(szSerialWire)); if (cCurrentRomType!='X') // HP49G Ir port is not connected GetDlgItemText(hDlg,IDC_IR,szSerialIr,ARRAYSIZEOF(szSerialIr)); + // set window Z order + hWndInsertAfter = bAlwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST; + SetWindowPos(hWnd,hWndInsertAfter,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); + if (hDlgDebug != NULL) + { + SetWindowPos(hDlgDebug,hWndInsertAfter,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE); + } // no break case IDCANCEL: EndDialog(hDlg, LOWORD(wParam)); @@ -496,7 +584,7 @@ static BOOL CALLBACK SettingsProc(HWND hDlg, UINT message, DWORD wParam, LONG lP break; } return FALSE; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); } @@ -727,12 +815,13 @@ cancel: // static LRESULT OnFileNew(VOID) { - SaveBackup(); if (pbyRom) { SwitchToState(SM_INVALID); if (IDCANCEL == SaveChanges(bAutoSave)) goto cancel; + + SaveBackup(); } if (NewDocument()) SetWindowTitle(_T("Untitled")); UpdateWindowStatus(); @@ -810,7 +899,6 @@ static LRESULT OnFileClose(VOID) if (SaveChanges(bAutoSave)!=IDCANCEL) { DisableDebugger(); - KillKML(); ResetDocument(); SetWindowTitle(NULL); } @@ -889,7 +977,7 @@ static LRESULT OnViewCopy(VOID) if (wBits != 24) // a 24 bitcount DIB has no color table { // add size for color table - dwLen += (1 << wBits) * sizeof(RGBQUAD); + dwLen += (DWORD) (1 << wBits) * sizeof(RGBQUAD); } // memory allocation for clipboard data @@ -1151,7 +1239,7 @@ static LRESULT OnObjectSave(VOID) // // ID_TOOL_DISASM // -static BOOL CALLBACK Disasm(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static DWORD dwAddress, dwAddressMax; @@ -1222,7 +1310,7 @@ static BOOL CALLBACK Disasm(HWND hDlg, UINT message, DWORD wParam, LONG lParam) return FALSE; i = wsprintf(szAddress,(dwAddress <= 0xFFFFF) ? _T("%05lX ") : _T("%06lX "),dwAddress); dwAddress = disassemble(dwAddress,&szAddress[i],VIEW_LONG); - i = SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_ADDSTRING,0,(LPARAM) szAddress); + i = (LONG) SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_ADDSTRING,0,(LPARAM) szAddress); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SELITEMRANGE,FALSE,MAKELPARAM(0,i)); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SETSEL,TRUE,i); SendDlgItemMessage(hDlg,IDC_DISASM_WIN,LB_SETTOPINDEX,i,0); @@ -1238,13 +1326,13 @@ static BOOL CALLBACK Disasm(HWND hDlg, UINT message, DWORD wParam, LONG lParam) break; } return FALSE; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); } // // ID_ABOUT // -static BOOL CALLBACK About(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -1262,7 +1350,7 @@ static BOOL CALLBACK About(HWND hDlg, UINT message, DWORD wParam, LONG lParam) break; } return FALSE; - UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(lParam); } static LRESULT OnToolDisasm(VOID) // disasm dialogbox call @@ -1297,12 +1385,31 @@ static LRESULT OnLButtonUp(UINT nFlags, WORD x, WORD y) static LRESULT OnMouseMove(UINT nFlags, WORD x, WORD y) { + // emulator not active but cursor is over emulator window + if (bActFollowsMouse && GetActiveWindow() != hWnd) + { + ForceForegroundWindow(hWnd); // force emulator window to foreground + } + if (nMacroState == MACRO_PLAY) return 0; // playing macro if (nState == SM_RUN) MouseMovesTo(nFlags, x,y); return 0; } -static LRESULT OnKeyDown(int nVirtKey, DWORD lKeyData) +static LRESULT OnNcMouseMove(UINT nFlags, WORD x, WORD y) +{ + // emulator not active but cursor is over emulator window + if (bActFollowsMouse && GetActiveWindow() != hWnd) + { + ForceForegroundWindow(hWnd); // force emulator window to foreground + } + return 0; + UNREFERENCED_PARAMETER(nFlags); + UNREFERENCED_PARAMETER(x); + UNREFERENCED_PARAMETER(y); +} + +static LRESULT OnKeyDown(int nVirtKey, LPARAM lKeyData) { if (nMacroState == MACRO_PLAY) return 0; // playing macro // call RunKey() only once (suppress autorepeat feature) @@ -1311,7 +1418,7 @@ static LRESULT OnKeyDown(int nVirtKey, DWORD lKeyData) return 0; } -static LRESULT OnKeyUp(int nVirtKey, DWORD lKeyData) +static LRESULT OnKeyUp(int nVirtKey, LPARAM lKeyData) { if (nMacroState == MACRO_PLAY) return 0; // playing macro if (nState == SM_RUN) RunKey((BYTE)nVirtKey, FALSE); @@ -1388,9 +1495,10 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar } break; case WM_RBUTTONDOWN: - case WM_LBUTTONDOWN: return OnLButtonDown(wParam, LOWORD(lParam), HIWORD(lParam)); - case WM_LBUTTONUP: return OnLButtonUp(wParam, LOWORD(lParam), HIWORD(lParam)); - case WM_MOUSEMOVE: return OnMouseMove(wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_LBUTTONDOWN: return OnLButtonDown((UINT) wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_LBUTTONUP: return OnLButtonUp((UINT) wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_MOUSEMOVE: return OnMouseMove((UINT) wParam, LOWORD(lParam), HIWORD(lParam)); + case WM_NCMOUSEMOVE: return OnNcMouseMove((UINT) wParam, LOWORD(lParam), HIWORD(lParam)); case WM_KEYUP: return OnKeyUp((int)wParam, lParam); case WM_KEYDOWN: return OnKeyDown((int)wParam, lParam); } @@ -1404,7 +1512,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC RECT rectWindow; HACCEL hAccel; HSZ hszService, hszTopic; // variables for DDE server - DWORD dwAffMask; + DWORD_PTR dwAffMask; hApp = hInst; #if defined _UNICODE @@ -1516,6 +1624,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC return FALSE; } + // init clipboard format and name service + uCF_HpObj = RegisterClipboardFormat(_T(CF_HPOBJ)); + hszService = DdeCreateStringHandle(idDdeInst,szAppName,0); + hszTopic = DdeCreateStringHandle(idDdeInst,szTopic,0); + DdeNameService(idDdeInst,hszService,NULL,DNS_REGISTER); + _ASSERT(hWnd != NULL); _ASSERT(hWindowDC != NULL); @@ -1531,24 +1645,23 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC _ASSERT(hWnd != NULL); VERIFY(GetClientRect(hWnd,&rectClient)); - GetCutPathName(szBufferFilename,&szTemp[8],MAX_PATH,rectClient.right/10-8); + GetCutPathName(szBufferFilename,&szTemp[8],MAX_PATH,rectClient.right/11); SetWindowTitle(szTemp); if (OpenDocument(szBufferFilename)) + { + ShowWindow(hWnd,nCmdShow); goto start; + } } + SetWindowTitle(_T("New Document")); + ShowWindow(hWnd,nCmdShow); // show emulator menu + // no default document, ask for new one - SetWindowTitle(NewDocument() ? _T("Untitled") : _T("New Document")); + if (NewDocument()) SetWindowTitle(_T("Untitled")); start: - // init clipboard format and name service - uCF_HpObj = RegisterClipboardFormat(_T(CF_HPOBJ)); - hszService = DdeCreateStringHandle(idDdeInst,szAppName,0); - hszTopic = DdeCreateStringHandle(idDdeInst,szTopic,0); - DdeNameService(idDdeInst,hszService,NULL,DNS_REGISTER); - - ShowWindow(hWnd, nCmdShow); - + if (bStartupBackup) SaveBackup(); // make a RAM backup at startup if (pbyRom) SwitchToState(SM_RUN); while (GetMessage(&msg, NULL, 0, 0)) @@ -1576,12 +1689,13 @@ start: _ASSERT(nState == SM_RETURN); // emulation thread down? ResetDocument(); ResetBackup(); + _ASSERT(pbyRom == NULL); // rom file unmapped _ASSERT(pbyPort2 == NULL); // port2 file unmapped _ASSERT(pKml == NULL); // KML script not closed _ASSERT(szTitle == NULL); // freed allocated memory _ASSERT(hPalette == NULL); // freed resource memory - return msg.wParam; + return (int) msg.wParam; UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(hPrevInst); } diff --git a/Sources/Emu48/EMU48.DSP b/Sources/Emu48/EMU48.DSP index 3c0391f..39f90bc 100644 --- a/Sources/Emu48/EMU48.DSP +++ b/Sources/Emu48/EMU48.DSP @@ -210,6 +210,10 @@ SOURCE=.\kml.c # End Source File # Begin Source File +SOURCE=.\lowbat.c +# End Source File +# Begin Source File + SOURCE=.\mops.c # End Source File # Begin Source File diff --git a/Sources/Emu48/EMU48.H b/Sources/Emu48/EMU48.H index a7e923b..85cdf78 100644 --- a/Sources/Emu48/EMU48.H +++ b/Sources/Emu48/EMU48.H @@ -22,6 +22,8 @@ #define BINARYHEADER48 "HPHP48-W" #define BINARYHEADER49 "HPHP49-W" +#define CF_HPOBJ "CF_HPOBJ" // clipboard format for DDE + // CPU cycles in 16384 Hz time frame #define T2CYCLES ((cCurrentRomType=='S')?dwSXCycles:dwGXCycles) @@ -31,8 +33,11 @@ #define SM_SLEEP 3 #define S_ERR_NO 0 // stack errorcodes -#define S_ERR_BINARY 1 -#define S_ERR_ASCII 2 +#define S_ERR_OBJECT 1 +#define S_ERR_BINARY 2 +#define S_ERR_ASCII 3 + +#define BAD_OB (0xFFFFFFFF) // bad object #define NO_SERIAL "disabled" // port not open @@ -94,17 +99,20 @@ extern HWND hDlgProfile; extern HDC hWindowDC; extern HCURSOR hCursorArrow; extern HCURSOR hCursorHand; -extern BOOL bClassicCursor; extern BOOL bAutoSave; extern BOOL bAutoSaveOnExit; extern BOOL bSaveDefConfirm; +extern BOOL bStartupBackup; extern BOOL bAlwaysDisplayLog; extern BOOL bLoadObjectWarning; +extern BOOL bAlwaysOnTop; +extern BOOL bActFollowsMouse; extern HANDLE hThread; extern DWORD lThreadId; extern VOID SetWindowTitle(LPCTSTR szString); extern VOID CopyItemsToClipboard(HWND hWnd); extern VOID UpdateWindowStatus(VOID); +extern VOID ForceForegroundWindow(HWND hWnd); // Settings.c extern VOID ReadSettings(VOID); @@ -191,25 +199,28 @@ extern TCHAR szCurrentFilename[MAX_PATH]; extern TCHAR szBackupFilename[MAX_PATH]; extern TCHAR szBufferFilename[MAX_PATH]; extern TCHAR szPort2Filename[MAX_PATH]; -extern LPBYTE pbyRom; -extern DWORD dwRomSize; extern BYTE cCurrentRomType; extern UINT nCurrentClass; +extern LPBYTE pbyRom; extern BOOL bRomWriteable; +extern DWORD dwRomSize; +extern WORD wRomCrc; extern LPBYTE pbyPort2; extern BOOL bPort2Writeable; extern BOOL bPort2IsShared; extern DWORD dwPort2Size; extern DWORD dwPort2Mask; +extern WORD wPort2Crc; extern BOOL bBackup; extern VOID SetWindowLocation(HWND hWnd,INT nPosX,INT nPosY); extern DWORD GetCutPathName(LPCTSTR szFileName,LPTSTR szBuffer,DWORD dwBufferLength,INT nCutLength); extern VOID SetWindowPathTitle(LPCTSTR szFileName); extern VOID UpdatePatches(BOOL bPatch); extern BOOL PatchRom(LPCTSTR szFilename); +extern BOOL CrcRom(WORD *pwChk); extern BOOL MapRom(LPCTSTR szFilename); extern VOID UnmapRom(VOID); -extern WORD CrcPort2(VOID); +extern BOOL CrcPort2(WORD *pwCrc); extern BOOL MapPort2(LPCTSTR szFilename); extern VOID UnmapPort2(VOID); extern VOID ResetDocument(VOID); @@ -224,7 +235,7 @@ extern BOOL GetOpenFilename(VOID); extern BOOL GetSaveAsFilename(VOID); extern BOOL GetLoadObjectFilename(VOID); extern BOOL GetSaveObjectFilename(VOID); -extern WORD WriteStack(LPBYTE lpBuf,DWORD dwSize); +extern WORD WriteStack(UINT nStkLevel,LPBYTE lpBuf,DWORD dwSize); extern BOOL LoadObject(LPCTSTR szFilename); extern BOOL SaveObject(LPCTSTR szFilename); extern HBITMAP LoadBitmapFile(LPCTSTR szFilename); @@ -238,7 +249,7 @@ extern VOID SetT2(DWORD dwValue); extern BYTE ReadT1(VOID); extern VOID SetT1(BYTE byValue); -// MOps.c +// Mops.c extern BOOL bFlashRomArray; extern BYTE disp; extern LPBYTE RMap[256]; @@ -259,9 +270,14 @@ extern DWORD Read5(DWORD d); extern VOID Write5(DWORD d, DWORD n); extern VOID Write2(DWORD d, BYTE n); extern VOID IOBit(DWORD d, BYTE b, BOOL s); -extern VOID ReadIO(BYTE *a, DWORD b, DWORD s); +extern VOID ReadIO(BYTE *a, DWORD b, DWORD s, BOOL bUpdate); extern VOID WriteIO(BYTE *a, DWORD b, DWORD s); +// Lowbat.c +extern VOID StartBatMeasure(VOID); +extern VOID StopBatMeasure(VOID); +extern VOID GetBatteryState(BOOL *pbLBI, BOOL *pbVLBI); + // Keyboard.c extern VOID ScanKeyboard(BOOL bActive, BOOL bReset); extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in); @@ -283,11 +299,12 @@ extern LRESULT OnStackPaste(VOID); // RPL.c extern BOOL RPL_GetSystemFlag(INT nFlag); extern DWORD RPL_SkipOb(DWORD d); -extern DWORD RPL_ObjectSize(BYTE *o); +extern DWORD RPL_ObjectSize(BYTE *o,DWORD s); extern DWORD RPL_CreateTemp(DWORD l); +extern UINT RPL_Depth(VOID); extern DWORD RPL_Pick(UINT l); extern VOID RPL_Replace(DWORD n); -extern VOID RPL_Push(DWORD n); +extern VOID RPL_Push(UINT l,DWORD n); // External.c extern BOOL bWaveBeep; diff --git a/Sources/Emu48/EMU48.RC b/Sources/Emu48/EMU48.RC index ca4b77f..c9c6317 100644 --- a/Sources/Emu48/EMU48.RC +++ b/Sources/Emu48/EMU48.RC @@ -74,7 +74,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 160 TOPMARGIN, 4 - BOTTOMMARGIN, 256 + BOTTOMMARGIN, 270 END IDD_CHOOSEKML, DIALOG @@ -225,14 +225,14 @@ FONT 8, "MS Sans Serif" BEGIN ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP - LTEXT "Copyright © 2006 Sébastien Carlier && Christoph Gießelink", + LTEXT "Copyright © 2007 Sébastien Carlier && Christoph Gießelink", IDC_STATIC,29,18,181,8 DEFPUSHBUTTON "OK",IDOK,215,12,39,14 EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY END -IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 263 +IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings" FONT 8, "MS Sans Serif" @@ -241,49 +241,53 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10 CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10 + CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10 + CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,37,89,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10 CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,114,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,114,10 CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,61,102,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10 CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,133,10 - GROUPBOX "General",IDC_STATIC,7,4,153,83 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10 + GROUPBOX "General",IDC_STATIC,7,4,153,107 CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,13,101,65,11 + WS_GROUP | WS_TABSTOP,13,125,65,11 CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button", - BS_AUTORADIOBUTTON,84,101,70,11 - GROUPBOX "Disassembler",IDC_STATIC,7,90,153,28 - LTEXT "Volume",IDC_STATIC,13,134,24,8 + BS_AUTORADIOBUTTON,84,125,70,11 + GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28 + LTEXT "Volume",IDC_STATIC,13,158,24,8 CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32", - TBS_AUTOTICKS | WS_TABSTOP,39,129,68,18 + TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18 CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,111,128,43,10 + WS_GROUP | WS_TABSTOP,111,152,43,10 CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111, - 139,43,10 - GROUPBOX "Sound",IDC_STATIC,7,120,153,34 + 163,43,10 + GROUPBOX "Sound",IDC_STATIC,7,144,153,34 CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,13,165,67,10 + WS_TABSTOP,13,189,67,10 CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,165,69,10 + BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10 CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,177,65,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,201,65,10 CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,177,69,10 - LTEXT "Port 2 File :",IDC_STATIC,13,192,37,8 - EDITTEXT IDC_PORT2,51,190,94,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_PORT2LOAD,145,190,10,12 - GROUPBOX "Memory Cards",IDC_STATIC,7,156,153,51 - LTEXT "Wire:",IDC_STATIC,13,221,17,8 - COMBOBOX IDC_WIRE,31,219,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | + BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10 + LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8 + EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12 + GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51 + LTEXT "Wire:",IDC_STATIC,13,245,17,8 + COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "IR:",IDC_STATIC,89,221,9,8 - COMBOBOX IDC_IR,107,219,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "IR:",IDC_STATIC,89,245,9,8 + COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Serial Ports",IDC_STATIC,7,209,153,27 - DEFPUSHBUTTON "&Ok",IDOK,9,242,50,14 - PUSHBUTTON "&Cancel",IDCANCEL,107,242,50,14 + GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27 + DEFPUSHBUTTON "&Ok",IDOK,9,266,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,107,266,50,14 END IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66 @@ -295,9 +299,9 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,138,27,50,14 COMBOBOX IDC_KMLSCRIPT,7,47,181,120,CBS_DROPDOWNLIST | CBS_OEMCONVERT | CBS_SORT | WS_VSCROLL | WS_TABSTOP - EDITTEXT IDC_EMUDIR,7,17,107,14,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_EMUDIRSEL,114,17,10,14 - PUSHBUTTON "V",IDC_UPDATE,124,17,10,14 + EDITTEXT IDC_EMUDIR,7,17,106,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_EMUDIRSEL,113,17,10,14 + PUSHBUTTON "V",IDC_UPDATE,123,17,10,14 LTEXT "Emu48 Directory :",IDC_STATIC,7,7,115,8 LTEXT "Current KML Script :",IDC_STATIC,7,37,115,8 END @@ -549,8 +553,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,2,0 - PRODUCTVERSION 1,4,2,0 + FILEVERSION 1,4,4,0 + PRODUCTVERSION 1,4,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -567,12 +571,12 @@ BEGIN BEGIN VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 4, 2, 0\0" + VALUE "FileVersion", "1, 4, 4, 0\0" VALUE "InternalName", "Emu48\0" - VALUE "LegalCopyright", "Copyright © 2006\0" + VALUE "LegalCopyright", "Copyright © 2007\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 4, 2, 0\0" + VALUE "ProductVersion", "1, 4, 4, 0\0" END END BLOCK "VarFileInfo" @@ -780,7 +784,7 @@ END // 24 // -CREATEPROCESS_MANIFEST_RESOURCE_ID 24 MOVEABLE PURE "Emu48.xml" +1 24 MOVEABLE PURE "Emu48.xml" ///////////////////////////////////////////////////////////////////////////// // diff --git a/Sources/Emu48/ENGINE.C b/Sources/Emu48/ENGINE.C index 3dde5be..e920d37 100644 --- a/Sources/Emu48/ENGINE.C +++ b/Sources/Emu48/ENGINE.C @@ -559,6 +559,7 @@ loop: QueryPerformanceCounter(&lDummyInt); dwSpeedRef = lDummyInt.LowPart; SetHP48Time(); // update HP48 time & date + StartBatMeasure(); // start battery measurement StartTimers(); // start display counter/update engine StartDisplay((BYTE)(((Chipset.IORam[LINECOUNT+1]<<4)|Chipset.IORam[LINECOUNT])&0x3F)); @@ -618,6 +619,7 @@ loop: _ASSERT(nNextState != SM_RUN); StopDisplay(); // stop display counter/update + StopBatMeasure(); // stop battery measurement StopTimers(); while (nNextState == SM_SLEEP) // go into sleep state diff --git a/Sources/Emu48/EXTERNAL.C b/Sources/Emu48/EXTERNAL.C index 71315da..013cb4f 100644 --- a/Sources/Emu48/EXTERNAL.C +++ b/Sources/Emu48/EXTERNAL.C @@ -58,7 +58,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration) wf.wBitsPerSample = 8; wf.cbSize = 0; - if (waveOutOpen(&hSoundDevice,WAVE_MAPPER,&wf,(DWORD)hEventSound,0,CALLBACK_EVENT) != 0) + if (waveOutOpen(&hSoundDevice,WAVE_MAPPER,&wf,(DWORD_PTR)hEventSound,0,CALLBACK_EVENT) != 0) { CloseHandle(hEventSound); // no sound available return; @@ -93,6 +93,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration) static __inline VOID BeepWin9x(DWORD dwFrequency,DWORD dwDuration) { +#if !defined _WIN64 #define PIT8254_CNT2 0x42 #define PIT8254_MCR 0x43 #define PPI8255_PBO 0x61 @@ -125,6 +126,7 @@ static __inline VOID BeepWin9x(DWORD dwFrequency,DWORD dwDuration) #undef PIT8254_CNT2 #undef PIT8254_MCR #undef PPI8255_PBO +#endif } static __inline VOID Return(CHIPSET* w) diff --git a/Sources/Emu48/FILES.C b/Sources/Emu48/FILES.C index f449188..bd00c56 100644 --- a/Sources/Emu48/FILES.C +++ b/Sources/Emu48/FILES.C @@ -23,21 +23,27 @@ TCHAR szBackupFilename[MAX_PATH]; TCHAR szBufferFilename[MAX_PATH]; TCHAR szPort2Filename[MAX_PATH]; -LPBYTE pbyRom = NULL; -static HANDLE hRomFile = NULL; -static HANDLE hRomMap = NULL; -DWORD dwRomSize = 0; BYTE cCurrentRomType = 0; // Model -> hardware UINT nCurrentClass = 0; // Class -> derivate -BOOL bRomWriteable = TRUE; // flag if ROM writeable -static HANDLE hPort2File = NULL; -static HANDLE hPort2Map = NULL; +LPBYTE pbyRom = NULL; +BOOL bRomWriteable = TRUE; // flag if ROM writeable +DWORD dwRomSize = 0; +WORD wRomCrc = 0; // fingerprint of patched ROM + LPBYTE pbyPort2 = NULL; BOOL bPort2Writeable = FALSE; BOOL bPort2IsShared = FALSE; DWORD dwPort2Size = 0; // size of mapped port2 DWORD dwPort2Mask = 0; +WORD wPort2Crc = 0; // fingerprint of port2 + +BOOL bBackup = FALSE; + +static HANDLE hRomFile = NULL; +static HANDLE hRomMap = NULL; +static HANDLE hPort2File = NULL; +static HANDLE hPort2Map = NULL; // document signatures static BYTE pbySignatureA[16] = "Emu38 Document\xFE"; @@ -49,8 +55,6 @@ static HANDLE hCurrentFile = NULL; static CHIPSET BackupChipset; -BOOL bBackup = FALSE; - //################ //# //# Window Position Tools @@ -110,10 +114,35 @@ DWORD GetCutPathName(LPCTSTR szFileName, LPTSTR szBuffer, DWORD dwBufferLength, if (nPathLen > nMaxPathLen) // have to cut path { - TCHAR cDirTemp[_MAX_DIR] = _T("\\..."); + TCHAR cDirTemp[_MAX_DIR] = _T(""); LPTSTR szPtr; - nMaxPathLen -= 4; // need 4 chars for additional "\..." + // UNC name + if (cDir[0] == _T('\\') && cDir[1] == _T('\\')) + { + // skip server + if ((szPtr = _tcschr(cDir + 2,_T('\\'))) != NULL) + { + // skip share + if ((szPtr = _tcschr(szPtr + 1,_T('\\'))) != NULL) + { + INT nLength = szPtr - cDir; + + *szPtr = 0; // set EOS behind share + + // enough room for \\server\\share and "\...\" + if (nLength + 5 <= nMaxPathLen) + { + lstrcpyn(cDirTemp,cDir,ARRAYSIZEOF(cDirTemp)); + nMaxPathLen -= nLength; + } + + } + } + } + + lstrcat(cDirTemp,_T("\\...")); + nMaxPathLen -= 5; // need 6 chars for additional "\..." + "\" if (nMaxPathLen < 0) nMaxPathLen = 0; // get earliest possible '\' character @@ -141,7 +170,7 @@ VOID SetWindowPathTitle(LPCTSTR szFileName) { _ASSERT(hWnd != NULL); VERIFY(GetClientRect(hWnd,&rectClient)); - GetCutPathName(szFileName,cPath,ARRAYSIZEOF(cPath),rectClient.right/10); + GetCutPathName(szFileName,cPath,ARRAYSIZEOF(cPath),rectClient.right/11); SetWindowTitle(cPath); } return; @@ -169,6 +198,7 @@ static __inline BYTE Asc2Nib(BYTE c) // functions to restore ROM patches typedef struct tnode { + BOOL bPatch; // TRUE = ROM address patched DWORD dwAddress; // patch address BYTE byROM; // original ROM value BYTE byPatch; // patched ROM value @@ -185,6 +215,7 @@ static BOOL PatchNibble(DWORD dwAddress, BYTE byPatch) if((p = HeapAlloc(hHeap,0,sizeof(TREENODE))) == NULL) return TRUE; + p->bPatch = TRUE; // address patched p->dwAddress = dwAddress; // save current values p->byROM = pbyRom[dwAddress]; p->byPatch = byPatch; @@ -219,16 +250,27 @@ VOID UpdatePatches(BOOL bPatch) _ASSERT(pbyRom); // ROM defined while (p != NULL) { - if (bPatch) + if (bPatch) // patch ROM { - // save original data and patch address - p->byROM = pbyRom[p->dwAddress]; - pbyRom[p->dwAddress] = p->byPatch; + if (!p->bPatch) // patch only if not patched + { + // use original data for patch restore + p->byROM = pbyRom[p->dwAddress]; + + // restore patch data + pbyRom[p->dwAddress] = p->byPatch; + p->bPatch = TRUE; // address patched + } + else + { + _ASSERT(FALSE); // call ROM patch on a patched ROM + } } - else + else // restore ROM { // restore original data pbyRom[p->dwAddress] = p->byROM; + p->bPatch = FALSE; // address not patched } p = p->next; // next node @@ -296,7 +338,7 @@ BOOL PatchRom(LPCTSTR szFilename) continue; } dwAddress = strtoul(&lpBuf[nPos], &lpStop, 16); - nPos += lpStop-&lpBuf[nPos]+1; + nPos += (UINT) (lpStop - &lpBuf[nPos]) + 1; if (*lpStop != ':' || *lpStop == 0) continue; while (lpBuf[nPos]) @@ -320,21 +362,28 @@ BOOL PatchRom(LPCTSTR szFilename) //# //################ -static WORD CrcRom(VOID) // calculate fingerprint of ROM +BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM { - DWORD dwCount; - DWORD dwFileSize; - DWORD dwCrc = 0; - - dwFileSize = GetFileSize(hRomFile, &dwCount); // get real filesize - _ASSERT(dwCount == 0); // isn't created by MapRom() + DWORD *pdwData,dwSize; + DWORD dwChk = 0; _ASSERT(pbyRom); // view on ROM - // use checksum, because it's faster - for (dwCount = 0;dwCount < dwFileSize; dwCount+=sizeof(dwCrc)) - dwCrc += *((DWORD *) &pbyRom[dwCount]); + pdwData = (DWORD *) pbyRom; - return (WORD) dwCrc; + _ASSERT((dwRomSize % sizeof(*pdwData)) == 0); + dwSize = dwRomSize / sizeof(*pdwData); // file size in DWORD's + + // use checksum, because it's faster + while (dwSize-- > 0) + { + DWORD dwData = *pdwData++; + if ((dwData & 0xF0F0F0F0) != 0) // data packed? + return FALSE; + dwChk += dwData; + } + + *pwChk = (WORD) ((dwChk >> 16) + (dwChk & 0xFFFF)); + return TRUE; } BOOL MapRom(LPCTSTR szFilename) @@ -416,19 +465,12 @@ BOOL MapRom(LPCTSTR szFilename) dwRomSize = 0; return FALSE; } - // check for packed ROM image - if ((*(DWORD *) pbyRom & 0xF0F0F0F0) != 0) - { - UnmapRom(); // free memory - AbortMessage(_T("Packed ROM image detected!")); - return FALSE; - } return TRUE; } VOID UnmapRom(VOID) { - if (pbyRom==NULL) return; + if (pbyRom == NULL) return; RestorePatches(); // restore ROM Patches UnmapViewOfFile(pbyRom); CloseHandle(hRomMap); @@ -437,6 +479,7 @@ VOID UnmapRom(VOID) hRomMap = NULL; hRomFile = NULL; dwRomSize = 0; + wRomCrc = 0; return; } @@ -448,28 +491,33 @@ VOID UnmapRom(VOID) //# //################ -WORD CrcPort2(VOID) // calculate fingerprint of port2 +BOOL CrcPort2(WORD *pwCrc) // calculate fingerprint of port2 { DWORD dwCount; DWORD dwFileSize; - WORD wCrc = 0; + + *pwCrc = 0; // port2 CRC isn't available - if (pbyPort2 == NULL) return wCrc; + if (pbyPort2 == NULL) return TRUE; dwFileSize = GetFileSize(hPort2File, &dwCount); // get real filesize _ASSERT(dwCount == 0); // isn't created by MapPort2() for (dwCount = 0;dwCount < dwFileSize; ++dwCount) - wCrc = (wCrc >> 4) ^ (((wCrc ^ ((WORD) pbyPort2[dwCount])) & 0xf) * 0x1081); - return wCrc; + { + if ((pbyPort2[dwCount] & 0xF0) != 0) // data packed? + return FALSE; + + *pwCrc = (*pwCrc >> 4) ^ (((*pwCrc ^ ((WORD) pbyPort2[dwCount])) & 0xf) * 0x1081); + } + return TRUE; } BOOL MapPort2(LPCTSTR szFilename) { - DWORD dwFileSizeLo; - DWORD dwFileSizeHi; - + DWORD dwFileSizeLo,dwFileSizeHi,dwCount; + if (pbyPort2 != NULL) return FALSE; bPort2Writeable = TRUE; dwPort2Size = 0; // reset size of port2 @@ -509,14 +557,23 @@ BOOL MapPort2(LPCTSTR szFilename) bPort2Writeable = FALSE; return FALSE; } - if (dwFileSizeLo & 0x2FFFF) - { // file size is wrong + + // count number of set bits + for (dwCount = 0, dwFileSizeHi = dwFileSizeLo; dwFileSizeHi != 0;dwFileSizeHi >>= 1) + { + if ((dwFileSizeHi & 0x1) != 0) ++dwCount; + } + + // size not 32, 128, 256, 512, 1024, 2048 or 4096 KB + if (dwCount != 1 || (dwFileSizeLo & 0xFF02FFFF) != 0) + { CloseHandle(hPort2File); hPort2File = NULL; dwPort2Mask = 0; bPort2Writeable = FALSE; return FALSE; } + dwPort2Mask = (dwFileSizeLo - 1) >> 18; // mask for valid address lines of the BS-FF hPort2Map = CreateFileMapping(hPort2File, NULL, bPort2Writeable ? PAGE_READWRITE : PAGE_READONLY, 0, dwFileSizeLo, NULL); @@ -540,12 +597,19 @@ BOOL MapPort2(LPCTSTR szFilename) return FALSE; } dwPort2Size = dwFileSizeLo / 2048; // mapping size of port2 + + if (CrcPort2(&wPort2Crc) == FALSE) // calculate fingerprint of port2 + { + UnmapPort2(); // free memory + AbortMessage(_T("Packed Port 2 image detected!")); + return FALSE; + } return TRUE; } VOID UnmapPort2(VOID) { - if (pbyPort2==NULL) return; + if (pbyPort2 == NULL) return; UnmapViewOfFile(pbyPort2); CloseHandle(hPort2Map); CloseHandle(hPort2File); @@ -555,6 +619,7 @@ VOID UnmapPort2(VOID) dwPort2Size = 0; // reset size of port2 dwPort2Mask = 0; bPort2Writeable = FALSE; + wPort2Crc = 0; return; } @@ -566,6 +631,19 @@ VOID UnmapPort2(VOID) //# //################ +static BOOL IsDataPacked(VOID *pMem, DWORD dwSize) +{ + _ASSERT((dwSize % sizeof(DWORD)) == 0); + if ((dwSize % sizeof(DWORD)) != 0) return TRUE; + + for (dwSize /= sizeof(DWORD); dwSize-- > 0;) + { + if ((*((DWORD *) pMem)++ & 0xF0F0F0F0) != 0) + return TRUE; + } + return FALSE; +} + VOID ResetDocument(VOID) { if (szCurrentKml[0]) @@ -691,6 +769,8 @@ restore: BOOL OpenDocument(LPCTSTR szFilename) { + #define CHECKAREA(s,e) (offsetof(CHIPSET,e)-offsetof(CHIPSET,s)+sizeof(((CHIPSET *)NULL)->e)) + HANDLE hFile = INVALID_HANDLE_VALUE; DWORD lBytesRead,lSizeofChipset; BYTE pbyFileSignature[16]; @@ -840,6 +920,8 @@ BOOL OpenDocument(LPCTSTR szFilename) ReadFile(hFile, Chipset.Port0, Chipset.Port0Size*2048, &lBytesRead, NULL); if (lBytesRead != Chipset.Port0Size*2048) goto read_err; + + if (IsDataPacked(Chipset.Port0,Chipset.Port0Size*2048)) goto read_err; } if (Chipset.Port1Size) @@ -853,6 +935,8 @@ BOOL OpenDocument(LPCTSTR szFilename) ReadFile(hFile, Chipset.Port1, Chipset.Port1Size*2048, &lBytesRead, NULL); if (lBytesRead != Chipset.Port1Size*2048) goto read_err; + + if (IsDataPacked(Chipset.Port1,Chipset.Port1Size*2048)) goto read_err; } // HP48SX/GX @@ -860,7 +944,7 @@ BOOL OpenDocument(LPCTSTR szFilename) { MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]); // port2 changed and card detection enabled - if ( Chipset.wPort2Crc != CrcPort2() + if ( Chipset.wPort2Crc != wPort2Crc && (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0 ) { @@ -884,20 +968,26 @@ BOOL OpenDocument(LPCTSTR szFilename) ReadFile(hFile, Chipset.Port2, Chipset.Port2Size*2048, &lBytesRead, NULL); if (lBytesRead != Chipset.Port2Size*2048) goto read_err; + if (IsDataPacked(Chipset.Port2,Chipset.Port2Size*2048)) goto read_err; + bPort2Writeable = TRUE; Chipset.cards_status = 0xF; } } - LoadBreakpointList(hFile); // load debugger breakpoint list RomSwitch(Chipset.Bank_FF); // reload ROM view of HP49G and map memory - if (Chipset.wRomCrc != CrcRom()) // ROM changed + if (Chipset.wRomCrc != wRomCrc) // ROM changed { CpuReset(); Chipset.Shutdn = FALSE; // automatic restart } + // check CPU main registers + if (IsDataPacked(Chipset.A,CHECKAREA(A,R4))) goto read_err; + + LoadBreakpointList(hFile); // load debugger breakpoint list + lstrcpy(szCurrentFilename, szFilename); _ASSERT(hCurrentFile == NULL); hCurrentFile = hFile; @@ -924,13 +1014,13 @@ restore: MapPort2((nArgc < 3) ? szPort2Filename : ppArgv[2]); } return FALSE; + #undef CHECKAREA } BOOL SaveDocument(VOID) { DWORD lBytesWritten; DWORD lSizeofChipset; - LPBYTE pbySig; UINT nLength; WINDOWPLACEMENT wndpl; @@ -944,18 +1034,14 @@ BOOL SaveDocument(VOID) SetFilePointer(hCurrentFile,0,NULL,FILE_BEGIN); - // get document signature - pbySig = (Chipset.type=='6' || Chipset.type=='A') - ? pbySignatureA : (Chipset.type=='E' ? pbySignatureB : ((Chipset.type!='X') ? pbySignatureE : pbySignatureV)); - - if (!WriteFile(hCurrentFile, pbySig, 16, &lBytesWritten, NULL)) + if (!WriteFile(hCurrentFile, pbySignatureE, sizeof(pbySignatureE), &lBytesWritten, NULL)) { AbortMessage(_T("Could not write into file !")); return FALSE; } - Chipset.wRomCrc = CrcRom(); // save fingerprint of ROM - Chipset.wPort2Crc = CrcPort2(); // save fingerprint of port2 + CrcRom(&Chipset.wRomCrc); // save fingerprint of ROM + CrcPort2(&Chipset.wPort2Crc); // save fingerprint of port2 nLength = lstrlen(szCurrentKml); WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL); @@ -1027,6 +1113,8 @@ BOOL SaveBackup(VOID) if (pbyRom == NULL) return FALSE; + _ASSERT(nState != SM_RUN); // emulation engine is running + // save window position _ASSERT(hWnd); // window open wndpl.length = sizeof(wndpl); // update saved window position @@ -1185,7 +1273,6 @@ BOOL GetSaveAsFilename(VOID) _T("Emu39 Document (*.E39)\0*.E39\0") _T("Emu48 Document (*.E48)\0*.E48\0") _T("Emu49 Document (*.E49)\0*.E49\0") - _T("Win48 Document (*.W48)\0*.W48\0") _T("\0\0"); ofn.lpstrDefExt = _T("E48"); // HP48SX/GX ofn.nFilterIndex = 3; @@ -1229,7 +1316,6 @@ BOOL GetLoadObjectFilename(VOID) if (GetOpenFileName(&ofn) == FALSE) return FALSE; _ASSERT(ARRAYSIZEOF(szBufferFilename) == ofn.nMaxFile); lstrcpy(szBufferFilename, ofn.lpstrFile); - HeapFree(hHeap,0,ofn.lpstrFile); return TRUE; } @@ -1259,7 +1345,7 @@ BOOL GetSaveObjectFilename(VOID) //# //################ -WORD WriteStack(LPBYTE lpBuf,DWORD dwSize) // separated from LoadObject() +WORD WriteStack(UINT nStkLevel,LPBYTE lpBuf,DWORD dwSize) // separated from LoadObject() { BOOL bBinary; DWORD dwAddress, i; @@ -1272,31 +1358,32 @@ WORD WriteStack(LPBYTE lpBuf,DWORD dwSize) // separated from LoadObject() && (lpBuf[dwSize+5]==((cCurrentRomType!='X') ? '8' : '9')) && (lpBuf[dwSize+6]=='-')); - for (i = 0; i < dwSize; i++) + for (dwAddress = 0, i = 0; i < dwSize; i++) { BYTE byTwoNibs = lpBuf[i+dwSize]; - lpBuf[i*2 ] = (BYTE)(byTwoNibs&0xF); - lpBuf[i*2+1] = (BYTE)(byTwoNibs>>4); + lpBuf[dwAddress++] = (BYTE)(byTwoNibs&0xF); + lpBuf[dwAddress++] = (BYTE)(byTwoNibs>>4); } + dwSize = dwAddress; // unpacked buffer size + if (bBinary == TRUE) { // load as binary - dwSize = RPL_ObjectSize(lpBuf+16); + dwSize = RPL_ObjectSize(lpBuf+16,dwSize-16); + if (dwSize == BAD_OB) return S_ERR_OBJECT; dwAddress = RPL_CreateTemp(dwSize); if (dwAddress == 0) return S_ERR_BINARY; - Nwrite(lpBuf+16,dwAddress,dwSize); } else { // load as string - dwSize *= 2; dwAddress = RPL_CreateTemp(dwSize+10); if (dwAddress == 0) return S_ERR_ASCII; Write5(dwAddress,0x02A2C); // String Write5(dwAddress+5,dwSize+5); // length of String Nwrite(lpBuf,dwAddress+10,dwSize); // data } - RPL_Push(dwAddress); + RPL_Push(nStkLevel,dwAddress); return S_ERR_NO; } @@ -1331,7 +1418,10 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part ReadFile(hFile, lpBuf+dwFileSizeLow, dwFileSizeLow, &dwFileSizeHigh, NULL); CloseHandle(hFile); - wError = WriteStack(lpBuf,dwFileSizeLow); + wError = WriteStack(1,lpBuf,dwFileSizeLow); + + if (wError == S_ERR_OBJECT) + AbortMessage(_T("This isn't a valid binary file.")); if (wError == S_ERR_BINARY) AbortMessage(_T("The calculator does not have enough\nfree memory to load this binary file.")); diff --git a/Sources/Emu48/KEYBOARD.C b/Sources/Emu48/KEYBOARD.C index c4c82b6..53d3dab 100644 --- a/Sources/Emu48/KEYBOARD.C +++ b/Sources/Emu48/KEYBOARD.C @@ -14,6 +14,7 @@ static WORD Keyboard_GetIR(VOID) { WORD r = 0; + // OR[0:8] are wired on Clarke/Yorke chip if (Chipset.out==0) return 0; if (Chipset.out&0x001) r|=Chipset.Keyboard_Row[0]; if (Chipset.out&0x002) r|=Chipset.Keyboard_Row[1]; @@ -34,10 +35,17 @@ VOID ScanKeyboard(BOOL bActive, BOOL bReset) // bReset = TRUE -> Reset Chipset.in interrupt state register // FALSE -> generate interrupt only for new pressed keys - // keyboard read active? + // keyboard read not active? if (!( bActive || Chipset.Shutdn || Chipset.IR15X || (Chipset.intk && (Chipset.IORam[TIMER2_CTRL]&RUN) != 0))) - return; // -> no + { + EnterCriticalSection(&csKeyLock); + { + Chipset.in &= ~0x8000; // remove ON key + } + LeaveCriticalSection(&csKeyLock); + return; + } EnterCriticalSection(&csKeyLock); // synchronize { @@ -106,6 +114,8 @@ VOID KeyboardEvent(BOOL bPress, UINT out, UINT in) // "out" is outside Keyboard_Row if (out >= ARRAYSIZEOF(Chipset.Keyboard_Row)) return; + // in &= 0x1FF; // only IR[0:8] are wired on Clarke/Yorke chip + _ASSERT(out < ARRAYSIZEOF(Chipset.Keyboard_Row)); if (bPress) // key pressed Chipset.Keyboard_Row[out] |= in; // set key marker in keyboard row diff --git a/Sources/Emu48/KEYMACRO.C b/Sources/Emu48/KEYMACRO.C index dc41644..37be34f 100644 --- a/Sources/Emu48/KEYMACRO.C +++ b/Sources/Emu48/KEYMACRO.C @@ -153,7 +153,7 @@ LRESULT OnToolMacroNew(VOID) if (hMacroFile == INVALID_HANDLE_VALUE) return 0; // write header - WriteFile(hMacroFile,KEYMACROHEAD,strlen(KEYMACROHEAD),&dwWritten,NULL); + WriteFile(hMacroFile,KEYMACROHEAD,sizeof(KEYMACROHEAD) - 1,&dwWritten,NULL); _ASSERT(dwWritten == (DWORD) strlen(KEYMACROHEAD)); // write extension length @@ -294,7 +294,7 @@ static VOID SliderEnable(HWND hDlg,BOOL bEnable) // // Macro settings dialog // -static BOOL CALLBACK MacroProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK MacroProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { @@ -319,7 +319,7 @@ static BOOL CALLBACK MacroProc(HWND hDlg, UINT message, DWORD wParam, LONG lPara return TRUE; case IDOK: // get macro data - nMacroTimeout = MAX_SPEED - SendDlgItemMessage(hDlg,IDC_MACRO_SLIDER,TBM_GETPOS,0,0); + nMacroTimeout = MAX_SPEED - (INT) SendDlgItemMessage(hDlg,IDC_MACRO_SLIDER,TBM_GETPOS,0,0); bMacroRealSpeed = IsDlgButtonChecked(hDlg,IDC_MACRO_REAL); // no break case IDCANCEL: diff --git a/Sources/Emu48/KML.C b/Sources/Emu48/KML.C index b52c7c2..1e5d421 100644 --- a/Sources/Emu48/KML.C +++ b/Sources/Emu48/KML.C @@ -195,7 +195,7 @@ static VOID __cdecl PrintfToLog(LPCTSTR lpFormat, ...) return; } -static BOOL CALLBACK KMLLogProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK KMLLogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { LPCTSTR szString; @@ -203,7 +203,7 @@ static BOOL CALLBACK KMLLogProc(HWND hDlg, UINT message, DWORD wParam, LONG lPar { case WM_INITDIALOG: // set OK - EnableWindow(GetDlgItem(hDlg,IDOK),lParam); + EnableWindow(GetDlgItem(hDlg,IDOK),(BOOL) lParam); // set IDC_TITLE szString = GetStringParam(pKml, TOK_GLOBAL, TOK_TITLE, 0); if (szString == NULL) szString = _T("Untitled"); @@ -384,7 +384,7 @@ static VOID BrowseFolder(HWND hDlg) return; } -static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG lParam) +static INT_PTR CALLBACK ChooseKMLProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { HWND hList; KmlScript* pList; @@ -399,7 +399,7 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l pList = pKmlList; while (pList) { - nIndex = SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)pList->szTitle); + nIndex = (UINT) SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)pList->szTitle); SendMessage(hList, CB_SETITEMDATA, nIndex, (LPARAM)pList->nId); pList = pList->pNext; } @@ -420,7 +420,7 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l pList = pKmlList; while (pList) { - nIndex = SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)pList->szTitle); + nIndex = (UINT) SendMessage(hList, CB_ADDSTRING, 0, (LPARAM)pList->szTitle); SendMessage(hList, CB_SETITEMDATA, nIndex, (LPARAM)pList->nId); pList = pList->pNext; } @@ -429,8 +429,8 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l case IDOK: GetDlgItemText(hDlg,IDC_EMUDIR,szEmuDirectory,ARRAYSIZEOF(szEmuDirectory)); hList = GetDlgItem(hDlg,IDC_KMLSCRIPT); - nIndex = SendMessage(hList, CB_GETCURSEL, 0, 0); - nIndex = SendMessage(hList, CB_GETITEMDATA, nIndex, 0); + nIndex = (UINT) SendMessage(hList, CB_GETCURSEL, 0, 0); + nIndex = (UINT) SendMessage(hList, CB_GETITEMDATA, nIndex, 0); pList = pKmlList; while (pList) { @@ -454,12 +454,12 @@ static BOOL CALLBACK ChooseKMLProc(HWND hDlg, UINT message, DWORD wParam, LONG l BOOL DisplayChooseKml(CHAR cType) { - BOOL bResult; + INT_PTR nResult; cKmlType = cType; CreateKmlList(); - bResult = DialogBox(hApp, MAKEINTRESOURCE(IDD_CHOOSEKML), hWnd, (DLGPROC)ChooseKMLProc); + nResult = DialogBox(hApp, MAKEINTRESOURCE(IDD_CHOOSEKML), hWnd, (DLGPROC)ChooseKMLProc); DestroyKmlList(); - return (bResult == IDOK); + return (nResult == IDOK); } @@ -775,7 +775,7 @@ loop: PrintfToLog(_T("%i: Parameter %i of %s must be a string."), nLexLine, j+1, pLexToken[i].szName); goto errline; // free memory of arguments } - pLine->nParam[j++] = (DWORD)szLexString; + pLine->nParam[j++] = (DWORD_PTR) szLexString; nParams >>= 3; goto loop; } @@ -1111,11 +1111,11 @@ static VOID InitGlobal(KmlBlock* pBlock) PrintfToLog(_T("Calculator Model : %c"), cCurrentRomType); break; case TOK_CLASS: - nCurrentClass = pLine->nParam[0]; + nCurrentClass = (UINT) pLine->nParam[0]; PrintfToLog(_T("Calculator Class : %u"), nCurrentClass); break; case TOK_DEBUG: - bDebug = pLine->nParam[0]&1; + bDebug = (BOOL) pLine->nParam[0]&1; PrintfToLog(_T("Debug %s"), bDebug?_T("On"):_T("Off")); break; case TOK_ROM: @@ -1174,12 +1174,12 @@ static KmlLine* InitBackground(KmlBlock* pBlock) switch (pLine->eCommand) { case TOK_OFFSET: - nBackgroundX = pLine->nParam[0]; - nBackgroundY = pLine->nParam[1]; + nBackgroundX = (UINT) pLine->nParam[0]; + nBackgroundY = (UINT) pLine->nParam[1]; break; case TOK_SIZE: - nBackgroundW = pLine->nParam[0]; - nBackgroundH = pLine->nParam[1]; + nBackgroundW = (UINT) pLine->nParam[0]; + nBackgroundH = (UINT) pLine->nParam[1]; break; case TOK_END: return pLine; @@ -1199,16 +1199,17 @@ static KmlLine* InitLcd(KmlBlock* pBlock) switch (pLine->eCommand) { case TOK_OFFSET: - nLcdX = pLine->nParam[0]; - nLcdY = pLine->nParam[1]; + nLcdX = (UINT) pLine->nParam[0]; + nLcdY = (UINT) pLine->nParam[1]; break; case TOK_ZOOM: - nLcdZoom = pLine->nParam[0]; + nLcdZoom = (UINT) pLine->nParam[0]; if (!(nLcdZoom >= 1 && nLcdZoom <= 4)) nLcdZoom = 1; break; case TOK_COLOR: - SetLcdColor(pLine->nParam[0],pLine->nParam[1],pLine->nParam[2],pLine->nParam[3]); + SetLcdColor((UINT) pLine->nParam[0],(UINT) pLine->nParam[1], + (UINT) pLine->nParam[2],(UINT) pLine->nParam[3]); break; case TOK_END: return pLine; @@ -1235,16 +1236,16 @@ static KmlLine* InitAnnunciator(KmlBlock* pBlock) switch (pLine->eCommand) { case TOK_OFFSET: - pAnnunciator[nId].nOx = pLine->nParam[0]; - pAnnunciator[nId].nOy = pLine->nParam[1]; + pAnnunciator[nId].nOx = (UINT) pLine->nParam[0]; + pAnnunciator[nId].nOy = (UINT) pLine->nParam[1]; break; case TOK_DOWN: - pAnnunciator[nId].nDx = pLine->nParam[0]; - pAnnunciator[nId].nDy = pLine->nParam[1]; + pAnnunciator[nId].nDx = (UINT) pLine->nParam[0]; + pAnnunciator[nId].nDy = (UINT) pLine->nParam[1]; break; case TOK_SIZE: - pAnnunciator[nId].nCx = pLine->nParam[0]; - pAnnunciator[nId].nCy = pLine->nParam[1]; + pAnnunciator[nId].nCx = (UINT) pLine->nParam[0]; + pAnnunciator[nId].nCy = (UINT) pLine->nParam[1]; break; case TOK_END: return pLine; @@ -1281,23 +1282,23 @@ static VOID InitButton(KmlBlock* pBlock) switch (pLine->eCommand) { case TOK_TYPE: - pButton[nButtons].nType = pLine->nParam[0]; + pButton[nButtons].nType = (UINT) pLine->nParam[0]; break; case TOK_OFFSET: - pButton[nButtons].nOx = pLine->nParam[0]; - pButton[nButtons].nOy = pLine->nParam[1]; + pButton[nButtons].nOx = (UINT) pLine->nParam[0]; + pButton[nButtons].nOy = (UINT) pLine->nParam[1]; break; case TOK_DOWN: - pButton[nButtons].nDx = pLine->nParam[0]; - pButton[nButtons].nDy = pLine->nParam[1]; + pButton[nButtons].nDx = (UINT) pLine->nParam[0]; + pButton[nButtons].nDy = (UINT) pLine->nParam[1]; break; case TOK_SIZE: - pButton[nButtons].nCx = pLine->nParam[0]; - pButton[nButtons].nCy = pLine->nParam[1]; + pButton[nButtons].nCx = (UINT) pLine->nParam[0]; + pButton[nButtons].nCy = (UINT) pLine->nParam[1]; break; case TOK_OUTIN: - pButton[nButtons].nOut = pLine->nParam[0]; - pButton[nButtons].nIn = pLine->nParam[1]; + pButton[nButtons].nOut = (UINT) pLine->nParam[0]; + pButton[nButtons].nIn = (UINT) pLine->nParam[1]; break; case TOK_ONDOWN: pButton[nButtons].pOnDown = pLine; @@ -1397,15 +1398,15 @@ static KmlLine* RunLine(KmlLine* pLine) { case TOK_MAP: if (byVKeyMap[pLine->nParam[0]&0xFF]&1) - PressButtonById(pLine->nParam[1]); + PressButtonById((UINT) pLine->nParam[1]); else - ReleaseButtonById(pLine->nParam[1]); + ReleaseButtonById((UINT) pLine->nParam[1]); break; case TOK_PRESS: - PressButtonById(pLine->nParam[0]); + PressButtonById((UINT) pLine->nParam[0]); break; case TOK_RELEASE: - ReleaseButtonById(pLine->nParam[0]); + ReleaseButtonById((UINT) pLine->nParam[0]); break; case TOK_MENUITEM: PostMessage(hWnd, WM_COMMAND, 0x19C40+(pLine->nParam[0]&0xFF), 0); @@ -1519,6 +1520,7 @@ VOID KillKML(VOID) nBackgroundH = 0; nLcdZoom = 1; cCurrentRomType = 0; + nCurrentClass = 0; UpdateWindowStatus(); ResizeWindow(); return; @@ -1564,7 +1566,7 @@ static DWORD GetIntegerParam(KmlBlock* pBlock, TokenId eBlock, TokenId eCommand, { if (pLine->eCommand == eCommand) { - return pLine->nParam[nParam]; + return (DWORD) pLine->nParam[nParam]; } pLine = pLine->pNext; } @@ -1626,23 +1628,27 @@ static VOID AdjustPixel(UINT x, UINT y, BYTE byOffset) static __inline VOID TransparentCircle(UINT cx, UINT cy, UINT r) { #define HIGHADJ 0x80 // color incr. at center - #define LOWADJ 0x08 // color incr. at border + #define LOWADJ 0x10 // color incr. at border - INT x, y; - INT rr = r * r; // calculate r^2 + UINT x, y, rr, rrc; + + if (r < 2) return; // radius 2 pixel minimum + + rr = r * r; // calculate r^2 + rrc = (r-1) * (r-1); // calculate (r-1)^2 for color steps // y-rows of circle - for (y = 0; y < (INT) r; ++y) + for (y = 0; y < r; ++y) { - INT yy = y * y; // calculate y^2 + UINT yy = y * y; // calculate y^2 // x-columns of circle - INT nXWidth = iSqrt(rr-yy); + UINT nXWidth = iSqrt(rr-yy); for (x = 0; x < nXWidth; ++x) { - // color offset, sqrt(x*x+y*y) <= r !!! - BYTE byOff = HIGHADJ - (BYTE) (iSqrt((x*x+yy) * (HIGHADJ-LOWADJ)*(HIGHADJ-LOWADJ) / rr)); + // color offset, sqrt(x*x+y*y) < r !!! + BYTE byOff = HIGHADJ - (BYTE) (iSqrt((x*x+yy) * (HIGHADJ-LOWADJ)*(HIGHADJ-LOWADJ) / rrc)); AdjustPixel(cx+x, cy+y, byOff); if (x != 0) AdjustPixel(cx-x, cy+y, byOff); @@ -2002,19 +2008,20 @@ VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y) _ASSERT(hCursorArrow); _ASSERT(hCursorHand); hCursor = hCursorArrow; // normal arrow cursor - if (!bClassicCursor) + for (i = 0; i < nButtons; i++) // scan all buttons { - for (i = 0; i < nButtons; i++) // scan all buttons + if (ClipButton(x,y,i)) // cursor over button? { - if (ClipButton(x,y,i)) // cursor over button? - { - hCursor = hCursorHand; // hand cursor - break; - } + hCursor = hCursorHand; // hand cursor + break; } } // make sure that class cursor is NULL - _ASSERT(GetClassLong(hWnd,GCL_HCURSOR) == 0); + #if defined _WIN64 + _ASSERT(GetClassLong(hWnd,GCLP_HCURSOR) == 0); + #else + _ASSERT(GetClassLong(hWnd,GCL_HCURSOR) == 0); + #endif SetCursor(hCursor); if (!(nFlags&MK_LBUTTON)) return; // left mouse key not pressed -> quit @@ -2224,6 +2231,12 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog) AddToLog(_T("This KML Script doesn't specify the background bitmap, or bitmap could not be loaded.")); goto quit; } + if (!CrcRom(&wRomCrc)) // build patched ROM fingerprint and check for unpacked data + { + AddToLog(_T("Packed ROM image detected.")); + UnmapRom(); // free memory + goto quit; + } CreateLcdBitmap(); diff --git a/Sources/Emu48/KML.H b/Sources/Emu48/KML.H index 69b772b..0d188dd 100644 --- a/Sources/Emu48/KML.H +++ b/Sources/Emu48/KML.H @@ -77,7 +77,7 @@ typedef struct KmlLine { struct KmlLine* pNext; TokenId eCommand; - DWORD nParam[6]; + DWORD_PTR nParam[6]; } KmlLine; typedef struct KmlBlock diff --git a/Sources/Emu48/LOWBAT.C b/Sources/Emu48/LOWBAT.C new file mode 100644 index 0000000..c082e21 --- /dev/null +++ b/Sources/Emu48/LOWBAT.C @@ -0,0 +1,118 @@ +/* + * lowbat.c + * + * This file is part of Emu48 + * + * Copyright (C) 2006 Christoph Gießelink + * + */ +#include "pch.h" +#include "Emu48.h" +#include "io.h" // I/O definitions + +// #define BAT_SIMULATION // switch low bat simulation + +#define BAT_FREQ (60*1000) // bat update time in ms (real machine = 60us, HP28C = 60s) + +static HANDLE hCThreadBat = NULL; +static HANDLE hEventBat; + +static DWORD WINAPI LowBatThread(LPVOID pParam) +{ + BOOL bLBI,bVLBI; + + do + { + GetBatteryState(&bLBI,&bVLBI); // get battery state + + // very low bat detection + bVLBI = bVLBI && (Chipset.IORam[LPE] & EVLBI) != 0; + + IOBit(LPD,VLBI,bVLBI); // set VLBI + IOBit(SRQ1,VSRQ,bVLBI); // and service bit + + if (bVLBI) // VLBI detected + { + Chipset.SoftInt = TRUE; + bInterrupt = TRUE; + + if (Chipset.Shutdn) // CPU shut down + { + Chipset.bShutdnWake = TRUE; // wake up from SHUTDN mode + SetEvent(hEventShutdn); // wake up emulation thread + } + } + } + while (WaitForSingleObject(hEventBat,BAT_FREQ) == WAIT_TIMEOUT); + + return 0; + UNREFERENCED_PARAMETER(pParam); +} + +VOID StartBatMeasure(VOID) +{ + if (hCThreadBat) // Bat measuring thread running + return; // -> quit + + // event to cancel Bat refresh loop + hEventBat = CreateEvent(NULL,FALSE,FALSE,NULL); + + VERIFY(hCThreadBat = CreateThread(NULL,0,&LowBatThread,NULL,0,NULL)); + return; +} + +VOID StopBatMeasure(VOID) +{ + if (hCThreadBat == NULL) // thread stopped + return; // -> quit + + SetEvent(hEventBat); // leave Bat update thread + WaitForSingleObject(hCThreadBat,INFINITE); + CloseHandle(hCThreadBat); + hCThreadBat = NULL; // set flag Bat update stopped + CloseHandle(hEventBat); // close Bat event + return; +} + +VOID GetBatteryState(BOOL *pbLBI, BOOL *pbVLBI) +{ +#if defined BAT_SIMULATION + switch (GetPrivateProfileInt(_T("LowBat"),_T("Level"),2,_T(".\\Lowbat.ini"))) + { + case 0: // empty + *pbLBI = TRUE; + *pbVLBI = TRUE; + break; + case 1: // low + *pbLBI = TRUE; + *pbVLBI = FALSE; + break; + default: // full + *pbLBI = FALSE; + *pbVLBI = FALSE; + break; + } +#else + SYSTEM_POWER_STATUS sSps; + + *pbLBI = FALSE; // no battery warning + *pbVLBI = FALSE; + + VERIFY(GetSystemPowerStatus(&sSps)); + + // battery powered + if (sSps.ACLineStatus == AC_LINE_OFFLINE) + { + // on critical battery state make sure that lowbat flag is also set + if ((sSps.BatteryFlag & BATTERY_FLAG_CRITICAL) != 0) + sSps.BatteryFlag |= BATTERY_FLAG_LOW; + + // low bat detection + *pbLBI = ((sSps.BatteryFlag & BATTERY_FLAG_LOW) != 0); + + // very low bat detection + *pbVLBI = ((sSps.BatteryFlag & BATTERY_FLAG_CRITICAL) != 0); + } +#endif + return; +} diff --git a/Sources/Emu48/MOPS.C b/Sources/Emu48/MOPS.C index 8e2d939..f814f1b 100644 --- a/Sources/Emu48/MOPS.C +++ b/Sources/Emu48/MOPS.C @@ -721,7 +721,7 @@ VOID Npeek(BYTE *a, DWORD d, UINT s) c = MIN(s,0x40-v); } while (0); - ReadIO(a,v,c); + ReadIO(a,v,c,FALSE); } while (0); } @@ -772,7 +772,7 @@ VOID Nread(BYTE *a, DWORD d, UINT s) { v = d&0x3F; c = MIN(s,0x40-v); - ReadIO(a,v,c); + ReadIO(a,v,c,TRUE); // reading MSB of timer2 update the CRC register if (v+c == 0x40) UpCRC(a[c-1]); // timer2 MSB touched, update the CRC register @@ -987,10 +987,10 @@ VOID IOBit(DWORD d, BYTE b, BOOL s) // set/clear bit in I/O section LeaveCriticalSection(&csIOLock); } -VOID ReadIO(BYTE *a, DWORD d, DWORD s) +VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) { - BOOL bNINT; - BOOL bNINT2; + BOOL bNINT,bNINT2; + BOOL bLBI,bVLBI; BYTE c = 0xFF; // LINECOUNT not initialized BOOL rbr_acc = FALSE; // flag to receive data @@ -1015,10 +1015,28 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s) case 0x05: *a = (Chipset.crc>> 4)&0xF; break; case 0x06: *a = (Chipset.crc>> 8)&0xF; break; case 0x07: *a = (Chipset.crc>>12)&0xF; break; - case 0x08: *a = 0; break; + case 0x08: // LPD + // LB2 and LB1 not emulated, must be 0 + _ASSERT((Chipset.IORam[LPD] & (LB2 | LB1)) == 0); + + GetBatteryState(&bLBI,&bVLBI); // get battery state + + // check if battery states enabled + bLBI = bLBI && ((Chipset.IORam[LPE] & ELBI) != 0); + bVLBI = bVLBI && ((Chipset.IORam[LPE] & EVLBI) != 0); + + // set IO bits + IOBit(LPD,LB0,bLBI); + IOBit(LPD,VLBI,bVLBI); + IOBit(SRQ1,VSRQ,bVLBI); + *a = Chipset.IORam[d]; + break; case 0x09: // LPE *a = Chipset.IORam[d]; - Chipset.IORam[d] &= ~RST; // clear RST bit after reading + if (bUpdate) + { + Chipset.IORam[d] &= ~RST; // clear RST bit after reading + } break; case 0x0A: *a = 0; break; // case 0x0B: *a = Chipset.IORam[d]; break; @@ -1091,17 +1109,25 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s) break; case 0x14: // RBR LSB case 0x15: // RBR MSB - Chipset.IORam[RCS]&=~RBF; - *a = Chipset.IORam[d]; // return RBR value - UpdateUSRQ(); // update USRQ - rbr_acc = TRUE; // search for new RBR value - #if defined DEBUG_SERIAL + if (bUpdate) { - TCHAR buffer[256]; - wsprintf(buffer,_T("%.5lx: RBR %s Read: %x\n"),Chipset.pc,(d==0x14) ? "LSB" : "MSB",*a); - OutputDebugString(buffer); + Chipset.IORam[RCS] &= ~RBF; + *a = Chipset.IORam[d]; // return RBR value + UpdateUSRQ(); // update USRQ + rbr_acc = TRUE; // search for new RBR value + #if defined DEBUG_SERIAL + { + TCHAR buffer[256]; + wsprintf(buffer,_T("%.5lx: RBR %s Read: %x\n"),Chipset.pc,(d==0x14) ? "LSB" : "MSB",*a); + OutputDebugString(buffer); + } + #endif + } + else + { + *a = Chipset.IORam[d]; // return RBR value + UpdateUSRQ(); // update USRQ } - #endif break; // case 0x16: *a = Chipset.IORam[d]; break; // TBR LSB // case 0x17: *a = Chipset.IORam[d]; break; // TBR MSB diff --git a/Sources/Emu48/OPCODES.C b/Sources/Emu48/OPCODES.C index d94aa24..f3d9bcc 100644 --- a/Sources/Emu48/OPCODES.C +++ b/Sources/Emu48/OPCODES.C @@ -1028,7 +1028,8 @@ VOID o807(LPBYTE I) // SHUTDN bShutdn = FALSE; // don't shut down } } - if (w.in==0 && bShutdn) // shut down only when enabled + ScanKeyboard(TRUE,FALSE); // update Chipset.in register (direct) + if (w.in == 0 && bShutdn) // shut down only when enabled { w.Shutdn = TRUE; // set mode before exit emulation loop bInterrupt = TRUE; @@ -1797,10 +1798,7 @@ VOID o83n(LPBYTE I) // ?HST=0 m { w.cycles+=6; w.pc+=3; - if ((w.HST&I[2])==0) - w.carry=TRUE; - else - w.carry=FALSE; + w.carry=((w.HST&I[2])==0); GOYES3; } @@ -1840,10 +1838,7 @@ VOID o88n(LPBYTE I) // ?P# n { w.cycles+=6; w.pc+=3; - if (w.P!=I[2]) - w.carry=TRUE; - else - w.carry=FALSE; + w.carry=(w.P!=I[2]); GOYES3; } @@ -1851,10 +1846,7 @@ VOID o89n(LPBYTE I) // ?P= n { w.cycles+=6; w.pc+=3; - if (w.P==I[2]) - w.carry=TRUE; - else - w.carry=FALSE; + w.carry=(w.P==I[2]); GOYES3; } diff --git a/Sources/Emu48/OPS.H b/Sources/Emu48/OPS.H index 8b6b939..5d6aa6a 100644 --- a/Sources/Emu48/OPS.H +++ b/Sources/Emu48/OPS.H @@ -63,7 +63,7 @@ static __inline void rstkpush(DWORD d) Chipset.rstkp=(Chipset.rstkp+1)&7; } -static __inline DWORD rstkpop() +static __inline DWORD rstkpop(VOID) { DWORD r; @@ -167,7 +167,7 @@ static __inline void Nincx(BYTE *a, UINT s) } a[i] -= 16; } - Chipset.carry=TRUE; + Chipset.carry = TRUE; } static __inline void Ndec(BYTE *a, UINT s, UINT d) @@ -371,18 +371,12 @@ static __inline void Nbit1(BYTE *a, UINT b) static __inline void Tbit0(BYTE *a, UINT b) { - if (a[b>>2] & (1<<(b&3))) - Chipset.carry = FALSE; - else - Chipset.carry = TRUE; + Chipset.carry = ((a[b>>2] & (1<<(b&3))) == 0); } static __inline void Tbit1(BYTE *a, UINT b) { - if (a[b>>2] & (1<<(b&3))) - Chipset.carry = TRUE; - else - Chipset.carry = FALSE; + Chipset.carry = ((a[b>>2] & (1<<(b&3))) != 0); } static __inline void Te(BYTE *a, BYTE *b, UINT s) @@ -440,35 +434,23 @@ static __inline void Tnz(BYTE *a, UINT s) static __inline void Ta(BYTE *a, BYTE *b, UINT s) { while (--s) if (a[s]!=b[s]) break; - if (a[s]>b[s]) - Chipset.carry = TRUE; - else - Chipset.carry = FALSE; + Chipset.carry = (a[s]>b[s]); } static __inline void Tb(BYTE *a, BYTE *b, UINT s) { while (--s) if (a[s]!=b[s]) break; - if (a[s]=b[s]) - Chipset.carry = TRUE; - else - Chipset.carry = FALSE; + Chipset.carry = (a[s]>=b[s]); } static __inline void Tbe(BYTE *a, BYTE *b, UINT s) { while (--s) if (a[s]!=b[s]) break; - if (a[s]<=b[s]) - Chipset.carry = TRUE; - else - Chipset.carry = FALSE; + Chipset.carry = (a[s]<=b[s]); } diff --git a/Sources/Emu48/PCH.H b/Sources/Emu48/PCH.H index 34d1989..8e5f784 100644 --- a/Sources/Emu48/PCH.H +++ b/Sources/Emu48/PCH.H @@ -3,6 +3,7 @@ // #define _WIN32_IE 0x0200 +#define _CRT_SECURE_NO_DEPRECATE #include #include @@ -10,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -28,3 +30,6 @@ #define IDC_HAND MAKEINTRESOURCE(32649) #endif +#if _MSC_VER <= 1200 // missing type definition in the MSVC6.0 SDK and earlier +typedef SIZE_T DWORD_PTR, *PDWORD_PTR; +#endif diff --git a/Sources/Emu48/RESOURCE.H b/Sources/Emu48/RESOURCE.H index 1c2ccfb..4d9155e 100644 --- a/Sources/Emu48/RESOURCE.H +++ b/Sources/Emu48/RESOURCE.H @@ -2,8 +2,6 @@ // Microsoft Developer Studio generated include file. // Used by Emu48.rc // -#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 -#define RT_MANIFEST 24 #define IDI_EMU48 100 #define IDR_MENU 101 #define IDR_DEBUG 102 @@ -29,127 +27,129 @@ #define IDD_MACROSET 122 #define IDC_REALSPEED 1000 #define IDC_GRAYSCALE 1001 -#define IDC_AUTOSAVE 1002 -#define IDC_AUTOSAVEONEXIT 1003 -#define IDC_OBJECTLOADWARNING 1004 -#define IDC_ALWAYSDISPLOG 1005 -#define IDC_PORT1EN 1006 -#define IDC_PORT1WR 1007 -#define IDC_PORT2ISSHARED 1008 -#define IDC_PORT2WR 1009 -#define IDC_PORT2 1010 -#define IDC_PORT2LOAD 1011 -#define IDC_WIRE 1012 -#define IDC_IR 1013 -#define IDC_EMUDIR 1014 -#define IDC_EMUDIRSEL 1015 -#define IDC_UPDATE 1016 -#define IDC_KMLSCRIPT 1017 -#define IDC_AUTHOR 1018 -#define IDC_TITLE 1019 -#define IDC_KMLLOG 1020 -#define IDC_VERSION 1021 -#define IDC_LICENSE 1022 -#define IDC_DISASM_WIN 1023 -#define IDC_DISASM_MAP 1024 -#define IDC_DISASM_ROM 1025 -#define IDC_DISASM_RAM 1026 -#define IDC_DISASM_PORT1 1027 -#define IDC_DISASM_PORT2 1028 -#define IDC_DISASM_MODULE 1029 -#define IDC_DISASM_HP 1030 -#define IDC_DISASM_CLASS 1031 -#define IDC_ADDRESS 1032 -#define IDC_DISASM_ADR 1033 -#define IDC_DISASM_NEXT 1034 -#define IDC_DISASM_COPY 1035 -#define IDC_DEBUG_CODE 1036 -#define IDC_STATIC_CODE 1037 -#define IDC_STATIC_REGISTERS 1038 -#define IDC_STATIC_MEMORY 1039 -#define IDC_STATIC_STACK 1040 -#define IDC_REG_A 1041 -#define IDC_REG_B 1042 -#define IDC_REG_C 1043 -#define IDC_REG_D 1044 -#define IDC_REG_R0 1045 -#define IDC_REG_R1 1046 -#define IDC_REG_R2 1047 -#define IDC_REG_R3 1048 -#define IDC_REG_R4 1049 -#define IDC_REG_D0 1050 -#define IDC_REG_D1 1051 -#define IDC_REG_P 1052 -#define IDC_REG_PC 1053 -#define IDC_REG_OUT 1054 -#define IDC_REG_IN 1055 -#define IDC_REG_ST 1056 -#define IDC_REG_CY 1057 -#define IDC_REG_MODE 1058 -#define IDC_REG_MP 1059 -#define IDC_REG_SR 1060 -#define IDC_REG_SB 1061 -#define IDC_REG_XM 1062 -#define IDC_MISC_INT 1063 -#define IDC_MISC_KEY 1064 -#define IDC_MISC_BS 1065 -#define IDC_NEWVALUE 1066 -#define IDC_ENTERADR 1067 -#define IDC_DEBUG_MEM 1068 -#define IDC_DEBUG_MEM_ADDR 1069 -#define IDC_DEBUG_MEM_COL0 1070 -#define IDC_DEBUG_MEM_COL1 1071 -#define IDC_DEBUG_MEM_COL2 1072 -#define IDC_DEBUG_MEM_COL3 1073 -#define IDC_DEBUG_MEM_COL4 1074 -#define IDC_DEBUG_MEM_COL5 1075 -#define IDC_DEBUG_MEM_COL6 1076 -#define IDC_DEBUG_MEM_COL7 1077 -#define IDC_DEBUG_MEM_TEXT 1078 -#define IDC_DEBUG_STACK 1079 -#define IDC_STATIC_BREAKPOINT 1080 -#define IDC_BREAKEDIT_ADD 1081 -#define IDC_BREAKEDIT_DELETE 1082 -#define IDC_BREAKEDIT_WND 1083 -#define IDC_STATIC_MMU 1084 -#define IDC_MMU_IO_A 1085 -#define IDC_MMU_NCE2_A 1086 -#define IDC_MMU_CE1_A 1087 -#define IDC_MMU_CE2_A 1088 -#define IDC_MMU_NCE3_A 1089 -#define IDC_MMU_IO_S 1090 -#define IDC_MMU_CE1_S 1091 -#define IDC_MMU_CE2_S 1092 -#define IDC_MMU_NCE2_S 1093 -#define IDC_MMU_NCE3_S 1094 -#define IDC_STATIC_MISC 1095 -#define IDC_MISC_BS_TXT 1096 -#define IDC_INSTR_TEXT 1097 -#define IDC_INSTR_CODE 1098 -#define IDC_INSTR_COPY 1099 -#define IDC_INSTR_CLEAR 1100 -#define IDC_PROFILE_LASTCYCLES 1101 -#define IDC_PROFILE_LASTTIME 1102 -#define IDC_BPCODE 1103 -#define IDC_BPRPL 1104 -#define IDC_BPACCESS 1105 -#define IDC_BPREAD 1106 -#define IDC_BPWRITE 1107 -#define IDC_FIND_DATA 1108 -#define IDC_FIND_ASCII 1109 -#define IDC_FIND_CASE 1110 -#define IDC_ADDR20_24 1111 -#define IDC_ADDR25_27 1112 -#define IDC_ADDR28_29 1113 -#define IDC_ADDR30_34 1114 -#define IDC_MACRO_SLOW 1115 -#define IDC_MACRO_FAST 1116 -#define IDC_MACRO_SLIDER 1117 -#define IDC_MACRO_REAL 1118 -#define IDC_MACRO_MANUAL 1119 -#define IDC_SOUND_SLIDER 1120 -#define IDC_SOUND_SPEAKER 1121 -#define IDC_SOUND_WAVE 1122 +#define IDC_ALWAYSONTOP 1002 +#define IDC_ACTFOLLOWSMOUSE 1003 +#define IDC_AUTOSAVE 1004 +#define IDC_AUTOSAVEONEXIT 1005 +#define IDC_OBJECTLOADWARNING 1006 +#define IDC_ALWAYSDISPLOG 1007 +#define IDC_PORT1EN 1008 +#define IDC_PORT1WR 1009 +#define IDC_PORT2ISSHARED 1010 +#define IDC_PORT2WR 1011 +#define IDC_PORT2 1012 +#define IDC_PORT2LOAD 1013 +#define IDC_WIRE 1014 +#define IDC_IR 1015 +#define IDC_EMUDIR 1016 +#define IDC_EMUDIRSEL 1017 +#define IDC_UPDATE 1018 +#define IDC_KMLSCRIPT 1019 +#define IDC_AUTHOR 1020 +#define IDC_TITLE 1021 +#define IDC_KMLLOG 1022 +#define IDC_VERSION 1023 +#define IDC_LICENSE 1024 +#define IDC_DISASM_WIN 1025 +#define IDC_DISASM_MAP 1026 +#define IDC_DISASM_ROM 1027 +#define IDC_DISASM_RAM 1028 +#define IDC_DISASM_PORT1 1029 +#define IDC_DISASM_PORT2 1030 +#define IDC_DISASM_MODULE 1031 +#define IDC_DISASM_HP 1032 +#define IDC_DISASM_CLASS 1033 +#define IDC_ADDRESS 1034 +#define IDC_DISASM_ADR 1035 +#define IDC_DISASM_NEXT 1036 +#define IDC_DISASM_COPY 1037 +#define IDC_DEBUG_CODE 1038 +#define IDC_STATIC_CODE 1039 +#define IDC_STATIC_REGISTERS 1040 +#define IDC_STATIC_MEMORY 1041 +#define IDC_STATIC_STACK 1042 +#define IDC_REG_A 1043 +#define IDC_REG_B 1044 +#define IDC_REG_C 1045 +#define IDC_REG_D 1046 +#define IDC_REG_R0 1047 +#define IDC_REG_R1 1048 +#define IDC_REG_R2 1049 +#define IDC_REG_R3 1050 +#define IDC_REG_R4 1051 +#define IDC_REG_D0 1052 +#define IDC_REG_D1 1053 +#define IDC_REG_P 1054 +#define IDC_REG_PC 1055 +#define IDC_REG_OUT 1056 +#define IDC_REG_IN 1057 +#define IDC_REG_ST 1058 +#define IDC_REG_CY 1059 +#define IDC_REG_MODE 1060 +#define IDC_REG_MP 1061 +#define IDC_REG_SR 1062 +#define IDC_REG_SB 1063 +#define IDC_REG_XM 1064 +#define IDC_MISC_INT 1065 +#define IDC_MISC_KEY 1066 +#define IDC_MISC_BS 1067 +#define IDC_NEWVALUE 1068 +#define IDC_ENTERADR 1069 +#define IDC_DEBUG_MEM 1070 +#define IDC_DEBUG_MEM_ADDR 1071 +#define IDC_DEBUG_MEM_COL0 1072 +#define IDC_DEBUG_MEM_COL1 1073 +#define IDC_DEBUG_MEM_COL2 1074 +#define IDC_DEBUG_MEM_COL3 1075 +#define IDC_DEBUG_MEM_COL4 1076 +#define IDC_DEBUG_MEM_COL5 1077 +#define IDC_DEBUG_MEM_COL6 1078 +#define IDC_DEBUG_MEM_COL7 1079 +#define IDC_DEBUG_MEM_TEXT 1080 +#define IDC_DEBUG_STACK 1081 +#define IDC_STATIC_BREAKPOINT 1082 +#define IDC_BREAKEDIT_ADD 1083 +#define IDC_BREAKEDIT_DELETE 1084 +#define IDC_BREAKEDIT_WND 1085 +#define IDC_STATIC_MMU 1086 +#define IDC_MMU_IO_A 1087 +#define IDC_MMU_NCE2_A 1088 +#define IDC_MMU_CE1_A 1089 +#define IDC_MMU_CE2_A 1090 +#define IDC_MMU_NCE3_A 1091 +#define IDC_MMU_IO_S 1092 +#define IDC_MMU_CE1_S 1093 +#define IDC_MMU_CE2_S 1094 +#define IDC_MMU_NCE2_S 1095 +#define IDC_MMU_NCE3_S 1096 +#define IDC_STATIC_MISC 1097 +#define IDC_MISC_BS_TXT 1098 +#define IDC_INSTR_TEXT 1099 +#define IDC_INSTR_CODE 1100 +#define IDC_INSTR_COPY 1101 +#define IDC_INSTR_CLEAR 1102 +#define IDC_PROFILE_LASTCYCLES 1103 +#define IDC_PROFILE_LASTTIME 1104 +#define IDC_BPCODE 1105 +#define IDC_BPRPL 1106 +#define IDC_BPACCESS 1107 +#define IDC_BPREAD 1108 +#define IDC_BPWRITE 1109 +#define IDC_FIND_DATA 1110 +#define IDC_FIND_ASCII 1111 +#define IDC_FIND_CASE 1112 +#define IDC_ADDR20_24 1113 +#define IDC_ADDR25_27 1114 +#define IDC_ADDR28_29 1115 +#define IDC_ADDR30_34 1116 +#define IDC_MACRO_SLOW 1117 +#define IDC_MACRO_FAST 1118 +#define IDC_MACRO_SLIDER 1119 +#define IDC_MACRO_REAL 1120 +#define IDC_MACRO_MANUAL 1121 +#define IDC_SOUND_SLIDER 1122 +#define IDC_SOUND_SPEAKER 1123 +#define IDC_SOUND_WAVE 1124 #define ID_FILE_NEW 40001 #define ID_FILE_OPEN 40002 #define ID_FILE_SAVE 40003 @@ -221,7 +221,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 123 #define _APS_NEXT_COMMAND_VALUE 40067 -#define _APS_NEXT_CONTROL_VALUE 1122 +#define _APS_NEXT_CONTROL_VALUE 1125 #define _APS_NEXT_SYMED_VALUE 108 #endif #endif diff --git a/Sources/Emu48/RPL.C b/Sources/Emu48/RPL.C index 0324e48..e300175 100644 --- a/Sources/Emu48/RPL.C +++ b/Sources/Emu48/RPL.C @@ -16,14 +16,16 @@ //#F068D #806EE #806EE #7056F #806EE #806EE =TEMPTOP //#F0692 #806F3 #806F3 #70574 #806F3 #806F3 =RSKTOP (B) //#F0697 #806F8 #806F8 #70579 #806F8 #806F8 =DSKTOP (D1) +//#F069C #806FD #806FD #7057E #806FD #806FD =EDITLINE //#F0DEA #80E9B #80E9B #7066E #807ED #80E9B =AVMEM (D) //#F0705 #8076B #8076B #705B0 #8072F #8076B =INTRPPTR (D0) -// #80F02 #80F02 #706C5 #80843 #80F02 =SystemFlags +//#F0E42 #80F02 #80F02 #706C5 #80843 #80F02 =SystemFlags #define TEMPOB ((cCurrentRomType=='S')?0x7056A:0x806E9) #define TEMPTOP ((cCurrentRomType=='S')?0x7056F:0x806EE) #define RSKTOP ((cCurrentRomType=='S')?0x70574:0x806F3) #define DSKTOP ((cCurrentRomType=='S')?0x70579:0x806F8) +#define EDITLINE ((cCurrentRomType=='S')?0x7057E:0x806FD) #define AVMEM ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x7066E:0x807ED):0x80E9B) #define INTRPPTR ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x705B0:0x8072F):0x8076B) #define SYSTEMFLAGS ((cCurrentRomType!='X')?((cCurrentRomType=='S')?0x706C5:0x80843):0x80F02) @@ -237,11 +239,12 @@ DWORD RPL_SkipOb(DWORD d) return d+l; } -DWORD RPL_ObjectSize(BYTE *o) +DWORD RPL_ObjectSize(BYTE *o,DWORD s) { DWORD n, l = 0; - n = Npack(o, 5); // read prolog + if (s < 5) return BAD_OB; // size too small for prolog + n = Npack(o,5); // read prolog switch (n) { case DOFLASHP: l = (cCurrentRomType!='X') ? 5 : 12; break; // Flash PTR (HP49G) @@ -263,29 +266,45 @@ DWORD RPL_ObjectSize(BYTE *o) case DOSYMB: // Algebraic case DOEXT: // Unit case DOCOL: // Program - n=5; - do { l+=n; o+=n; n=RPL_ObjectSize(o); } while (n); + n = 5; // prolog length + do + { + l += n; + if (l > s) return BAD_OB; // prevent negative size argument + n = RPL_ObjectSize(o+l,s-l); // get new object + if (n == BAD_OB) return BAD_OB; // buffer overflow + } + while (n); l += 5; break; case SEMI: l = 0; break; // SEMI case DOIDNT: // Global Name case DOLAM: // Local Name case DOTAG: // Tagged - n = 7 + Npack(o+5,2)*2; - l = n + RPL_ObjectSize(o+n); + if (s < 5 + 2) return BAD_OB; + l = 7 + Npack(o+5,2) * 2; // prolog + name length + if (l > s) return BAD_OB; // prevent negative size argument + n = RPL_ObjectSize(o+l,s-l); // get new object + if (n == BAD_OB) return BAD_OB; // buffer overflow + l += n; break; case DORRP: // Directory + if (s < 8 + 5) return BAD_OB; n = Npack(o+8,5); - if (n==0) // empty dir + if (n == 0) // empty dir { - l=13; + l = 13; } else { - l = 8+n; - n = Npack(o+l,2)*2 + 4; + l = 8 + n; + if (s < l + 2) return BAD_OB; + n = Npack(o+l,2) * 2 + 4; + l += n; + if (l > s) return BAD_OB; // prevent negative size argument + n = RPL_ObjectSize(o+l,s-l); // next rrp + if (n == BAD_OB) return BAD_OB; // buffer overflow l += n; - l += RPL_ObjectSize(o+l); } break; case DOINT: // Precision Integer (HP49G) @@ -308,13 +327,16 @@ DWORD RPL_ObjectSize(BYTE *o) case DOEXT3: // Reserved 2 case DOEXT4: // Reserved 3 case DOCODE: // Code + if (s < 5 + 5) return BAD_OB; l = 5 + Npack(o+5,5); break; case DOLNGREAL: // Precision Real (HP49G) l = 5; if (cCurrentRomType=='X') { + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); } break; @@ -322,15 +344,19 @@ DWORD RPL_ObjectSize(BYTE *o) l = 5; if (cCurrentRomType=='X') { + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); + if (s < l + 5) return BAD_OB; l += Npack(o+l,5); } break; - default: l=5; + default: l = 5; } - return l; + return (s >= l) ? l : BAD_OB; } DWORD RPL_CreateTemp(DWORD l) @@ -360,18 +386,23 @@ DWORD RPL_CreateTemp(DWORD l) return (a+1); // return base address of new object } +UINT RPL_Depth(VOID) +{ + return (Read5(EDITLINE) - Read5(DSKTOP)) / 5 - 1; +} + DWORD RPL_Pick(UINT l) { DWORD stkp; - _ASSERT(l > 0); // first stack elememt is one - if (l==0) return 0; + _ASSERT(l > 0); // first stack element is one + if (l == 0) return 0; if (METAKERNEL) ++l; // Metakernel support + if (RPL_Depth() < l) return 0; // not enough elements on stack stkp = Read5(DSKTOP) + (l-1)*5; - return Read5(stkp); + return Read5(stkp); // return object address } -#if 0 // function not needed yet VOID RPL_Replace(DWORD n) { DWORD stkp; @@ -381,28 +412,30 @@ VOID RPL_Replace(DWORD n) Write5(stkp,n); return; } -#endif -VOID RPL_Push(DWORD n) +VOID RPL_Push(UINT l,DWORD n) { + UINT i; DWORD stkp, avmem; + if (l > RPL_Depth() + 1) return; // invalid stack level + avmem = Read5(AVMEM); // amount of free memory - if (avmem==0) return; // no memory free + if (avmem == 0) return; // no memory free avmem--; // fetch memory Write5(AVMEM,avmem); // save new amount of free memory - stkp = Read5(DSKTOP); // get pointer to stack level 1 - if (METAKERNEL) // Metakernel running ? + + if (METAKERNEL) ++l; // Metakernel, save MK object on stack level 1 + + stkp = Read5(DSKTOP) - 5; // get pointer of new stack level 1 + Write5(DSKTOP,stkp); // save it + + for (i = 1; i < l; ++i) // move down stack level entries before insert pos { - Write5(stkp-5,Read5(stkp)); // copy object pointer of stack level 1 to new stack level 1 entry - Write5(stkp,n); // save pointer to new object on stack level 2 - stkp-=5; // fetch new stack entry + Write5(stkp,Read5(stkp+5)); // move down stack level entry + stkp += 5; // next stack entry } - else - { - stkp-=5; // fetch new stack entry - Write5(stkp,n); // save pointer to new object on stack level 1 - } - Write5(DSKTOP,stkp); // save new pointer to stack level 1 + + Write5(stkp,n); // save pointer of new object on given stack level return; } diff --git a/Sources/Emu48/SERIAL.C b/Sources/Emu48/SERIAL.C index 0f3dcf8..752101c 100644 --- a/Sources/Emu48/SERIAL.C +++ b/Sources/Emu48/SERIAL.C @@ -104,7 +104,7 @@ BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort) if (lstrcmp(strPort, _T(NO_SERIAL))) // port defined { - TCHAR szDevice[16] = _T("\\\\.\\"); + TCHAR szDevice[256] = _T("\\\\.\\"); // check if device buffer is big enough _ASSERT(lstrlen(szDevice) + lstrlen(strPort) < ARRAYSIZEOF(szDevice)); diff --git a/Sources/Emu48/SETTINGS.C b/Sources/Emu48/SETTINGS.C index 0a68aa7..c505cfe 100644 --- a/Sources/Emu48/SETTINGS.C +++ b/Sources/Emu48/SETTINGS.C @@ -142,22 +142,24 @@ VOID ReadSettings(VOID) bAutoSave = ReadInt(_T("Files"),_T("AutoSave"),bAutoSave); bAutoSaveOnExit = ReadInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit); bSaveDefConfirm = ReadInt(_T("Files"),_T("SaveDefaultConfirm"),bSaveDefConfirm); + bStartupBackup = ReadInt(_T("Files"),_T("StartupBackup"),bStartupBackup); bLoadObjectWarning = ReadInt(_T("Files"),_T("LoadObjectWarning"),bLoadObjectWarning); // Port2 bPort2IsShared = ReadInt(_T("Port2"),_T("IsShared"),bPort2IsShared); ReadString(_T("Port2"),_T("Filename"),_T("SHARED.BIN"),szPort2Filename,ARRAYSIZEOF(szPort2Filename)); // KML bAlwaysDisplayLog = ReadInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog); - bClassicCursor = ReadInt(_T("KML"),_T("ClassicCursor"),bClassicCursor); // Disassembler disassembler_mode = ReadInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode); // Emulator - bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); - dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); - dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); - bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale); - bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep); - dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol); + bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); + bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); + bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); + dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); + dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); + bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale); + bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep); + dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol); SetSpeed(bRealSpeed); // set speed // Macro bMacroRealSpeed = ReadInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed); @@ -178,16 +180,18 @@ VOID WriteSettings(VOID) WriteInt(_T("Files"),_T("AutoSave"),bAutoSave); WriteInt(_T("Files"),_T("AutoSaveOnExit"),bAutoSaveOnExit); WriteInt(_T("Files"),_T("SaveDefaultConfirm"),bSaveDefConfirm); + WriteInt(_T("Files"),_T("StartupBackup"),bStartupBackup); WriteInt(_T("Files"),_T("LoadObjectWarning"),bLoadObjectWarning); // Port2 WriteInt(_T("Port2"),_T("IsShared"),bPort2IsShared); WriteString(_T("Port2"),_T("Filename"),szPort2Filename); // KML WriteInt(_T("KML"),_T("AlwaysDisplayLog"),bAlwaysDisplayLog); - WriteInt(_T("KML"),_T("ClassicCursor"),bClassicCursor); // Disassembler WriteInt(_T("Disassembler"),_T("Mnemonics"),disassembler_mode); // Emulator + WriteInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); + WriteInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); diff --git a/Sources/Emu48/STACK.C b/Sources/Emu48/STACK.C index 48f6e50..66a9bdd 100644 --- a/Sources/Emu48/STACK.C +++ b/Sources/Emu48/STACK.C @@ -303,7 +303,7 @@ static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYT for (i = nExpLen; i > 0; --i) // convert number into digits { - byNum[nMantLen + i] = lExp % 10; + byNum[nMantLen + i] = (BYTE) (lExp % 10); lExp /= 10; } @@ -574,7 +574,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack Nwrite(byNumber,dwAddress+10,s); // data // push object to stack - RPL_Push(dwAddress); + RPL_Push(1,dwAddress); } break; } @@ -593,7 +593,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack Nwrite(byNumber,dwAddress+5,s); // data // push object to stack - RPL_Push(dwAddress); + RPL_Push(1,dwAddress); } break; } @@ -603,6 +603,9 @@ LRESULT OnStackPaste(VOID) // paste data to stack DWORD dwSize = lstrlen(lpstrClipdata); if ((lpbyData = HeapAlloc(hHeap,0,dwSize * 2))) { + LPBYTE lpbySrc,lpbyDest; + DWORD dwLoop; + #if defined _UNICODE // copy data UNICODE -> ASCII WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, @@ -612,7 +615,31 @@ LRESULT OnStackPaste(VOID) // paste data to stack // copy data memcpy(lpbyData+dwSize,lpstrClipdata,dwSize); #endif - bSuccess = (WriteStack(lpbyData,dwSize) == S_ERR_NO); + + // unpack data + lpbySrc = lpbyData+dwSize; + lpbyDest = lpbyData; + dwLoop = dwSize; + while (dwLoop-- > 0) + { + BYTE byTwoNibs = *lpbySrc++; + *lpbyDest++ = (BYTE) (byTwoNibs & 0xF); + *lpbyDest++ = (BYTE) (byTwoNibs >> 4); + } + + dwSize *= 2; // size in nibbles + + // get TEMPOB memory for string object + dwAddress = RPL_CreateTemp(dwSize+10); + if ((bSuccess = (dwAddress > 0))) + { + Write5(dwAddress,DOCSTR); // String + Write5(dwAddress+5,dwSize+5); // length of String + Nwrite(lpbyData,dwAddress+10,dwSize); // data + + // push object to stack + RPL_Push(1,dwAddress); + } HeapFree(hHeap,0,lpbyData); } } diff --git a/Sources/Emu48/TIMER.C b/Sources/Emu48/TIMER.C index 0c04bad..d71cea9 100644 --- a/Sources/Emu48/TIMER.C +++ b/Sources/Emu48/TIMER.C @@ -42,7 +42,7 @@ static UINT uT2MaxTicks; // max. timer2 ticks handled by one timer event static DWORD dwT2Ref; // timer2 value at last timer2 access static DWORD dwT2Cyc; // cpu cycle counter at last timer2 access -static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2); +static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2); static DWORD CalcT2(VOID) // calculate timer2 value { @@ -89,6 +89,18 @@ static DWORD CalcT2(VOID) // calculate timer2 value // valid actual time -> new synchronizing dwT2Cyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwCycPerTick; } + + // check if timer2 interrupt is active -> no timer2 value below 0xFFFFFFFF + if ( Chipset.inte + && (dwT2 & 0x80000000) != 0 + && (!Chipset.Shutdn || (Chipset.IORam[TIMER2_CTRL]&WKE)) + && (Chipset.IORam[TIMER2_CTRL]&INTR) + ) + { + dwT2 = 0xFFFFFFFF; + dwT2Cyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwCycPerTick; + } + dwT2Ref = dwT2; // new reference time } return dwT2; @@ -195,7 +207,7 @@ static VOID AbortT2(VOID) return; } -static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) +static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { _ASSERT(uEventId); // illegal EventId diff --git a/Sources/GCCPatch/EMU48GCC.RC b/Sources/GCCPatch/EMU48GCC.RC index 8606479..c3c5254 100644 --- a/Sources/GCCPatch/EMU48GCC.RC +++ b/Sources/GCCPatch/EMU48GCC.RC @@ -74,7 +74,7 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 160 TOPMARGIN, 4 - BOTTOMMARGIN, 256 + BOTTOMMARGIN, 270 END IDD_CHOOSEKML, DIALOG @@ -225,14 +225,14 @@ FONT 8, "MS Sans Serif" BEGIN ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP - LTEXT "Copyright © 2006 Sébastien Carlier && Christoph Gießelink", + LTEXT "Copyright © 2007 Sébastien Carlier && Christoph Gießelink", IDC_STATIC,29,18,181,8 DEFPUSHBUTTON "OK",IDOK,215,12,39,14 EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY END -IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 263 +IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Settings" FONT 8, "MS Sans Serif" @@ -241,49 +241,53 @@ BEGIN BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10 CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10 + CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10 + CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,37,89,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10 CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,114,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,114,10 CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,61,102,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10 CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,133,10 - GROUPBOX "General",IDC_STATIC,7,4,153,83 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10 + GROUPBOX "General",IDC_STATIC,7,4,153,107 CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,13,101,65,11 + WS_GROUP | WS_TABSTOP,13,125,65,11 CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button", - BS_AUTORADIOBUTTON,84,101,70,11 - GROUPBOX "Disassembler",IDC_STATIC,7,90,153,28 - LTEXT "Volume",IDC_STATIC,13,134,24,8 + BS_AUTORADIOBUTTON,84,125,70,11 + GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28 + LTEXT "Volume",IDC_STATIC,13,158,24,8 CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32", - TBS_AUTOTICKS | WS_TABSTOP,39,129,68,18 + TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18 CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON | - WS_GROUP | WS_TABSTOP,111,128,43,10 + WS_GROUP | WS_TABSTOP,111,152,43,10 CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111, - 139,43,10 - GROUPBOX "Sound",IDC_STATIC,7,120,153,34 + 163,43,10 + GROUPBOX "Sound",IDC_STATIC,7,144,153,34 CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,13,165,67,10 + WS_TABSTOP,13,189,67,10 CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,165,69,10 + BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10 CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,13,177,65,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,201,65,10 CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,84,177,69,10 - LTEXT "Port 2 File :",IDC_STATIC,13,192,37,8 - EDITTEXT IDC_PORT2,51,190,94,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_PORT2LOAD,145,190,10,12 - GROUPBOX "Memory Cards",IDC_STATIC,7,156,153,51 - LTEXT "Wire:",IDC_STATIC,13,221,17,8 - COMBOBOX IDC_WIRE,31,219,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | + BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10 + LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8 + EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12 + GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51 + LTEXT "Wire:",IDC_STATIC,13,245,17,8 + COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "IR:",IDC_STATIC,89,221,9,8 - COMBOBOX IDC_IR,107,219,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "IR:",IDC_STATIC,89,245,9,8 + COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Serial Ports",IDC_STATIC,7,209,153,27 - DEFPUSHBUTTON "&Ok",IDOK,9,242,50,14 - PUSHBUTTON "&Cancel",IDCANCEL,107,242,50,14 + GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27 + DEFPUSHBUTTON "&Ok",IDOK,9,266,50,14 + PUSHBUTTON "&Cancel",IDCANCEL,107,266,50,14 END IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66 @@ -295,9 +299,9 @@ BEGIN PUSHBUTTON "Cancel",IDCANCEL,138,27,50,14 COMBOBOX IDC_KMLSCRIPT,7,47,181,120,CBS_DROPDOWNLIST | CBS_OEMCONVERT | CBS_SORT | WS_VSCROLL | WS_TABSTOP - EDITTEXT IDC_EMUDIR,7,17,107,14,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_EMUDIRSEL,114,17,10,14 - PUSHBUTTON "V",IDC_UPDATE,124,17,10,14 + EDITTEXT IDC_EMUDIR,7,17,106,14,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_EMUDIRSEL,113,17,10,14 + PUSHBUTTON "V",IDC_UPDATE,123,17,10,14 LTEXT "Emu48 Directory :",IDC_STATIC,7,7,115,8 LTEXT "Current KML Script :",IDC_STATIC,7,37,115,8 END @@ -577,8 +581,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,2,0 - PRODUCTVERSION 1,4,2,0 + FILEVERSION 1,4,4,0 + PRODUCTVERSION 1,4,4,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -595,12 +599,12 @@ BEGIN BEGIN VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" - VALUE "FileVersion", "1, 4, 2, 0\0" + VALUE "FileVersion", "1, 4, 4, 0\0" VALUE "InternalName", "Emu48\0" - VALUE "LegalCopyright", "Copyright © 2006\0" + VALUE "LegalCopyright", "Copyright © 2007\0" VALUE "OriginalFilename", "Emu48.exe\0" VALUE "ProductName", "Emu48\0" - VALUE "ProductVersion", "1, 4, 2, 0\0" + VALUE "ProductVersion", "1, 4, 4, 0\0" END END BLOCK "VarFileInfo" @@ -839,7 +843,7 @@ END // Manifest // -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "Emu48.xml" +1 24 MOVEABLE PURE "Emu48.xml" #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/Sources/GCCPatch/Makefile b/Sources/GCCPatch/Makefile index 6f5fdbc..908aa2d 100644 --- a/Sources/GCCPatch/Makefile +++ b/Sources/GCCPatch/Makefile @@ -5,9 +5,8 @@ LD=gcc # This is to make GCC not bitch at things M$ allows -CFLAGS= -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized -O3 - -# Things we need around to compile successfully +CFLAGS= -Wall -Wno-missing-braces -Wno-format -Wno-uninitialized \ + -Wno-strict-aliasing -Wno-unused-function -O3 DEFINES= -DIDC_STATIC=-1 @@ -24,8 +23,8 @@ RSRCOBJ=$(PRJ).o OBJS=cursor.o disasm.o display.o debugger.o ddeserv.o \ emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \ - keymacro.o kml.o mops.o opcodes.o rpl.o serial.o settings.o stack.o \ - timer.o \ + keymacro.o kml.o lowbat.o mops.o opcodes.o rpl.o serial.o settings.o \ + stack.o timer.o \ $(RSRCOBJ) LIBS=-lwinmm -lcomctl32 @@ -92,6 +91,9 @@ keymacro.o: keymacro.c pch.h resource.h Emu48.h kml.h kml.o: kml.c pch.h resource.h emu48.h types.h kml.h $(CC) $(CFLAGS) $(DEFINES) -c -o kml.o kml.c +lowbat.o: lowbat.c pch.h Emu48.h io.h + $(CC) $(CFLAGS) $(DEFINES) -c -o lowbat.o lowbat.c + mops.o: mops.c pch.h emu48.h types.h opcodes.h io.h \ i28f160.h $(CC) $(CFLAGS) $(DEFINES) -c -o mops.o mops.c diff --git a/Sources/GCCPatch/PCH.H b/Sources/GCCPatch/PCH.H index 7a94210..c0ab333 100644 --- a/Sources/GCCPatch/PCH.H +++ b/Sources/GCCPatch/PCH.H @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -36,6 +37,10 @@ #define __min(a,b) (((a) < (b)) ? (a) : (b)) #endif +// normally defined in CONIO.H +int __cdecl _inp(unsigned short); +int __cdecl _outp(unsigned short, int); + // normally defined in missing CRTDBG.H #if !defined _ASSERT #define _ASSERT(a) diff --git a/Sources/GCCPatch/README.TXT b/Sources/GCCPatch/README.TXT index eace99f..6b68aa0 100644 --- a/Sources/GCCPatch/README.TXT +++ b/Sources/GCCPatch/README.TXT @@ -8,18 +8,6 @@ of the compiler and the necessary files is MinGW at www.mingw.org. Emu48 was tested with the following MinGW file versions: -MinGW-3.1.0-1.exe - -or - -MinGW-3.1.0-1.exe -w32api-2.5.tar.gz -mingw-runtime-3.3.tar.gz -binutils-2.15.90-20040222-1.tar.gz -gcc-core-3.4.1-20040711-1.tar.gz - -or - MinGW-3.1.0-1.exe w32api-3.3.tar.gz mingw-runtime-3.8.tar.gz @@ -34,6 +22,14 @@ mingw-runtime-3.9.tar.gz binutils-2.16.91-20060119-1.tar.gz gcc-core-3.4.5-20060117-1.tar.gz +or + +MinGW-3.1.0-1.exe +w32api-3.8.tar.gz +mingw-runtime-3.11.tar.gz +binutils-2.16.91-20060119-1.tar.gz +gcc-core-3.4.5-20060117-1.tar.gz + Older versions of the MinGW package might not work, because there are several bug fixes, especially in the header files, made in the last time. @@ -45,4 +41,4 @@ Many thanks to Pedro A. Arranda Guti compatible. -08/16/06 (c) by Christoph Gießelink +04/12/07 (c) by Christoph Gießelink diff --git a/Sources/MkShared/MKSHARED.C b/Sources/MkShared/MKSHARED.C index 9f9844e..9a7172f 100644 --- a/Sources/MkShared/MKSHARED.C +++ b/Sources/MkShared/MKSHARED.C @@ -21,6 +21,7 @@ #define WIN32_EXTRA_LEAN #include #include +#include #include #include "resource.h" @@ -72,25 +73,6 @@ static BOOL WriteCardFile(LPCTSTR strFilename,INT nBlocks) return TRUE; } -static HBRUSH OnCtlColorStatic(HDC hDC,HWND hWnd) -{ - if (GetDlgCtrlID(hWnd) == IDC_RESULT) - { - switch (eState) - { - case STATE_GOOD: - SetTextColor(hDC,(COLORREF) 0xFFFFFF); // white - SetBkMode(hDC,TRANSPARENT); - return hBrushGreen; - case STATE_FAIL: - SetTextColor(hDC,(COLORREF) 0xFFFFFF); // white - SetBkMode(hDC,TRANSPARENT); - return hBrushRed; - } - } - return NULL; // original color -} - static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { static WORD wSize; @@ -161,7 +143,21 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lPar } return 0; case WM_CTLCOLORSTATIC: - return (LRESULT) OnCtlColorStatic((HDC) wParam,(HWND) lParam); + if (GetDlgCtrlID((HWND) lParam) == IDC_RESULT) + { + switch (eState) + { + case STATE_GOOD: + SetTextColor((HDC) wParam,(COLORREF) 0xFFFFFF); // white + SetBkMode((HDC) wParam,TRANSPARENT); + return (LRESULT) hBrushGreen; + case STATE_FAIL: + SetTextColor((HDC) wParam,(COLORREF) 0xFFFFFF); // white + SetBkMode((HDC) wParam,TRANSPARENT); + return (LRESULT) hBrushRed; + } + } + break; // default handler for all other windows case WM_DESTROY: PostQuitMessage(0); return 0; @@ -178,6 +174,8 @@ INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpszCmdLine,INT nCmdSho // RECT rc; HFONT hFont; + InitCommonControls(); + // create background brushes hBrushGreen = CreateSolidBrush(0x008000); hBrushRed = CreateSolidBrush(0x0000FF); @@ -207,7 +205,10 @@ INT WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpszCmdLine,INT nCmdSho #endif // initialization - hFont = CreateFont(20,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET,OUT_DEVICE_PRECIS,CLIP_DEFAULT_PRECIS,PROOF_QUALITY,DEFAULT_PITCH|TMPF_TRUETYPE|FF_ROMAN,"Times New Roman"); + hFont = CreateFont(20,0,0,0,FW_NORMAL,0,0,0,ANSI_CHARSET, + OUT_DEVICE_PRECIS,CLIP_DEFAULT_PRECIS, + PROOF_QUALITY,DEFAULT_PITCH|TMPF_TRUETYPE|FF_ROMAN, + _T("Times New Roman")); _ASSERT(hFont); SendDlgItemMessage(hWnd,IDC_STATIC_TITLE,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); SendDlgItemMessage(hWnd,IDC_RESULT,WM_SETFONT,(WPARAM)hFont,MAKELPARAM(TRUE,0)); diff --git a/Sources/MkShared/MKSHARED.RC b/Sources/MkShared/MKSHARED.RC index fb02357..79d01a5 100644 --- a/Sources/MkShared/MKSHARED.RC +++ b/Sources/MkShared/MKSHARED.RC @@ -15,11 +15,11 @@ #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// -// German (Germany) resources +// English (U.S.) resources -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) #ifdef _WIN32 -LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US #pragma code_page(1252) #endif //_WIN32 @@ -121,7 +121,16 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_MKSHARED ICON DISCARDABLE "MKSHARED.ICO" +IDI_MKSHARED ICON DISCARDABLE "MkShared.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// 24 +// + +1 24 MOVEABLE PURE "MkShared.xml" + #ifndef _MAC ///////////////////////////////////////////////////////////////////////////// @@ -130,8 +139,8 @@ IDI_MKSHARED ICON DISCARDABLE "MKSHARED.ICO" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,4,0,0 - PRODUCTVERSION 1,4,0,0 + FILEVERSION 1,5,0,0 + PRODUCTVERSION 1,5,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -148,12 +157,12 @@ BEGIN BEGIN VALUE "CompanyName", "Christoph Gießelink\0" VALUE "FileDescription", "HP48 RAM Card Creator for Emu48\0" - VALUE "FileVersion", "1, 4, 0, 0\0" + VALUE "FileVersion", "1, 5, 0, 0\0" VALUE "InternalName", "MkShared\0" VALUE "LegalCopyright", "Copyright © 2006\0" VALUE "OriginalFilename", "MkShared.exe\0" VALUE "ProductName", "MkShared\0" - VALUE "ProductVersion", "1, 4, 0, 0\0" + VALUE "ProductVersion", "1, 5, 0, 0\0" END END BLOCK "VarFileInfo" @@ -164,7 +173,7 @@ END #endif // !_MAC -#endif // German (Germany) resources +#endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/Sources/MkShared/MKSHARED.XML b/Sources/MkShared/MKSHARED.XML new file mode 100644 index 0000000..fac6375 --- /dev/null +++ b/Sources/MkShared/MKSHARED.XML @@ -0,0 +1,22 @@ + + + +MkShared + + + + + + diff --git a/uninst.exe b/uninst.exe index 1d672e0..0bae7a5 100755 Binary files a/uninst.exe and b/uninst.exe differ