2012-09-15: Updated to version 1.53

Signed-off-by: Gwenhael Le Moine <gwenhael.le.moine@gmail.com>
This commit is contained in:
Gwenhael Le Moine 2024-03-19 23:35:30 +01:00
parent b1d252bee0
commit 27520054a1
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
45 changed files with 2792 additions and 1156 deletions

View file

@ -301,9 +301,17 @@ CE1 | nc. | BS | Slt1 32/128KB | BS | BS
CE2 | nc. | nc. | Slt2 32/128KB | Slt1 32/128KB | RAM 128KB CE2 | nc. | nc. | Slt2 32/128KB | Slt1 32/128KB | RAM 128KB
NCE3 | nc. | RAM 128KB | nc. | Slt2 32KB-4MB | RAM 128KB NCE3 | nc. | RAM 128KB | nc. | Slt2 32KB-4MB | RAM 128KB
- Load Memory Data...
The "Load Memory Data" dialog box allows loading memory dump files to the specified address inside the Saturn address area. The specified address must point to RAM, writing into ROM areas isn't possible. The memory dump file must be in packed data format, meaning each byte in file contain two Saturn data nibbles with the low nibble containing the even and the high nibble the following odd address. The disadvantage of packed files is that you cannot load memory files with an odd number of data nibbles, but the advantage is that you can directly load an assembler output to memory.
- Save Memory Data...
The "Save Memory Data" dialog box allows saving the data of the specified Saturn address area into a memory dump file. The memory dump file contain the data in packed data format, meaning each byte in file contain two Saturn data nibbles with the low nibble containing the even and the high nibble the following odd address.
- RPL Object Viewer... - RPL Object Viewer...
This opens a small toolbox window showing the decompiled RPL object at the memory address marked by the cursor. If the toolbox window is already open the content will be updated. There's a problem if you want to select an address inside the marked two addresses. The easiest way to switch the address is the use of the + and - keys changing the memory position by one nibble under the cursor. This opens a small toolbox window showing the decompiled RPL object in the selected memory map mode at the memory address marked by the cursor. If the toolbox window is already open the content will be updated. There's a problem if you want to select an address inside the marked two addresses. The easiest way to switch the address is the use of the + and - keys changing the memory position by one nibble under the cursor.
9.) Stack window 9.) Stack window
@ -346,4 +354,4 @@ The Miscellaneous window show you the internal state of the interrupt flag, the
You can change the values by pressing the left mouse button over the old content. You can change the values by pressing the left mouse button over the old content.
04/04/09 (c) by Christoph Gießelink 05/02/12 (c) by Christoph Gießelink

BIN
EMU48.EXE

Binary file not shown.

BIN
Emu48.exe Executable file

Binary file not shown.

View file

@ -1,12 +1,12 @@
{\rtf1\ansi\ansicpg1252\deff0\deflang1031\deflangfe1031{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2\fswiss\fprq2\fcharset0 Arial;}} {\rtf1\ansi\ansicpg1252\deff0\deflang1031\deflangfe1031{\fonttbl{\f0\froman\fprq2\fcharset0 Times New Roman;}{\f1\fmodern\fprq1\fcharset0 Courier New;}{\f2\fswiss\fprq2\fcharset0 Arial;}{\f3\froman\fprq2\fcharset2 Symbol;}}
{\colortbl ;\red0\green0\blue0;\red0\green0\blue255;} {\colortbl ;\red0\green0\blue0;\red0\green0\blue255;}
{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\nowidctlpar\qc\lang1033\f0\fs56 EmuXY and KML 2.0\par {\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\nowidctlpar\qc\lang1033\f0\fs56 EmuXY and KML 2.0\par
\pard\nowidctlpar\fs24\par \pard\nowidctlpar\fs24\par
\b\fs28 Introduction\b0\par \b\fs28 Introduction\b0\par
\fs24\par \fs24\par
\pard\nowidctlpar\qj\tab This document explains in detail the KML 2.0 scripting files. KML, Keyboard Mapping Language, started of as a script that Emu48 used to map keyboard buttons with buttons of the emulator, now it has become much more. KML 2.0, also used by Emu10, Emu28 and Emu42, now makes it possible to change many advanced options of the way the emulator looks.\par \pard\nowidctlpar\qj\tab This document explains in detail the KML 2.0 scripting files. KML, Keyboard Mapping Language, started as a script that Emu48 used to map keyboard buttons with buttons of the emulator, now it has become much more. KML 2.0, also used by Emu10, Emu28, Emu42 and Emu71, now makes it possible to change many advanced options of the way the emulator looks.\par
\par \par
The description of Emu32 has been removed from this document. The development of Emu32 was quit, the emulated calculators are now emulated by Emu42. So Emu42 now emulates two quite different hardware platforms, the High End Pioneer and Clamshell series with a dot matrix display which base on the Lewis chip and the Mid Range Pioneer series with a semi dot matrix display which base on the Sacajawea chip. To distinguish both emulation platforms I use, if necessary, Emu42 (Lewis) and Emu42 (Sacajawea) in the further text.\par The description of Emu32 has been removed from this document. The development of Emu32 has quit, the emulated calculators are now emulated by Emu42. So Emu42 now emulates two quite different hardware platforms, the High End Pioneer and Clamshell series with a dot matrix display which base on the Lewis chip and the Mid Range Pioneer series with a semi dot matrix display which base on the Sacajawea chip. To distinguish both emulation platforms I use, if necessary, Emu42 (Lewis) and Emu42 (Sacajawea) in the further text.\par
\pard\nowidctlpar\par \pard\nowidctlpar\par
\b\fs40 Index\fs28\par \b\fs40 Index\fs28\par
\b0\fs24\par \b0\fs24\par
@ -18,8 +18,8 @@ Digit\tab Page 9\par
\lang1040 Annunciator\tab Page 10\par \lang1040 Annunciator\tab Page 10\par
Button\tab Page 11\par Button\tab Page 11\par
\lang1036 OutIn Codes\tab Page 13\par \lang1036 OutIn Codes\tab Page 13\par
Scancode\tab Page 21\par Scancode\tab Page 22\par
Conclusion\b\fs28\tab\b0\fs24 Page 24\par Conclusion\b\fs28\tab\b0\fs24 Page 25\par
\pard\nowidctlpar\b\fs28\par \pard\nowidctlpar\b\fs28\par
\lang1033 Basics\b0\par \lang1033 Basics\b0\par
\fs24\par \fs24\par
@ -54,13 +54,15 @@ End\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj Hardware is the emulated calculator hardware. This definition is optional on Emu48. The parameter is necessary to separate the KML scripts from each emulator. Valid entries are\par \pard\nowidctlpar\qj Hardware is the emulated calculator hardware. This definition is optional on Emu48. The parameter is necessary to separate the KML scripts from each emulator. Valid entries are\par
\pard\nowidctlpar Emu10:\par \pard\nowidctlpar Emu10:\par
\f1\fs16\tab\lang1031 Hardware \ldblquote Bert\rdblquote\par \f1\fs16\tab Hardware \ldblquote Bert\rdblquote\par
\f0\fs24 Emu28:\par \f0\fs24 Emu28:\par
\f1\fs16\tab\lang1033 Hardware \ldblquote Centipede\rdblquote\par \f1\fs16\tab Hardware \ldblquote Centipede\rdblquote\par
\f0\fs24 Emu42:\par \f0\fs24 Emu42:\par
\f1\fs16\tab Hardware \ldblquote Lewis\rdblquote\par \f1\fs16\tab Hardware \ldblquote Lewis\rdblquote\par
\f0\fs24 Emu48:\par \f0\fs24 Emu48:\par
\f1\fs16\tab Hardware \ldblquote Yorke\rdblquote\par \f1\fs16\tab Hardware \ldblquote Yorke\rdblquote\par
\f0\fs24 Emu71:\par
\f1\fs16\tab Hardware \ldblquote Saturn\rdblquote\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj\page Model is the model of your emulated calculator inside the hardware family. The model entries differ from hardware to hardware. This setting groups KML files of the same hardware and ROM together.\cf1 When switching between KML scripts, it is the first character of the parameter that is checked against the type of the current document (which was set by the Model command in the KML file with which the document was created). Valid entries are:\par \pard\nowidctlpar\qj\page Model is the model of your emulated calculator inside the hardware family. The model entries differ from hardware to hardware. This setting groups KML files of the same hardware and ROM together.\cf1 When switching between KML scripts, it is the first character of the parameter that is checked against the type of the current document (which was set by the Model command in the KML file with which the document was created). Valid entries are:\par
Emu10:\par Emu10:\par
@ -85,8 +87,10 @@ Emu10:\par
\ldblquote G\rdblquote = HP48G, HP48G+ or HP48GX\par \ldblquote G\rdblquote = HP48G, HP48G+ or HP48GX\par
\ldblquote S\rdblquote = HP48S or HP48SX\par \ldblquote S\rdblquote = HP48S or HP48SX\par
\ldblquote X\rdblquote = HP49G\cf1\par \ldblquote X\rdblquote = HP49G\cf1\par
\pard\nowidctlpar\qj\cf0 Example:\par \pard\nowidctlpar\qj Emu71:\par
\pard\nowidctlpar\f1\fs16\tab Model \ldblquote G\rdblquote\par \pard\nowidctlpar\fi720\qj\cf0\lang1036\ldblquote T\rdblquote = HP71B\par
\pard\nowidctlpar\qj Example:\par
\pard\nowidctlpar\f1\fs16\tab\lang1033 Model \ldblquote G\rdblquote\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj Class is used for different calculators base on the same ROM for further distinction. For other models than listed below this argument can be omitted. \cf1 Valid entries are:\par \pard\nowidctlpar\qj Class is used for different calculators base on the same ROM for further distinction. For other models than listed below this argument can be omitted. \cf1 Valid entries are:\par
Emu42:\par Emu42:\par
@ -159,13 +163,13 @@ End\par
\lang1031\f1\fs16 Lcd\par \lang1031\f1\fs16 Lcd\par
\tab Zoom INTEGER\par \tab Zoom INTEGER\par
\tab Zoomxy INTEGER INTEGER\par \tab Zoomxy INTEGER INTEGER\par
\tab Vertical INTEGER\par \tab\lang1033 Vertical INTEGER\par
\tab Offset INTEGER INTEGER\par \tab Offset INTEGER INTEGER\par
\tab Color INTEGER INTEGER INTEGER INTEGER\par \tab Color INTEGER INTEGER INTEGER INTEGER\par
\lang1033 End\par End\par
\f0\fs24\par \f0\fs24\par
\par \par
\pard\nowidctlpar\qj Zoom is the size of the pixels in the LCD screen. This command is only valid for Emu28, Emu42 (Lewis) and Emu48 and will be ignored on Emu10 and Emu42 (Sacajawea). Valid entries are 1, 2, 3 or 4. Zoom factor two is usually used by the dot matrix LCD types emulated by Emu28, Emu42 (Lewis) and Emu48.\par \pard\nowidctlpar\qj Zoom is the size of the pixels in the LCD screen. This command is only valid for Emu28, Emu42 (Lewis) Emu48 and Emu71 and will be ignored on Emu10 and Emu42 (Sacajawea). Valid entries are 1, 2, 3 or 4. Zoom factor two is usually used by the dot matrix LCD types emulated by Emu28, Emu42 (Lewis), Emu48 and Emu71.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\f1\fs16\tab Zoom 2\par \f1\fs16\tab Zoom 2\par
\f0\fs24\par \f0\fs24\par
@ -177,19 +181,22 @@ Example:\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\f1\fs16\tab Offset 20 20\par \f1\fs16\tab Offset 20 20\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj Color sets the color of the LCD display for different contrast settings. The first Integer is the contrast setting for each possible value. The number of settings depend on the hardware type.\par \pard\nowidctlpar\qj Color sets the color of the LCD display for different contrast settings. The first Integer is the contrast setting value. The number of setting values depends on the hardware type.\par
\par
Emu10:\par Emu10:\par
\pard\nowidctlpar\fi720\qj 0-7 = 0 is lightest, 7 is darkest\par \pard\nowidctlpar\fi720\qj 0-7 = 0 is lightest, 7 is darkest\par
\pard\nowidctlpar\qj Emu42 (Sacajawea):\par \pard\nowidctlpar\qj Emu42 (Sacajawea), Emu71:\par
\pard\nowidctlpar\fi720\qj 0-15 = foreground colors (Pixel on), 0 is lightest, 15 is darkest\par \pard\nowidctlpar\fi720\qj 0-15 = foreground colors (Pixel on), 0 is lightest, 15 is darkest\par
16-31 = background colors (Pixel off), 16 corresponds to 0, 17 to 1, \'85\par 16-31 = background colors (Pixel off), 16 corresponds to 0, 17 to 1, \'85\par
unused number at background colors = transparent\par \pard\nowidctlpar\qj Emu28, Emu42 (Lewis):\par
\pard\nowidctlpar\qj Emu28, Emu42 (Lewis), Emu48:\par
\pard\nowidctlpar\fi720\qj 0-31 = foreground colors (Pixel on), 0 is lightest, 15 is darkest\par \pard\nowidctlpar\fi720\qj 0-31 = foreground colors (Pixel on), 0 is lightest, 15 is darkest\par
32-63 = background colors (Pixel off), 32 corresponds to 0, 33 to 1, \'85\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 Emu48:\par
\pard\nowidctlpar\fi720\qj 0-31 = foreground colors (Pixel on), 0 is lightest, 15 is darkest\par
32-63 = background colors (Pixel off), 32 corresponds to 0, 33 to 1, \'85\par
unused value at background color = use color defined by setting 0\par
\pard\nowidctlpar\qj\par \pard\nowidctlpar\qj\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 (Lewis) and Emu48 and transparent mode by Emu10 and Emu42 (Sacajawea).\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. At Emu42 for Pocket PC and Emu48 an undefined foreground color value 0 mean \ldblquote white\rdblquote else \ldblquote black\rdblquote , an undefined background color means using foreground color 0. At Emu10, Emu28, Emu42 (Sacajawea), Emu42 (Lewis) and Emu71 undefined contrast settings mean transparent mode showing the background image.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\f1\fs16\tab Color 0 255 255 255\par \f1\fs16\tab Color 0 255 255 255\par
\tab Color 1 220 220 220\par \tab Color 1 220 220 220\par
@ -198,7 +205,7 @@ You should include one line for every foreground color setting. The other three
\tab Color 31 0 0 0\par \tab Color 31 0 0 0\par
\tab Color 32 255 255 255\tab # optional background color for contrast setting\par \tab Color 32 255 255 255\tab # optional background color for contrast setting\par
\pard\nowidctlpar\qj\f0\fs24\par \pard\nowidctlpar\qj\f0\fs24\par
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 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 \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 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 \par
@ -223,13 +230,14 @@ The contrast settings outside these areas (accessible by hardware so it\rquote s
\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\nowidctlpar HP42S\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3 \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\nowidctlpar HP42S\cell Emu42\cell 0-31\cell 22\cell 15\cell 31\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
\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\nowidctlpar HP48SX\cell Emu48\cell 0-31\cell 11\cell 3\cell 19\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3 \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\nowidctlpar HP48SX\cell Emu48\cell 0-31\cell 11\cell 3\cell 19\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
\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\nowidctlpar HP48GX\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3 \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\nowidctlpar HP48GX\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx5812\pard\intbl\nowidctlpar HP49G\cell Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row\pard\nowidctlpar\qj\par \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\nowidctlpar HP49G\cell\lang1031 Emu48\cell 0-31\cell 14\cell 9\cell 24\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx5812\pard\intbl\nowidctlpar HP71B\cell Emu71\cell\lang1033 0-15\cell 9\cell 0\cell 15\cell\row\pard\nowidctlpar\qj\par
Range\tab : hardware range (accessible by assembler)\par Range\tab : hardware range (accessible by assembler)\par
Reset\tab : contrast value after calculator reset\par Reset\tab : contrast value after calculator reset\par
Min\tab : min. adjustable contrast value by keyboard\par Min\tab : min. adjustable contrast value by keyboard\par
Max\tab : max. adjustable contrast value by keyboard\par Max\tab : max. adjustable contrast value by keyboard\par
\par \par
\pard\nowidctlpar On Emu28 and Emu42 (Lewis) 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 \pard\nowidctlpar On Emu28 and Emu42 (Lewis) the contrast setting of the annunciators depends 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 \par
\pard\nowidctlpar\qj Vertical is a special command only for the Pocket PC versions of Emu42 (Lewis) 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\qj Vertical is a special command only for the Pocket PC versions of Emu42 (Lewis) 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 \pard\nowidctlpar Example:\par
@ -237,12 +245,12 @@ Max\tab : max. adjustable contrast value by keyboard\par
\f0\fs24\par \f0\fs24\par
\page\b\fs28 Digit\par \page\b\fs28 Digit\par
\fs24\par \fs24\par
\pard\nowidctlpar\qj\b0\tab This section is only valid for Emu10 and Emu42 (Sacajawea) and describes the (alpha-) numeric part of the LCD screen. Emu10 and Emu42 (Sacajawea) use different methods for creating a numeric value.\b\par \pard\nowidctlpar\qj\b0\tab This section is only valid for Emu10 and Emu42 (Sacajawea) and describes the (alpha-) numeric part of the LCD screen. Emu10 and Emu42 (Sacajawea) are using different methods for creating a numeric value.\b\par
\pard\nowidctlpar\b0\par \pard\nowidctlpar\b0\par
\lang1031\f1\fs16 Digit\par \lang1031\f1\fs16 Digit\par
\tab Offset INTEGER INTEGER\par \tab Offset INTEGER INTEGER\par
\tab\lang1033 Size INTEGER INTEGER\par \tab Size INTEGER INTEGER\par
\tab Distance INTEGER\par \tab\lang1033 Distance INTEGER\par
\tab Bitmap STRING\par \tab Bitmap STRING\par
End\par End\par
\f0\fs24\par \f0\fs24\par
@ -260,7 +268,7 @@ The commands Offset and Size are unused.\par
\f1\fs16\tab Bitmap \ldblquote mylcd.bmp\rdblquote\par \f1\fs16\tab Bitmap \ldblquote mylcd.bmp\rdblquote\par
\f0\fs24\par \f0\fs24\par
Emu42 (Sacajawea):\par Emu42 (Sacajawea):\par
The mid range Pioneer series use a 5x7 pixel dot matrix for each digit.\par The Mid Range Pioneer series use a 5x7 pixel dot matrix for each digit.\par
\par \par
Size is the size of one pixel in the LCD screen. Width Height.\par Size is the size of one pixel in the LCD screen. Width Height.\par
Example:\par Example:\par
@ -280,17 +288,17 @@ Example:\par
\f0\fs24\par \f0\fs24\par
\b\fs28\page Annunciator\par \b\fs28\page Annunciator\par
\b0\fs24\par \b0\fs24\par
\pard\nowidctlpar\qj\tab Annunciators are the 23 (Emu10), 60 (Emu42 (Sacajawea)), six (Emu48) and seven (Emu28, Emu42 (Lewis)) status icons on the screen. You must specify one of these blocks for each annunciator.\par \pard\nowidctlpar\qj\tab Annunciators are the 23 (Emu10), 60 (Emu42 (Sacajawea)), six (Emu48), seven (Emu28, Emu42 (Lewis)) and 32 (Emu71) status icons on the screen. You must specify one of these blocks for each annunciator.\par
\pard\nowidctlpar\par \pard\nowidctlpar\par
\par \par
\lang1031\f1\fs16 Annunciator INTEGER\par \f1\fs16 Annunciator INTEGER\par
\tab Size INTEGER INTEGER\par \tab Size INTEGER INTEGER\par
\tab Offset INTEGER INTEGER\par \tab Offset INTEGER INTEGER\par
\tab\lang1033 Down INTEGER INTEGER\par \tab Down INTEGER INTEGER\par
End\par End\par
\f0\fs24\par \f0\fs24\par
\par \par
\pard\nowidctlpar\qj Annunciator tells which annunciator you are setting. Valid entries are emulator depending and can vary from 1 through 6, 7, 23 or 60. The annunciator symbol itself depends on the specific LCD of the calculator. Refer to existing KML scripts for getting the symbol of each annunciator.\par \pard\nowidctlpar\qj Annunciator tells which annunciator you are setting. Valid entries are emulator depending and can vary from 1 through 6, 7, 23, 32 or 60. The annunciator symbol itself depends on the specific LCD of the calculator. Refer to existing KML scripts for getting the symbol of each annunciator.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\pard\nowidctlpar\fi720\f1\fs16 Annunciator 1\par \pard\nowidctlpar\fi720\f1\fs16 Annunciator 1\par
\pard\nowidctlpar\f0\fs24\par \pard\nowidctlpar\f0\fs24\par
@ -302,7 +310,7 @@ Offset is the position that the annunciator will be displayed. This is the blank
Example:\par Example:\par
\f1\fs16\tab Offset 61 4\par \f1\fs16\tab Offset 61 4\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj Down is the position of the annunciator in the bitmap when it is on. There are some restrictions on the different emulators. On Emu10 and Emu42 (Sacajawea) the annunciators must be drawn in black on a white background. On Emu28 and Emu42 (Lewis) the pixel at the Down position must contain the background color, this is necessary for masking operation. Emu48 don\rquote t mask the background color, here the annunciator must have the background color of the target area.\par \pard\nowidctlpar\qj Down is the position of the annunciator in the bitmap when it is on. There are some restrictions on the different emulators. On Emu10 and Emu42 (Sacajawea) the annunciators must draw in black on a white background. On Emu28 and Emu42 (Lewis) and Emu71 the pixel at the Down position must contain the background color, this is necessary for masking operation. Emu48 don\rquote t mask the background color, here the annunciator must have the background color of the target area.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\f1\fs16\tab Down 16 485\par \f1\fs16\tab Down 16 485\par
\f0\fs24\par \f0\fs24\par
@ -310,11 +318,11 @@ Example:\par
\b0\fs24\par \b0\fs24\par
\tab Button sets the position of the button and what the button does.\par \tab Button sets the position of the button and what the button does.\par
\par \par
\lang1031\f1\fs16 Button INTEGER\par \f1\fs16 Button INTEGER\par
\tab Type INTEGER\par \tab Type INTEGER\par
\tab Size INTEGER INTEGER\par \tab Size INTEGER INTEGER\par
\tab Offset INTEGER INTEGER\par \tab Offset INTEGER INTEGER\par
\tab\lang1033 Down INTEGER INTEGER\par \tab Down INTEGER INTEGER\par
\tab OutIn INTEGER INTEGER\par \tab OutIn INTEGER INTEGER\par
\tab Virtual\par \tab Virtual\par
\tab NoHold\par \tab NoHold\par
@ -327,8 +335,8 @@ Example:\par
End\par End\par
\f0\fs24\par \f0\fs24\par
\par \par
\pard\nowidctlpar\qj Button tells the number of the button you are creating. This can be any number. Most of the time this \cf1 is set to a number that represents the row and column of the button. Any number can be used, but only 256 buttons can be declared. If more buttons are declared, only the first 256 will be used, and the others will be ignored.\par \pard\nowidctlpar\qj Button tells the number of the button you are creating. This can be any number. Most times the number is chosen representing \cf1 the row and column number of the button.\cf0 \cf1 Any number can be used, but only 256 buttons can be declared. If more buttons are declared, only the first 256 will be used, and the others will be ignored.\cf0\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar\cf1 Example:\par
\cf0\f1\fs16\tab Button 11\par \cf0\f1\fs16\tab Button 11\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj\cf1 Type tells how the button will behave when it is pressed. Valid entries are 0, 1, 2, 3, 4, or 5.\par \pard\nowidctlpar\qj\cf1 Type tells how the button will behave when it is pressed. Valid entries are 0, 1, 2, 3, 4, or 5.\par
@ -345,7 +353,7 @@ Type 4 is copying a part of the background bitmap with the dimension Size from t
\par \par
Type 5 is drawing a transparent circle inside the rectangle given by Size into the middle of the button area given by target position Offset and the dimension Size.\par Type 5 is drawing a transparent circle inside the rectangle given by Size into the middle of the button area given by target position Offset and the dimension Size.\par
\par \par
All other Type values are drawing a black rectangle with the dimension Size at the target position Offset. Remember that this behavior can change on introducing a new type. So don\rquote t use this type in public scripts.\par \page All other Type values are drawing a black rectangle with the dimension Size at the target position Offset. Remember that this behavior can change on introducing a new type. So don\rquote t use this type in public scripts.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\cf0\f1\fs16\tab Type 0\par \cf0\f1\fs16\tab Type 0\par
\f0\fs24\par \f0\fs24\par
@ -361,7 +369,7 @@ Example:\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\f1\fs16\tab Down 302 25\par \f1\fs16\tab Down 302 25\par
\f0\fs24\par \f0\fs24\par
\pard\nowidctlpar\qj OutIn tells the emulator which button is being pressed. A table of OutIn codes are on the next page of this document.\par \pard\nowidctlpar\qj OutIn tells the emulator which button is being pressed. Tables of OutIn codes are on the next pages of this document.\par
\pard\nowidctlpar Example:\par \pard\nowidctlpar Example:\par
\pard\nowidctlpar\qj\f1\fs16\tab OutIn 1 16\par \pard\nowidctlpar\qj\f1\fs16\tab OutIn 1 16\par
\f0\fs24\par \f0\fs24\par
@ -680,8 +688,32 @@ Example:\par
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 7 4\cell 3 4\cell 2 4\cell 1 4\cell 0 4\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3 \clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 7 4\cell 3 4\cell 2 4\cell 1 4\cell 0 4\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 /-.>\cell 1\cell 2\cell 3\cell +\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3 \clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 /-.>\cell 1\cell 2\cell 3\cell +\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 7 2\cell 3 2\cell 2 2\cell 1 2\cell 0 2\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3 \clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 7 2\cell 3 2\cell 2 2\cell 1 2\cell 0 2\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 ON\cell 0\cell .\cell SPC\cell ENTER\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3 \clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 ON\cell\lang1036 0\cell .\cell SPC\cell ENTER\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 0 32768\cell 3 1\cell 2 1\cell 1 1\cell 0 1\cell\row\pard\nowidctlpar\cf0\b\f0\fs28\page Scancode\b0\fs24\par \clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1179\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2389\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3598\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4808\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 0 32768\cell 3 1\cell 2 1\cell 1 1\cell 0 1\cell\row\pard\nowidctlpar\cf0\f0\fs24\par
\pard\nowidctlpar\qj\b\fs28 OutIn Codes HP71B\par
\pard\nowidctlpar\b0\fs24\par
\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx849\cellx1698\cellx2549\cellx3399\cellx4250\cellx5100\cellx5951\cellx6801\cellx7653\cellx8505\pard\intbl\nowidctlpar\cf2\lang1033\b\f2 Key\cell\b0\cell\cell\cell\cell\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx849\cellx1698\cellx2549\cellx3399\cellx4250\cellx5100\cellx5951\cellx6801\cellx7653\cellx8505\pard\intbl\nowidctlpar\cf1\b\fs20 OutIn\cell\b0\cell\cell\cell\cell\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\cellx849\cellx1698\cellx2549\cellx3399\cellx4250\cellx5100\cellx5951\cellx6801\cellx7653\cellx8505\pard\intbl\nowidctlpar\b\fs16\cell\b0\cell\cell\cell\cell\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf2\b\fs24 Q\cell\lang1040 W\cell E\cell R\cell\lang1036 T\cell Y\cell U\cell\lang1040 I\cell O\cell P\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf1\lang1033\b0\fs20 3 1\cell 3 2\cell 3 4\cell 3 8\cell 3 16\cell 3 32\cell 3 64\cell 3 128\cell 3 256\cell 3 512\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf2\b\fs24 A\cell S\cell D\cell F\cell G\cell H\cell\lang1031 J\cell K\cell L\cell =\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf1\b0\fs20 2 1\cell 2 2\cell 2 4\cell 2 8\cell 2 16\cell 2 32\cell 2 64\cell 2 128\cell 2 256\cell 2 512\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf2\b\fs24 Z\cell X\cell C\cell\lang1033 V\cell B\cell N\cell M\cell (\cell )\cell END\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf1\b0\fs20 1 1\cell 1 2\cell 1 4\cell 1 8\cell 1 16\cell 1 32\cell 1 64\cell 1 128\cell 1 256\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf2\b\fs24 ON\cell F\cell G\cell RUN\cell <\cell >\cell SPC\cell\f3\'d9\f2\cell\f3\'da\f2\cell LINE\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx849\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1698\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2549\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3399\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4250\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5100\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5951\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6801\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx7653\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx8505\pard\intbl\nowidctlpar\cf1\b0\fs20 0 32769\cell 0 2\cell 0 4\cell 0 8\cell 0 16\cell 0 32\cell 0 64\cell 0 128\cell 0 256\cell 1 512\cell\row\pard\nowidctlpar\cf0\b\f0\fs28\par
\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf2\f2\fs24 7\cell 8\cell 9\cell /\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf1\b0\fs20 3 1024\cell 3 2048\cell 3 4096\cell 3 8192\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf2\b\fs24 4\cell 5\cell 6\cell *\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf1\b0\fs20 2 1024\cell 2 2048\cell 2 4096\cell 2 8192\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf2\b\fs24 1\cell 2\cell 3\cell -\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf1\b0\fs20 1 1024\cell 1 2048\cell 1 4096\cell 1 8192\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf2\b\fs24 0\cell .\cell ,\cell +\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx851\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1701\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2552\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx3402\pard\intbl\nowidctlpar\cf1\b0\fs20 0 1024\cell 0 2048\cell 0 4096\cell 0 8192\cell\row\pard\nowidctlpar\cf0\b\f0\fs28\par
\page Scancode\b0\fs24\par
\par \par
\pard\nowidctlpar\qj\tab The Scancode defines what the emulator will do when a certain key on the keyboard is pressed. Pressing a key that has no scancode defined will (only if debug mode is on) display a message box with the key's scancode number, so that you can write a Scancode block. The commands in the Scancode block are executed twice, first when the key is pressed and a second time when the key is released. Flags can help to transfer information (for example can be set to show that a shift key is pressed) from one Scancode block to another. Valid flags are 0-31.\par \pard\nowidctlpar\qj\tab The Scancode defines what the emulator will do when a certain key on the keyboard is pressed. Pressing a key that has no scancode defined will (only if debug mode is on) display a message box with the key's scancode number, so that you can write a Scancode block. The commands in the Scancode block are executed twice, first when the key is pressed and a second time when the key is released. Flags can help to transfer information (for example can be set to show that a shift key is pressed) from one Scancode block to another. Valid flags are 0-31.\par
\pard\nowidctlpar\par \pard\nowidctlpar\par
@ -703,16 +735,16 @@ or\par
\tab\tab <COMMANDS>\par \tab\tab <COMMANDS>\par
\tab End\par \tab End\par
Or\par Or\par
\tab\lang1031 IfMem INTEGER INTEGER INTEGER\par \tab IfMem INTEGER INTEGER INTEGER\par
\tab\tab\lang1033 <COMMANDS>\par \tab\tab <COMMANDS>\par
\tab Else\par \tab Else\par
\tab\tab <COMMANDS>\par \tab\tab <COMMANDS>\par
\tab End\par \tab End\par
or\par or\par
\tab\lang1031 SetFlag INTEGER\par \tab SetFlag INTEGER\par
or\par or\par
\tab ResetFlag INTEGER\par \tab ResetFlag INTEGER\par
\lang1033 or\par or\par
\tab NotFlag INTEGER\par \tab NotFlag INTEGER\par
or\par or\par
\tab IfFlag INTEGER\par \tab IfFlag INTEGER\par
@ -772,31 +804,32 @@ Example:\par
\par \par
\page MenuItem will open a menu (only if it\rquote s supported). The following values are accepted:\par \page MenuItem will open a menu (only if it\rquote s supported). The following values are accepted:\par
\par \par
\pard\nowidctlpar\fi720\cf1\f1\fs16 FILE_NEW 1\par \pard\nowidctlpar\fi720\cf1\f1\fs16 FILE_NEW 1\par
FILE_OPEN 2\par FILE_OPEN 2\par
FILE_SAVE 3\par FILE_SAVE 3\par
FILE_SAVEAS 4\par FILE_SAVEAS 4\par
FILE_EXIT 5\par FILE_EXIT 5\par
EDIT_COPY_SCREEN 6\par EDIT_COPY_SCREEN 6\par
FILE_SETTINGS 7\par FILE_SETTINGS 7\par
EDIT_RESET 8\par EDIT_RESET 8\par
EDIT_LOAD_OBJECT 9\par EDIT_LOAD_OBJECT 9\par
EDIT_SAVE_OBJECT 10\par EDIT_SAVE_OBJECT 10\par
HELP_ABOUT 11\par HELP_ABOUT 11\par
HELP_TOPICS 12\par HELP_TOPICS 12\par
FILE_CLOSE 13\par FILE_CLOSE 13\par
EDIT_BACKUP_SAVE 14\par EDIT_BACKUP_SAVE 14\par
EDIT_BACKUP_RESTORE 15\par EDIT_BACKUP_RESTORE 15\par
EDIT_BACKUP_DELETE 16\par EDIT_BACKUP_DELETE 16\par
VIEW_SCRIPT 17\par VIEW_SCRIPT 17\par
EDIT_COPY_STRING 19\par EDIT_PORT_CONFIGURATION 18\par
EDIT_PASTE_STRING 20\par EDIT_COPY_STRING 19\par
TOOL_DISASM 21\par EDIT_PASTE_STRING 20\par
TOOL_DEBUG 22\par TOOL_DISASM 21\par
TOOL_MACRO_RECORD 23\par TOOL_DEBUG 22\par
TOOL_MACRO_PLAY 24\par TOOL_MACRO_RECORD 23\par
TOOL_MACRO_STOP 25\par TOOL_MACRO_PLAY 24\par
TOOL_MACRO_SETTINGS 26\par TOOL_MACRO_STOP 25\par
TOOL_MACRO_SETTINGS 26\par
\pard\nowidctlpar\f0\fs24\par \pard\nowidctlpar\f0\fs24\par
\cf0\b\fs28\page Conclusion\par \cf0\b\fs28\page Conclusion\par
\b0\fs24\par \b0\fs24\par
@ -814,6 +847,6 @@ The latest updates are available at:\par
http://hp.giesselink.com/\par http://hp.giesselink.com/\par
\pard\nowidctlpar\par \pard\nowidctlpar\par
\par \par
Release 14: September 9th, 2009\par Release 16: May 18th, 2012\par
} }

View file

@ -1,4 +1,4 @@
Known bugs and restrictions of Emu48 V1.50 Known bugs and restrictions of Emu48 V1.53
------------------------------------------ ------------------------------------------
- the following I/O bits aren't emulated (incomplete) - the following I/O bits aren't emulated (incomplete)
@ -12,8 +12,7 @@ Known bugs and restrictions of Emu48 V1.50
SRQ1 (0x118) [ISQR] SRQ1 (0x118) [ISQR]
SRQ2 (0x119) [LSRQ] SRQ2 (0x119) [LSRQ]
IRC (0x11A) [IRI EIRU EIRI IRE] IRC (0x11A) [IRI EIRU EIRI IRE]
LCR (0x11C) [LED ELBE LBZ LBF] LCR (0x11C) [LBZ LBF]
LBR (0x11D) [LBO]
- the baudrates 1920, 3840, 7680 and 15360 aren't emulated on most - the baudrates 1920, 3840, 7680 and 15360 aren't emulated on most
operating systems operating systems
Windows 95a 1920, 3840, 7680 work, 15360 fail Windows 95a 1920, 3840, 7680 work, 15360 fail
@ -41,7 +40,6 @@ Known bugs and restrictions of Emu48 V1.50
- no beeper support with OUT command -> all programs that aren't - no beeper support with OUT command -> all programs that aren't
use the "=makebeep" subroutine, like alarm wake up, have no sound use the "=makebeep" subroutine, like alarm wake up, have no sound
- beeper emulation, ATTN key doesn't work - beeper emulation, ATTN key doesn't work
- no infrared printer support
- Shell OS: clock isn't synchronized with real time - Shell OS: clock isn't synchronized with real time
- HP49G: the flash memory is emulated now with some restrictions - HP49G: the flash memory is emulated now with some restrictions
- no flash programming times, the flash state machine returns - no flash programming times, the flash state machine returns
@ -52,4 +50,4 @@ Known bugs and restrictions of Emu48 V1.50
- quitting the emulator while programming the flash isn't allowed, - quitting the emulator while programming the flash isn't allowed,
because the content of flash state machine isn't saved so far because the content of flash state machine isn't saved so far
07/27/10 (c) by Christoph Gießelink, c dot giesselink at gmx dot de 08/07/12 (c) by Christoph Gießelink, c dot giesselink at gmx dot de

View file

@ -1,3 +1,362 @@
Service Pack 53 for Emu48 Version 1.0
DEBUGGER.C
- removed structure MODEL_MAP_T, variables pbyNoMEM, MemMap[],
pbyMapData, dwMapDataSize and pMapping, the implementation behind
moved to module DISMEM.C
- changed function SetMappingMenu(), changed to DISMEM.C
implementation and added control of memory data menu items
- changed function GetMemCurAddr(), OnMemGoAdr(), OnKeyUpDown() and
OnKeyPlusMinus(), variable dwMapDataSize isn't global any more,
use function GetMemDataMask() instead
- changed function InitMemMap(), ViewMemWnd() and OnFindOK(),
changed to DISMEM.C implementation
- changed function ViewCodeWnd(), set disassembler to memory mapped
mode
- bugfix in function OnDblClick(), fixed buffer overflow when
converting a 2 byte hexadecimal string to a byte and added an
update of code window
- changed function Debugger(), changed disassembler mode setting and
added initialization of RPL object viewer get nibble function in
WM_INITDIALOG message and added calls of "Load Memory Data..." and
"Save Memory Data..." handling functions
- bugfix in function UpdateRplObjViewWnd(), show entry point names
only in mapped mode and end address for RPL object viewer depend
on the actual memory mapping mode and with the design change to
the DISMEM.C implementation in all debugger and disassembler
related parts, the RPL object viewer also works in all memory
mapping modes properly now
- added functions OnBrowseLoadMem(), OnBrowseSaveMem(),
LoadMemData(), SaveMemData(), GetAddr(), DebugMemLoad(),
OnMemLoadData(), DebugMemSave() and OnMemSaveData() to handle the
Load/Save Memory Data feature
DISASM.C
- removed global variable disassembler_map
- removed functions rn_map(), rn_rom(), rn_ram(), rn_port1() and
rn_port2()
- changed function read_nibble(), call function GetMemNib() from the
new module DISMEM.C for mapping mode memory access and made
function static again
DISMEM.C
- new module for accessing memory data for debug view purpose
DISPLAY.C
- changed function GetLineCounterGray() to static
DISRPL.C
- the get nibble function is not hard referenced as read_nibble()
call any more, it's now called over RplReadNibble() function
pointer
- changed function PrintTail(), expanded to handle 6 digit addresses
DISRPL.H
- added extern declaration of RplReadNibble() function pointer
EMU48.C
- changed function Disasm(), replaced the radio button
implementation for the memory mapping mode by a combo box
solution; the combo box solution don't work with the HP48 module
names any more, it now use the memory controller names used in the
debugger memory viewer for a more general approach for the non
HP48 calculator models
- changed function WinMain(), added more flexible CPU binding for
the Saturn core emulation thread on Windows NT4.0 and later
EMU48.DSP
- added dismem.c sources
EMU48.H
- replaced old "memory module definitions" by the enum MEM_MAPPING
- extern declaration of global functions
- removed extern declaration of global variables
EMU48.RC
- changed IDD_DISASM dialog, replaced the radio buttons for the
memory mapping mode by a more general combo box
- added dialogs IDD_DEBUG_MEMSAVE and IDD_DEBUG_MEMLOAD
- added "Load Memory Data..." and "Save Memory Data..." menu entries
in debugger "Memory" context menu
- changed version
KML.C
- bugfix in function ReloadButtons(), ON key button wasn't handled
RESOURCE.H
- added several definitions
- deleted some radio button definitions from the IDD_DISASM dialog
TIMER.C
- changed function SetHP48Time(), time calculation now work properly
for host system dates before 1970/01/01 and after 2106/02/07
Service Pack 52 for Emu48 Version 1.0
DEBUGGER.C
- changed function ViewMemWnd(), removed initialized but unused
variable
DISPLAY.C
- changed DIBPIXEL4() and DIBPIXEL3() define, generates the same
code on MSVC6.0 but made it GCC4 compiler compatible
DISRPL.C
- changed function RplCreateObjView(), defined end pointer also as
constant
EMU48.C
- added property sheet page handlers SettingsGeneralProc(),
SettingsMemoryProc() and SettingsPeripheralProc()
- removed function SettingsProc(), replaced by the property sheet
page handler functions
- bugfix in function OnDropFiles(), changed function prototype to
the correct structure type of dropped file names and initialized
the bSuccess variable for the case the wNumFiles variable is 0
- added function PropSheetProc(), callback function for setup the
property sheet
- changed function OnViewSettings(), now creating a propery sheet
instead of a settings dialog
- changed function MainWndProc(), made correct type cast to argument
of function OnDropFiles()
- changed function WinMain(), replaced multiple class name usage
with atom variable, moved read settings before window creation,
and added check for setting "SingleInstance" to switch to an
already running program instance instead of creating a new one
EMU48.H
- extern declaration of global variable and function
EMU48.RC
- split IDD_SETTINGS dialog into the property pages IDD_SET_GENERAL,
IDD_SET_MEMORY and IDD_SET_PERIPHERAL and added item
"Single Instance" in the "General" property page
- removed IDD_SETTINGS dialog
- changed version and copyright
FILES.C
- bugfix in function DecodeBmp() and DecodeGif(), a 2nd bitmap load
allocated and bound a 2nd palette to the main window, now only the
1st bitmap (mostly the KML background bitmap) bound his palette to
the main window
KML.C
- changed table pLexToken[], defined table as constant and changed
last token id table preset from constant number to member of token
id enumerator
- bugfix in function ParseString(), decoding the \" sequence as
quotation mark inside a string was incomplete, so every single '\'
character was also removed
MRU.C
- changed function MruUpdateMenu(), changed variable type of
variable hMenu
- changed function MruReadList(), removed initialized but unused
variable
RESOURCE.H
- removed IDD_SETTINGS definition
- added some definitions
SETTINGS.C
- changed function ReadSettings(), moved CPU speed setting to
MainWndProc()
- changed function ReadSettings() and WriteSettings(), added item
"SingleInstance" in section [Emulator] in the INI-File
UDP.C
- added function ResetUdp(), reset UDP address
- bugfix in function SendByteUdp(), fixed memory leak at error
condition and optimized IP address decoding
Service Pack 51 for Emu48 Version 1.0
DDESERV.C
- replaced all HeapAlloc() with malloc() memory requests
DEBUGGER.C
- replaced all HeapAlloc() with malloc() memory requests
- changed function ToggleBreakpoint() and EditBreakpoint(), minor
code optimization purging breakpoint
- changed function Debugger(), removed all UpdateWindowStatus()
function calls
- bugfix in function LoadBreakpointList(), added check of breakpoint
entries against breakpoint table size
DISRPL.C
- replaced all HeapAlloc() with malloc() memory requests
- bugfix in function BCDx(), fixed possible uninitialized bExpflag
variable
- bugfix in function DoRrp(), fixed possible uninitialized bErr
variable
EMU48.C
- removed global variable hHeap
- replaced all HeapAlloc() with malloc() memory requests
- changed function SettingsProc(), added infrared printer settings
- changed function SaveChanges(), detect if document is available
now over the variable bDocumentAvail and not over the variable
pbyRom any more; in the case of an illegal KML script there maybe
a document loaded, but no ROM image, so pbyRom will be NULL in
this case
- renamed function UpdateWindowStatus() to OnInitMenu() and modified
it to a WM_INITMENU message handler
- changed function OnFileNew() and WinMain(), removed all
UpdateWindowStatus() function calls
- bugfix function OnViewScript(), when quitted the dialog "Choose
Your KML Script" with the Cancel button when chosen an invalid
script the function returned without the possibility of saving the
current document; now the function try to reload the primarily KML
script and if this also fails then the current document is saved
- changed function MainWndProc(), added WM_INITMENU message handler
and call of _CrtDumpMemoryLeaks() at end of program to detect
malloc() memory leaks
EMU48.DSP
- changed the resource natural language to English
- added redeye.c and udp.c sources
- added library Ws2_32.lib
EMU48.H
- removed extern declaration of hHeap
- extern declaration of global variables and functions
- removed declaration of global function UpdateWindowStatus()
- replaced all HeapAlloc() with malloc() memory requests
EMU48.RC
- changed version and copyright
ENGINE.C
- added global variable nOpcSlow to hold the number of CPU opcodes
slowing down the CPU core
- changed function AdjustSpeed(), added CPU opcode slow down
implementation
- added function InitAdjustSpeed(), initialize CPU slow down part
if necessary
- changed function AdjKeySpeed() and SetSpeed(), use function
InitAdjustSpeed() to initialize the CPU slow down variables
- changed function SwitchToState(), removed all UpdateWindowStatus()
function calls
EXTERNAL.C
- replaced all HeapAlloc() with malloc() memory requests
FILES.C
- replaced all HeapAlloc() with malloc() memory requests
- changed TREENODE structure, added prev element for a double linked
list
- changed function PatchNibble(), added prev element handling
- bugfix in function UpdatePatches(), in the case an address was
patched more than one time, the ROM was patched in wrong order and
moreover the original content of the double patched ROM address
was destroyed
- changed function CrcRom(), if no ROM available return without
modifying the checksum
- changed function MapRom(), removed using of memory mapped files
which has the major advantage that packed ROM files are also valid
now
- changed function UnmapRom(), adjusted to changed MapRom() function
- changed function ResetDocument(), OpenDocument(),
SaveDocumentAs(), SaveBackup(), RestoreBackup() and ResetBackup(),
removed all UpdateWindowStatus() function calls
- changed function ResetDocument(), NewDocument(), OpenDocument()
and RestoreBackup(), added state variable if document is available
- bugfix in function OpenDocument(), added check of KML script name
length against target buffer size
- changed function DibNumColors(), changed function prototype from
UINT to WORD return
- changed function CreateBIPalette(), changed variable
UINT nNumColors to WORD wNumColors to avoid variable overflow
loading palNumEntries of LOGPALETTE structure
I28F160.C
- added functions WrDirtyPage(), EraseBlock(), WriteByte() and
ReadByte() for access to the ROM buffer
- changed function WrStateE8C(), WrState40D(), WrState20C(),
WrState30C() and RdStateData(), changed implementation using the
new ROM buffer access functions
IO.H
- added LBR and LBO bit definitions
KEYMACRO.C
- changed function OnToolMacroNew(), OnToolMacroPlay() and
OnToolMacroStop(), removed all UpdateWindowStatus() function calls
- changed function EventThread(), added minimum key hold time for
keyboard macro playing and subtract minimum key hold time from
saved waiting time, this is more accurate when the user has
selected a different minimum key hold time than the default one
- changed function KeyMacroRecord(), now saving the complete waiting
time including the key state holding time, the key state holding
time is now subtract in the player function thread EventThread()
- changed function OnToolMacroNew(), removed adding the key state
holding time to the reference time, this is not necessary any more
KML.C
- replaced all HeapAlloc() with malloc() memory requests
- changed function ParseLines(), BOOL expression was missing in main
while() loop, worked because TOK_NONE is 0
- bugfix in function ParseBlock(), string argument wasn't freed in
error case
- changed function KillKML(), removed UpdateWindowStatus() function
call
- changed function LoadKMLGlobal(), used wrong variable type for
variable eToken
MOPS.C
- added function ReadT2Acc(), reading timer2 value with checking for
CPU speed measurement behaviour
- bugfix in function ReadIO(), added implementation of the LED and
ELBE bit in the LCR (0x11C) register and of the LBO bit in the LBR
(0x11D) register
- changed function ReadIO(), the timer2 register content is now read
by function ReadT2Acc() to analyze the read access scheme
- bugfix in function WriteIO(), added implementation of the ELBE bit
in the LCR (0x11C) register and of the LBO bit in the LBR (0x11D)
register
MRU.C
- replaced all HeapAlloc() with malloc() memory requests
OPS.H
- bugfix in function FASTPTR(), longest opcode calculation from
buffer size was wrong, so MMU boundary fixup wasn't working
properly
PCH.H
- added include winsock2.h
REDEYE.C
- new module for decoding the redeye data stream for a HP82240B
printer
RESOURCE.H
- added some definitions
RPL.C
- replaced all HeapAlloc() with malloc() memory requests
SETTINGS.C
- changed function ReadSettings() and WriteSettings(), added item
"KeyMinDelay" in section [Macro] and the items "Address" and
"Port" in section [IrPrinter] in the INI-File
STACK.C
- replaced all HeapAlloc() with malloc() memory requests
- bugfix in function RPL_GetBcd(), fixed possible uninitialized
bExpflag variable
- bugfix in function OnStackCopy(), fixed possible uninitialized
uClipboardFormat variable in DOCSTR case
SYMBFILE.C
- replaced all HeapAlloc() with malloc() memory requests
UDP.C
- new module for sending a byte over UDP
Service Pack 50 for Emu48 Version 1.0 Service Pack 50 for Emu48 Version 1.0
DEBUGGER.C DEBUGGER.C

View file

@ -11,8 +11,8 @@
#include "io.h" #include "io.h"
HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv, HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
HSZ hsz1,HSZ hsz2,HDDEDATA hData, HSZ hsz1,HSZ hsz2,HDDEDATA hData,
DWORD dwData1,DWORD dwData2) DWORD dwData1,DWORD dwData2)
{ {
TCHAR *psz,szBuffer[32]; TCHAR *psz,szBuffer[32];
HDDEDATA hReturn; HDDEDATA hReturn;
@ -50,7 +50,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
DdeUnaccessData(hData); DdeUnaccessData(hData);
// reserve memory // reserve memory
if ((lpData = HeapAlloc(hHeap,0,dwSize * 2)) == NULL) if ((lpData = malloc(dwSize * 2)) == NULL)
return (HDDEDATA) DDE_FNOTPROCESSED; return (HDDEDATA) DDE_FNOTPROCESSED;
SuspendDebugger(); // suspend debugger SuspendDebugger(); // suspend debugger
@ -66,7 +66,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state if (WaitForSleepState()) // wait for cpu SHUTDN then sleep state
{ {
HeapFree(hHeap,0,lpData); // free memory free(lpData); // free memory
hReturn = DDE_FNOTPROCESSED; hReturn = DDE_FNOTPROCESSED;
goto cancel; goto cancel;
} }
@ -80,7 +80,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
dwSize = dwIndex; dwSize = dwIndex;
dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD)); dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD));
bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO); bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO);
HeapFree(hHeap,0,lpData); // free memory free(lpData); // free memory
SwitchToState(SM_RUN); // run state SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);
@ -138,7 +138,7 @@ cancel:
dwSize += dwIndex + sizeof(DWORD); dwSize += dwIndex + sizeof(DWORD);
// reserve memory // reserve memory
if ((lpData = HeapAlloc(hHeap,0,dwSize)) == NULL) if ((lpData = malloc(dwSize)) == NULL)
{ {
SwitchToState(SM_RUN); // run state SwitchToState(SM_RUN); // run state
return NULL; return NULL;
@ -156,7 +156,7 @@ cancel:
// write data // write data
hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0); hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0);
HeapFree(hHeap,0,lpData); free(lpData);
SwitchToState(SM_RUN); // run state SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);

File diff suppressed because it is too large Load diff

View file

@ -11,7 +11,7 @@
#define BP_EXEC 0x01 // code breakpoint #define BP_EXEC 0x01 // code breakpoint
#define BP_READ 0x02 // read memory breakpoint #define BP_READ 0x02 // read memory breakpoint
#define BP_WRITE 0x04 // write memory breakpoint #define BP_WRITE 0x04 // write memory breakpoint
#define BP_RPL 0x08 // RPL breakpoint #define BP_RPL 0x08 // RPL breakpoint
#define BP_ACCESS (BP_READ|BP_WRITE) // read/write memory breakpoint #define BP_ACCESS (BP_READ|BP_WRITE) // read/write memory breakpoint
// breakpoint notify definitions // breakpoint notify definitions
@ -24,8 +24,8 @@
#define DBG_OFF 0 #define DBG_OFF 0
#define DBG_RUN 1 #define DBG_RUN 1
#define DBG_STEPINTO 2 #define DBG_STEPINTO 2
#define DBG_STEPOVER 3 #define DBG_STEPOVER 3
#define DBG_STEPOUT 4 #define DBG_STEPOUT 4
// debugger.c // debugger.c
extern VOID UpdateDbgCycleCounter(VOID); extern VOID UpdateDbgCycleCounter(VOID);

View file

@ -16,7 +16,6 @@
BOOL disassembler_mode = HP_MNEMONICS; BOOL disassembler_mode = HP_MNEMONICS;
BOOL disassembler_symb = FALSE; BOOL disassembler_symb = FALSE;
WORD disassembler_map = MEM_MAP;
static LPCTSTR hex[] = static LPCTSTR hex[] =
{ {
@ -215,82 +214,13 @@ static LPCTSTR hst_bits[8] =
_T("xm"), _T("sb"), _T("sr"), _T("mp") _T("xm"), _T("sb"), _T("sr"), _T("mp")
}; };
// static functions
static BYTE rn_map (DWORD *p)
{
BYTE byVal;
Npeek(&byVal, *p, 1);
*p = ++(*p) & 0xFFFFF;
return byVal;
}
static BYTE rn_rom (DWORD *p)
{
DWORD d = *p;
*p = ++(*p) & (dwRomSize - 1);
_ASSERT(d < dwRomSize);
return *(pbyRom + d);
}
static BYTE rn_ram (DWORD *p)
{
DWORD d = *p;
*p = ++(*p) & (Chipset.Port0Size * 2048 - 1);
_ASSERT(d < Chipset.Port0Size * 2048);
return *(Port0 + d);
}
static BYTE rn_port1 (DWORD *p)
{
DWORD d = *p;
*p = ++(*p) & (Chipset.Port1Size * 2048 - 1);
_ASSERT(d < Chipset.Port1Size * 2048);
return *(Port1 + d);
}
static BYTE rn_port2 (DWORD *p)
{
BYTE *pbyVal;
DWORD d = *p;
if (Chipset.Port2Size) // HP39/40G, HP49G
{
*p = ++(*p) & (Chipset.Port2Size * 2048 - 1);
_ASSERT(d < Chipset.Port2Size * 2048);
pbyVal = Port2;
}
else // HP48SX/GX
{
*p = ++(*p) & (((dwPort2Mask + 1) << 18) - 1);
_ASSERT(d < ((dwPort2Mask + 1) << 18));
pbyVal = pbyPort2;
}
return *(pbyVal + d);
}
// global functions
BYTE read_nibble (DWORD *p)
{
BYTE (*pnread[])(DWORD *) = { rn_map, rn_rom, rn_ram, rn_port1, rn_port2 };
_ASSERT(disassembler_map < ARRAYSIZEOF(pnread));
return pnread[disassembler_map](p);
}
// general functions // general functions
static BYTE read_nibble (DWORD *p)
{
return GetMemNib(p);
}
static int read_int (DWORD *addr, int n) static int read_int (DWORD *addr, int n)
{ {
int i, t; int i, t;
@ -835,7 +765,7 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
{ {
case HP_MNEMONICS: case HP_MNEMONICS:
wsprintf (buf, _T("%cBIT=%d"), (fn & 8) ? _T('C') : _T('A'), wsprintf (buf, _T("%cBIT=%d"), (fn & 8) ? _T('C') : _T('A'),
(fn & 1) ? 1 : 0); (fn & 1) ? 1 : 0);
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
p = append_imm_nibble (p, addr, 1); p = append_imm_nibble (p, addr, 1);
@ -909,7 +839,7 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
{ {
case HP_MNEMONICS: case HP_MNEMONICS:
wsprintf (buf, (n == 0xf) ? _T("%c%cEX") : _T("%c=%c"), wsprintf (buf, (n == 0xf) ? _T("%c%cEX") : _T("%c=%c"),
(n == 0xd) ? _T('P') : _T('C'), (n == 0xd) ? _T('C') : _T('P')); (n == 0xd) ? _T('P') : _T('C'), (n == 0xd) ? _T('C') : _T('P'));
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
wsprintf (buf, _T("%d"), fn); wsprintf (buf, _T("%d"), fn);
@ -919,7 +849,7 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
p = append_str (out, (n == 0xf) ? _T("exg.1") : _T("move.1")); p = append_str (out, (n == 0xf) ? _T("exg.1") : _T("move.1"));
p = append_tab (out); p = append_tab (out);
wsprintf (buf, (n == 0xd) ? _T("p, c.%d") : _T("c.%d, p"), fn); wsprintf (buf, (n == 0xd) ? _T("p, c.%d") : _T("c.%d, p"), fn);
p = append_str (p, buf); p = append_str (p, buf);
break; break;
default: default:
p = append_str (out, _T("Unknown disassembler mode")); p = append_str (out, _T("Unknown disassembler mode"));
@ -988,9 +918,9 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
{ {
case HP_MNEMONICS: case HP_MNEMONICS:
wsprintf (buf, _T("%s=%s%cCON"), wsprintf (buf, _T("%s=%s%cCON"),
op_str_81[(n & 3) + 4 * disassembler_mode], op_str_81[(n & 3) + 4 * disassembler_mode],
op_str_81[(n & 3) + 4 * disassembler_mode], op_str_81[(n & 3) + 4 * disassembler_mode],
(n < 8) ? _T('+') : _T('-')); (n < 8) ? _T('+') : _T('-'));
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
p = append_field (p, fn); p = append_field (p, fn);
@ -1053,18 +983,18 @@ static LPTSTR disasm_8 (DWORD *addr, LPTSTR out)
if (n == 2) if (n == 2)
{ {
wsprintf (buf, _T("%cR%dEX.F"), ((int) c < 8) ? _T('A') : _T('C'), wsprintf (buf, _T("%cR%dEX.F"), ((int) c < 8) ? _T('A') : _T('C'),
(int) c & 7); (int) c & 7);
} }
else else
if (n == 1) if (n == 1)
{ {
wsprintf (buf, _T("%c=R%d.F"), ((int) c < 8) ? _T('A') : _T('C'), wsprintf (buf, _T("%c=R%d.F"), ((int) c < 8) ? _T('A') : _T('C'),
(int) c & 7); (int) c & 7);
} }
else else
{ {
wsprintf (buf, _T("R%d=%c.F"), (int) c & 7, wsprintf (buf, _T("R%d=%c.F"), (int) c & 7,
((int) c < 8) ? _T('A') : _T('C')); ((int) c < 8) ? _T('A') : _T('C'));
} }
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
@ -1395,7 +1325,7 @@ DWORD disassemble (DWORD addr, LPTSTR out)
{ {
case HP_MNEMONICS: case HP_MNEMONICS:
wsprintf (buf, op_str_0[(n & 7) + 8 * HP_MNEMONICS], wsprintf (buf, op_str_0[(n & 7) + 8 * HP_MNEMONICS],
(n < 8) ? _T('&') : _T('!')); (n < 8) ? _T('&') : _T('!'));
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
p = append_field (p, fn); p = append_field (p, fn);
@ -1609,10 +1539,10 @@ DWORD disassemble (DWORD addr, LPTSTR out)
case HP_MNEMONICS: case HP_MNEMONICS:
if ((c == 0) && (n >= 8)) if ((c == 0) && (n >= 8))
wsprintf (buf, op_str_9[(n & 3) + 8 * HP_MNEMONICS + 4], wsprintf (buf, op_str_9[(n & 3) + 8 * HP_MNEMONICS + 4],
in_str_9[((n >> 2) & 3) + 4 * c + 8 * HP_MNEMONICS]); in_str_9[((n >> 2) & 3) + 4 * c + 8 * HP_MNEMONICS]);
else else
wsprintf (buf, op_str_9[(n & 3) + 8 * HP_MNEMONICS], wsprintf (buf, op_str_9[(n & 3) + 8 * HP_MNEMONICS],
in_str_9[((n >> 2) & 3) + 4 * c + 8 * HP_MNEMONICS]); in_str_9[((n >> 2) & 3) + 4 * c + 8 * HP_MNEMONICS]);
p = append_str (out, buf); p = append_str (out, buf);
p = append_tab (out); p = append_tab (out);
p = append_field (p, fn); p = append_field (p, fn);

221
Sources/Emu48/DISMEM.C Normal file
View file

@ -0,0 +1,221 @@
/*
* dismem.c
*
* This file is part of Emu48
*
* Copyright (C) 2012 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
typedef struct // type of model memory mapping
{
CONST BYTE byType; // calculator type
CONST LPBYTE *ppbyNCE1; // NCE1 data
CONST DWORD *pdwNCE1Size; // NCE1 size
CONST LPBYTE *ppbyNCE2; // NCE2 data
CONST DWORD *pdwNCE2Size; // NCE2 size
CONST LPBYTE *ppbyCE1; // CE1 data
CONST DWORD *pdwCE1Size; // CE1 size
CONST LPBYTE *ppbyCE2; // CE2 data
CONST DWORD *pdwCE2Size; // CE2 size
CONST LPBYTE *ppbyNCE3; // NCE3 data
CONST DWORD *pdwNCE3Size; // NCE3 size
} MODEL_MAP_T;
static CONST LPBYTE pbyNoMEM = NULL; // no memory module
static CONST MODEL_MAP_T MemMap[] =
{
{
0, // default
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL // nc.
},
{
'6', // HP38G (64K)
&pbyRom, &dwRomSize, // ROM
&Port0, &Chipset.Port0Size, // RAM
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL // nc.
},
{
'A', // HP38G
&pbyRom, &dwRomSize, // ROM
&Port0, &Chipset.Port0Size, // RAM
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL, // nc.
&pbyNoMEM, NULL // nc.
},
{
'E', // HP39/40G
&pbyRom, &dwRomSize, // ROM
&Port0, &Chipset.Port0Size, // RAM part 1
&pbyNoMEM, NULL, // BS
&pbyNoMEM, NULL, // nc.
&Port2, &Chipset.Port2Size // RAM part 2
},
{
'G', // HP48GX
&pbyRom, &dwRomSize, // ROM
&Port0, &Chipset.Port0Size, // RAM
&pbyNoMEM, NULL, // BS
&Port1, &Chipset.Port1Size, // Card slot 1
&pbyPort2, &dwPort2Size // Card slot 2
},
{
'S', // HP48SX
&pbyRom, &dwRomSize, // ROM
&Port0, &Chipset.Port0Size, // RAM
&Port1, &Chipset.Port1Size, // Card slot 1
&pbyPort2, &dwPort2Size, // Card slot 2
&pbyNoMEM, NULL // nc.
},
{
'X', // HP49G
&pbyRom, &dwRomSize, // Flash
&Port0, &Chipset.Port0Size, // RAM
&pbyNoMEM, NULL, // BS
&Port1, &Chipset.Port1Size, // Port 1 part 1
&Port2, &Chipset.Port2Size // Port 1 part 2
}
};
static MODEL_MAP_T CONST *pMapping = MemMap; // model specific memory mapping
static enum MEM_MAPPING eMapType = MEM_MMU; // MMU memory mapping
static LPBYTE pbyMapData = NULL;
static DWORD dwMapDataSize = 0;
static DWORD dwMapDataMask = 0;
BOOL SetMemRomType(BYTE cCurrentRomType)
{
INT i;
pMapping = MemMap; // init default mapping
// scan for all table entries
for (i = 0; i < ARRAYSIZEOF(MemMap); ++i)
{
if (MemMap[i].byType == cCurrentRomType)
{
pMapping = &MemMap[i]; // found entry
return TRUE;
}
}
return FALSE;
}
BOOL SetMemMapType(enum MEM_MAPPING eType)
{
BOOL bSucc = TRUE;
eMapType = eType;
switch (eMapType)
{
case MEM_MMU:
pbyMapData = NULL; // data
dwMapDataSize = 512 * 1024 * 2; // data size
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
case MEM_NCE1:
pbyMapData = *pMapping->ppbyNCE1;
dwMapDataSize = *pMapping->pdwNCE1Size; // ROM size is always in nibbles
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
case MEM_NCE2:
pbyMapData = *pMapping->ppbyNCE2;
dwMapDataSize = *pMapping->pdwNCE2Size * 1024 * 2;
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
case MEM_CE1:
pbyMapData = *pMapping->ppbyCE1;
dwMapDataSize = *pMapping->pdwCE1Size * 1024 * 2;
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
case MEM_CE2:
pbyMapData = *pMapping->ppbyCE2;
dwMapDataSize = *pMapping->pdwCE2Size * 1024 * 2;
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
case MEM_NCE3:
pbyMapData = *pMapping->ppbyNCE3;
dwMapDataSize = *pMapping->pdwNCE3Size * 1024 * 2;
dwMapDataMask = dwMapDataSize - 1; // size mask
break;
default: _ASSERT(FALSE);
pbyMapData = NULL;
dwMapDataSize = 0;
dwMapDataMask = 0;
bSucc = FALSE;
}
return bSucc;
}
enum MEM_MAPPING GetMemMapType(VOID)
{
return eMapType;
}
BOOL GetMemAvail(enum MEM_MAPPING eType)
{
switch (eType)
{
case MEM_MMU: return TRUE;
case MEM_NCE1: return *pMapping->ppbyNCE1 != NULL;
case MEM_NCE2: return *pMapping->ppbyNCE2 != NULL;
case MEM_CE1: return *pMapping->ppbyCE1 != NULL;
case MEM_CE2: return *pMapping->ppbyCE2 != NULL;
case MEM_NCE3: return *pMapping->ppbyNCE3 != NULL;
default: _ASSERT(FALSE);
}
return FALSE;
}
DWORD GetMemDataSize(VOID)
{
return dwMapDataSize;
}
DWORD GetMemDataMask(VOID)
{
return dwMapDataMask;
}
BYTE GetMemNib(DWORD *p)
{
BYTE byVal;
if (pbyMapData == NULL)
{
Npeek(&byVal, *p, 1);
}
else
{
byVal = pbyMapData[*p];
}
*p = (*p + 1) & dwMapDataMask;
return byVal;
}
VOID GetMemPeek(BYTE *a, DWORD d, UINT s)
{
if (pbyMapData == NULL)
{
Npeek(a, d, s);
}
else
{
for (; s > 0; --s, ++d)
{
*a++ = pbyMapData[d & dwMapDataMask];
}
}
return;
}

View file

@ -34,8 +34,12 @@
|((((c)-1)>>1)<<8) \ |((((c)-1)>>1)<<8) \
|((((c)-1)>>1))) |((((c)-1)>>1)))
#define DIBPIXEL4(d,p) *((DWORD*)(d)) = ((*((DWORD*)(d)) & dwGrayMask) << 1) | (p); (BYTE *) d += 4 #define DIBPIXEL4(d,p) *((DWORD*)(d)) = ((*((DWORD*)(d)) & dwGrayMask) << 1) | (p); \
#define DIBPIXEL3(d,p) *(d+2) = *(d+1) = *d = ((*d & (BYTE) dwGrayMask) << 1) | (p); (BYTE *) d += 3 *((LPBYTE*) &(d)) += 4
#define DIBPIXEL3(d,p) *((LPBYTE)(d)+2) = \
*((LPBYTE)(d)+1) = \
*((LPBYTE)(d)+0) = ((*(LPBYTE)(d) & (BYTE) dwGrayMask) << 1) | (p); \
*((LPBYTE*) &(d)) += 3
BOOL bGrayscale = FALSE; BOOL bGrayscale = FALSE;
UINT nBackgroundX = 0; UINT nBackgroundX = 0;
@ -882,7 +886,7 @@ static VOID CALLBACK LcdProc(UINT uEventId, UINT uMsg, DWORD dwUser, DWORD dw1,
} }
// LCD line counter calculation // LCD line counter calculation
BYTE GetLineCounterGray(VOID) static BYTE GetLineCounterGray(VOID)
{ {
LARGE_INTEGER lLC; LARGE_INTEGER lLC;
BYTE byTime; BYTE byTime;

View file

@ -34,7 +34,7 @@ static VOID PutSn(String *str, LPCTSTR szVal, DWORD dwLen)
if (str->dwSize == 0) // no buffer allocated if (str->dwSize == 0) // no buffer allocated
{ {
str->dwSize = ALLOCSIZE; // buffer size str->dwSize = ALLOCSIZE; // buffer size
VERIFY(str->szBuffer = HeapAlloc(hHeap,0,str->dwSize * sizeof(TCHAR))); VERIFY(str->szBuffer = (LPTSTR) malloc(str->dwSize * sizeof(TCHAR)));
str->dwPos = 0; str->dwPos = 0;
} }
@ -51,7 +51,7 @@ static VOID PutSn(String *str, LPCTSTR szVal, DWORD dwLen)
dwMinSize *= ALLOCSIZE; dwMinSize *= ALLOCSIZE;
str->dwSize += dwMinSize; // new buffer size str->dwSize += dwMinSize; // new buffer size
VERIFY(str->szBuffer = HeapReAlloc(hHeap,0,str->szBuffer,str->dwSize * sizeof(TCHAR))); VERIFY(str->szBuffer = (LPTSTR) realloc(str->szBuffer,str->dwSize * sizeof(TCHAR)));
} }
CopyMemory(&str->szBuffer[str->dwPos],szVal,dwLen * sizeof(TCHAR)); CopyMemory(&str->szBuffer[str->dwPos],szVal,dwLen * sizeof(TCHAR));
@ -117,7 +117,7 @@ static DWORD Readx(DWORD *pdwAddr,DWORD n)
DWORD i, t; DWORD i, t;
for (i = 0, t = 0; i < n; ++i) for (i = 0, t = 0; i < n; ++i)
t |= read_nibble(pdwAddr) << (i * 4); t |= RplReadNibble(pdwAddr) << (i * 4);
return t; return t;
} }
@ -145,6 +145,7 @@ static BOOL BCDx(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,String *str)
lExp -= nMantLen - 1; // set decimal point to end of mantissa lExp -= nMantLen - 1; // set decimal point to end of mantissa
bPflag = FALSE; // show no decimal point bPflag = FALSE; // show no decimal point
bExpflag = FALSE; // show no exponent
// scan mantissa // scan mantissa
for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--) for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--)
@ -214,10 +215,10 @@ static BOOL BINx(DWORD *pdwAddr,INT nBinLen,String *str)
LPBYTE pbyNumber; LPBYTE pbyNumber;
INT i; INT i;
VERIFY(pbyNumber = HeapAlloc(hHeap,0,nBinLen)); VERIFY(pbyNumber = (LPBYTE) malloc(nBinLen));
for (i = 0; i < nBinLen; ++i) // read data for (i = 0; i < nBinLen; ++i) // read data
pbyNumber[i] = read_nibble(pdwAddr); pbyNumber[i] = RplReadNibble(pdwAddr);
// strip leading zeros // strip leading zeros
for (i = nBinLen - 1; pbyNumber[i] == 0 && i > 0; --i) { } for (i = nBinLen - 1; pbyNumber[i] == 0 && i > 0; --i) { }
@ -227,7 +228,7 @@ static BOOL BINx(DWORD *pdwAddr,INT nBinLen,String *str)
PutC(str,cHex[pbyNumber[i]]); PutC(str,cHex[pbyNumber[i]]);
} }
HeapFree(hHeap,0,pbyNumber); free(pbyNumber);
return FALSE; return FALSE;
} }
@ -269,7 +270,7 @@ static BOOL DoHexStream(DWORD *pdwAddr,String *str,UINT *pnLevel)
for (;dwLength > 0; --dwLength) for (;dwLength > 0; --dwLength)
{ {
PutC(str,cHex[read_nibble(pdwAddr)]); // write digit PutC(str,cHex[RplReadNibble(pdwAddr)]); // write digit
} }
return FALSE; return FALSE;
} }
@ -321,10 +322,10 @@ static BOOL DoIntStream(DWORD *pdwAddr,String *str,UINT *pnLevel)
dwLength -= 5; // object length dwLength -= 5; // object length
VERIFY(pbyData = HeapAlloc(hHeap,0,dwLength)); VERIFY(pbyData = (LPBYTE) malloc(dwLength));
for (i = 0; i < dwLength; ++i) // read data for (i = 0; i < dwLength; ++i) // read data
pbyData[i] = read_nibble(pdwAddr); pbyData[i] = RplReadNibble(pdwAddr);
if (dwLength == 1) // special implementation for zero if (dwLength == 1) // special implementation for zero
{ {
@ -343,7 +344,7 @@ static BOOL DoIntStream(DWORD *pdwAddr,String *str,UINT *pnLevel)
} }
} }
HeapFree(hHeap,0,pbyData); free(pbyData);
return FALSE; return FALSE;
} }
@ -369,7 +370,7 @@ static BOOL DoReal(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get real object content // get real object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
return BCDx(byNumber,12,3,str); return BCDx(byNumber,12,3,str);
} }
@ -383,7 +384,7 @@ BOOL DoERel(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get extended real object content // get extended real object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
return BCDx(byNumber,15,5,str); return BCDx(byNumber,15,5,str);
} }
@ -397,7 +398,7 @@ static BOOL DoCmp(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get real part of complex object content // get real part of complex object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
BCDx(byNumber,12,3,str); BCDx(byNumber,12,3,str);
@ -405,7 +406,7 @@ static BOOL DoCmp(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get imaginary part of complex object content // get imaginary part of complex object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
return BCDx(byNumber,12,3,str); return BCDx(byNumber,12,3,str);
} }
@ -419,7 +420,7 @@ static BOOL DoECmp(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get real part of extended complex object content // get real part of extended complex object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
BCDx(byNumber,15,5,str); BCDx(byNumber,15,5,str);
@ -427,7 +428,7 @@ static BOOL DoECmp(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get imaginary part of extended complex object content // get imaginary part of extended complex object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i) for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr); byNumber[i] = RplReadNibble(pdwAddr);
return BCDx(byNumber,15,5,str); return BCDx(byNumber,15,5,str);
} }
@ -670,7 +671,7 @@ static BOOL DoHxs(DWORD *pdwAddr,String *str,UINT *pnLevel)
for (i = 0; i < dwLength; ++i) for (i = 0; i < dwLength; ++i)
{ {
byVal = read_nibble(pdwAddr); byVal = RplReadNibble(pdwAddr);
// remove leading zeros // remove leading zeros
if (byVal == 0 && bRemove && i + 1 < dwLength) if (byVal == 0 && bRemove && i + 1 < dwLength)
@ -752,7 +753,7 @@ static BOOL Semi(DWORD *pdwAddr,String *str,UINT *pnLevel)
static BOOL DoRrp(DWORD *pdwAddr,String *str,UINT *pnLevel) static BOOL DoRrp(DWORD *pdwAddr,String *str,UINT *pnLevel)
{ {
DWORD dwOffset,dwObjStart,dwBufferPos,dwAddr; DWORD dwOffset,dwObjStart,dwBufferPos,dwAddr;
BOOL bErr; BOOL bErr = FALSE;
dwObjStart = *pdwAddr; // remember start position of RRP dwObjStart = *pdwAddr; // remember start position of RRP
dwBufferPos = str->dwPos; // insert address of text dwBufferPos = str->dwPos; // insert address of text
@ -1254,10 +1255,13 @@ static BOOL FetchObj(DWORD *pdwAddr,String *str,UINT *pnLevel)
return bErr; return bErr;
} }
BYTE (*RplReadNibble)(DWORD *p) = NULL; // get nibble function pointer
DWORD RplSkipObject(DWORD dwAddr) DWORD RplSkipObject(DWORD dwAddr)
{ {
UINT nLevel = 1; // nest DOCOL objects UINT nLevel = 1; // nest DOCOL objects
_ASSERT(RplReadNibble != NULL); // get nibble function defined
FetchObj(&dwAddr,NULL,&nLevel); // decode object without output FetchObj(&dwAddr,NULL,&nLevel); // decode object without output
return dwAddr; return dwAddr;
} }
@ -1269,12 +1273,14 @@ LPTSTR RplDecodeObject(DWORD dwAddr, DWORD *pdwNxtAddr)
UINT nLevel = 0; // don't nest DOCOL objects UINT nLevel = 0; // don't nest DOCOL objects
dwNxtAddr = dwAddr; // init next address dwNxtAddr = dwAddr; // init next address
_ASSERT(RplReadNibble != NULL); // get nibble function defined
FetchObj(&dwNxtAddr,&str,&nLevel); // decode object FetchObj(&dwNxtAddr,&str,&nLevel); // decode object
PutC(&str,0); // set EOS PutC(&str,0); // set EOS
// release unnecessary allocated buffer memory // release unnecessary allocated buffer memory
VERIFY(str.szBuffer = HeapReAlloc(hHeap,0,str.szBuffer,str.dwPos * sizeof(str.szBuffer[0]))); VERIFY(str.szBuffer = (LPTSTR) realloc(str.szBuffer,str.dwPos * sizeof(str.szBuffer[0])));
// return address of next object // return address of next object
if (pdwNxtAddr != NULL) *pdwNxtAddr = dwNxtAddr; if (pdwNxtAddr != NULL) *pdwNxtAddr = dwNxtAddr;
@ -1310,7 +1316,7 @@ static VOID PrintHead(DWORD dwStartAddr, DWORD dwEndAddr, String *str)
if (dwStartAddr < dwEndAddr) // still show hex nibble if (dwStartAddr < dwEndAddr) // still show hex nibble
{ {
c = cHex[read_nibble(&dwStartAddr)]; c = cHex[RplReadNibble(&dwStartAddr)];
} }
PutC(str,c); // write data content PutC(str,c); // write data content
@ -1342,6 +1348,10 @@ static VOID PrintTail(DWORD dwStartAddr, DWORD dwEndAddr, String *str)
{ {
// spaces instead of show address // spaces instead of show address
PutS(str,_T(" ")); PutS(str,_T(" "));
// address has 6 digit
if (dwActAddr >= 0x100000)
PutC(str,_T(' '));
} }
dwRemain = dwEndAddr - dwActAddr; dwRemain = dwEndAddr - dwActAddr;
@ -1350,7 +1360,7 @@ static VOID PrintTail(DWORD dwStartAddr, DWORD dwEndAddr, String *str)
for (; dwRemain > 0; --dwRemain) for (; dwRemain > 0; --dwRemain)
{ {
// write data content // write data content
PutC(str,cHex[read_nibble(&dwActAddr)]); PutC(str,cHex[RplReadNibble(&dwActAddr)]);
} }
PutS(str,_T("\r\n")); PutS(str,_T("\r\n"));
@ -1444,6 +1454,8 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
LPTSTR lpszObject; LPTSTR lpszObject;
DWORD dwLevel,dwAddr,dwNxtAddr; DWORD dwLevel,dwAddr,dwNxtAddr;
_ASSERT(RplReadNibble != NULL); // get nibble function defined
lpszObject = NULL; // no memory allocated lpszObject = NULL; // no memory allocated
dwLevel = 0; // nesting level dwLevel = 0; // nesting level
@ -1465,15 +1477,14 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
PutFS(&str,_T("=%s\r\n"),lpszName); PutFS(&str,_T("=%s\r\n"),lpszName);
} }
PrintHead(dwAddr,dwAddr+5,&str); // write initial head PrintHead(dwAddr,dwAddr+5,&str); // write initial head
do do
{ {
// check for special RRP handling // check for special RRP handling
if (_tcsncmp(lpszObject,_T("DIR\n"),4) == 0) if (_tcsncmp(lpszObject,_T("DIR\n"),4) == 0)
{ {
LPCTSTR lpszStart; LPCTSTR lpszStart,lpszEnd;
LPTSTR lpszEnd;
lpszStart = lpszEnd = lpszObject; lpszStart = lpszEnd = lpszObject;
@ -1525,13 +1536,12 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
while (FALSE); while (FALSE);
PutS(&str,_T("\r\n")); PutS(&str,_T("\r\n"));
// write additional binary data PrintTail(dwAddr+5,dwNxtAddr,&str); // write additional binary data
PrintTail(dwAddr+5,dwNxtAddr,&str);
if (lstrcmp(lpszObject,_T("::")) == 0) if (lstrcmp(lpszObject,_T("::")) == 0)
++dwLevel; ++dwLevel;
HeapFree(hHeap,0,lpszObject); // free object string free(lpszObject); // free object string
lpszObject = NULL; lpszObject = NULL;
if ( (bSingleObj && dwLevel == 0) // single object decoding? if ( (bSingleObj && dwLevel == 0) // single object decoding?
@ -1554,6 +1564,6 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
PutC(&str,0); // set EOS PutC(&str,0); // set EOS
// release unnecessary allocated buffer memory // release unnecessary allocated buffer memory
VERIFY(str.szBuffer = HeapReAlloc(hHeap,0,str.szBuffer,str.dwPos * sizeof(str.szBuffer[0]))); VERIFY(str.szBuffer = (LPTSTR) realloc(str.szBuffer,str.dwPos * sizeof(str.szBuffer[0])));
return str.szBuffer; return str.szBuffer;
} }

View file

@ -19,6 +19,7 @@ extern BOOL bRplViewName; // show entry point name
extern BOOL bRplViewAddr; // show adress extern BOOL bRplViewAddr; // show adress
extern BOOL bRplViewBin; // show binary data extern BOOL bRplViewBin; // show binary data
extern BOOL bRplViewAsm; // show ASM code instead of hex data extern BOOL bRplViewAsm; // show ASM code instead of hex data
extern BYTE (*RplReadNibble)(DWORD *p); // read nibble function pointer
extern DWORD RplSkipObject(DWORD dwAddr); extern DWORD RplSkipObject(DWORD dwAddr);
extern LPTSTR RplDecodeObject(DWORD dwAddr, DWORD *pdwNxtAddr); extern LPTSTR RplDecodeObject(DWORD dwAddr, DWORD *pdwNxtAddr);
extern LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj); extern LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj);

View file

@ -13,7 +13,7 @@
#include "kml.h" #include "kml.h"
#include "debugger.h" #include "debugger.h"
#define VERSION "1.50" #define VERSION "1.53"
// #define MONOCHROME // CF_BITMAP clipboard format // #define MONOCHROME // CF_BITMAP clipboard format
@ -59,7 +59,6 @@ LARGE_INTEGER lFreq; // high performance counter frequency
LARGE_INTEGER lAppStart; // high performance counter value at Appl. start LARGE_INTEGER lAppStart; // high performance counter value at Appl. start
DWORD idDdeInst; // DDE server id DWORD idDdeInst; // DDE server id
UINT uCF_HpObj; // DDE clipboard format UINT uCF_HpObj; // DDE clipboard format
HANDLE hHeap;
HANDLE hThread; HANDLE hThread;
DWORD lThreadId; DWORD lThreadId;
HANDLE hEventShutdn; // event handle to stop cpu thread HANDLE hEventShutdn; // event handle to stop cpu thread
@ -84,7 +83,7 @@ BOOL bAlwaysDisplayLog = TRUE;
BOOL bLoadObjectWarning = TRUE; BOOL bLoadObjectWarning = TRUE;
BOOL bAlwaysOnTop = FALSE; // emulator window always on top BOOL bAlwaysOnTop = FALSE; // emulator window always on top
BOOL bActFollowsMouse = FALSE; // emulator window activation follows mouse BOOL bActFollowsMouse = FALSE; // emulator window activation follows mouse
BOOL bSingleInstance = FALSE; // multiple emulator instances allowed
//################ //################
@ -95,7 +94,7 @@ BOOL bActFollowsMouse = FALSE; // emulator window activation follows
VOID SetWindowTitle(LPCTSTR szString) VOID SetWindowTitle(LPCTSTR szString)
{ {
if (szTitle) HeapFree(hHeap,0,szTitle); if (szTitle) free(szTitle);
_ASSERT(hWnd != NULL); _ASSERT(hWnd != NULL);
if (szString) if (szString)
@ -111,44 +110,6 @@ VOID SetWindowTitle(LPCTSTR szString)
return; return;
} }
VOID UpdateWindowStatus(VOID)
{
if (hWnd) // window open
{
// disable stack loading items on HP38G, HP39/40G
BOOL bStackEnable = cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='E';
BOOL bRun = nState == SM_RUN || nState == SM_SLEEP;
UINT uStackEnable = (bRun && bStackEnable) ? MF_ENABLED : MF_GRAYED;
UINT uRun = bRun ? MF_ENABLED : MF_GRAYED;
UINT uBackup = bBackup ? MF_ENABLED : MF_GRAYED;
HMENU hMenu = GetMenu(hWnd); // get menu handle
EnableMenuItem(hMenu,ID_FILE_NEW,MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_OPEN,MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_SAVE,(bRun && szCurrentFilename[0]) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_FILE_SAVEAS,uRun);
EnableMenuItem(hMenu,ID_FILE_CLOSE,uRun);
EnableMenuItem(hMenu,ID_OBJECT_LOAD,uStackEnable);
EnableMenuItem(hMenu,ID_OBJECT_SAVE,uStackEnable);
EnableMenuItem(hMenu,ID_VIEW_COPY,uRun);
EnableMenuItem(hMenu,ID_STACK_COPY,uStackEnable);
EnableMenuItem(hMenu,ID_STACK_PASTE,uStackEnable);
EnableMenuItem(hMenu,ID_VIEW_RESET,uRun);
EnableMenuItem(hMenu,ID_BACKUP_SAVE,uRun);
EnableMenuItem(hMenu,ID_BACKUP_RESTORE,uBackup);
EnableMenuItem(hMenu,ID_BACKUP_DELETE,uBackup);
EnableMenuItem(hMenu,ID_VIEW_SCRIPT,uRun);
EnableMenuItem(hMenu,ID_TOOL_DISASM,uRun);
EnableMenuItem(hMenu,ID_TOOL_DEBUG,(bRun && nDbgState == DBG_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_RECORD,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_PLAY,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_STOP,(bRun && nMacroState != MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
}
return;
}
VOID ForceForegroundWindow(HWND hWnd) VOID ForceForegroundWindow(HWND hWnd)
{ {
// force window to foreground // force window to foreground
@ -178,7 +139,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar
if ((i = (LONG) SendMessage(hWnd,LB_GETSELCOUNT,0,0)) == 0) if ((i = (LONG) SendMessage(hWnd,LB_GETSELCOUNT,0,0)) == 0)
return; // no items selected return; // no items selected
if ((lpnCount = HeapAlloc(hHeap,0,i * sizeof(INT))) != NULL) if ((lpnCount = malloc(i * sizeof(INT))) != NULL)
{ {
LPTSTR lpszData; LPTSTR lpszData;
HANDLE hClipObj; HANDLE hClipObj;
@ -223,7 +184,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar
GlobalFree(hClipObj); GlobalFree(hClipObj);
} }
} }
HeapFree(hHeap,0,lpnCount); // free item table free(lpnCount); // free item table
} }
return; return;
} }
@ -327,16 +288,11 @@ static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting)
return; return;
} }
static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) static BOOL CALLBACK SettingsGeneralProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam)
{ {
HWND hWndInsertAfter; HWND hWndInsertAfter;
LPCTSTR szActPort2Filename = _T(""); switch (uMsg)
BOOL bPort2CfgChange = FALSE;
BOOL bPort2AttChange = FALSE;
switch (message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
// init speed checkbox // init speed checkbox
@ -344,6 +300,12 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
CheckDlgButton(hDlg,IDC_GRAYSCALE,bGrayscale); CheckDlgButton(hDlg,IDC_GRAYSCALE,bGrayscale);
CheckDlgButton(hDlg,IDC_ALWAYSONTOP,bAlwaysOnTop); CheckDlgButton(hDlg,IDC_ALWAYSONTOP,bAlwaysOnTop);
CheckDlgButton(hDlg,IDC_ACTFOLLOWSMOUSE,bActFollowsMouse); CheckDlgButton(hDlg,IDC_ACTFOLLOWSMOUSE,bActFollowsMouse);
#if defined _USRDLL // DLL version
CheckDlgButton(hDlg,IDC_SINGLEINSTANCE,FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_SINGLEINSTANCE),FALSE);
#else
CheckDlgButton(hDlg,IDC_SINGLEINSTANCE,bSingleInstance);
#endif
CheckDlgButton(hDlg,IDC_AUTOSAVE,bAutoSave); CheckDlgButton(hDlg,IDC_AUTOSAVE,bAutoSave);
CheckDlgButton(hDlg,IDC_AUTOSAVEONEXIT,bAutoSaveOnExit); CheckDlgButton(hDlg,IDC_AUTOSAVEONEXIT,bAutoSaveOnExit);
CheckDlgButton(hDlg,IDC_OBJECTLOADWARNING,bLoadObjectWarning); CheckDlgButton(hDlg,IDC_OBJECTLOADWARNING,bLoadObjectWarning);
@ -351,24 +313,58 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
// set disassebler mode // set disassebler mode
CheckDlgButton(hDlg,(disassembler_mode == HP_MNEMONICS) ? IDC_DISASM_HP : IDC_DISASM_CLASS,BST_CHECKED); CheckDlgButton(hDlg,(disassembler_mode == HP_MNEMONICS) ? IDC_DISASM_HP : IDC_DISASM_CLASS,BST_CHECKED);
return TRUE;
// set sound slider case WM_NOTIFY:
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETRANGE,FALSE,MAKELONG(0,255)); switch (((LPNMHDR) lParam)->code)
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETTICFREQ,256/8,0);
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETPOS,TRUE,dwWaveVol);
// set sound radio button
CheckDlgButton(hDlg,bWaveBeep ? IDC_SOUND_WAVE : IDC_SOUND_SPEAKER,BST_CHECKED);
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),bWaveBeep);
// set combobox parameter
SetCommList(hDlg,szSerialWire,szSerialIr);
if (bCommInit) // disable when port open
{ {
EnableWindow(GetDlgItem(hDlg,IDC_WIRE),FALSE); case PSN_KILLACTIVE:
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE); // get speed checkbox value
} bRealSpeed = IsDlgButtonChecked(hDlg,IDC_REALSPEED);
bAlwaysOnTop = IsDlgButtonChecked(hDlg,IDC_ALWAYSONTOP);
bActFollowsMouse = IsDlgButtonChecked(hDlg,IDC_ACTFOLLOWSMOUSE);
bSingleInstance = IsDlgButtonChecked(hDlg,IDC_SINGLEINSTANCE);
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))
{
UINT nOldState = SwitchToState(SM_INVALID);
SetLcdMode(!bGrayscale); // set new display mode
SwitchToState(nOldState);
}
// set disassembler mode
disassembler_mode = IsDlgButtonChecked(hDlg,IDC_DISASM_HP) ? HP_MNEMONICS : CLASS_MNEMONICS;
// bAlwaysOnTop maybe changed, so set new 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);
}
return TRUE;
}
break;
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
}
static BOOL CALLBACK SettingsMemoryProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam)
{
LPCTSTR szActPort2Filename = _T("");
BOOL bPort2CfgChange = FALSE;
BOOL bPort2AttChange = FALSE;
switch (uMsg)
{
case WM_INITDIALOG:
// HP48SX/GX // HP48SX/GX
if (cCurrentRomType=='S' || cCurrentRomType=='G' || cCurrentRomType==0) if (cCurrentRomType=='S' || cCurrentRomType=='G' || cCurrentRomType==0)
{ {
@ -405,22 +401,11 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
EnableWindow(GetDlgItem(hDlg,IDC_PORT2WR),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_PORT2WR),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_PORT2),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_PORT2LOAD),FALSE); EnableWindow(GetDlgItem(hDlg,IDC_PORT2LOAD),FALSE);
if (cCurrentRomType=='X') // HP49G
{
SendDlgItemMessage(hDlg,IDC_IR,CB_RESETCONTENT,0,0);
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE);
}
} }
return TRUE; return TRUE;
case WM_COMMAND: case WM_COMMAND:
switch (LOWORD(wParam)) switch (LOWORD(wParam))
{ {
case IDC_SOUND_SPEAKER:
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),FALSE);
return TRUE;
case IDC_SOUND_WAVE:
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),TRUE);
return TRUE;
case IDC_PORT2LOAD: case IDC_PORT2LOAD:
if (GetLoadObjectFilename(_T(BIN_FILTER),_T("BIN"))) if (GetLoadObjectFilename(_T(BIN_FILTER),_T("BIN")))
{ {
@ -442,12 +427,17 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
CheckDlgButton(hDlg,IDC_PORT2WR,IsFileWriteable(szBufferFilename)); CheckDlgButton(hDlg,IDC_PORT2WR,IsFileWriteable(szBufferFilename));
} }
return TRUE; return TRUE;
case IDOK: }
break;
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
case PSN_KILLACTIVE:
if (Chipset.Port1Size && cCurrentRomType!='X') if (Chipset.Port1Size && cCurrentRomType!='X')
{ {
UINT nOldState = SwitchToState(SM_SLEEP); UINT nOldState = SwitchToState(SM_SLEEP);
// save old card status // save old card status
BYTE bCardsStatus = Chipset.cards_status; BYTE byCardsStatus = Chipset.cards_status;
// port1 disabled? // port1 disabled?
Chipset.cards_status &= ~(PORT1_PRESENT | PORT1_WRITE); Chipset.cards_status &= ~(PORT1_PRESENT | PORT1_WRITE);
@ -459,7 +449,7 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
} }
// changed card status in slot1? // changed card status in slot1?
if ( ((bCardsStatus ^ Chipset.cards_status) & (PORT1_PRESENT | PORT1_WRITE)) != 0 if ( ((byCardsStatus ^ Chipset.cards_status) & (PORT1_PRESENT | PORT1_WRITE)) != 0
&& (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0 && (Chipset.IORam[CARDCTL] & ECDT) != 0 && (Chipset.IORam[TIMER2_CTRL] & RUN) != 0
) )
{ {
@ -504,22 +494,7 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
bPort2CfgChange = TRUE; // slot2 configuration changed bPort2CfgChange = TRUE; // slot2 configuration changed
} }
} }
// get speed checkbox value
bRealSpeed = IsDlgButtonChecked(hDlg,IDC_REALSPEED);
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))
{
UINT nOldState = SwitchToState(SM_INVALID);
SetLcdMode(!bGrayscale); // set new display mode
SwitchToState(nOldState);
}
if (bPort2CfgChange) // slot2 configuration changed if (bPort2CfgChange) // slot2 configuration changed
{ {
UINT nOldState = SwitchToState(SM_INVALID); UINT nOldState = SwitchToState(SM_INVALID);
@ -563,32 +538,83 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
} }
SwitchToState(nOldState); SwitchToState(nOldState);
} }
// set disassembler mode return TRUE;
disassembler_mode = IsDlgButtonChecked(hDlg,IDC_DISASM_HP) ? HP_MNEMONICS : CLASS_MNEMONICS;
// set sound data
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));
} }
break; break;
} }
return FALSE; return FALSE;
UNREFERENCED_PARAMETER(lParam);
} }
static BOOL CALLBACK SettingsPeripheralProc(HWND hDlg, UINT uMsg, DWORD wParam, LONG lParam)
{
TCHAR cPort[8];
switch (uMsg)
{
case WM_INITDIALOG:
// set sound slider
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETRANGE,FALSE,MAKELONG(0,255));
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETTICFREQ,256/8,0);
SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_SETPOS,TRUE,dwWaveVol);
// set sound radio button
CheckDlgButton(hDlg,bWaveBeep ? IDC_SOUND_WAVE : IDC_SOUND_SPEAKER,BST_CHECKED);
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),bWaveBeep);
// UDP infrared printer settings
SetDlgItemText(hDlg,IDC_IR_ADDR,szUdpServer);
wsprintf(cPort,_T("%u"),wUdpPort);
SetDlgItemText(hDlg,IDC_IR_PORT,cPort);
// set combobox parameter
SetCommList(hDlg,szSerialWire,szSerialIr);
if (bCommInit) // disable when port open
{
EnableWindow(GetDlgItem(hDlg,IDC_WIRE),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE);
}
if (cCurrentRomType=='X') // HP49G
{
SendDlgItemMessage(hDlg,IDC_IR,CB_RESETCONTENT,0,0);
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE);
}
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_SOUND_SPEAKER:
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),FALSE);
return TRUE;
case IDC_SOUND_WAVE:
EnableWindow(GetDlgItem(hDlg,IDC_SOUND_SLIDER),TRUE);
return TRUE;
}
break;
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
case PSN_KILLACTIVE:
// set sound data
dwWaveVol = (DWORD) SendDlgItemMessage(hDlg,IDC_SOUND_SLIDER,TBM_GETPOS,0,0);
bWaveBeep = IsDlgButtonChecked(hDlg,IDC_SOUND_WAVE);
// UDP infrared printer settings
GetDlgItemText(hDlg,IDC_IR_ADDR,szUdpServer,ARRAYSIZEOF(szUdpServer));
GetDlgItemText(hDlg,IDC_IR_PORT,cPort,ARRAYSIZEOF(cPort));
wUdpPort = (WORD) _ttoi(cPort);
ResetUdp(); // invalidate saved UDP address
// 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));
return TRUE;
}
break;
}
return FALSE;
}
//################ //################
//# //#
@ -607,7 +633,7 @@ static UINT SaveChanges(BOOL bAuto)
{ {
UINT uReply; UINT uReply;
if (pbyRom == NULL) return IDNO; if (bDocumentAvail == FALSE) return IDNO;
if (bAuto) if (bAuto)
uReply = IDYES; uReply = IDYES;
@ -755,14 +781,50 @@ static LRESULT OnPaint(HWND hWindow)
return 0; return 0;
} }
//
// WM_INITMENU
//
static LRESULT OnInitMenu(HMENU hMenu)
{
// disable stack loading items on HP38G, HP39/40G
BOOL bStackEnable = cCurrentRomType!='6' && cCurrentRomType!='A' && cCurrentRomType!='E';
BOOL bRun = nState == SM_RUN || nState == SM_SLEEP;
UINT uStackEnable = (bRun && bStackEnable) ? MF_ENABLED : MF_GRAYED;
UINT uRun = bRun ? MF_ENABLED : MF_GRAYED;
UINT uBackup = bBackup ? MF_ENABLED : MF_GRAYED;
EnableMenuItem(hMenu,ID_FILE_NEW,MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_OPEN,MF_ENABLED);
EnableMenuItem(hMenu,ID_FILE_SAVE,(bRun && szCurrentFilename[0]) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_FILE_SAVEAS,uRun);
EnableMenuItem(hMenu,ID_FILE_CLOSE,uRun);
EnableMenuItem(hMenu,ID_OBJECT_LOAD,uStackEnable);
EnableMenuItem(hMenu,ID_OBJECT_SAVE,uStackEnable);
EnableMenuItem(hMenu,ID_VIEW_COPY,uRun);
EnableMenuItem(hMenu,ID_STACK_COPY,uStackEnable);
EnableMenuItem(hMenu,ID_STACK_PASTE,uStackEnable);
EnableMenuItem(hMenu,ID_VIEW_RESET,uRun);
EnableMenuItem(hMenu,ID_BACKUP_SAVE,uRun);
EnableMenuItem(hMenu,ID_BACKUP_RESTORE,uBackup);
EnableMenuItem(hMenu,ID_BACKUP_DELETE,uBackup);
EnableMenuItem(hMenu,ID_VIEW_SCRIPT,uRun);
EnableMenuItem(hMenu,ID_TOOL_DISASM,uRun);
EnableMenuItem(hMenu,ID_TOOL_DEBUG,(bRun && nDbgState == DBG_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_RECORD,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_PLAY,(bRun && nMacroState == MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenu,ID_TOOL_MACRO_STOP,(bRun && nMacroState != MACRO_OFF) ? MF_ENABLED : MF_GRAYED);
return 0;
}
// //
// WM_DROPFILES // WM_DROPFILES
// //
static LRESULT OnDropFiles(HANDLE hFilesInfo) static LRESULT OnDropFiles(HDROP hFilesInfo)
{ {
TCHAR szFileName[MAX_PATH]; TCHAR szFileName[MAX_PATH];
WORD wNumFiles,wIndex; WORD wNumFiles,wIndex;
BOOL bSuccess; BOOL bSuccess = FALSE;
// get number of files dropped // get number of files dropped
wNumFiles = DragQueryFile (hFilesInfo,(UINT)-1,NULL,0); wNumFiles = DragQueryFile (hFilesInfo,(UINT)-1,NULL,0);
@ -833,7 +895,6 @@ static LRESULT OnFileNew(VOID)
SaveBackup(); SaveBackup();
} }
if (NewDocument()) SetWindowTitle(_T("Untitled")); if (NewDocument()) SetWindowTitle(_T("Untitled"));
UpdateWindowStatus();
cancel: cancel:
if (pbyRom) SwitchToState(SM_RUN); if (pbyRom) SwitchToState(SM_RUN);
return 0; return 0;
@ -1028,7 +1089,7 @@ static LRESULT OnViewCopy(VOID)
lpbi->biClrImportant = 0; lpbi->biClrImportant = 0;
// get bitmap color table and bitmap data // get bitmap color table and bitmap data
GetDIBits(hBmpDC, hBmp, 0, lpbi->biHeight, (LPBYTE)lpbi + dwLen - dwSizeImage, GetDIBits(hBmpDC, hBmp, 0, lpbi->biHeight, (LPBYTE)lpbi + dwLen - dwSizeImage,
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); (LPBITMAPINFO)lpbi, DIB_RGB_COLORS);
GlobalUnlock(hClipObj); GlobalUnlock(hClipObj);
SetClipboardData(CF_DIB, hClipObj); SetClipboardData(CF_DIB, hClipObj);
@ -1036,13 +1097,13 @@ static LRESULT OnViewCopy(VOID)
GetObject(hPalette,sizeof(WORD),&wBits); GetObject(hPalette,sizeof(WORD),&wBits);
// memory allocation for temporary palette data // memory allocation for temporary palette data
if ((ppal = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(LOGPALETTE) + wBits * sizeof(PALETTEENTRY))) != NULL) if ((ppal = calloc(sizeof(LOGPALETTE) + wBits * sizeof(PALETTEENTRY),1)) != NULL)
{ {
ppal->palVersion = PALVERSION; ppal->palVersion = PALVERSION;
ppal->palNumEntries = wBits; ppal->palNumEntries = wBits;
GetPaletteEntries(hPalette, 0, wBits, ppal->palPalEntry); GetPaletteEntries(hPalette, 0, wBits, ppal->palPalEntry);
SetClipboardData(CF_PALETTE, CreatePalette(ppal)); SetClipboardData(CF_PALETTE, CreatePalette(ppal));
HeapFree(hHeap,0,ppal); free(ppal);
} }
} }
DeleteDC(hBmpDC); DeleteDC(hBmpDC);
@ -1087,13 +1148,80 @@ static LRESULT OnViewReset(VOID)
// //
// ID_VIEW_SETTINGS // ID_VIEW_SETTINGS
// //
static INT_PTR CALLBACK PropSheetProc(HWND hwndPropSheet, UINT uMsg, LPARAM lParam)
{
switch(uMsg)
{
// called before the dialog is created, hwndPropSheet = NULL, lParam points to dialog resource
case PSCB_PRECREATE:
{
LPDLGTEMPLATE lpTemplate = (LPDLGTEMPLATE) lParam;
if(!(lpTemplate->style & WS_SYSMENU))
{
lpTemplate->style |= WS_SYSMENU;
}
}
break;
// called after the dialog is created
case PSCB_INITIALIZED:
break;
}
return 0;
UNREFERENCED_PARAMETER(hwndPropSheet);
}
static LRESULT OnViewSettings(VOID) static LRESULT OnViewSettings(VOID)
{ {
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh;
// not in nState = SM_INVALID or port2 file must be closed from document // not in nState = SM_INVALID or port2 file must be closed from document
_ASSERT(nState != SM_INVALID || pbyPort2 == NULL); _ASSERT(nState != SM_INVALID || pbyPort2 == NULL);
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_SETTINGS), hWnd, (DLGPROC)SettingsProc) == -1) psp[0].dwSize = sizeof(PROPSHEETPAGE);
AbortMessage(_T("Settings Dialog Creation Error !")); psp[0].dwFlags = PSP_DEFAULT;
psp[0].hInstance = hApp;
psp[0].pszTemplate = MAKEINTRESOURCE(IDD_SET_GENERAL);
psp[0].hIcon = NULL;
psp[0].pszTitle = NULL;
psp[0].pfnDlgProc = (DLGPROC) SettingsGeneralProc;
psp[0].lParam = 0;
psp[0].pfnCallback = NULL;
psp[1].dwSize = sizeof(PROPSHEETPAGE);
psp[1].dwFlags = PSP_DEFAULT;
psp[1].hInstance = hApp;
psp[1].pszTemplate = MAKEINTRESOURCE(IDD_SET_MEMORY);
psp[1].hIcon = NULL;
psp[1].pszTitle = NULL;
psp[1].pfnDlgProc = (DLGPROC) SettingsMemoryProc;
psp[1].lParam = 0;
psp[1].pfnCallback = NULL;
psp[2].dwSize = sizeof(PROPSHEETPAGE);
psp[2].dwFlags = PSP_DEFAULT;
psp[2].hInstance = hApp;
psp[2].pszTemplate = MAKEINTRESOURCE(IDD_SET_PERIPHERAL);
psp[2].hIcon = NULL;
psp[2].pszTitle = NULL;
psp[2].pfnDlgProc = (DLGPROC) SettingsPeripheralProc;
psp[2].lParam = 0;
psp[2].pfnCallback = NULL;
psh.dwSize = sizeof(PROPSHEETHEADER);
psh.dwFlags = PSH_PROPSHEETPAGE | PSH_USECALLBACK | PSH_NOAPPLYNOW;
psh.hwndParent = hWnd;
psh.hInstance = hApp;
psh.hIcon = NULL;
psh.pszCaption = _T("Settings");
psh.nPages = ARRAYSIZEOF(psp);
psh.nStartPage = 0;
psh.ppsp = (LPCPROPSHEETPAGE) &psp;
psh.pfnCallback = (PFNPROPSHEETCALLBACK) PropSheetProc;
if (PropertySheet(&psh) == -1)
AbortMessage(_T("Settings Property Sheet Creation Error!"));
WriteSettings(); WriteSettings();
return 0; return 0;
@ -1104,6 +1232,9 @@ static LRESULT OnViewSettings(VOID)
// //
static LRESULT OnViewScript(VOID) static LRESULT OnViewScript(VOID)
{ {
TCHAR szKmlFile[MAX_PATH];
BOOL bKMLChanged,bSucc;
BYTE cType = cCurrentRomType; BYTE cType = cCurrentRomType;
if (nState != SM_RUN) if (nState != SM_RUN)
{ {
@ -1113,14 +1244,50 @@ static LRESULT OnViewScript(VOID)
} }
SwitchToState(SM_INVALID); SwitchToState(SM_INVALID);
// make a copy of the current KML script file name
_ASSERT(sizeof(szKmlFile) == sizeof(szCurrentKml));
lstrcpyn(szKmlFile,szCurrentKml,ARRAYSIZEOF(szKmlFile));
bKMLChanged = FALSE; // KML script not changed
bSucc = TRUE; // KML script successful loaded
do do
{ {
if (!DisplayChooseKml(cType)) break; if (!DisplayChooseKml(cType)) // quit with Cancel
} {
while (!InitKML(szCurrentKml,FALSE)); if (!bKMLChanged) // KML script not changed
break; // exit loop with current loaded KML script
SetWindowPathTitle(szCurrentFilename); // update window title line // restore KML script file name
if (pbyRom) SwitchToState(SM_RUN); lstrcpyn(szCurrentKml,szKmlFile,ARRAYSIZEOF(szCurrentKml));
// try to restore old KML script
if ((bSucc = InitKML(szCurrentKml,FALSE)))
break; // exit loop with success
// restoring failed, save document
if (IDCANCEL != SaveChanges(bAutoSave))
break; // exit loop with no success
_ASSERT(bSucc == FALSE); // for continuing loop
}
else // quit with Ok
{
bKMLChanged = TRUE; // KML script changed
bSucc = InitKML(szCurrentKml,FALSE);
}
}
while (!bSucc); // retry if KML script is invalid
if (bSucc)
{
if (pbyRom) SwitchToState(SM_RUN); // continue emulation
}
else
{
ResetDocument(); // close document
SetWindowTitle(NULL);
}
return 0; return 0;
} }
@ -1271,58 +1438,74 @@ static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
{ {
static DWORD dwAddress,dwAddressMax; static DWORD dwAddress,dwAddressMax;
enum MEM_MAPPING eMode;
LONG i; LONG i;
DWORD dwNxtAddr; DWORD dwNxtAddr;
TCHAR *cpStop,szAddress[256] = _T("0"); TCHAR szAddress[256] = _T("0");
switch (message) switch (message)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
VERIFY(SetMemRomType(cCurrentRomType)); // set current model
// set fonts & cursor // set fonts & cursor
SendDlgItemMessage(hDlg,IDC_DISASM_MODULE,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_MODULE,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_MAP,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_MODE_TEXT,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_ROM,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_MODE,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_RAM,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_PORT1,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_PORT2,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_MAP,BM_SETCHECK,1,0);
SendDlgItemMessage(hDlg,IDC_ADDRESS,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_ADDRESS,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_ADR,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_ADR,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_NEXT,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_NEXT,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDC_DISASM_COPY,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDC_DISASM_COPY,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
SendDlgItemMessage(hDlg,IDCANCEL,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0)); SendDlgItemMessage(hDlg,IDCANCEL,WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
// fill disassembler mode combo box
{
// disassemble mode window
HWND hWnd = GetDlgItem(hDlg,IDC_DISASM_MODE);
if (hDlgDebug == NULL) // debugger not open
{
LPCTSTR lpszModes[] = { _T("Map"), _T("NCE1"), _T("NCE2"), _T("CE1"), _T("CE2"), _T("NCE3") };
for (eMode = MEM_MMU; eMode <= MEM_NCE3; eMode = (enum MEM_MAPPING) (eMode + 1))
{
if (GetMemAvail(eMode))
{
_ASSERT(eMode < ARRAYSIZEOF(lpszModes));
i = (LONG) SendMessage(hWnd,CB_ADDSTRING,0,(LPARAM) lpszModes[eMode]);
SendMessage(hWnd,CB_SETITEMDATA,i,(LPARAM) eMode);
}
}
VERIFY(SendMessage(hWnd,CB_SETCURSEL,0,0) != LB_ERR);
// disassemble with mapped modules
VERIFY(SetMemMapType(MEM_MMU));
}
else // debugger open
{
EnableWindow(hWnd,FALSE);
}
}
SetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress); SetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress);
disassembler_map = MEM_MAP; // disassemble with mapped modules dwAddressMax = GetMemDataSize();
dwAddress = _tcstoul(szAddress,&cpStop,16); dwAddress = _tcstoul(szAddress,NULL,16);
dwAddressMax = 0x100000; // greatest address (mapped mode)
return TRUE; return TRUE;
case WM_COMMAND: case WM_COMMAND:
switch(LOWORD(wParam)) switch(LOWORD(wParam))
{ {
// decode radio buttons // decode memory mode combo box
case IDC_DISASM_MAP: case IDC_DISASM_MODE:
disassembler_map = MEM_MAP; // new combo box item selected
dwAddressMax = 0x100000; if (HIWORD(wParam) == CBN_SELENDOK)
return TRUE; {
case IDC_DISASM_ROM: HWND hWnd = GetDlgItem(hDlg,IDC_DISASM_MODE);
disassembler_map = MEM_ROM; i = (LONG) SendMessage(hWnd,CB_GETCURSEL,0,0);
dwAddressMax = dwRomSize; eMode = (enum MEM_MAPPING) SendMessage(hWnd,CB_GETITEMDATA,i,0);
return TRUE; VERIFY(SetMemMapType(eMode));
case IDC_DISASM_RAM: dwAddressMax = GetMemDataSize();
disassembler_map = MEM_RAM; }
dwAddressMax = Chipset.Port0Size * 2048; break;
return TRUE;
case IDC_DISASM_PORT1:
disassembler_map = MEM_PORT1;
dwAddressMax = ((Chipset.cards_status & PORT1_PRESENT) != 0) ? (Chipset.Port1Size * 2048) : 0;
return TRUE;
case IDC_DISASM_PORT2:
disassembler_map = MEM_PORT2;
dwAddressMax = ((cCurrentRomType=='E' || cCurrentRomType=='X')
? Chipset.Port2Size
: dwPort2Size)
* 2048;
return TRUE;
case IDOK: case IDOK:
SendDlgItemMessage(hDlg,IDC_DISASM_ADR,EM_SETSEL,0,-1); SendDlgItemMessage(hDlg,IDC_DISASM_ADR,EM_SETSEL,0,-1);
GetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress,ARRAYSIZEOF(szAddress)); GetDlgItemText(hDlg,IDC_DISASM_ADR,szAddress,ARRAYSIZEOF(szAddress));
@ -1332,7 +1515,7 @@ static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
if (_istxdigit(szAddress[i]) == FALSE) if (_istxdigit(szAddress[i]) == FALSE)
return FALSE; return FALSE;
} }
dwAddress = _tcstoul(szAddress,&cpStop,16); dwAddress = _tcstoul(szAddress,NULL,16);
// no break // no break
case IDC_DISASM_NEXT: case IDC_DISASM_NEXT:
if (dwAddress >= dwAddressMax) if (dwAddress >= dwAddressMax)
@ -1403,7 +1586,7 @@ static LRESULT OnToolDisasm(VOID) // disasm dialogbox call
{ {
if (pbyRom) SwitchToState(SM_SLEEP); if (pbyRom) SwitchToState(SM_SLEEP);
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DISASM), hWnd, (DLGPROC)Disasm) == -1) if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DISASM), hWnd, (DLGPROC)Disasm) == -1)
AbortMessage(_T("Disassembler Dialog Box Creation Error !")); AbortMessage(_T("Disassembler Dialog Box Creation Error!"));
if (pbyRom) SwitchToState(SM_RUN); if (pbyRom) SwitchToState(SM_RUN);
return 0; return 0;
} }
@ -1411,7 +1594,7 @@ static LRESULT OnToolDisasm(VOID) // disasm dialogbox call
static LRESULT OnAbout(VOID) static LRESULT OnAbout(VOID)
{ {
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1) if (DialogBox(hApp, MAKEINTRESOURCE(IDD_ABOUT), hWnd, (DLGPROC)About) == -1)
AbortMessage(_T("About Dialog Box Creation Error !")); AbortMessage(_T("About Dialog Box Creation Error!"));
return 0; return 0;
} }
@ -1479,7 +1662,8 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_CREATE: return OnCreate(hWindow); case WM_CREATE: return OnCreate(hWindow);
case WM_DESTROY: return OnDestroy(hWindow); case WM_DESTROY: return OnDestroy(hWindow);
case WM_PAINT: return OnPaint(hWindow); case WM_PAINT: return OnPaint(hWindow);
case WM_DROPFILES: return OnDropFiles((HANDLE)wParam); case WM_INITMENU: return OnInitMenu((HMENU) wParam);
case WM_DROPFILES: return OnDropFiles((HDROP) wParam);
case WM_ACTIVATE: case WM_ACTIVATE:
if (LOWORD(wParam)==WA_INACTIVE) break; if (LOWORD(wParam)==WA_INACTIVE) break;
case WM_QUERYNEWPALETTE: case WM_QUERYNEWPALETTE:
@ -1557,12 +1741,16 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow) int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow)
{ {
typedef DWORD (WINAPI *LPFN_STIP)(HANDLE hThread,DWORD dwIdealProcessor);
MSG msg; MSG msg;
WNDCLASS wc; WNDCLASS wc;
ATOM classAtom;
RECT rectWindow; RECT rectWindow;
HACCEL hAccel; HACCEL hAccel;
LPFN_STIP fnSetThreadIdealProcessor;
DWORD dwProcessor;
HSZ hszService, hszTopic; // variables for DDE server HSZ hszService, hszTopic; // variables for DDE server
DWORD_PTR dwAffMask;
LPTSTR lpFilePart; LPTSTR lpFilePart;
hApp = hInst; hApp = hInst;
@ -1577,13 +1765,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
} }
#endif #endif
hHeap = GetProcessHeap();
if (hHeap == NULL)
{
AbortMessage(_T("Heap creation failed."));
return FALSE;
}
wc.style = CS_BYTEALIGNCLIENT; wc.style = CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
@ -1595,7 +1776,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU); wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = _T("CEmu48"); wc.lpszClassName = _T("CEmu48");
if (!RegisterClass(&wc)) if (!(classAtom = RegisterClass(&wc)))
{ {
AbortMessage( AbortMessage(
_T("CEmu48 class registration failed.\n") _T("CEmu48 class registration failed.\n")
@ -1603,6 +1784,21 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
return FALSE; return FALSE;
} }
// read emulator settings
GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory),szCurrentDirectory);
ReadSettings();
// running an instance of me?
if (bSingleInstance && (hWnd = FindWindow(MAKEINTATOM(classAtom),NULL)) != NULL)
{
if (IsIconic(hWnd)) // window minimized
ShowWindow(hWnd,SW_RESTORE); // show window
// put the window into foreground
ForceForegroundWindow(GetLastActivePopup(hWnd));
return 0; // quit
}
// Create window // Create window
rectWindow.left = 0; rectWindow.left = 0;
rectWindow.top = 0; rectWindow.top = 0;
@ -1610,13 +1806,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
rectWindow.bottom = 0; rectWindow.bottom = 0;
AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE); AdjustWindowRect(&rectWindow, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, TRUE);
hWnd = CreateWindow(_T("CEmu48"), _T("Emu48"), hWnd = CreateWindow(MAKEINTATOM(classAtom),_T("Emu48"),
WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED, WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_OVERLAPPED,
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
rectWindow.right - rectWindow.left, rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top, rectWindow.bottom - rectWindow.top,
NULL,NULL,hApp,NULL NULL,NULL,hApp,NULL);
);
if (hWnd == NULL) if (hWnd == NULL)
{ {
@ -1630,13 +1825,10 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
QueryPerformanceFrequency(&lFreq); // init high resolution counter QueryPerformanceFrequency(&lFreq); // init high resolution counter
QueryPerformanceCounter(&lAppStart); QueryPerformanceCounter(&lAppStart);
GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory), szCurrentDirectory);
szCurrentKml[0] = 0; // no KML file selected szCurrentKml[0] = 0; // no KML file selected
ReadSettings(); SetSpeed(bRealSpeed); // set speed
MruInit(4); // init MRU entries MruInit(4); // init MRU entries
UpdateWindowStatus();
// create auto event handle // create auto event handle
hEventShutdn = CreateEvent(NULL,FALSE,FALSE,NULL); hEventShutdn = CreateEvent(NULL,FALSE,FALSE,NULL);
if (hEventShutdn == NULL) if (hEventShutdn == NULL)
@ -1656,17 +1848,26 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
DestroyWindow(hWnd); DestroyWindow(hWnd);
return FALSE; return FALSE;
} }
// SetThreadIdealProcessor() is available since Windows NT4.0
fnSetThreadIdealProcessor = (LPFN_STIP) GetProcAddress(GetModuleHandle(_T("kernel32")),
"SetThreadIdealProcessor");
// bind Saturn CPU emulation thread to current ideal processor
dwProcessor = (fnSetThreadIdealProcessor != NULL) // running on NT4.0 or later
? fnSetThreadIdealProcessor(hThread,MAXIMUM_PROCESSORS) // get ideal processor no.
: 0; // select 1st processor
// on multiprocessor machines for QueryPerformanceCounter() // on multiprocessor machines for QueryPerformanceCounter()
dwAffMask = SetThreadAffinityMask(hThread,1); VERIFY(SetThreadAffinityMask(hThread,(DWORD_PTR) (1 << dwProcessor)));
_ASSERT(dwAffMask != 0);
ResumeThread(hThread); // start thread ResumeThread(hThread); // start thread
while (nState!=nNextState) Sleep(0); // wait for thread initialized while (nState!=nNextState) Sleep(0); // wait for thread initialized
idDdeInst = 0; // initialize DDE server idDdeInst = 0; // initialize DDE server
if (DdeInitialize(&idDdeInst,(PFNCALLBACK) &DdeCallback, if (DdeInitialize(&idDdeInst,(PFNCALLBACK) &DdeCallback,
APPCLASS_STANDARD | APPCLASS_STANDARD |
CBF_FAIL_EXECUTES | CBF_FAIL_ADVISES | CBF_FAIL_EXECUTES | CBF_FAIL_ADVISES |
CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,0)) CBF_SKIP_REGISTRATIONS | CBF_SKIP_UNREGISTRATIONS,0))
{ {
TerminateThread(hThread, 0); // kill emulation thread TerminateThread(hThread, 0); // kill emulation thread
CloseHandle(hEventShutdn); // close event handle CloseHandle(hEventShutdn); // close event handle
@ -1720,9 +1921,9 @@ start:
{ {
if ( !TranslateAccelerator(hWnd, hAccel, &msg) if ( !TranslateAccelerator(hWnd, hAccel, &msg)
&& (hDlgDebug == NULL || !IsDialogMessage(hDlgDebug, &msg)) && (hDlgDebug == NULL || !IsDialogMessage(hDlgDebug, &msg))
&& (hDlgFind == NULL || !IsDialogMessage(hDlgFind, &msg)) && (hDlgFind == NULL || !IsDialogMessage(hDlgFind, &msg))
&& (hDlgProfile == NULL || !IsDialogMessage(hDlgProfile, &msg)) && (hDlgProfile == NULL || !IsDialogMessage(hDlgProfile, &msg))
&& (hDlgRplObjView == NULL || !IsDialogMessage(hDlgRplObjView, &msg))) && (hDlgRplObjView == NULL || !IsDialogMessage(hDlgRplObjView, &msg)))
{ {
TranslateMessage(&msg); TranslateMessage(&msg);
DispatchMessage(&msg); DispatchMessage(&msg);
@ -1753,6 +1954,7 @@ start:
_ASSERT(pKml == NULL); // KML script not closed _ASSERT(pKml == NULL); // KML script not closed
_ASSERT(szTitle == NULL); // freed allocated memory _ASSERT(szTitle == NULL); // freed allocated memory
_ASSERT(hPalette == NULL); // freed resource memory _ASSERT(hPalette == NULL); // freed resource memory
_CrtDumpMemoryLeaks(); // show memory leaks
return (int) msg.wParam; return (int) msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine); UNREFERENCED_PARAMETER(lpCmdLine);

View file

@ -7,21 +7,21 @@
CFG=Emu48 - Win32 Release CFG=Emu48 - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run !MESSAGE use the Export Makefile command and run
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "Emu48.mak". !MESSAGE NMAKE /f "Emu48.mak".
!MESSAGE !MESSAGE
!MESSAGE You can specify a configuration when running NMAKE !MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "Emu48.mak" CFG="Emu48 - Win32 Release" !MESSAGE NMAKE /f "Emu48.mak" CFG="Emu48 - Win32 Release"
!MESSAGE !MESSAGE
!MESSAGE Possible choices for configuration are: !MESSAGE Possible choices for configuration are:
!MESSAGE !MESSAGE
!MESSAGE "Emu48 - Win32 Release" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "Emu48 - Win32 Debug" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE "Emu48 - Win32 Release Unicode" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Release Unicode" (based on "Win32 (x86) Application")
!MESSAGE "Emu48 - Win32 Debug Unicode" (based on "Win32 (x86) Application") !MESSAGE "Emu48 - Win32 Debug Unicode" (based on "Win32 (x86) Application")
!MESSAGE !MESSAGE
# Begin Project # Begin Project
# PROP AllowPerConfigDependencies 0 # PROP AllowPerConfigDependencies 0
@ -48,14 +48,14 @@ RSC=rc.exe
# ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c # ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /win32 # ADD BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug" !ELSEIF "$(CFG)" == "Emu48 - Win32 Debug"
@ -74,14 +74,14 @@ LINK32=link.exe
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /win32 # ADD BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386
!ELSEIF "$(CFG)" == "Emu48 - Win32 Release Unicode" !ELSEIF "$(CFG)" == "Emu48 - Win32 Release Unicode"
@ -101,14 +101,14 @@ LINK32=link.exe
# ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c # ADD CPP /nologo /Gr /MT /W3 /GX /O2 /Ob2 /D "NDEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG" # ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "Emu48 - Win32 Debug Unicode" !ELSEIF "$(CFG)" == "Emu48 - Win32 Debug Unicode"
@ -128,16 +128,17 @@ LINK32=link.exe
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c # ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_DEBUG" /D "_UNICODE" /D "UNICODE" /D "WIN32" /D "_WINDOWS" /D "STRICT" /D "REGISTRY" /FR /Yu"pch.h" /FD /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 # ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG" # ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG"
# SUBTRACT RSC /x
BSC32=bscmake.exe BSC32=bscmake.exe
# ADD BASE BSC32 /nologo # ADD BASE BSC32 /nologo
# ADD BSC32 /nologo # ADD BSC32 /nologo
LINK32=link.exe LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib /nologo /subsystem:windows /debug /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib comdlg32.lib shell32.lib winmm.lib comctl32.lib advapi32.lib ws2_32.lib /nologo /subsystem:windows /debug /machine:I386
!ENDIF !ENDIF
# Begin Target # Begin Target
@ -166,6 +167,10 @@ SOURCE=.\disasm.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\dismem.c
# End Source File
# Begin Source File
SOURCE=.\display.c SOURCE=.\display.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -235,6 +240,10 @@ SOURCE=.\pch.c
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\redeye.c
# End Source File
# Begin Source File
SOURCE=.\rpl.c SOURCE=.\rpl.c
# End Source File # End Source File
# Begin Source File # Begin Source File
@ -257,6 +266,10 @@ SOURCE=.\symbfile.c
SOURCE=.\timer.c SOURCE=.\timer.c
# End Source File # End Source File
# Begin Source File
SOURCE=.\udp.c
# End Source File
# End Group # End Group
# Begin Group "Header Files" # Begin Group "Header Files"

View file

@ -35,24 +35,18 @@
#define SM_RETURN 2 #define SM_RETURN 2
#define SM_SLEEP 3 #define SM_SLEEP 3
#define S_ERR_NO 0 // stack errorcodes #define S_ERR_NO 0 // stack errorcodes
#define S_ERR_OBJECT 1 #define S_ERR_OBJECT 1
#define S_ERR_BINARY 2 #define S_ERR_BINARY 2
#define S_ERR_ASCII 3 #define S_ERR_ASCII 3
#define BAD_OB (0xFFFFFFFF) // bad object #define BAD_OB (0xFFFFFFFF) // bad object
#define NO_SERIAL "disabled" // port not open #define NO_SERIAL "disabled" // port not open
#define HP_MNEMONICS FALSE // disassembler mnenomics mode #define HP_MNEMONICS FALSE // disassembler mnenomics mode
#define CLASS_MNEMONICS TRUE #define CLASS_MNEMONICS TRUE
#define MEM_MAP 0 // memory module definition
#define MEM_ROM 1
#define MEM_RAM 2
#define MEM_PORT1 3
#define MEM_PORT2 4
#define MACRO_OFF 0 // macro recorder off #define MACRO_OFF 0 // macro recorder off
#define MACRO_NEW 1 #define MACRO_NEW 1
#define MACRO_PLAY 2 #define MACRO_PLAY 2
@ -62,12 +56,17 @@
#define DISP_MENUE 0x04 #define DISP_MENUE 0x04
#define DISP_ANNUN 0x08 #define DISP_ANNUN 0x08
#define ROMPAGESIZE (1<<12) // ROM dirty page size in nibbles
// macro to check for valid calculator model // macro to check for valid calculator model
#define isModelValid(m) (m != 0 && strchr(MODELS,m) != NULL) #define isModelValid(m) (m != 0 && strchr(MODELS,m) != NULL)
// values for mapping area // values for mapping area
enum MMUMAP { M_IO, M_ROM, M_RAM, M_P1, M_P2, M_BS }; enum MMUMAP { M_IO, M_ROM, M_RAM, M_P1, M_P2, M_BS };
// values for disassembler memory mapping modes
enum MEM_MAPPING { MEM_MMU, MEM_NCE1, MEM_NCE2, MEM_CE1, MEM_CE2, MEM_NCE3 };
// Emu48.c // Emu48.c
extern HPALETTE hPalette; extern HPALETTE hPalette;
extern HPALETTE hOldPalette; extern HPALETTE hOldPalette;
@ -90,7 +89,6 @@ extern LARGE_INTEGER lFreq;
extern LARGE_INTEGER lAppStart; extern LARGE_INTEGER lAppStart;
extern DWORD idDdeInst; extern DWORD idDdeInst;
extern UINT uCF_HpObj; extern UINT uCF_HpObj;
extern HANDLE hHeap;
extern HINSTANCE hApp; extern HINSTANCE hApp;
extern HWND hWnd; extern HWND hWnd;
extern HWND hDlgDebug; extern HWND hDlgDebug;
@ -109,11 +107,11 @@ extern BOOL bAlwaysDisplayLog;
extern BOOL bLoadObjectWarning; extern BOOL bLoadObjectWarning;
extern BOOL bAlwaysOnTop; extern BOOL bAlwaysOnTop;
extern BOOL bActFollowsMouse; extern BOOL bActFollowsMouse;
extern BOOL bSingleInstance;
extern HANDLE hThread; extern HANDLE hThread;
extern DWORD lThreadId; extern DWORD lThreadId;
extern VOID SetWindowTitle(LPCTSTR szString); extern VOID SetWindowTitle(LPCTSTR szString);
extern VOID CopyItemsToClipboard(HWND hWnd); extern VOID CopyItemsToClipboard(HWND hWnd);
extern VOID UpdateWindowStatus(VOID);
extern VOID ForceForegroundWindow(HWND hWnd); extern VOID ForceForegroundWindow(HWND hWnd);
// mru.c // mru.c
@ -174,6 +172,7 @@ extern UINT nState;
extern UINT nNextState; extern UINT nNextState;
extern BOOL bRealSpeed; extern BOOL bRealSpeed;
extern BOOL bKeySlow; extern BOOL bKeySlow;
extern UINT nOpcSlow;
extern BOOL bCommInit; extern BOOL bCommInit;
extern CHIPSET Chipset; extern CHIPSET Chipset;
extern TCHAR szSerialWire[16]; extern TCHAR szSerialWire[16];
@ -198,6 +197,7 @@ extern WORD wInstrRp;
extern VOID SuspendDebugger(VOID); extern VOID SuspendDebugger(VOID);
extern VOID ResumeDebugger(VOID); extern VOID ResumeDebugger(VOID);
extern VOID CheckSerial(VOID); extern VOID CheckSerial(VOID);
extern VOID InitAdjustSpeed(VOID);
extern VOID AdjKeySpeed(VOID); extern VOID AdjKeySpeed(VOID);
extern VOID SetSpeed(BOOL bAdjust); extern VOID SetSpeed(BOOL bAdjust);
extern VOID UpdateKdnBit(VOID); extern VOID UpdateKdnBit(VOID);
@ -217,6 +217,7 @@ extern TCHAR szCurrentFilename[MAX_PATH];
extern TCHAR szBackupFilename[MAX_PATH]; extern TCHAR szBackupFilename[MAX_PATH];
extern TCHAR szBufferFilename[MAX_PATH]; extern TCHAR szBufferFilename[MAX_PATH];
extern TCHAR szPort2Filename[MAX_PATH]; extern TCHAR szPort2Filename[MAX_PATH];
extern BOOL bDocumentAvail;
extern BYTE cCurrentRomType; extern BYTE cCurrentRomType;
extern UINT nCurrentClass; extern UINT nCurrentClass;
extern LPBYTE Port0; extern LPBYTE Port0;
@ -225,6 +226,8 @@ extern LPBYTE Port2;
extern LPBYTE pbyRom; extern LPBYTE pbyRom;
extern BOOL bRomWriteable; extern BOOL bRomWriteable;
extern DWORD dwRomSize; extern DWORD dwRomSize;
extern LPBYTE pbyRomDirtyPage;
extern DWORD dwRomDirtyPageSize;
extern WORD wRomCrc; extern WORD wRomCrc;
extern LPBYTE pbyPort2; extern LPBYTE pbyPort2;
extern BOOL bPort2Writeable; extern BOOL bPort2Writeable;
@ -309,12 +312,22 @@ extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in);
extern INT nMacroState; extern INT nMacroState;
extern INT nMacroTimeout; extern INT nMacroTimeout;
extern BOOL bMacroRealSpeed; extern BOOL bMacroRealSpeed;
extern DWORD dwMacroMinDelay;
extern VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in); extern VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in);
extern LRESULT OnToolMacroNew(VOID); extern LRESULT OnToolMacroNew(VOID);
extern LRESULT OnToolMacroPlay(VOID); extern LRESULT OnToolMacroPlay(VOID);
extern LRESULT OnToolMacroStop(VOID); extern LRESULT OnToolMacroStop(VOID);
extern LRESULT OnToolMacroSettings(VOID); extern LRESULT OnToolMacroSettings(VOID);
// Redeye.c
extern VOID IrPrinter(BYTE c);
// Udp.c
extern TCHAR szUdpServer[1024];
extern WORD wUdpPort;
extern VOID ResetUdp(VOID);
extern BOOL SendByteUdp(BYTE byData);
// Stack.c // Stack.c
extern BOOL bDetectClpObject; extern BOOL bDetectClpObject;
extern LRESULT OnStackCopy(VOID); extern LRESULT OnStackCopy(VOID);
@ -339,11 +352,19 @@ extern VOID RCKBp(CHIPSET* w);
// DDEserv.c // DDEserv.c
extern HDDEDATA CALLBACK DdeCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD); extern HDDEDATA CALLBACK DdeCallback(UINT, UINT, HCONV, HSZ, HSZ, HDDEDATA, DWORD, DWORD);
// Dismem.c
extern BOOL SetMemRomType(BYTE cCurrentRomType);
extern BOOL SetMemMapType(enum MEM_MAPPING eType);
extern enum MEM_MAPPING GetMemMapType(VOID);
extern BOOL GetMemAvail(enum MEM_MAPPING eType);
extern DWORD GetMemDataSize(VOID);
extern DWORD GetMemDataMask(VOID);
extern BYTE GetMemNib(DWORD *p);
extern VOID GetMemPeek(BYTE *a, DWORD d, UINT s);
// Disasm.c // Disasm.c
extern BOOL disassembler_mode; extern BOOL disassembler_mode;
extern BOOL disassembler_symb; extern BOOL disassembler_symb;
extern WORD disassembler_map;
extern BYTE read_nibble(DWORD *p);
extern DWORD disassemble(DWORD addr, LPTSTR out); extern DWORD disassemble(DWORD addr, LPTSTR out);
// Symbfile.c // Symbfile.c
@ -385,7 +406,7 @@ static __inline int YesNoCancelMessage(LPCTSTR szMessage,UINT uStyle) {return Me
static __inline LPTSTR DuplicateString(LPCTSTR szString) static __inline LPTSTR DuplicateString(LPCTSTR szString)
{ {
UINT uLength = lstrlen(szString) + 1; UINT uLength = lstrlen(szString) + 1;
LPTSTR szDup = HeapAlloc(hHeap,0,uLength*sizeof(szDup[0])); LPTSTR szDup = malloc(uLength*sizeof(szDup[0]));
lstrcpy(szDup,szString); lstrcpy(szDup,szString);
return szDup; return szDup;
} }

View file

@ -77,12 +77,40 @@ BEGIN
BOTTOMMARGIN, 145 BOTTOMMARGIN, 145
END END
IDD_SETTINGS, DIALOG IDD_SET_GENERAL, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 160 RIGHTMARGIN, 244
TOPMARGIN, 4 VERTGUIDE, 14
BOTTOMMARGIN, 280 VERTGUIDE, 161
VERTGUIDE, 168
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
END
IDD_SET_MEMORY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 244
VERTGUIDE, 14
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
END
IDD_SET_PERIPHERAL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 244
VERTGUIDE, 14
VERTGUIDE, 147
VERTGUIDE, 154
VERTGUIDE, 161
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
HORZGUIDE, 82
END END
IDD_CHOOSEKML, DIALOG IDD_CHOOSEKML, DIALOG
@ -157,6 +185,22 @@ BEGIN
BOTTOMMARGIN, 74 BOTTOMMARGIN, 74
END END
IDD_DEBUG_MEMSAVE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 257
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
IDD_DEBUG_MEMLOAD, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 257
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
IDD_DEBUG_SETTINGS, DIALOG IDD_DEBUG_SETTINGS, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
@ -252,69 +296,88 @@ FONT 8, "MS Sans Serif"
BEGIN BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2010 Christoph Gießelink && Sébastien Carlier", LTEXT "Copyright © 2012 Christoph Gießelink && Sébastien Carlier",
IDC_STATIC,29,18,181,8 IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14 DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY ES_READONLY
END END
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287 IDD_SET_GENERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Settings" CAPTION "General"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button", CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,17,133,10
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button", CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,28,133,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button", CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX |
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10 WS_TABSTOP,14,40,133,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE, CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,"Button",
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,52,133,10
CONTROL "Single Instance",IDC_SINGLEINSTANCE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,64,133,10
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,76,133,10
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,114,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,88,133,10
CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button", CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,100,133,10
CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG, CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,112,133,10
GROUPBOX "General",IDC_STATIC,7,4,153,107 GROUPBOX "General",IDC_STATIC,7,7,148,120
CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON | CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,13,125,65,11 WS_GROUP | WS_TABSTOP,168,21,69,11
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button", CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
BS_AUTORADIOBUTTON,84,125,70,11 BS_AUTORADIOBUTTON,168,35,69,11
GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28 GROUPBOX "Disassembler",IDC_STATIC,161,7,83,120
LTEXT "Volume",IDC_STATIC,13,158,24,8 END
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18 IDD_SET_MEMORY DIALOG DISCARDABLE 0, 0, 251, 134
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
WS_GROUP | WS_TABSTOP,111,152,43,10 CAPTION "Memory"
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111, FONT 8, "MS Sans Serif"
163,43,10 BEGIN
GROUPBOX "Sound",IDC_STATIC,7,144,153,34
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX | CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,189,67,10 WS_TABSTOP,14,20,67,10
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10 BS_AUTOCHECKBOX | WS_TABSTOP,124,20,69,10
CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button", CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,201,65,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,32,65,10
CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button", CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10 BS_AUTOCHECKBOX | WS_TABSTOP,124,32,69,10
LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8 LTEXT "Port 2 File :",IDC_STATIC,14,47,37,8
EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL EDITTEXT IDC_PORT2,52,45,175,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12 PUSHBUTTON "...",IDC_PORT2LOAD,227,45,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51 GROUPBOX "Memory Cards",IDC_STATIC,7,7,237,58
LTEXT "Wire:",IDC_STATIC,13,245,17,8 END
COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
IDD_SET_PERIPHERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Peripheral"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Volume",IDC_STATIC,14,21,24,8
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,40,16,84,18
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,135,20,43,10
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,194,20,
43,10
GROUPBOX "Sound",IDC_STATIC,7,7,237,34
LTEXT "IP Address:",IDC_STATIC,14,60,37,8
LTEXT "Port:",IDC_STATIC,119,60,16,8
EDITTEXT IDC_IR_ADDR,14,70,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_IR_PORT,119,70,28,12,ES_NUMBER
GROUPBOX "Infrared Printer",IDC_STATIC,7,43,147,50
LTEXT "Wire:",IDC_STATIC,168,58,17,8
COMBOBOX IDC_WIRE,189,56,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
LTEXT "IR:",IDC_STATIC,89,245,9,8 LTEXT "IR:",IDC_STATIC,168,74,9,8
COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | COMBOBOX IDC_IR,189,72,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27 GROUPBOX "Serial Ports",IDC_STATIC,161,43,83,50
DEFPUSHBUTTON "OK",IDOK,9,266,50,14
PUSHBUTTON "Cancel",IDCANCEL,107,266,50,14
END END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66 IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
@ -362,19 +425,12 @@ BEGIN
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14 PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14 PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14
PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14 PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14
LTEXT "Mapping Mode:",IDC_DISASM_MODE_TEXT,12,17,45,8
COMBOBOX IDC_DISASM_MODE,60,14,35,90,CBS_DROPDOWNLIST |
WS_TABSTOP
GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26 GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26
CONTROL "Map",IDC_DISASM_MAP,"Button",BS_AUTORADIOBUTTON | LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY |
WS_GROUP | WS_TABSTOP,14,16,37,10 LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
CONTROL "ROM",IDC_DISASM_ROM,"Button",BS_AUTORADIOBUTTON,61,16,
37,10
CONTROL "RAM",IDC_DISASM_RAM,"Button",BS_AUTORADIOBUTTON,108,16,
37,10
CONTROL "Port 1",IDC_DISASM_PORT1,"Button",BS_AUTORADIOBUTTON,
155,16,37,10
CONTROL "Port 2",IDC_DISASM_PORT2,"Button",BS_AUTORADIOBUTTON,
202,16,37,10
LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
END END
@ -543,6 +599,36 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14 PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14
END END
IDD_DEBUG_MEMSAVE DIALOG DISCARDABLE 0, 0, 264, 65
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Save Memory Data"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "File:",IDC_STATIC,7,10,14,8
EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14
LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8
EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14
LTEXT "End Address (hexadecimal):",IDC_STATIC,7,46,88,8
EDITTEXT IDC_DEBUG_DATA_ENDADDR,101,44,37,14
PUSHBUTTON "OK",IDOK,207,27,50,14
PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14
END
IDD_DEBUG_MEMLOAD DIALOG DISCARDABLE 0, 0, 264, 65
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Load Memory Data"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "File:",IDC_STATIC,7,10,14,8
EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14
LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8
EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14
PUSHBUTTON "OK",IDOK,207,27,50,14
PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14
END
IDD_DEBUG_SETTINGS DIALOG DISCARDABLE 0, 0, 184, 116 IDD_DEBUG_SETTINGS DIALOG DISCARDABLE 0, 0, 184, 116
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger Settings" CAPTION "Debugger Settings"
@ -602,8 +688,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,0 FILEVERSION 1,5,3,0
PRODUCTVERSION 1,5,0,0 PRODUCTVERSION 1,5,3,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -620,12 +706,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0" VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 5, 0, 0\0" VALUE "FileVersion", "1, 5, 3, 0\0"
VALUE "InternalName", "Emu48\0" VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2010\0" VALUE "LegalCopyright", "Copyright © 2012\0"
VALUE "OriginalFilename", "Emu48.exe\0" VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0" VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 5, 0, 0\0" VALUE "ProductVersion", "1, 5, 3, 0\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -791,6 +877,9 @@ BEGIN
, GRAYED , GRAYED
END END
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "&Load Memory Data...", ID_DEBUG_MEM_LOAD
MENUITEM "S&ave Memory Data...", ID_DEBUG_MEM_SAVE
MENUITEM SEPARATOR
MENUITEM "&RPL Object Viewer...", ID_DEBUG_MEM_RPLVIEW MENUITEM "&RPL Object Viewer...", ID_DEBUG_MEM_RPLVIEW
END END
END END

View file

@ -19,6 +19,7 @@ UINT nState = SM_INVALID;
UINT nNextState = SM_RUN; UINT nNextState = SM_RUN;
BOOL bRealSpeed = FALSE; BOOL bRealSpeed = FALSE;
BOOL bKeySlow = FALSE; // slow down for key emulation BOOL bKeySlow = FALSE; // slow down for key emulation
UINT nOpcSlow = 0; // no. of opcodes to slow down
BOOL bCommInit = FALSE; // COM port not open BOOL bCommInit = FALSE; // COM port not open
CHIPSET Chipset; CHIPSET Chipset;
@ -275,7 +276,7 @@ static __inline VOID CheckDisp(BOOL bSync)
static __inline VOID AdjustSpeed(VOID) // adjust emulation speed static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
{ {
if (bCpuSlow || bKeySlow) // emulation slow down if (bCpuSlow || bKeySlow || nOpcSlow > 0) // emulation slow down
{ {
DWORD dwCycles,dwTicks; DWORD dwCycles,dwTicks;
@ -298,6 +299,8 @@ static __inline VOID AdjustSpeed(VOID) // adjust emulation speed
dwOldCyc += T2CYCLES; // adjust cycles reference dwOldCyc += T2CYCLES; // adjust cycles reference
dwSpeedRef += dwTickRef; // adjust reference time dwSpeedRef += dwTickRef; // adjust reference time
} }
if (nOpcSlow > 0) --nOpcSlow; // decr. slow down opcode counter
} }
LeaveCriticalSection(&csSlowLock); LeaveCriticalSection(&csSlowLock);
} }
@ -321,26 +324,34 @@ VOID CheckSerial(VOID)
return; return;
} }
VOID InitAdjustSpeed(VOID)
{
// slow down function not initalized
if (!bCpuSlow && !bKeySlow && nOpcSlow == 0)
{
LARGE_INTEGER lTime; // sample timer ticks
// save reference cycles
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lTime); // get timer ticks
dwSpeedRef = lTime.LowPart; // save reference time
}
return;
}
VOID AdjKeySpeed(VOID) // slow down key repeat VOID AdjKeySpeed(VOID) // slow down key repeat
{ {
WORD i; WORD i;
BOOL bKey; BOOL bKey;
if (bCpuSlow) return; // no need to slow down
bKey = FALSE; // search for a pressed key bKey = FALSE; // search for a pressed key
for (i = 0;i < ARRAYSIZEOF(Chipset.Keyboard_Row) && !bKey;++i) for (i = 0;i < ARRAYSIZEOF(Chipset.Keyboard_Row) && !bKey;++i)
bKey = (Chipset.Keyboard_Row[i] != 0); bKey = (Chipset.Keyboard_Row[i] != 0);
EnterCriticalSection(&csSlowLock); EnterCriticalSection(&csSlowLock);
{ {
if (!bKeySlow && bKey) // key pressed, init variables if (bKey) // key pressed
{ {
LARGE_INTEGER lTime; // sample timer ticks InitAdjustSpeed(); // init variables if necessary
// save reference cycles
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lTime); // get timer ticks
dwSpeedRef = lTime.LowPart; // save reference time
} }
bKeySlow = bKey; // save new state bKeySlow = bKey; // save new state
} }
@ -354,11 +365,7 @@ VOID SetSpeed(BOOL bAdjust) // set emulation speed
{ {
if (bAdjust) // switch to real speed if (bAdjust) // switch to real speed
{ {
LARGE_INTEGER lTime; // sample timer ticks InitAdjustSpeed(); // init variables if necessary
// save reference cycles
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lTime); // get timer ticks
dwSpeedRef = lTime.LowPart; // save reference time
} }
bCpuSlow = bAdjust; // save emulation speed bCpuSlow = bAdjust; // save emulation speed
} }
@ -412,7 +419,6 @@ UINT SwitchToState(UINT nNewState)
bInterrupt = TRUE; bInterrupt = TRUE;
SuspendDebugger(); // suspend debugger SuspendDebugger(); // suspend debugger
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break; break;
case SM_RETURN: // -> Return case SM_RETURN: // -> Return
DisableDebugger(); // disable debugger DisableDebugger(); // disable debugger
@ -425,7 +431,6 @@ UINT SwitchToState(UINT nNewState)
nNextState = SM_RETURN; nNextState = SM_RETURN;
SetEvent(hEventShutdn); SetEvent(hEventShutdn);
WaitForSingleObject(hThread,INFINITE); WaitForSingleObject(hThread,INFINITE);
UpdateWindowStatus();
break; break;
case SM_SLEEP: // -> Sleep case SM_SLEEP: // -> Sleep
nNextState = SM_SLEEP; nNextState = SM_SLEEP;
@ -449,7 +454,6 @@ UINT SwitchToState(UINT nNewState)
ResumeDebugger(); ResumeDebugger();
SetEvent(hEventShutdn); SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break; break;
case SM_RETURN: // -> Return case SM_RETURN: // -> Return
DisableDebugger(); // disable debugger DisableDebugger(); // disable debugger
@ -461,7 +465,6 @@ UINT SwitchToState(UINT nNewState)
nNextState = SM_SLEEP; nNextState = SM_SLEEP;
SetEvent(hEventShutdn); SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break; break;
} }
break; break;
@ -479,7 +482,6 @@ UINT SwitchToState(UINT nNewState)
nNextState = SM_INVALID; nNextState = SM_INVALID;
SetEvent(hEventShutdn); SetEvent(hEventShutdn);
while (nState!=nNextState) Sleep(0); while (nState!=nNextState) Sleep(0);
UpdateWindowStatus();
break; break;
case SM_RETURN: // -> Return case SM_RETURN: // -> Return
DisableDebugger(); // disable debugger DisableDebugger(); // disable debugger
@ -489,7 +491,6 @@ UINT SwitchToState(UINT nNewState)
nNextState = SM_RETURN; nNextState = SM_RETURN;
SetEvent(hEventShutdn); SetEvent(hEventShutdn);
WaitForSingleObject(hThread,INFINITE); WaitForSingleObject(hThread,INFINITE);
UpdateWindowStatus();
break; break;
} }
break; break;
@ -603,6 +604,7 @@ loop:
dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF); dwOldCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
QueryPerformanceCounter(&lDummyInt); QueryPerformanceCounter(&lDummyInt);
dwSpeedRef = lDummyInt.LowPart; dwSpeedRef = lDummyInt.LowPart;
nOpcSlow = 0; // no opcodes to slow down
} }
} }
if (Chipset.SoftInt) if (Chipset.SoftInt)

View file

@ -66,7 +66,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration)
// (samp/sec) * msecs * (secs/msec) = samps // (samp/sec) * msecs * (secs/msec) = samps
wh.dwBufferLength = (DWORD) ((QWORD) MUSIC_FREQ * dwDuration / 1000); wh.dwBufferLength = (DWORD) ((QWORD) MUSIC_FREQ * dwDuration / 1000);
VERIFY(wh.lpData = HeapAlloc(hHeap,0,wh.dwBufferLength)); VERIFY(wh.lpData = malloc(wh.dwBufferLength));
wh.dwBytesRecorded = 0; wh.dwBytesRecorded = 0;
wh.dwUser = 0; wh.dwUser = 0;
wh.dwFlags = 0; wh.dwFlags = 0;
@ -86,7 +86,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration)
VERIFY(waveOutUnprepareHeader(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR); VERIFY(waveOutUnprepareHeader(hSoundDevice,&wh,sizeof(wh)) == MMSYSERR_NOERROR);
VERIFY(waveOutClose(hSoundDevice) == MMSYSERR_NOERROR); VERIFY(waveOutClose(hSoundDevice) == MMSYSERR_NOERROR);
HeapFree(hHeap,0,wh.lpData); free(wh.lpData);
CloseHandle(hEventSound); CloseHandle(hEventSound);
return; return;
} }

View file

@ -501,7 +501,7 @@ static const JMPTAB o8081_[] =
static const JMPTAB o808_[] = static const JMPTAB o808_[] =
{ {
o8080, F, o8080, F,
o8081_, 4, o8081_, 4,
o8082X, F, o8082X, F,
o8083, F, o8083, F,
o8084n, F, o8084n, F,

View file

@ -23,6 +23,8 @@ TCHAR szBackupFilename[MAX_PATH];
TCHAR szBufferFilename[MAX_PATH]; TCHAR szBufferFilename[MAX_PATH];
TCHAR szPort2Filename[MAX_PATH]; TCHAR szPort2Filename[MAX_PATH];
BOOL bDocumentAvail = FALSE; // document not available
BYTE cCurrentRomType = 0; // Model -> hardware BYTE cCurrentRomType = 0; // Model -> hardware
UINT nCurrentClass = 0; // Class -> derivate UINT nCurrentClass = 0; // Class -> derivate
@ -33,6 +35,8 @@ LPBYTE Port2 = NULL;
LPBYTE pbyRom = NULL; LPBYTE pbyRom = NULL;
BOOL bRomWriteable = TRUE; // flag if ROM writeable BOOL bRomWriteable = TRUE; // flag if ROM writeable
DWORD dwRomSize = 0; DWORD dwRomSize = 0;
LPBYTE pbyRomDirtyPage = NULL;
DWORD dwRomDirtyPageSize = 0;
WORD wRomCrc = 0; // fingerprint of patched ROM WORD wRomCrc = 0; // fingerprint of patched ROM
LPBYTE pbyPort2 = NULL; LPBYTE pbyPort2 = NULL;
@ -45,7 +49,6 @@ WORD wPort2Crc = 0; // fingerprint of port2
BOOL bBackup = FALSE; BOOL bBackup = FALSE;
static HANDLE hRomFile = NULL; static HANDLE hRomFile = NULL;
static HANDLE hRomMap = NULL;
static HANDLE hPort2File = NULL; static HANDLE hPort2File = NULL;
static HANDLE hPort2Map = NULL; static HANDLE hPort2Map = NULL;
@ -61,6 +64,7 @@ static CHIPSET BackupChipset;
static LPBYTE BackupPort0; static LPBYTE BackupPort0;
static LPBYTE BackupPort1; static LPBYTE BackupPort1;
static LPBYTE BackupPort2; static LPBYTE BackupPort2;
static BOOL bRomPacked;
//################ //################
//# //#
@ -209,6 +213,7 @@ typedef struct tnode
DWORD dwAddress; // patch address DWORD dwAddress; // patch address
BYTE byROM; // original ROM value BYTE byROM; // original ROM value
BYTE byPatch; // patched ROM value BYTE byPatch; // patched ROM value
struct tnode *prev; // previous node
struct tnode *next; // next node struct tnode *next; // next node
} TREENODE; } TREENODE;
@ -219,14 +224,17 @@ static BOOL PatchNibble(DWORD dwAddress, BYTE byPatch)
TREENODE *p; TREENODE *p;
_ASSERT(pbyRom); // ROM defined _ASSERT(pbyRom); // ROM defined
if ((p = HeapAlloc(hHeap,0,sizeof(TREENODE))) == NULL) if ((p = malloc(sizeof(TREENODE))) == NULL)
return TRUE; return TRUE;
p->bPatch = TRUE; // address patched p->bPatch = TRUE; // address patched
p->dwAddress = dwAddress; // save current values p->dwAddress = dwAddress; // save current values
p->byROM = pbyRom[dwAddress]; p->byROM = pbyRom[dwAddress];
p->byPatch = byPatch; p->byPatch = byPatch;
p->prev = NULL;
p->next = nodePatch; // save node p->next = nodePatch; // save node
if (nodePatch) nodePatch->prev = p; // add as previous element
nodePatch = p; nodePatch = p;
pbyRom[dwAddress] = byPatch; // patch ROM pbyRom[dwAddress] = byPatch; // patch ROM
@ -244,7 +252,7 @@ static VOID RestorePatches(VOID)
pbyRom[nodePatch->dwAddress] = nodePatch->byROM; pbyRom[nodePatch->dwAddress] = nodePatch->byROM;
p = nodePatch->next; // save pointer to next node p = nodePatch->next; // save pointer to next node
HeapFree(hHeap,0,nodePatch); // free node free(nodePatch); // free node
nodePatch = p; // new node nodePatch = p; // new node
} }
return; return;
@ -255,32 +263,42 @@ VOID UpdatePatches(BOOL bPatch)
TREENODE *p = nodePatch; TREENODE *p = nodePatch;
_ASSERT(pbyRom); // ROM defined _ASSERT(pbyRom); // ROM defined
while (p != NULL) if (bPatch) // patch ROM
{ {
if (bPatch) // patch ROM if (p) // something in patch list
{ {
if (!p->bPatch) // patch only if not patched // goto last element in list
{ for (; p->next != NULL; p = p->next) {}
// use original data for patch restore
p->byROM = pbyRom[p->dwAddress];
// restore patch data do
pbyRom[p->dwAddress] = p->byPatch;
p->bPatch = TRUE; // address patched
}
else
{ {
_ASSERT(FALSE); // call ROM patch on a patched ROM 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
}
p = p->prev;
} }
while (p != NULL);
} }
else // restore ROM }
else // restore ROM
{
for (; p != NULL; p = p->next)
{ {
// restore original data // restore original data
pbyRom[p->dwAddress] = p->byROM; pbyRom[p->dwAddress] = p->byROM;
p->bPatch = FALSE; // address not patched p->bPatch = FALSE; // address not patched
} }
p = p->next; // next node
} }
return; return;
} }
@ -311,7 +329,7 @@ BOOL PatchRom(LPCTSTR szFilename)
CloseHandle(hFile); CloseHandle(hFile);
return FALSE; return FALSE;
} }
lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow+1); lpBuf = malloc(dwFileSizeLow+1);
if (lpBuf == NULL) if (lpBuf == NULL)
{ {
CloseHandle(hFile); CloseHandle(hFile);
@ -360,7 +378,7 @@ BOOL PatchRom(LPCTSTR szFilename)
++nPos; ++nPos;
} }
} }
HeapFree(hHeap,0,lpBuf); free(lpBuf);
return TRUE; return TRUE;
} }
@ -377,6 +395,8 @@ BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM
DWORD *pdwData,dwSize; DWORD *pdwData,dwSize;
DWORD dwChk = 0; DWORD dwChk = 0;
if (pbyRom == NULL) return TRUE; // ROM CRC isn't available
_ASSERT(pbyRom); // view on ROM _ASSERT(pbyRom); // view on ROM
pdwData = (DWORD *) pbyRom; pdwData = (DWORD *) pbyRom;
@ -398,34 +418,34 @@ BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM
BOOL MapRom(LPCTSTR szFilename) BOOL MapRom(LPCTSTR szFilename)
{ {
DWORD dwFileSizeHigh; DWORD dwSize,dwFileSize,dwRead;
// open ROM for writing // open ROM for writing
BOOL bWrite = (cCurrentRomType == 'X') ? bRomWriteable : FALSE; BOOL bRomRW = (cCurrentRomType == 'X') ? bRomWriteable : FALSE;
if (pbyRom != NULL) if (pbyRom != NULL)
{ {
return FALSE; return FALSE;
} }
SetCurrentDirectory(szEmuDirectory); SetCurrentDirectory(szEmuDirectory);
if (bWrite) // ROM writeable if (bRomRW) // ROM writeable
{ {
hRomFile = CreateFile(szFilename, hRomFile = CreateFile(szFilename,
GENERIC_READ|GENERIC_WRITE, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ, FILE_SHARE_READ,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, FILE_FLAG_SEQUENTIAL_SCAN,
NULL); NULL);
if (hRomFile == INVALID_HANDLE_VALUE) if (hRomFile == INVALID_HANDLE_VALUE)
{ {
bWrite = FALSE; // ROM not writeable bRomRW = FALSE; // ROM not writeable
hRomFile = CreateFile(szFilename, hRomFile = CreateFile(szFilename,
GENERIC_READ, GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, FILE_FLAG_SEQUENTIAL_SCAN,
NULL); NULL);
} }
} }
@ -436,7 +456,7 @@ BOOL MapRom(LPCTSTR szFilename)
FILE_SHARE_READ, FILE_SHARE_READ,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, FILE_FLAG_SEQUENTIAL_SCAN,
NULL); NULL);
} }
SetCurrentDirectory(szCurrentDirectory); SetCurrentDirectory(szCurrentDirectory);
@ -445,49 +465,136 @@ BOOL MapRom(LPCTSTR szFilename)
hRomFile = NULL; hRomFile = NULL;
return FALSE; return FALSE;
} }
dwRomSize = GetFileSize(hRomFile, &dwFileSizeHigh); dwRomSize = GetFileSize(hRomFile, NULL);
if (dwFileSizeHigh != 0)
{ // file is too large. if (dwRomSize <= 4)
{ // file is too small.
CloseHandle(hRomFile); CloseHandle(hRomFile);
hRomFile = NULL; hRomFile = NULL;
dwRomSize = 0; dwRomSize = 0;
return FALSE; return FALSE;
} }
hRomMap = CreateFileMapping(hRomFile, NULL, bWrite ? PAGE_READWRITE : PAGE_WRITECOPY, 0, dwRomSize, NULL);
if (hRomMap == NULL) // read the first 4 bytes
{ ReadFile(hRomFile,&dwSize,sizeof(dwSize),&dwRead,NULL);
CloseHandle(hRomFile);
hRomFile = NULL; dwFileSize = dwRomSize; // calculate ROM image buffer size
dwRomSize = 0; bRomPacked = (dwSize & 0xF0F0F0F0) != 0; // ROM image packed
return FALSE; if (bRomPacked) dwRomSize *= 2; // unpacked ROM image has double size
}
if (GetLastError() == ERROR_ALREADY_EXISTS) pbyRom = VirtualAlloc(NULL,dwRomSize,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
{
AbortMessage(_T("Sharing file mapping handle."));
}
pbyRom = MapViewOfFile(hRomMap, bWrite ? FILE_MAP_WRITE : FILE_MAP_COPY, 0, 0, dwRomSize);
if (pbyRom == NULL) if (pbyRom == NULL)
{ {
CloseHandle(hRomMap);
CloseHandle(hRomFile); CloseHandle(hRomFile);
hRomMap = NULL;
hRomFile = NULL; hRomFile = NULL;
dwRomSize = 0; dwRomSize = 0;
return FALSE; return FALSE;
} }
*(DWORD *) pbyRom = dwSize; // save first 4 bytes
// load rest of file content
ReadFile(hRomFile,&pbyRom[sizeof(dwSize)],dwFileSize - sizeof(dwSize),&dwRead,NULL);
_ASSERT(dwFileSize - sizeof(dwSize) == dwRead);
if (bRomRW) // ROM is writeable
{
// no. of dirty pages
dwRomDirtyPageSize = dwRomSize / ROMPAGESIZE;
// alloc dirty page table
pbyRomDirtyPage = calloc(dwRomDirtyPageSize,sizeof(*pbyRomDirtyPage));
if (pbyRomDirtyPage == NULL)
{
VirtualFree(pbyRom,0,MEM_RELEASE); // free ROM image
CloseHandle(hRomFile);
dwRomDirtyPageSize = 0;
pbyRom = NULL;
hRomFile = NULL;
dwRomSize = 0;
return FALSE;
}
}
else
{
dwRomDirtyPageSize = 0;
CloseHandle(hRomFile);
hRomFile = NULL;
}
if (bRomPacked) // packed ROM image
{
dwSize = dwRomSize; // destination start address
while (dwFileSize > 0) // unpack source
{
BYTE byValue = pbyRom[--dwFileSize];
pbyRom[--dwSize] = byValue >> 4;
pbyRom[--dwSize] = byValue & 0xF;
}
}
return TRUE; return TRUE;
} }
VOID UnmapRom(VOID) VOID UnmapRom(VOID)
{ {
if (pbyRom == NULL) return; if (pbyRom == NULL) return; // ROM not mapped
RestorePatches(); // restore ROM Patches RestorePatches(); // restore ROM patches
UnmapViewOfFile(pbyRom); if (hRomFile) // ROM file still open (only in R/W case)
CloseHandle(hRomMap); {
CloseHandle(hRomFile); DWORD i;
_ASSERT(pbyRomDirtyPage != NULL);
// scan for every dirty page
for (i = 0; i < dwRomDirtyPageSize; ++i)
{
if (pbyRomDirtyPage[i]) // page dirty
{
DWORD dwSize,dwLinPos,dwFilePos,dwWritten;
dwLinPos = i * ROMPAGESIZE; // position inside emulator memory
dwSize = ROMPAGESIZE; // bytes to write
while (i+1 < dwRomDirtyPageSize && pbyRomDirtyPage[i+1])
{
dwSize += ROMPAGESIZE; // next page is also dirty
++i; // skip next page in outer loop
}
dwFilePos = dwLinPos; // ROM file position
if (bRomPacked) // repack data
{
LPBYTE pbySrc,pbyDest;
DWORD j;
dwSize /= 2; // adjust no. of bytes to write
dwFilePos /= 2; // linear pos in packed file
// pack data in page
pbySrc = pbyDest = &pbyRom[dwLinPos];
for (j = 0; j < dwSize; j++)
{
*pbyDest = *pbySrc++;
*pbyDest |= *pbySrc++ << 4;
pbyDest++;
}
}
SetFilePointer(hRomFile,dwFilePos,NULL,FILE_BEGIN);
WriteFile(hRomFile,&pbyRom[dwLinPos],dwSize,&dwWritten,NULL);
}
}
free(pbyRomDirtyPage);
CloseHandle(hRomFile);
pbyRomDirtyPage = NULL;
dwRomDirtyPageSize = 0;
hRomFile = NULL;
}
VirtualFree(pbyRom,0,MEM_RELEASE); // free ROM image
pbyRom = NULL; pbyRom = NULL;
hRomMap = NULL;
hRomFile = NULL;
dwRomSize = 0; dwRomSize = 0;
wRomCrc = 0; wRomCrc = 0;
return; return;
@ -670,13 +777,13 @@ VOID ResetDocument(VOID)
} }
szCurrentKml[0] = 0; szCurrentKml[0] = 0;
szCurrentFilename[0]=0; szCurrentFilename[0]=0;
if (Port0) { HeapFree(hHeap,0,Port0); Port0 = NULL; } if (Port0) { free(Port0); Port0 = NULL; }
if (Port1) { HeapFree(hHeap,0,Port1); Port1 = NULL; } if (Port1) { free(Port1); Port1 = NULL; }
if (Port2) { HeapFree(hHeap,0,Port2); Port2 = NULL; } else UnmapPort2(); if (Port2) { free(Port2); Port2 = NULL; } else UnmapPort2();
ZeroMemory(&Chipset,sizeof(Chipset)); ZeroMemory(&Chipset,sizeof(Chipset));
ZeroMemory(&RMap,sizeof(RMap)); // delete MMU mappings ZeroMemory(&RMap,sizeof(RMap)); // delete MMU mappings
ZeroMemory(&WMap,sizeof(WMap)); ZeroMemory(&WMap,sizeof(WMap));
UpdateWindowStatus(); bDocumentAvail = FALSE; // document not available
return; return;
} }
@ -746,21 +853,22 @@ BOOL NewDocument(VOID)
// allocate port memory // allocate port memory
if (Chipset.Port0Size) if (Chipset.Port0Size)
{ {
Port0 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port0Size*2048); Port0 = calloc(Chipset.Port0Size*2048,sizeof(*Port0));
_ASSERT(Port0 != NULL); _ASSERT(Port0 != NULL);
} }
if (Chipset.Port1Size) if (Chipset.Port1Size)
{ {
Port1 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port1Size*2048); Port1 = calloc(Chipset.Port1Size*2048,sizeof(*Port1));
_ASSERT(Port1 != NULL); _ASSERT(Port1 != NULL);
} }
if (Chipset.Port2Size) if (Chipset.Port2Size)
{ {
Port2 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port2Size*2048); Port2 = calloc(Chipset.Port2Size*2048,sizeof(*Port1));
_ASSERT(Port2 != NULL); _ASSERT(Port2 != NULL);
} }
LoadBreakpointList(NULL); // clear debugger breakpoint list LoadBreakpointList(NULL); // clear debugger breakpoint list
RomSwitch(0); // boot ROM view of HP49G and map memory RomSwitch(0); // boot ROM view of HP49G and map memory
bDocumentAvail = TRUE; // document available
return TRUE; return TRUE;
restore: restore:
RestoreBackup(); RestoreBackup();
@ -843,10 +951,13 @@ BOOL OpenDocument(LPCTSTR szFilename)
switch (pbyFileSignature[14]) switch (pbyFileSignature[14])
{ {
case 0xFE: // Win48 2.1 / Emu4x 0.99.x format case 0xFE: // Win48 2.1 / Emu4x 0.99.x format
// read length of KML script name
ReadFile(hFile,&nLength,sizeof(nLength),&lBytesRead,NULL); ReadFile(hFile,&nLength,sizeof(nLength),&lBytesRead,NULL);
// KML script name too long for file buffer
if (nLength >= ARRAYSIZEOF(szCurrentKml)) goto read_err;
#if defined _UNICODE #if defined _UNICODE
{ {
LPSTR szTmp = HeapAlloc(hHeap,0,nLength); LPSTR szTmp = malloc(nLength);
if (szTmp == NULL) if (szTmp == NULL)
{ {
AbortMessage(_T("Memory Allocation Failure.")); AbortMessage(_T("Memory Allocation Failure."));
@ -855,7 +966,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
ReadFile(hFile, szTmp, nLength, &lBytesRead, NULL); ReadFile(hFile, szTmp, nLength, &lBytesRead, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead,
szCurrentKml, ARRAYSIZEOF(szCurrentKml)); szCurrentKml, ARRAYSIZEOF(szCurrentKml));
HeapFree(hHeap,0,szTmp); free(szTmp);
} }
#else #else
{ {
@ -916,13 +1027,13 @@ BOOL OpenDocument(LPCTSTR szFilename)
goto restore; goto restore;
} }
// reload old button state // reload old button state
ReloadButtons(Chipset.Keyboard_Row,sizeof(Chipset.Keyboard_Row)); ReloadButtons(Chipset.Keyboard_Row,ARRAYSIZEOF(Chipset.Keyboard_Row));
FlashInit(); // init flash structure FlashInit(); // init flash structure
if (Chipset.Port0Size) if (Chipset.Port0Size)
{ {
Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); Port0 = malloc(Chipset.Port0Size*2048);
if (Port0 == NULL) if (Port0 == NULL)
{ {
AbortMessage(_T("Memory Allocation Failure.")); AbortMessage(_T("Memory Allocation Failure."));
@ -937,7 +1048,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
if (Chipset.Port1Size) if (Chipset.Port1Size)
{ {
Port1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); Port1 = malloc(Chipset.Port1Size*2048);
if (Port1 == NULL) if (Port1 == NULL)
{ {
AbortMessage(_T("Memory Allocation Failure.")); AbortMessage(_T("Memory Allocation Failure."));
@ -969,7 +1080,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
{ {
if (Chipset.Port2Size) if (Chipset.Port2Size)
{ {
Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); Port2 = malloc(Chipset.Port2Size*2048);
if (Port2 == NULL) if (Port2 == NULL)
{ {
AbortMessage(_T("Memory Allocation Failure.")); AbortMessage(_T("Memory Allocation Failure."));
@ -1007,7 +1118,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename); if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename);
#endif #endif
SetWindowPathTitle(szCurrentFilename); // update window title line SetWindowPathTitle(szCurrentFilename); // update window title line
UpdateWindowStatus(); bDocumentAvail = TRUE; // document available
return TRUE; return TRUE;
read_err: read_err:
@ -1058,14 +1169,14 @@ BOOL SaveDocument(VOID)
WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL); WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL);
#if defined _UNICODE #if defined _UNICODE
{ {
LPSTR szTmp = HeapAlloc(hHeap,0,nLength); LPSTR szTmp = malloc(nLength);
if (szTmp != NULL) if (szTmp != NULL)
{ {
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK, WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szCurrentKml, nLength, szCurrentKml, nLength,
szTmp, nLength, NULL, NULL); szTmp, nLength, NULL, NULL);
WriteFile(hCurrentFile, szTmp, nLength, &lBytesWritten, NULL); WriteFile(hCurrentFile, szTmp, nLength, &lBytesWritten, NULL);
HeapFree(hHeap,0,szTmp); free(szTmp);
} }
} }
#else #else
@ -1106,7 +1217,6 @@ BOOL SaveDocumentAs(LPCTSTR szFilename)
if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename); if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename);
#endif #endif
SetWindowPathTitle(szCurrentFilename); // update window title line SetWindowPathTitle(szCurrentFilename); // update window title line
UpdateWindowStatus(); // and draw it
return SaveDocument(); // save current content return SaveDocument(); // save current content
} }
@ -1135,23 +1245,22 @@ BOOL SaveBackup(VOID)
lstrcpy(szBackupFilename, szCurrentFilename); lstrcpy(szBackupFilename, szCurrentFilename);
lstrcpy(szBackupKml, szCurrentKml); lstrcpy(szBackupKml, szCurrentKml);
if (BackupPort0) HeapFree(hHeap,0,BackupPort0); if (BackupPort0) free(BackupPort0);
if (BackupPort1) HeapFree(hHeap,0,BackupPort1); if (BackupPort1) free(BackupPort1);
if (BackupPort2) HeapFree(hHeap,0,BackupPort2); if (BackupPort2) free(BackupPort2);
CopyMemory(&BackupChipset, &Chipset, sizeof(Chipset)); CopyMemory(&BackupChipset, &Chipset, sizeof(Chipset));
BackupPort0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); BackupPort0 = malloc(Chipset.Port0Size*2048);
CopyMemory(BackupPort0,Port0,Chipset.Port0Size*2048); CopyMemory(BackupPort0,Port0,Chipset.Port0Size*2048);
BackupPort1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); BackupPort1 = malloc(Chipset.Port1Size*2048);
CopyMemory(BackupPort1,Port1,Chipset.Port1Size*2048); CopyMemory(BackupPort1,Port1,Chipset.Port1Size*2048);
BackupPort2 = NULL; BackupPort2 = NULL;
if (Chipset.Port2Size) // internal port2 if (Chipset.Port2Size) // internal port2
{ {
BackupPort2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); BackupPort2 = malloc(Chipset.Port2Size*2048);
CopyMemory(BackupPort2,Port2,Chipset.Port2Size*2048); CopyMemory(BackupPort2,Port2,Chipset.Port2Size*2048);
} }
CreateBackupBreakpointList(); CreateBackupBreakpointList();
bBackup = TRUE; bBackup = TRUE;
UpdateWindowStatus();
return TRUE; return TRUE;
} }
@ -1182,13 +1291,13 @@ BOOL RestoreBackup(VOID)
} }
} }
CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset)); CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset));
Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048); Port0 = malloc(Chipset.Port0Size*2048);
CopyMemory(Port0,BackupPort0,Chipset.Port0Size*2048); CopyMemory(Port0,BackupPort0,Chipset.Port0Size*2048);
Port1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048); Port1 = malloc(Chipset.Port1Size*2048);
CopyMemory(Port1,BackupPort1,Chipset.Port1Size*2048); CopyMemory(Port1,BackupPort1,Chipset.Port1Size*2048);
if (Chipset.Port2Size) // internal port2 if (Chipset.Port2Size) // internal port2
{ {
Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048); Port2 = malloc(Chipset.Port2Size*2048);
CopyMemory(Port2,BackupPort2,Chipset.Port2Size*2048); CopyMemory(Port2,BackupPort2,Chipset.Port2Size*2048);
} }
// map port2 // map port2
@ -1205,7 +1314,7 @@ BOOL RestoreBackup(VOID)
SetWindowLocation(hWnd,Chipset.nPosX,Chipset.nPosY); SetWindowLocation(hWnd,Chipset.nPosX,Chipset.nPosY);
RestoreBackupBreakpointList(); // restore the debugger breakpoint list RestoreBackupBreakpointList(); // restore the debugger breakpoint list
if (bDbgOpen) OnToolDebug(); // reopen the debugger if (bDbgOpen) OnToolDebug(); // reopen the debugger
UpdateWindowStatus(); bDocumentAvail = TRUE; // document available
return TRUE; return TRUE;
} }
@ -1214,12 +1323,11 @@ BOOL ResetBackup(VOID)
if (!bBackup) return FALSE; if (!bBackup) return FALSE;
szBackupFilename[0] = 0; szBackupFilename[0] = 0;
szBackupKml[0] = 0; szBackupKml[0] = 0;
if (BackupPort0) { HeapFree(hHeap,0,BackupPort0); BackupPort0 = NULL; } if (BackupPort0) { free(BackupPort0); BackupPort0 = NULL; }
if (BackupPort1) { HeapFree(hHeap,0,BackupPort1); BackupPort1 = NULL; } if (BackupPort1) { free(BackupPort1); BackupPort1 = NULL; }
if (BackupPort2) { HeapFree(hHeap,0,BackupPort2); BackupPort2 = NULL; } if (BackupPort2) { free(BackupPort2); BackupPort2 = NULL; }
ZeroMemory(&BackupChipset,sizeof(BackupChipset)); ZeroMemory(&BackupChipset,sizeof(BackupChipset));
bBackup = FALSE; bBackup = FALSE;
UpdateWindowStatus();
return TRUE; return TRUE;
} }
@ -1413,7 +1521,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
CloseHandle(hFile); CloseHandle(hFile);
return FALSE; return FALSE;
} }
lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow*2); lpBuf = malloc(dwFileSizeLow*2);
if (lpBuf == NULL) if (lpBuf == NULL)
{ {
CloseHandle(hFile); CloseHandle(hFile);
@ -1433,7 +1541,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
if (wError == S_ERR_ASCII) if (wError == S_ERR_ASCII)
AbortMessage(_T("The calculator does not have enough\nfree memory to load this text file.")); AbortMessage(_T("The calculator does not have enough\nfree memory to load this text file."));
HeapFree(hHeap,0,lpBuf); free(lpBuf);
return (wError == S_ERR_NO); return (wError == S_ERR_NO);
} }
@ -1490,7 +1598,7 @@ typedef struct _BmpFile
LPBYTE pbyFile; // buffer LPBYTE pbyFile; // buffer
} BMPFILE, FAR *LPBMPFILE, *PBMPFILE; } BMPFILE, FAR *LPBMPFILE, *PBMPFILE;
static __inline UINT DibNumColors(BITMAPINFOHEADER CONST *lpbi) static __inline WORD DibNumColors(BITMAPINFOHEADER CONST *lpbi)
{ {
if (lpbi->biClrUsed != 0) return (UINT)lpbi->biClrUsed; if (lpbi->biClrUsed != 0) return (UINT)lpbi->biClrUsed;
@ -1502,7 +1610,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
{ {
LOGPALETTE* pPal; LOGPALETTE* pPal;
HPALETTE hpal = NULL; HPALETTE hpal = NULL;
UINT nNumColors; WORD wNumColors;
BYTE red; BYTE red;
BYTE green; BYTE green;
BYTE blue; BYTE blue;
@ -1517,29 +1625,28 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
// Get a pointer to the color table and the number of colors in it // Get a pointer to the color table and the number of colors in it
pRgb = (RGBQUAD FAR *)((LPBYTE)lpbi + (WORD)lpbi->biSize); pRgb = (RGBQUAD FAR *)((LPBYTE)lpbi + (WORD)lpbi->biSize);
nNumColors = DibNumColors(lpbi); wNumColors = DibNumColors(lpbi);
if (nNumColors) if (wNumColors)
{ {
// Allocate for the logical palette structure // Allocate for the logical palette structure
pPal = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)); pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY));
if (!pPal) if (!pPal) return NULL;
return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = 0x300; pPal->palVersion = 0x300;
pPal->palNumEntries = wNumColors;
// Fill in the palette entries from the DIB color table and // Fill in the palette entries from the DIB color table and
// create a logical color palette. // create a logical color palette.
for (i = 0; i < nNumColors; i++) for (i = 0; i < pPal->palNumEntries; i++)
{ {
pPal->palPalEntry[i].peRed = pRgb[i].rgbRed; pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen; pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue; pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
pPal->palPalEntry[i].peFlags = (BYTE)0; pPal->palPalEntry[i].peFlags = 0;
} }
hpal = CreatePalette(pPal); hpal = CreatePalette(pPal);
HeapFree(hHeap,0,pPal); free(pPal);
} }
else else
{ {
@ -1547,12 +1654,12 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
// 16, 24 and 32 bitcount DIB's have no color table entries so, set the // 16, 24 and 32 bitcount DIB's have no color table entries so, set the
// number of to the maximum value (256). // number of to the maximum value (256).
nNumColors = 256; wNumColors = 256;
pPal = HeapAlloc(hHeap,0,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY)); pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY));
if (!pPal) return NULL; if (!pPal) return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = 0x300; pPal->palVersion = 0x300;
pPal->palNumEntries = wNumColors;
red = green = blue = 0; red = green = blue = 0;
@ -1570,7 +1677,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
blue += 64; blue += 64;
} }
hpal = CreatePalette(pPal); hpal = CreatePalette(pPal);
HeapFree(hHeap,0,pPal); free(pPal);
} }
return hpal; return hpal;
} }
@ -1625,12 +1732,13 @@ static HBITMAP DecodeBmp(LPBMPFILE pBmp)
pBmi, DIB_RGB_COLORS)); pBmi, DIB_RGB_COLORS));
if (hBitmap == NULL) return NULL; if (hBitmap == NULL) return NULL;
_ASSERT(hPalette == NULL); // resource free if (hPalette == NULL)
hPalette = CreateBIPalette(&pBmi->bmiHeader); {
// save old palette hPalette = CreateBIPalette(&pBmi->bmiHeader);
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); // save old palette
RealizePalette(hWindowDC); hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
RealizePalette(hWindowDC);
}
return hBitmap; return hBitmap;
} }
@ -1719,7 +1827,7 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp)
bmi.bmiHeader.biWidth = nWidth; bmi.bmiHeader.biWidth = nWidth;
bmi.bmiHeader.biHeight = nHeight; bmi.bmiHeader.biHeight = nHeight;
bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 24; // create a true color DIB bmi.bmiHeader.biBitCount = 24; // create a true color DIB
bmi.bmiHeader.biCompression = BI_RGB; bmi.bmiHeader.biCompression = BI_RGB;
ZeroMemory(&sGlb,sizeof(sGlb)); // init global color map ZeroMemory(&sGlb,sizeof(sGlb)); // init global color map
@ -2115,14 +2223,16 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp)
} }
} }
_ASSERT(bDecoding == FALSE); // decoding successful _ASSERT(bDecoding == FALSE); // decoding successful
// normal decoding exit // normal decoding exit
_ASSERT(hPalette == NULL); // resource free if (hPalette == NULL)
hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi); {
// save old palette hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi);
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE); // save old palette
RealizePalette(hWindowDC); hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
RealizePalette(hWindowDC);
}
quit: quit:
if (hBitmap != NULL && bDecoding) // creation failed if (hBitmap != NULL && bDecoding) // creation failed

View file

@ -187,6 +187,51 @@ static CONST BYTE byQueryTab[] =
}; };
//
// ROM buffer access functions
//
static __inline void WrDirtyPage(DWORD d)
{
if (pbyRomDirtyPage) // using dirty ROM page table
{
DWORD dwPage = d / ROMPAGESIZE; // this is the page
_ASSERT(dwPage < dwRomDirtyPageSize);
pbyRomDirtyPage[dwPage] = TRUE; // page is dirty
}
return;
}
static __inline void EraseBlock(DWORD d,DWORD dwNibSize)
{
LPBYTE pbyAddr = pbyRom + d;
while (dwNibSize--)
{
WrDirtyPage(d++); // make page dirty
*pbyAddr++ = 0x0F; // clear address
}
return;
}
static __inline void WriteByte(DWORD d,BYTE byData)
{
WrDirtyPage(d); // make page dirty
_ASSERT(d+1 < dwRomSize); // address valid?
*(pbyRom+d) &= (byData & 0x0F); // write LSB
*(pbyRom+d+1) &= (byData >> 4); // write MSB
return;
}
static __inline BYTE ReadByte(DWORD d)
{
_ASSERT(d+1 < dwRomSize); // address valid?
return *(pbyRom+d)|(*(pbyRom+d+1)<<4); // get byte
}
// //
// write state functions // write state functions
// //
@ -367,8 +412,8 @@ static VOID WrStateE8C(BYTE a, DWORD d)
_ASSERT(d+1 < dwRomSize); // address valid? _ASSERT(d+1 < dwRomSize); // address valid?
// no error set in BWSLBS, because I could alway program a "0" // no error set in BWSLBS, because I could alway program a "0"
*(pbyRom+d++) &= (a & 0x0F); // write LSB WriteByte(d,a); // write byte
*(pbyRom+d++) &= (a >> 4); // write MSB d += 2; // next address
} }
} }
else else
@ -395,11 +440,8 @@ static VOID WrState40(DWORD d)
// byte/word program data // byte/word program data
static VOID WrState40D(BYTE a, DWORD d) static VOID WrState40D(BYTE a, DWORD d)
{ {
d <<= 1; // nibble start address
_ASSERT(d+1 < dwRomSize); // address valid?
// no error set in BWSLBS, because I could alway program a "0" // no error set in BWSLBS, because I could alway program a "0"
*(pbyRom+d++) &= (a & 0x0F); // write LSB WriteByte(d << 1,a); // write byte
*(pbyRom+d) &= (a >> 4); // write MSB
WSMset.byStatusReg |= WSMS; // data written WSMset.byStatusReg |= WSMS; // data written
WSMset.uWrState = WRS_DATA; WSMset.uWrState = WRS_DATA;
return; return;
@ -433,8 +475,7 @@ static VOID WrState20C(BYTE a, DWORD d)
d &= ~(dwBlockSize-1); // start of block d &= ~(dwBlockSize-1); // start of block
dwBlockSize *= 2; // block size in nibbles dwBlockSize *= 2; // block size in nibbles
_ASSERT(d+dwBlockSize <= dwRomSize); // address valid? _ASSERT(d+dwBlockSize <= dwRomSize); // address valid?
// write 128K nibble EraseBlock(d << 1,dwBlockSize); // erase 128K nibble
FillMemory(pbyRom + (d << 1),dwBlockSize,0x0F);
} }
} }
else else
@ -467,7 +508,7 @@ static VOID WrState30C(BYTE a, DWORD d)
WORD wNoOfBlocks = (byQueryTab[0x2E] << 8) | byQueryTab[0x2D]; WORD wNoOfBlocks = (byQueryTab[0x2E] << 8) | byQueryTab[0x2D];
DWORD dwBlockSize = ((byQueryTab[0x30] << 8) | byQueryTab[0x2F]) * 256; DWORD dwBlockSize = ((byQueryTab[0x30] << 8) | byQueryTab[0x2F]) * 256;
LPBYTE pbyBlock = pbyRom; DWORD dwBlockAddr = 0;
dwBlockSize *= 2; // block size in nibbles dwBlockSize *= 2; // block size in nibbles
@ -481,11 +522,11 @@ static VOID WrState30C(BYTE a, DWORD d)
// clear block lock bit // clear block lock bit
WSMset.dwLockCnfg &= ~(1<<i); WSMset.dwLockCnfg &= ~(1<<i);
// write 128K nibble // erase 128K nibble
FillMemory(pbyBlock,dwBlockSize,0x0F); EraseBlock(dwBlockAddr,dwBlockSize);
} }
pbyBlock += dwBlockSize; // next block dwBlockAddr += dwBlockSize; // next block
} }
} }
else else
@ -571,9 +612,7 @@ static VOID WrState60D(BYTE a, DWORD d)
// read array // read array
static BYTE RdStateData(DWORD d) static BYTE RdStateData(DWORD d)
{ {
d <<= 1; // nibble address return ReadByte(d << 1); // get byte
_ASSERT(d+1 < dwRomSize); // address valid?
return *(pbyRom+d)|(*(pbyRom+d+1)<<4); // get byte
} }
// read identifier codes // read identifier codes

View file

@ -28,6 +28,7 @@
#define SRQ2 0x19 // SRQ2 #define SRQ2 0x19 // SRQ2
#define IR_CTRL 0x1a // IR CONTROL #define IR_CTRL 0x1a // IR CONTROL
#define LCR 0x1c // Led Control Register #define LCR 0x1c // Led Control Register
#define LBR 0x1d // Led Buffer Register
#define DISP1CTL 0x20 // Display Start Address #define DISP1CTL 0x20 // Display Start Address
#define LINENIBS 0x25 // Display Line Offset #define LINENIBS 0x25 // Display Line Offset
#define LINECOUNT 0x28 // Display Line Counter #define LINECOUNT 0x28 // Display Line Counter
@ -125,6 +126,9 @@
#define LBZ 0x02 // Led Port Busy #define LBZ 0x02 // Led Port Busy
#define LBF 0x01 // Led Buffer Full #define LBF 0x01 // Led Buffer Full
// 0x1d Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero)
#define LBO 0x01
// 0x28 Display Line Counter LSB [LC3 LC2 LC1 LC0] // 0x28 Display Line Counter LSB [LC3 LC2 LC1 LC0]
#define LC3 0x08 // LC3 - Line Counter Bit3 #define LC3 0x08 // LC3 - Line Counter Bit3
#define LC2 0x04 // LC2 - Line Counter Bit2 #define LC2 0x04 // LC2 - Line Counter Bit2

View file

@ -13,8 +13,6 @@
#define KEYMACROHEAD "Emu-KeyMacro" // macro signature #define KEYMACROHEAD "Emu-KeyMacro" // macro signature
#define KEYHOLDTIME 50
#define MIN_SPEED 0 #define MIN_SPEED 0
#define MAX_SPEED 500 #define MAX_SPEED 500
@ -24,9 +22,10 @@ typedef struct
DWORD dwKeyEvent; // key code DWORD dwKeyEvent; // key code
} KeyData; } KeyData;
INT nMacroState = MACRO_OFF; INT nMacroState = MACRO_OFF;
INT nMacroTimeout = MIN_SPEED; INT nMacroTimeout = MIN_SPEED;
BOOL bMacroRealSpeed = TRUE; BOOL bMacroRealSpeed = TRUE;
DWORD dwMacroMinDelay = 0; // minimum macro play key hold time in ms
static DWORD dwTimeRef; static DWORD dwTimeRef;
@ -49,7 +48,7 @@ static VOID InitializeOFN(LPOPENFILENAME ofn)
static DWORD WINAPI EventThread(LPVOID pParam) static DWORD WINAPI EventThread(LPVOID pParam)
{ {
DWORD dwRead = 0; DWORD dwRead = 0;
DWORD dwData,dwTime = 0; DWORD dwData = 0,dwTime = 0;
while (WaitForSingleObject(hEventPlay,dwTime) == WAIT_TIMEOUT) while (WaitForSingleObject(hEventPlay,dwTime) == WAIT_TIMEOUT)
{ {
@ -59,8 +58,7 @@ static DWORD WINAPI EventThread(LPVOID pParam)
UINT nOut = (dwData >> 16) & 0xFF; UINT nOut = (dwData >> 16) & 0xFF;
BOOL bPress = (dwData >> 24) & 0xFF; BOOL bPress = (dwData >> 24) & 0xFF;
PlayKey(nOut,nIn,bPress); PlayKey(nOut,nIn,bPress);
// KeyboardEvent(bPress,nOut,nIn);
} }
dwTime = nMacroTimeout; // set default speed dwTime = nMacroTimeout; // set default speed
@ -84,6 +82,13 @@ static DWORD WINAPI EventThread(LPVOID pParam)
} }
continue; continue;
} }
// hold the key state the minimum macro play key hold time
if (dwTime < dwMacroMinDelay) dwTime = dwMacroMinDelay;
dwTime -= dwKeyMinDelay; // remove the actual key hold time
// set negative number to zero
if ((dwTime & 0x80000000) != 0) dwTime = 0;
break; // got key information break; // got key information
} }
} }
@ -102,9 +107,7 @@ VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in)
DWORD dwWritten; DWORD dwWritten;
dwWritten = GetTickCount(); // time reference dwWritten = GetTickCount(); // time reference
Data.dwTime = (dwWritten - dwTimeRef - KEYHOLDTIME); Data.dwTime = (dwWritten - dwTimeRef);
// set negative number to zero
if ((Data.dwTime & 0x80000000) != 0) Data.dwTime = 0;
Data.dwTime |= 0x80000000; // set time marker Data.dwTime |= 0x80000000; // set time marker
dwTimeRef = dwWritten; dwTimeRef = dwWritten;
@ -161,14 +164,13 @@ LRESULT OnToolMacroNew(VOID)
_ASSERT(dwWritten == sizeof(dwExtensionLength)); _ASSERT(dwWritten == sizeof(dwExtensionLength));
nMacroState = MACRO_NEW; nMacroState = MACRO_NEW;
UpdateWindowStatus();
MessageBox(hWnd, MessageBox(hWnd,
_T("Press OK to begin to record the Macro."), _T("Press OK to begin to record the Macro."),
_T("Macro Recorder"), _T("Macro Recorder"),
MB_OK|MB_ICONINFORMATION); MB_OK|MB_ICONINFORMATION);
dwTimeRef = GetTickCount() + KEYHOLDTIME; // time reference dwTimeRef = GetTickCount(); // time reference
return 0; return 0;
} }
@ -242,7 +244,6 @@ LRESULT OnToolMacroPlay(VOID)
hEventPlay = CreateEvent(NULL,FALSE,FALSE,NULL); hEventPlay = CreateEvent(NULL,FALSE,FALSE,NULL);
nMacroState = MACRO_PLAY; nMacroState = MACRO_PLAY;
UpdateWindowStatus();
// start playing thread // start playing thread
VERIFY(hThreadEv = CreateThread(NULL,0,&EventThread,NULL,0,&dwThreadId)); VERIFY(hThreadEv = CreateThread(NULL,0,&EventThread,NULL,0,&dwThreadId));
@ -273,7 +274,6 @@ LRESULT OnToolMacroStop(VOID)
if (hMacroFile != INVALID_HANDLE_VALUE) CloseHandle(hMacroFile); if (hMacroFile != INVALID_HANDLE_VALUE) CloseHandle(hMacroFile);
nMacroState = MACRO_OFF; nMacroState = MACRO_OFF;
UpdateWindowStatus();
} }
return 0; return 0;
} }

View file

@ -59,7 +59,7 @@ static LPCTSTR szLexDelim[] =
_T(" \t\r") // valid whitespaces for LEX_PARAM _T(" \t\r") // valid whitespaces for LEX_PARAM
}; };
static KmlToken pLexToken[] = static CONST KmlToken pLexToken[] =
{ {
{TOK_ANNUNCIATOR,000001,11,_T("Annunciator")}, {TOK_ANNUNCIATOR,000001,11,_T("Annunciator")},
{TOK_BACKGROUND, 000000,10,_T("Background")}, {TOK_BACKGROUND, 000000,10,_T("Background")},
@ -104,7 +104,7 @@ static KmlToken pLexToken[] =
{TOK_VGA, 000001, 3,_T("Vga")}, // for PPC compatibility reasons {TOK_VGA, 000001, 3,_T("Vga")}, // for PPC compatibility reasons
{TOK_LCD, 000000, 3,_T("Lcd")}, {TOK_LCD, 000000, 3,_T("Lcd")},
{TOK_END, 000000, 3,_T("End")}, {TOK_END, 000000, 3,_T("End")},
{0, 000000, 0,_T("")}, {TOK_NONE, 000000, 0,_T("")}
}; };
static CONST TokenId eIsGlobalBlock[] = static CONST TokenId eIsGlobalBlock[] =
@ -146,7 +146,7 @@ static VOID ClearLog()
nLogLength = 0; nLogLength = 0;
if (szLog != NULL) if (szLog != NULL)
{ {
HeapFree(hHeap,0,szLog); free(szLog);
szLog = NULL; szLog = NULL;
} }
return; return;
@ -158,7 +158,7 @@ static VOID AddToLog(LPCTSTR szString)
if (szLog == NULL) if (szLog == NULL)
{ {
nLogLength = nLength + 1; // \0 nLogLength = nLength + 1; // \0
szLog = HeapAlloc(hHeap,0,nLogLength*sizeof(szLog[0])); szLog = malloc(nLogLength*sizeof(szLog[0]));
if (szLog==NULL) if (szLog==NULL)
{ {
nLogLength = 0; nLogLength = 0;
@ -168,7 +168,7 @@ static VOID AddToLog(LPCTSTR szString)
} }
else else
{ {
LPTSTR szLogTmp = HeapReAlloc(hHeap,0,szLog,(nLogLength+nLength)*sizeof(szLog[0])); LPTSTR szLogTmp = realloc(szLog,(nLogLength+nLength)*sizeof(szLog[0]));
if (szLogTmp == NULL) if (szLogTmp == NULL)
{ {
ClearLog(); ClearLog();
@ -268,9 +268,9 @@ static VOID DestroyKmlList(VOID)
while (pKmlList) while (pKmlList)
{ {
pList = pKmlList->pNext; pList = pKmlList->pNext;
HeapFree(hHeap,0,pKmlList->szFilename); free(pKmlList->szFilename);
HeapFree(hHeap,0,pKmlList->szTitle); free(pKmlList->szTitle);
HeapFree(hHeap,0,pKmlList); free(pKmlList);
pKmlList = pList; pKmlList = pList;
} }
return; return;
@ -313,7 +313,7 @@ static VOID CreateKmlList(VOID)
FreeBlocks(pBlock); FreeBlocks(pBlock);
continue; continue;
} }
VERIFY(pScript = HeapAlloc(hHeap,0,sizeof(KmlScript))); VERIFY(pScript = malloc(sizeof(KmlScript)));
pScript->szFilename = DuplicateString(pFindFileData.cFileName); pScript->szFilename = DuplicateString(pFindFileData.cFileName);
szTitle = GetStringParam(pBlock,TOK_GLOBAL,TOK_TITLE,0); szTitle = GetStringParam(pBlock,TOK_GLOBAL,TOK_TITLE,0);
if (szTitle == NULL) szTitle = pScript->szFilename; if (szTitle == NULL) szTitle = pScript->szFilename;
@ -497,7 +497,7 @@ static LPTSTR MapKMLFile(HANDLE hFile)
goto fail; goto fail;
} }
lpBuf = HeapAlloc(hHeap,0,(dwFileSizeLow+1)*sizeof(lpBuf[0])); lpBuf = malloc((dwFileSizeLow+1)*sizeof(lpBuf[0]));
if (lpBuf == NULL) if (lpBuf == NULL)
{ {
PrintfToLog(_T("Cannot allocate %i bytes."), (dwFileSizeLow+1)*sizeof(lpBuf[0])); PrintfToLog(_T("Cannot allocate %i bytes."), (dwFileSizeLow+1)*sizeof(lpBuf[0]));
@ -505,17 +505,17 @@ static LPTSTR MapKMLFile(HANDLE hFile)
} }
#if defined _UNICODE #if defined _UNICODE
{ {
LPSTR szTmp = HeapAlloc(hHeap,0,dwFileSizeLow+1); LPSTR szTmp = malloc(dwFileSizeLow+1);
if (szTmp == NULL) if (szTmp == NULL)
{ {
HeapFree(hHeap,0,lpBuf); free(lpBuf);
lpBuf = NULL; lpBuf = NULL;
PrintfToLog(_T("Cannot allocate %i bytes."), dwFileSizeLow+1); PrintfToLog(_T("Cannot allocate %i bytes."), dwFileSizeLow+1);
goto fail; goto fail;
} }
ReadFile(hFile, szTmp, dwFileSizeLow, &lBytesRead, NULL); ReadFile(hFile, szTmp, dwFileSizeLow, &lBytesRead, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, lpBuf, dwFileSizeLow+1); MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, lpBuf, dwFileSizeLow+1);
HeapFree(hHeap,0,szTmp); free(szTmp);
} }
#else #else
{ {
@ -637,10 +637,10 @@ static TokenId ParseToken(UINT nMode)
if (bDebug) // token not found if (bDebug) // token not found
{ {
// allocate target string memory with token length // allocate target string memory with token length
LPTSTR szToken = HeapAlloc(hHeap,0,(i+1) * sizeof(szToken[0])); LPTSTR szToken = malloc((i+1) * sizeof(szToken[0]));
lstrcpyn(szToken,szText,i+1); // copy token text and append EOS lstrcpyn(szToken,szText,i+1); // copy token text and append EOS
PrintfToLog(_T("%i: Undefined token %s"),nLexLine,szToken); PrintfToLog(_T("%i: Undefined token %s"),nLexLine,szToken);
HeapFree(hHeap,0,szToken); free(szToken);
} }
return TOK_NONE; return TOK_NONE;
} }
@ -665,21 +665,33 @@ static LPTSTR ParseString(VOID)
szText++; // skip leading '"' szText++; // skip leading '"'
nLength = 0; nLength = 0;
nBlock = 256; nBlock = 256;
lpszString = HeapAlloc(hHeap,0,nBlock * sizeof(lpszString[0])); lpszString = malloc(nBlock * sizeof(lpszString[0]));
while (*szText != _T('"')) while (*szText != _T('"'))
{ {
if (nLength == nBlock - 1) // ran out of buffer space if (nLength == nBlock - 1) // ran out of buffer space
{ {
nBlock += 256; nBlock += 256;
lpszString = HeapReAlloc(hHeap,0,lpszString,nBlock * sizeof(lpszString[0])); lpszString = realloc(lpszString,nBlock * sizeof(lpszString[0]));
}
if (*szText == _T('\\')) // escape char
{
// skip a '\' escape char before a quotation to
// decode the \" sequence as a quotation mark inside text
switch (szText[1])
{
case _T('\"'):
case _T('\\'):
++szText; // skip escape char '\'
break;
}
} }
if (*szText == _T('\\')) szText++; // skip '\' escape char to decode \"
if (*szText == 0) // EOS found inside string if (*szText == 0) // EOS found inside string
{ {
lpszString[nLength] = 0; // set EOS lpszString[nLength] = 0; // set EOS
PrintfToLog(_T("%i: Invalid string %s."), nLexLine, lpszString); PrintfToLog(_T("%i: Invalid string %s."), nLexLine, lpszString);
HeapFree(hHeap,0,lpszString); free(lpszString);
return NULL; return NULL;
} }
lpszString[nLength++] = *szText++; // save char lpszString[nLength++] = *szText++; // save char
@ -688,7 +700,7 @@ static LPTSTR ParseString(VOID)
lpszString[nLength] = 0; // set EOS lpszString[nLength] = 0; // set EOS
// release unnecessary allocated bytes // release unnecessary allocated bytes
return HeapReAlloc(hHeap,0,lpszString,(nLength+1) * sizeof(lpszString[0])); return realloc(lpszString,(nLength+1) * sizeof(lpszString[0]));
} }
static TokenId Lex(UINT nMode) static TokenId Lex(UINT nMode)
@ -736,7 +748,7 @@ static KmlLine* ParseLine(TokenId eCommand)
} }
if (pLexToken[i].nLen == 0) return NULL; if (pLexToken[i].nLen == 0) return NULL;
pLine = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlLine)); pLine = calloc(1,sizeof(KmlLine));
pLine->eCommand = eCommand; pLine->eCommand = eCommand;
for (j = 0, nParams = pLexToken[i].nParams; TRUE; nParams >>= 3) for (j = 0, nParams = pLexToken[i].nParams; TRUE; nParams >>= 3)
@ -779,18 +791,18 @@ static KmlLine* ParseLine(TokenId eCommand)
} }
// if last argument was string, free it // if last argument was string, free it
if (eToken == TOK_STRING) HeapFree(hHeap,0,szLexString); if (eToken == TOK_STRING) free(szLexString);
nParams = pLexToken[i].nParams; // get argument types of command nParams = pLexToken[i].nParams; // get argument types of command
for (i = 0; i < j; ++i) // handle all scanned arguments for (i = 0; i < j; ++i) // handle all scanned arguments
{ {
if ((nParams & 7) == TYPE_STRING) // string type if ((nParams & 7) == TYPE_STRING) // string type
{ {
HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]); free((LPVOID)pLine->nParam[i]);
} }
nParams >>= 3; // next argument type nParams >>= 3; // next argument type
} }
HeapFree(hHeap,0,pLine); free(pLine);
return NULL; return NULL;
} }
@ -833,7 +845,7 @@ static KmlLine* IncludeLines(LPCTSTR szFilename)
nLexLine = uOldLine; nLexLine = uOldLine;
szText = szOldText; szText = szOldText;
HeapFree(hHeap,0,lpbyBuf); free(lpbyBuf);
return pLine; return pLine;
} }
@ -845,7 +857,7 @@ static KmlLine* ParseLines(VOID)
TokenId eToken; TokenId eToken;
UINT nLevel = 0; UINT nLevel = 0;
while ((eToken = Lex(LEX_COMMAND))) while ((eToken = Lex(LEX_COMMAND)) != TOK_NONE)
{ {
if (IsGlobalBlock(eToken)) // check for block command if (IsGlobalBlock(eToken)) // check for block command
{ {
@ -871,7 +883,7 @@ static KmlLine* ParseLines(VOID)
{ {
pLine = pFirst = IncludeLines(szLexString); pLine = pFirst = IncludeLines(szLexString);
} }
HeapFree(hHeap,0,szFilename); // free memory free(szFilename); // free memory
if (pLine == NULL) // parsing error if (pLine == NULL) // parsing error
goto abort; goto abort;
while (pLine->pNext) pLine=pLine->pNext; while (pLine->pNext) pLine=pLine->pNext;
@ -921,7 +933,7 @@ static KmlBlock* ParseBlock(TokenId eType)
nLinesIncludeLevel = 0; nLinesIncludeLevel = 0;
VERIFY(pBlock = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlBlock))); VERIFY(pBlock = calloc(1,sizeof(KmlBlock)));
pBlock->eType = eType; pBlock->eType = eType;
for (i = 0; pLexToken[i].nLen; ++i) // search for token for (i = 0; pLexToken[i].nLen; ++i) // search for token
@ -937,8 +949,9 @@ static KmlBlock* ParseBlock(TokenId eType)
eToken = Lex(LEX_PARAM); // decode argument eToken = Lex(LEX_PARAM); // decode argument
if (eToken != TOK_INTEGER) if (eToken != TOK_INTEGER)
{ {
if (eToken == TOK_STRING) free(szLexString);
PrintfToLog(_T("%i: Block %s parameter must be an integer."), nLexLine, pLexToken[i].szName); PrintfToLog(_T("%i: Block %s parameter must be an integer."), nLexLine, pLexToken[i].szName);
HeapFree(hHeap,0,pBlock); free(pBlock);
return NULL; return NULL;
} }
@ -949,14 +962,14 @@ static KmlBlock* ParseBlock(TokenId eType)
if (eToken != TOK_EOL) if (eToken != TOK_EOL)
{ {
PrintfToLog(_T("%i: Too many parameters for block %s."), nLexLine, pLexToken[i].szName); PrintfToLog(_T("%i: Too many parameters for block %s."), nLexLine, pLexToken[i].szName);
HeapFree(hHeap,0,pBlock); free(pBlock);
return NULL; return NULL;
} }
pBlock->pFirstLine = ParseLines(); pBlock->pFirstLine = ParseLines();
if (pBlock->pFirstLine == NULL) // break on ParseLines error if (pBlock->pFirstLine == NULL) // break on ParseLines error
{ {
HeapFree(hHeap,0,pBlock); free(pBlock);
pBlock = NULL; pBlock = NULL;
} }
@ -1002,7 +1015,7 @@ static KmlBlock* IncludeBlocks(LPCTSTR szFilename)
nLexLine = uOldLine; nLexLine = uOldLine;
szText = szOldText; szText = szOldText;
HeapFree(hHeap,0,lpbyBuf); free(lpbyBuf);
return pFirst; return pFirst;
} }
@ -1029,7 +1042,7 @@ static KmlBlock* ParseBlocks(VOID)
pBlock = pBlock->pNext = IncludeBlocks(szLexString); pBlock = pBlock->pNext = IncludeBlocks(szLexString);
else else
pBlock = pFirst = IncludeBlocks(szLexString); pBlock = pFirst = IncludeBlocks(szLexString);
HeapFree(hHeap,0,szFilename); // free memory free(szFilename); // free memory
if (pBlock == NULL) // parsing error if (pBlock == NULL) // parsing error
goto abort; goto abort;
while (pBlock->pNext) pBlock=pBlock->pNext; while (pBlock->pNext) pBlock=pBlock->pNext;
@ -1445,13 +1458,13 @@ static VOID FreeLines(KmlLine* pLine)
{ {
if ((nParams&7) == TYPE_STRING) // string type if ((nParams&7) == TYPE_STRING) // string type
{ {
HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]); free((LPVOID)pLine->nParam[i]);
} }
i++; // incr. parameter buffer index i++; // incr. parameter buffer index
nParams >>= 3; // next argument type nParams >>= 3; // next argument type
} }
pLine = pLine->pNext; // get next line pLine = pLine->pNext; // get next line
HeapFree(hHeap,0,pThisLine); free(pThisLine);
} }
return; return;
} }
@ -1463,7 +1476,7 @@ VOID FreeBlocks(KmlBlock* pBlock)
KmlBlock* pThisBlock = pBlock; KmlBlock* pThisBlock = pBlock;
pBlock = pBlock->pNext; pBlock = pBlock->pNext;
FreeLines(pThisBlock->pFirstLine); FreeLines(pThisBlock->pFirstLine);
HeapFree(hHeap,0,pThisBlock); free(pThisBlock);
} }
return; return;
} }
@ -1481,11 +1494,8 @@ VOID KillKML(VOID)
DestroyMainBitmap(); DestroyMainBitmap();
if (hPalette) if (hPalette)
{ {
BOOL err;
if (hWindowDC) SelectPalette(hWindowDC, hOldPalette, FALSE); if (hWindowDC) SelectPalette(hWindowDC, hOldPalette, FALSE);
err = DeleteObject(hPalette); VERIFY(DeleteObject(hPalette));
_ASSERT(err != FALSE); // freed resource memory
hPalette = NULL; hPalette = NULL;
} }
bClicking = FALSE; bClicking = FALSE;
@ -1508,7 +1518,6 @@ VOID KillKML(VOID)
nLcdZoom = 1; nLcdZoom = 1;
cCurrentRomType = 0; cCurrentRomType = 0;
nCurrentClass = 0; nCurrentClass = 0;
UpdateWindowStatus();
ResizeWindow(); ResizeWindow();
return; return;
} }
@ -1840,8 +1849,16 @@ VOID ReloadButtons(BYTE *Keyboard_Row, UINT nSize)
{ {
if (pButton[i].nOut < nSize) // valid out code if (pButton[i].nOut < nSize) // valid out code
{ {
// get state of button from keyboard matrix if (pButton[i].nIn == 0x8000) // ON key
pButton[i].bDown = ((Keyboard_Row[pButton[i].nOut] & pButton[i].nIn) != 0); {
// get state of ON button from interrupt line
pButton[i].bDown = (Chipset.IR15X != 0);
}
else
{
// get state of button from keyboard matrix
pButton[i].bDown = ((Keyboard_Row[pButton[i].nOut] & pButton[i].nIn) != 0);
}
// any key pressed? // any key pressed?
bKeyPressed = bKeyPressed || pButton[i].bDown; bKeyPressed = bKeyPressed || pButton[i].bDown;
@ -1987,7 +2004,7 @@ VOID MouseButtonUpAt(UINT nFlags, DWORD x, DWORD y)
bClicking = FALSE; bClicking = FALSE;
uButtonClicked = 0; uButtonClicked = 0;
return; return;
UNREFERENCED_PARAMETER(nFlags); UNREFERENCED_PARAMETER(nFlags);
} }
VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y) VOID MouseMovesTo(UINT nFlags, DWORD x, DWORD y)
@ -2109,7 +2126,7 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename)
HANDLE hFile; HANDLE hFile;
LPTSTR lpBuf; LPTSTR lpBuf;
KmlBlock* pBlock; KmlBlock* pBlock;
DWORD eToken; TokenId eToken;
SetCurrentDirectory(szEmuDirectory); SetCurrentDirectory(szEmuDirectory);
hFile = CreateFile(szFilename, hFile = CreateFile(szFilename,
@ -2137,7 +2154,7 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename)
} }
CleanLex(); CleanLex();
ClearLog(); ClearLog();
HeapFree(hHeap,0,lpBuf); free(lpBuf);
return pBlock; return pBlock;
} }
@ -2173,7 +2190,7 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
pKml = ParseBlocks(); pKml = ParseBlocks();
CleanLex(); CleanLex();
HeapFree(hHeap,0,lpBuf); free(lpBuf);
if (pKml == NULL) goto quit; if (pKml == NULL) goto quit;
pBlock = pKml; pBlock = pKml;

View file

@ -987,6 +987,29 @@ VOID IOBit(DWORD d, BYTE b, BOOL s) // set/clear bit in I/O section
LeaveCriticalSection(&csIOLock); LeaveCriticalSection(&csIOLock);
} }
static DWORD ReadT2Acc(VOID)
{
static DWORD dwCyc = 0; // CPU cycle counter at last timer2 read access
DWORD dwCycDif;
// CPU cycles since last call
dwCycDif = (DWORD) (Chipset.cycles & 0xFFFFFFFF) - dwCyc;
dwCyc = (DWORD) (Chipset.cycles & 0xFFFFFFFF);
// maybe CPU speed measurement, slow down the next 10 CPU opcodes
if (dwCycDif < 150)
{
EnterCriticalSection(&csSlowLock);
{
InitAdjustSpeed(); // init variables if necessary
nOpcSlow = 10; // slow down next 10 opcodes
}
LeaveCriticalSection(&csSlowLock);
}
return ReadT2();
}
VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate) VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate)
{ {
BOOL bNINT,bNINT2; BOOL bNINT,bNINT2;
@ -1173,8 +1196,13 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate)
#endif #endif
break; break;
case 0x1B: *a = 0; break; case 0x1B: *a = 0; break;
case 0x1C: *a = 0; break; // LED CONTROL case 0x1C: // LED CONTROL
case 0x1D: *a = 0; break; // LED BUFFER // put LBF and LBZ always to zero to indicate a free REDEYE buffer and formatter
*a = (Chipset.IORam[d] & (LED|ELBE));
break;
case 0x1D: // LED BUFFER
*a = (Chipset.IORam[d] & LBO);
break;
// case 0x1E: *a = Chipset.IORam[d]; break; // case 0x1E: *a = Chipset.IORam[d]; break;
// case 0x1F: *a = Chipset.IORam[d]; break; // case 0x1F: *a = Chipset.IORam[d]; break;
case 0x20: *a = 3; break; case 0x20: *a = 3; break;
@ -1227,14 +1255,14 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate)
case 0x35: *a = 0; break; case 0x35: *a = 0; break;
case 0x36: *a = 0; break; case 0x36: *a = 0; break;
case 0x37: *a = ReadT1(); break; case 0x37: *a = ReadT1(); break;
case 0x38: Nunpack(a, ReadT2() , s); return; case 0x38: Nunpack(a, ReadT2Acc() , s); return;
case 0x39: Nunpack(a, ReadT2()>> 4, s); return; case 0x39: Nunpack(a, ReadT2Acc()>> 4, s); return;
case 0x3A: Nunpack(a, ReadT2()>> 8, s); return; case 0x3A: Nunpack(a, ReadT2Acc()>> 8, s); return;
case 0x3B: Nunpack(a, ReadT2()>>12, s); return; case 0x3B: Nunpack(a, ReadT2Acc()>>12, s); return;
case 0x3C: Nunpack(a, ReadT2()>>16, s); return; case 0x3C: Nunpack(a, ReadT2Acc()>>16, s); return;
case 0x3D: Nunpack(a, ReadT2()>>20, s); return; case 0x3D: Nunpack(a, ReadT2Acc()>>20, s); return;
case 0x3E: Nunpack(a, ReadT2()>>24, s); return; case 0x3E: Nunpack(a, ReadT2Acc()>>24, s); return;
case 0x3F: Nunpack(a, ReadT2()>>28, s); return; case 0x3F: Nunpack(a, ReadT2Acc()>>28, s); return;
default: *a = Chipset.IORam[d]; default: *a = Chipset.IORam[d];
} }
d++; a++; d++; a++;
@ -1589,12 +1617,27 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
} }
#endif #endif
} }
if ((c^Chipset.IORam[d])&ELBE) // ELBE bit changed
{
// Led Service ReQuest on Led Buffer Empty enabled
BOOL bLSRQ = (c & (ELBE | LBF)) == ELBE;
IOBit(SRQ2,LSRQ,bLSRQ); // update LSRQ bit
if (bLSRQ) // interrupt on Led Buffer Empty enabled
{
Chipset.SoftInt = TRUE;
bInterrupt = TRUE;
}
}
Chipset.IORam[d]=c; Chipset.IORam[d]=c;
break; break;
// 0011D = NS:LBR // 0011D = NS:LBR
// 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero) // 0011D @ Led Buffer Register [0 0 0 LBO] (bits 1-3 read zero)
case 0x1D: Chipset.IORam[d]=c&1; break; case 0x1D:
IrPrinter((BYTE)(c&LBO));
Chipset.IORam[d]=c&LBO;
break;
// 0011E = NS:SCRATCHPAD // 0011E = NS:SCRATCHPAD
// 0011E @ Scratch pad // 0011E @ Scratch pad

View file

@ -73,7 +73,7 @@ BOOL MruInit(INT nNum)
if (nEntry > 0) // allocate MRU table if (nEntry > 0) // allocate MRU table
{ {
// create MRU table // create MRU table
if ((ppszFiles = HeapAlloc(hHeap,0,nEntry * sizeof(*ppszFiles))) == NULL) if ((ppszFiles = malloc(nEntry * sizeof(*ppszFiles))) == NULL)
return TRUE; return TRUE;
// fill each entry // fill each entry
@ -104,12 +104,12 @@ VOID MruCleanup(VOID)
for (i = 0; i < nEntry; ++i) // cleanup each entry for (i = 0; i < nEntry; ++i) // cleanup each entry
{ {
if (ppszFiles[i] != NULL) if (ppszFiles[i] != NULL)
HeapFree(hHeap,0,ppszFiles[i]); // cleanup entry free(ppszFiles[i]); // cleanup entry
} }
if (ppszFiles != NULL) // table defined if (ppszFiles != NULL) // table defined
{ {
HeapFree(hHeap,0,ppszFiles); // free table free(ppszFiles); // free table
ppszFiles = NULL; ppszFiles = NULL;
} }
return; return;
@ -140,7 +140,7 @@ VOID MruAdd(LPCTSTR lpszEntry)
i = nEntry - 1; // last index i = nEntry - 1; // last index
if (ppszFiles[i] != NULL) if (ppszFiles[i] != NULL)
HeapFree(hHeap,0,ppszFiles[i]); // free oldest entry free(ppszFiles[i]); // free oldest entry
for (; i > 0; --i) // move old entries 1 line down for (; i > 0; --i) // move old entries 1 line down
{ {
@ -156,7 +156,7 @@ VOID MruAdd(LPCTSTR lpszEntry)
VOID MruRemove(INT nIndex) VOID MruRemove(INT nIndex)
{ {
HeapFree(hHeap,0,ppszFiles[nIndex]); // free entry free(ppszFiles[nIndex]); // free entry
for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up for (; nIndex < nEntry - 1; ++nIndex) // move below entries 1 line up
{ {
@ -198,10 +198,10 @@ LPCTSTR MruFilename(INT nIndex)
VOID MruUpdateMenu(VOID) VOID MruUpdateMenu(VOID)
{ {
TCHAR szCurPath[MAX_PATH]; TCHAR szCurPath[MAX_PATH];
HANDLE hMenu; HMENU hMenu;
BOOL bEmpty; BOOL bEmpty;
INT i; INT i;
if (nEntry == 0) return; // no entries if (nEntry == 0) return; // no entries
@ -309,7 +309,6 @@ VOID MruReadList(VOID)
{ {
TCHAR szFilename[MAX_PATH]; TCHAR szFilename[MAX_PATH];
TCHAR szItemname[32]; TCHAR szItemname[32];
LPTSTR lpszValue;
INT i; INT i;
_ASSERT(ppszFiles != NULL); // MRU not initialized _ASSERT(ppszFiles != NULL); // MRU not initialized
@ -321,9 +320,8 @@ VOID MruReadList(VOID)
if (ppszFiles[i] != NULL) // already filled if (ppszFiles[i] != NULL) // already filled
{ {
HeapFree(hHeap,0,ppszFiles[i]); // free entry free(ppszFiles[i]); // free entry
ppszFiles[i] = NULL; // clear last line ppszFiles[i] = NULL; // clear last line
lpszValue = _T("");
} }
if (*szFilename) // read a valid entry if (*szFilename) // read a valid entry

View file

@ -1040,7 +1040,7 @@ VOID o807(LPBYTE I) // SHUTDN
// emulation of BS reset circuit in deep sleep // emulation of BS reset circuit in deep sleep
// HP39/40G, HP48GX, HP49G, display off, card control off or in slow mode // HP39/40G, HP48GX, HP49G, display off, card control off or in slow mode
if ( (cCurrentRomType=='E' || cCurrentRomType=='G' || cCurrentRomType=='X') if ( (cCurrentRomType=='E' || cCurrentRomType=='G' || cCurrentRomType=='X')
&& (w.IORam[BITOFFSET]&DON) == 0 && (w.IORam[BITOFFSET]&DON) == 0
&& ((w.IORam[CARDCTL]&(ECDT|RCDT)) != (ECDT|RCDT))) && ((w.IORam[CARDCTL]&(ECDT|RCDT)) != (ECDT|RCDT)))
{ {
// on HP48GX ROM must be selected (DA19=1) and // on HP48GX ROM must be selected (DA19=1) and
@ -2143,7 +2143,7 @@ VOID o8Fd5(LPBYTE I) // GOSBVL #ddddd
return; return;
} }
// ?r=s f // ?r=s f
VOID o9a0(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.A, w.B, I[1]); GOYES3; } VOID o9a0(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.A, w.B, I[1]); GOYES3; }
VOID o9a1(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.B, w.C, I[1]); GOYES3; } VOID o9a1(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.B, w.C, I[1]); GOYES3; }
VOID o9a2(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.C, w.A, I[1]); GOYES3; } VOID o9a2(LPBYTE I) { w.cycles+=6+F_l[I[1]]; w.pc+=3; TFe(w.C, w.A, I[1]); GOYES3; }

View file

@ -48,7 +48,7 @@ static __inline LPBYTE FASTPTR(DWORD d)
if ( !(Chipset.IOCfig && ((d & 0xFFFC0) == Chipset.IOBase)) if ( !(Chipset.IOCfig && ((d & 0xFFFC0) == Chipset.IOBase))
&& RMap[u] != NULL // page valid && RMap[u] != NULL // page valid
&& ( v < 0x1000 - ARRAYSIZEOF(lpbyPage) // complete opcode inside page && ( v < 0x1000 - ARRAYSIZEOF(pbyNULL) // complete opcode inside page
// or next page continue linear addressing // or next page continue linear addressing
|| (RMap[u] + 0x1000 == RMap[(u+1) & (ARRAYSIZEOF(RMap)-1)]) || (RMap[u] + 0x1000 == RMap[(u+1) & (ARRAYSIZEOF(RMap)-1)])
) )
@ -59,7 +59,7 @@ static __inline LPBYTE FASTPTR(DWORD d)
else else
{ {
lpbyPage = pbyNULL; // memory allocation lpbyPage = pbyNULL; // memory allocation
Npeek(lpbyPage, d, ARRAYSIZEOF(lpbyPage)); // fill with data (LAHEX + 16 digits = longest opcode) Npeek(lpbyPage, d, ARRAYSIZEOF(pbyNULL)); // fill with data (LAHEX + 16 digits = longest opcode)
} }
return lpbyPage; return lpbyPage;
} }

View file

@ -4,7 +4,9 @@
#define _WIN32_IE 0x0200 #define _WIN32_IE 0x0200
#define _CRT_SECURE_NO_DEPRECATE #define _CRT_SECURE_NO_DEPRECATE
#define _CRTDBG_MAP_ALLOC
#include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <tchar.h> #include <tchar.h>
#include <shellapi.h> #include <shellapi.h>

177
Sources/Emu48/REDEYE.C Normal file
View file

@ -0,0 +1,177 @@
/*
* redeye.c
*
* This file is part of Emu48
*
* Copyright (C) 2011 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
#include "io.h"
#define ERR_CHAR 127 // character for transfer error
#define H1 0x78
#define H2 0xE6
#define H3 0xD5
#define H4 0x8B
// HP redeye correction masks
static CONST BYTE byEmask[] = { H1, H2, H3, H4 };
static __inline UINT MAX(UINT a, UINT b)
{
return (a>b)?a:b;
}
static __inline BYTE Parity(BYTE b)
{
b ^= (b >> 4);
b ^= (b >> 2);
b ^= (b >> 1);
return b & 1;
}
static __inline BYTE CreateCorrectionBits(BYTE b)
{
INT i;
BYTE byVal = 0;
for (i = 0; i < ARRAYSIZEOF(byEmask);++i)
{
byVal <<= 1;
byVal |= Parity((BYTE) (b & byEmask[i]));
}
return byVal;
}
static __inline WORD CorrectData(WORD wData,WORD wMissed)
{
while ((wMissed & 0xFF) != 0) // clear every missed bit in data area
{
BYTE byBitMask;
// detect valid H(i) mask
WORD wMi = 0x800; // first M(i) bit
INT i = 0; // index to first H(i) mask
while (TRUE)
{
if ((wMissed & wMi) == 0) // possible valid mask
{
_ASSERT(i < ARRAYSIZEOF(byEmask));
// select bit to correct
byBitMask = wMissed & byEmask[i];
if (Parity(byBitMask)) // only one bit set (parity odd)
break; // -> valid H(i) mask
}
wMi >>= 1; // next M(i) bit
i++; // next H(i) mask
}
// correct bit with H(i) mask
wMissed ^= byBitMask; // clear this missed bit
// parity odd -> wrong data value
if (Parity((BYTE) ((wData & byEmask[i]) ^ ((wData & wMi) >> 8))))
wData ^= byBitMask; // correct value
}
return wData & 0xFF; // only data byte is correct
}
VOID IrPrinter(BYTE c)
{
static INT nFrame = 0; // frame counter
static DWORD dwData = 0; // half bit data container
static INT nStart = 0; // frame counter disabled
BOOL bLSRQ;
dwData = (dwData << 1) | (c & LBO); // grab the last 32 bit send through IR
// Led Service ReQuest on Led Buffer Empty enabled
bLSRQ = (Chipset.IORam[LCR] & ELBE) != 0;
IOBit(SRQ2,LSRQ,bLSRQ); // update LSRQ bit
if (bLSRQ) // interrupt on Led Buffer Empty enabled
{
Chipset.SoftInt = TRUE; // execute interrupt
bInterrupt = TRUE;
}
// HP40G and HP49G have no IR transmitter Led
if ((cCurrentRomType == 'E' && nCurrentClass == 40) || cCurrentRomType == 'X')
return;
if (nFrame == 0) // waiting for start bit condition
{
if ((dwData & 0x3F) == 0x07) // start bit condition (000111 pattern)
{
nStart = 1; // enable frame counter
}
}
if (nFrame == 24) // 24 half bit received
{
INT i;
WORD wData = 0; // data container
WORD wMissed = 0; // missed bit container
INT nCount = 0; // no. of missed bits
nFrame = 0; // reset for next character
nStart = 0; // disable frame counter
// separate to data and missed bits
for (i = 0; i < 12; ++i) // 12 bit frames
{
BYTE b = (BYTE) (dwData & 3); // last 2 half bits
if (b == 0x0 || b == 0x3) // illegal half bit combination
{
wMissed |= (1 << i); // this is a missed bit
++nCount; // incr. number of missed bits
}
else // valid data bit
{
wData |= ((b >> 1) << i); // add data bit
}
dwData >>= 2; // next 2 half bits
}
if (nCount <= 2) // error can be fixed
{
BYTE byOrgParity,byNewParity;
byOrgParity = wData >> 8; // the original parity information with missed bits
byNewParity = ~(wMissed >> 8); // missed bit mask for recalculated parity
if (nCount > 0) // error correction
{
wData = CorrectData(wData,wMissed);
}
wData &= 0xFF; // remove parity information
// recalculate parity data
byNewParity &= CreateCorrectionBits((BYTE) wData);
// wrong parity
if (byOrgParity != byNewParity)
wData = ERR_CHAR; // character for transfer error
}
else
{
wData = ERR_CHAR; // character for transfer error
}
SendByteUdp((BYTE) wData); // send data byte
return;
}
nFrame += nStart; // next frame
return;
}

View file

@ -12,53 +12,57 @@
#define IDR_DEBUG_STACK 106 #define IDR_DEBUG_STACK 106
#define IDB_CHECKBOX 107 #define IDB_CHECKBOX 107
#define IDD_ABOUT 108 #define IDD_ABOUT 108
#define IDD_SETTINGS 109 #define IDD_SET_GENERAL 109
#define IDD_CHOOSEKML 110 #define IDD_SET_MEMORY 110
#define IDD_KMLLOG 111 #define IDD_SET_PERIPHERAL 111
#define IDD_DISASM 112 #define IDD_CHOOSEKML 112
#define IDD_DEBUG 113 #define IDD_KMLLOG 113
#define IDD_NEWVALUE 114 #define IDD_DISASM 114
#define IDD_ENTERADR 115 #define IDD_DEBUG 115
#define IDD_BREAKEDIT 116 #define IDD_NEWVALUE 116
#define IDD_ENTERBREAK 117 #define IDD_ENTERADR 117
#define IDD_INSTRUCTIONS 118 #define IDD_BREAKEDIT 118
#define IDD_WRITEONLYREG 119 #define IDD_ENTERBREAK 119
#define IDD_FIND 120 #define IDD_INSTRUCTIONS 120
#define IDD_PROFILE 121 #define IDD_WRITEONLYREG 121
#define IDD_RPLVIEW 122 #define IDD_FIND 122
#define IDD_MACROSET 123 #define IDD_PROFILE 123
#define IDD_DEBUG_SETTINGS 124 #define IDD_RPLVIEW 124
#define IDD_MACROSET 125
#define IDD_DEBUG_MEMSAVE 126
#define IDD_DEBUG_MEMLOAD 127
#define IDD_DEBUG_SETTINGS 128
#define IDC_REALSPEED 1000 #define IDC_REALSPEED 1000
#define IDC_GRAYSCALE 1001 #define IDC_GRAYSCALE 1001
#define IDC_ALWAYSONTOP 1002 #define IDC_ALWAYSONTOP 1002
#define IDC_ACTFOLLOWSMOUSE 1003 #define IDC_ACTFOLLOWSMOUSE 1003
#define IDC_AUTOSAVE 1004 #define IDC_SINGLEINSTANCE 1004
#define IDC_AUTOSAVEONEXIT 1005 #define IDC_AUTOSAVE 1005
#define IDC_OBJECTLOADWARNING 1006 #define IDC_AUTOSAVEONEXIT 1006
#define IDC_ALWAYSDISPLOG 1007 #define IDC_OBJECTLOADWARNING 1007
#define IDC_PORT1EN 1008 #define IDC_ALWAYSDISPLOG 1008
#define IDC_PORT1WR 1009 #define IDC_PORT1EN 1009
#define IDC_PORT2ISSHARED 1010 #define IDC_PORT1WR 1010
#define IDC_PORT2WR 1011 #define IDC_PORT2ISSHARED 1011
#define IDC_PORT2 1012 #define IDC_PORT2WR 1012
#define IDC_PORT2LOAD 1013 #define IDC_PORT2 1013
#define IDC_WIRE 1014 #define IDC_PORT2LOAD 1014
#define IDC_IR 1015 #define IDC_IR_ADDR 1015
#define IDC_EMUDIR 1016 #define IDC_IR_PORT 1016
#define IDC_EMUDIRSEL 1017 #define IDC_WIRE 1017
#define IDC_UPDATE 1018 #define IDC_IR 1018
#define IDC_KMLSCRIPT 1019 #define IDC_EMUDIR 1019
#define IDC_AUTHOR 1020 #define IDC_EMUDIRSEL 1020
#define IDC_TITLE 1021 #define IDC_UPDATE 1021
#define IDC_KMLLOG 1022 #define IDC_KMLSCRIPT 1022
#define IDC_VERSION 1023 #define IDC_AUTHOR 1023
#define IDC_LICENSE 1024 #define IDC_TITLE 1024
#define IDC_DISASM_WIN 1025 #define IDC_KMLLOG 1025
#define IDC_DISASM_MAP 1026 #define IDC_VERSION 1026
#define IDC_DISASM_ROM 1027 #define IDC_LICENSE 1027
#define IDC_DISASM_RAM 1028 #define IDC_DISASM_WIN 1028
#define IDC_DISASM_PORT1 1029 #define IDC_DISASM_MODE_TEXT 1029
#define IDC_DISASM_PORT2 1030 #define IDC_DISASM_MODE 1030
#define IDC_DISASM_MODULE 1031 #define IDC_DISASM_MODULE 1031
#define IDC_DISASM_HP 1032 #define IDC_DISASM_HP 1032
#define IDC_DISASM_CLASS 1033 #define IDC_DISASM_CLASS 1033
@ -109,55 +113,59 @@
#define IDC_DEBUG_MEM_COL6 1078 #define IDC_DEBUG_MEM_COL6 1078
#define IDC_DEBUG_MEM_COL7 1079 #define IDC_DEBUG_MEM_COL7 1079
#define IDC_DEBUG_MEM_TEXT 1080 #define IDC_DEBUG_MEM_TEXT 1080
#define IDC_DEBUG_STACK 1081 #define IDC_DEBUG_DATA_FILE 1081
#define IDC_STATIC_BREAKPOINT 1082 #define IDC_DEBUG_DATA_BUT 1082
#define IDC_BREAKEDIT_ADD 1083 #define IDC_DEBUG_DATA_STARTADDR 1083
#define IDC_BREAKEDIT_DELETE 1084 #define IDC_DEBUG_DATA_ENDADDR 1084
#define IDC_BREAKEDIT_WND 1085 #define IDC_DEBUG_SET_SYMB 1085
#define IDC_STATIC_MMU 1086 #define IDC_DEBUG_SET_MODEL 1086
#define IDC_MMU_IO_A 1087 #define IDC_DEBUG_SET_FILE 1087
#define IDC_MMU_NCE2_A 1088 #define IDC_DEBUG_SET_BROWSE 1088
#define IDC_MMU_CE1_A 1089 #define IDC_DEBUG_STACK 1089
#define IDC_MMU_CE2_A 1090 #define IDC_STATIC_BREAKPOINT 1090
#define IDC_MMU_NCE3_A 1091 #define IDC_BREAKEDIT_ADD 1091
#define IDC_MMU_IO_S 1092 #define IDC_BREAKEDIT_DELETE 1092
#define IDC_MMU_CE1_S 1093 #define IDC_BREAKEDIT_WND 1093
#define IDC_MMU_CE2_S 1094 #define IDC_STATIC_MMU 1094
#define IDC_MMU_NCE2_S 1095 #define IDC_MMU_IO_A 1095
#define IDC_MMU_NCE3_S 1096 #define IDC_MMU_NCE2_A 1096
#define IDC_STATIC_MISC 1097 #define IDC_MMU_CE1_A 1097
#define IDC_MISC_BS_TXT 1098 #define IDC_MMU_CE2_A 1098
#define IDC_INSTR_TEXT 1099 #define IDC_MMU_NCE3_A 1099
#define IDC_INSTR_CODE 1100 #define IDC_MMU_IO_S 1100
#define IDC_INSTR_COPY 1101 #define IDC_MMU_CE1_S 1101
#define IDC_INSTR_CLEAR 1102 #define IDC_MMU_CE2_S 1102
#define IDC_PROFILE_LASTCYCLES 1103 #define IDC_MMU_NCE2_S 1103
#define IDC_PROFILE_LASTTIME 1104 #define IDC_MMU_NCE3_S 1104
#define IDC_BPCODE 1105 #define IDC_STATIC_MISC 1105
#define IDC_BPRPL 1106 #define IDC_MISC_BS_TXT 1106
#define IDC_BPACCESS 1107 #define IDC_INSTR_TEXT 1107
#define IDC_BPREAD 1108 #define IDC_INSTR_CODE 1108
#define IDC_BPWRITE 1109 #define IDC_INSTR_COPY 1109
#define IDC_FIND_DATA 1110 #define IDC_INSTR_CLEAR 1110
#define IDC_FIND_ASCII 1111 #define IDC_PROFILE_LASTCYCLES 1111
#define IDC_FIND_CASE 1112 #define IDC_PROFILE_LASTTIME 1112
#define IDC_ADDR20_24 1113 #define IDC_BPCODE 1113
#define IDC_ADDR25_27 1114 #define IDC_BPRPL 1114
#define IDC_ADDR28_29 1115 #define IDC_BPACCESS 1115
#define IDC_ADDR30_34 1116 #define IDC_BPREAD 1116
#define IDC_RPLVIEW_DATA 1117 #define IDC_BPWRITE 1117
#define IDC_MACRO_SLOW 1118 #define IDC_FIND_DATA 1118
#define IDC_MACRO_FAST 1119 #define IDC_FIND_ASCII 1119
#define IDC_MACRO_SLIDER 1120 #define IDC_FIND_CASE 1120
#define IDC_MACRO_REAL 1121 #define IDC_ADDR20_24 1121
#define IDC_MACRO_MANUAL 1122 #define IDC_ADDR25_27 1122
#define IDC_SOUND_SLIDER 1123 #define IDC_ADDR28_29 1123
#define IDC_SOUND_SPEAKER 1124 #define IDC_ADDR30_34 1124
#define IDC_SOUND_WAVE 1125 #define IDC_RPLVIEW_DATA 1125
#define IDC_DEBUG_SET_SYMB 1126 #define IDC_MACRO_SLOW 1126
#define IDC_DEBUG_SET_MODEL 1127 #define IDC_MACRO_FAST 1127
#define IDC_DEBUG_SET_FILE 1128 #define IDC_MACRO_SLIDER 1128
#define IDC_DEBUG_SET_BROWSE 1129 #define IDC_MACRO_REAL 1129
#define IDC_MACRO_MANUAL 1130
#define IDC_SOUND_SLIDER 1131
#define IDC_SOUND_SPEAKER 1132
#define IDC_SOUND_WAVE 1133
#define ID_FILE_NEW 40001 #define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002 #define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003 #define ID_FILE_SAVE 40003
@ -215,23 +223,25 @@
#define ID_DEBUG_MEM_CE1 40057 #define ID_DEBUG_MEM_CE1 40057
#define ID_DEBUG_MEM_CE2 40058 #define ID_DEBUG_MEM_CE2 40058
#define ID_DEBUG_MEM_NCE3 40059 #define ID_DEBUG_MEM_NCE3 40059
#define ID_DEBUG_MEM_RPLVIEW 40060 #define ID_DEBUG_MEM_SAVE 40060
#define ID_DEBUG_STACK_PUSH 40061 #define ID_DEBUG_MEM_LOAD 40061
#define ID_DEBUG_STACK_POP 40062 #define ID_DEBUG_MEM_RPLVIEW 40062
#define ID_DEBUG_STACK_MODIFY 40063 #define ID_DEBUG_STACK_PUSH 40063
#define ID_INTR_STEPOVERINT 40064 #define ID_DEBUG_STACK_POP 40064
#define ID_INFO_LASTINSTRUCTIONS 40065 #define ID_DEBUG_STACK_MODIFY 40065
#define ID_INFO_PROFILE 40066 #define ID_INTR_STEPOVERINT 40066
#define ID_INFO_WRITEONLYREG 40067 #define ID_INFO_LASTINSTRUCTIONS 40067
#define ID_INFO_PROFILE 40068
#define ID_INFO_WRITEONLYREG 40069
#define ID_FILE_MRU_FILE1 40100 #define ID_FILE_MRU_FILE1 40100
// Next default values for new objects // Next default values for new objects
// //
#ifdef APSTUDIO_INVOKED #ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 125 #define _APS_NEXT_RESOURCE_VALUE 132
#define _APS_NEXT_COMMAND_VALUE 40068 #define _APS_NEXT_COMMAND_VALUE 40070
#define _APS_NEXT_CONTROL_VALUE 1130 #define _APS_NEXT_CONTROL_VALUE 1134
#define _APS_NEXT_SYMED_VALUE 108 #define _APS_NEXT_SYMED_VALUE 108
#endif #endif
#endif #endif

View file

@ -390,10 +390,10 @@ DWORD RPL_CreateTemp(DWORD l)
Write5(TEMPTOP, a+l); // adjust new end of top object Write5(TEMPTOP, a+l); // adjust new end of top object
Write5(RSKTOP, b+l); // adjust new end of rtn stack Write5(RSKTOP, b+l); // adjust new end of rtn stack
Write5(AVMEM, (c-b-l)/5); // calculate free memory (*5 nibbles) Write5(AVMEM, (c-b-l)/5); // calculate free memory (*5 nibbles)
p = HeapAlloc(hHeap,0,b-a); // move down rtn stack p = malloc(b-a); // move down rtn stack
Npeek(p,a,b-a); Npeek(p,a,b-a);
Nwrite(p,a+l,b-a); Nwrite(p,a+l,b-a);
HeapFree(hHeap,0,p); free(p);
Write5(a+l-5,l); // set object length field Write5(a+l-5,l); // set object length field
return (a+1); // return base address of new object return (a+1); // return base address of new object
} }

View file

@ -113,11 +113,11 @@ BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort)
_tcscat(szDevice,strPort); // device name _tcscat(szDevice,strPort); // device name
hComm = CreateFile(szDevice, hComm = CreateFile(szDevice,
GENERIC_READ | GENERIC_WRITE, GENERIC_READ | GENERIC_WRITE,
0, 0,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (hComm != INVALID_HANDLE_VALUE) if (hComm != INVALID_HANDLE_VALUE)
@ -140,7 +140,7 @@ BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort)
hCThreadTxd = CreateThread(NULL,0,&TransmitThread,NULL,CREATE_SUSPENDED,&dwThreadId); hCThreadTxd = CreateThread(NULL,0,&TransmitThread,NULL,CREATE_SUSPENDED,&dwThreadId);
_ASSERT(hCThreadTxd); _ASSERT(hCThreadTxd);
SetThreadPriority(hCThreadTxd,THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hCThreadTxd,THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(hCThreadTxd); // start thread ResumeThread(hCThreadTxd); // start thread
// create Comm event handler // create Comm event handler
bReading = FALSE; bReading = FALSE;
@ -148,7 +148,7 @@ BOOL CommOpen(LPTSTR strWirePort,LPTSTR strIrPort)
hCThreadEv = CreateThread(NULL,0,&EventThread,NULL,CREATE_SUSPENDED,&dwThreadId); hCThreadEv = CreateThread(NULL,0,&EventThread,NULL,CREATE_SUSPENDED,&dwThreadId);
_ASSERT(hCThreadEv); _ASSERT(hCThreadEv);
SetThreadPriority(hCThreadEv,THREAD_PRIORITY_ABOVE_NORMAL); SetThreadPriority(hCThreadEv,THREAD_PRIORITY_ABOVE_NORMAL);
ResumeThread(hCThreadEv); // start thread ResumeThread(hCThreadEv); // start thread
while (!bReading) Sleep(0); // wait for SerialThread started while (!bReading) Sleep(0); // wait for SerialThread started
} }
else else

View file

@ -63,7 +63,7 @@ static VOID ReadReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, LPBYTE lpData, DWORD
lstrcat(lpKey, lpSubKey); // full registry key lstrcat(lpKey, lpSubKey); // full registry key
retCode = RegOpenKeyEx(HKEY_CURRENT_USER, retCode = RegOpenKeyEx(HKEY_CURRENT_USER,
lpKey, lpKey,
0, 0,
KEY_QUERY_VALUE, KEY_QUERY_VALUE,
&hKey); &hKey);
@ -91,9 +91,9 @@ static BOOL WriteReg(LPCTSTR lpSubKey, LPCTSTR lpValueName, DWORD dwType, CONST
retCode = RegCreateKeyEx(HKEY_CURRENT_USER, retCode = RegCreateKeyEx(HKEY_CURRENT_USER,
lpKey, lpKey,
0,_T(""), 0,_T(""),
REG_OPTION_NON_VOLATILE, REG_OPTION_NON_VOLATILE,
KEY_WRITE, KEY_WRITE,
NULL, NULL,
&hKey, &hKey,
&dwDisposition); &dwDisposition);
_ASSERT(retCode == ERROR_SUCCESS); _ASSERT(retCode == ERROR_SUCCESS);
@ -113,7 +113,7 @@ static BOOL DelReg(LPCTSTR lpSubKey, LPCTSTR lpValueName)
lstrcat(lpKey, lpSubKey); // full registry key lstrcat(lpKey, lpSubKey); // full registry key
retCode = RegOpenKeyEx(HKEY_CURRENT_USER, retCode = RegOpenKeyEx(HKEY_CURRENT_USER,
lpKey, lpKey,
0, 0,
KEY_SET_VALUE, KEY_SET_VALUE,
&hKey); &hKey);
@ -179,6 +179,7 @@ VOID ReadSettings(VOID)
// Emulator // Emulator
bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
bSingleInstance = ReadInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
@ -187,12 +188,15 @@ VOID ReadSettings(VOID)
bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale); bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep); bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep);
dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol); dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
SetSpeed(bRealSpeed); // set speed
// LowBat // LowBat
bLowBatDisable = ReadInt(_T("LowBat"),_T("Disable"),bLowBatDisable); bLowBatDisable = ReadInt(_T("LowBat"),_T("Disable"),bLowBatDisable);
// Macro // Macro
bMacroRealSpeed = ReadInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed); bMacroRealSpeed = ReadInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
nMacroTimeout = ReadInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout); nMacroTimeout = ReadInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout);
dwMacroMinDelay = ReadInt(_T("Macro"),_T("KeyMinDelay"),dwMacroMinDelay);
// IrPrinter
ReadString(_T("IrPrinter"),_T("Address"),szUdpServer,szUdpServer,ARRAYSIZEOF(szUdpServer));
wUdpPort = ReadInt(_T("IrPrinter"),_T("Port"),wUdpPort);
// Serial // Serial
ReadString(_T("Serial"),_T("Wire"),_T(NO_SERIAL),szSerialWire,ARRAYSIZEOF(szSerialWire)); ReadString(_T("Serial"),_T("Wire"),_T(NO_SERIAL),szSerialWire,ARRAYSIZEOF(szSerialWire));
ReadString(_T("Serial"),_T("Ir"),_T(NO_SERIAL),szSerialIr,ARRAYSIZEOF(szSerialIr)); ReadString(_T("Serial"),_T("Ir"),_T(NO_SERIAL),szSerialIr,ARRAYSIZEOF(szSerialIr));
@ -222,6 +226,7 @@ VOID WriteSettings(VOID)
// Emulator // Emulator
WriteInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop); WriteInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
WriteInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse); WriteInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
WriteInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed); WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles); WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles); WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
@ -235,6 +240,10 @@ VOID WriteSettings(VOID)
// Macro // Macro
WriteInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed); WriteInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
WriteInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout); WriteInt(_T("Macro"),_T("ReplayTimeout"),nMacroTimeout);
WriteInt(_T("Macro"),_T("KeyMinDelay"),dwMacroMinDelay);
// IrPrinter
WriteString(_T("IrPrinter"),_T("Address"),szUdpServer);
WriteInt(_T("IrPrinter"),_T("Port"),wUdpPort);
// Serial // Serial
WriteString(_T("Serial"),_T("Wire"),szSerialWire); WriteString(_T("Serial"),_T("Wire"),szSerialWire);
WriteString(_T("Serial"),_T("Ir"),szSerialIr); WriteString(_T("Serial"),_T("Ir"),szSerialIr);

View file

@ -88,7 +88,7 @@ static INT RPL_SetZInt(LPCTSTR cp,LPBYTE pbyNum,INT nSize)
} }
// nStrLen = no. of digits without sign // nStrLen = no. of digits without sign
if (nStrLen >= nSize) // destination buffer too small if (nStrLen >= nSize) // destination buffer too small
return 0; return 0;
nNumSize = nStrLen + 1; // no. of written data nNumSize = nStrLen + 1; // no. of written data
@ -128,6 +128,7 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD
i = 0; // first character i = 0; // first character
bPflag = FALSE; // show no decimal point bPflag = FALSE; // show no decimal point
bExpflag = FALSE; // show no exponent
// scan mantissa // scan mantissa
for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--) for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--)
@ -225,7 +226,7 @@ static INT RPL_SetBcd(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,LPBYT
if (*cp != cDec) // no decimal point if (*cp != cDec) // no decimal point
{ {
// count integer part // count integer part
while (*cp >= _T('0') && *cp <= _T('9')) while (*cp >= _T('0') && *cp <= _T('9'))
byNum[++nIp] = *cp++ - _T('0'); byNum[++nIp] = *cp++ - _T('0');
if (!nIp) return 0; if (!nIp) return 0;
} }
@ -402,7 +403,7 @@ static INT RPL_SetComplex(LPCTSTR cp,INT nMantLen,INT nExpLen,CONST TCHAR cDec,L
} }
} }
} }
HeapFree(hHeap,0,pszData); free(pszData);
} }
return nLen; return nLen;
} }
@ -460,12 +461,12 @@ static INT DoInt(DWORD dwAddress,LPTSTR cp,INT nSize)
if (nIntLen <= 0) return 0; // error in calculator object if (nIntLen <= 0) return 0; // error in calculator object
nLength = 0; nLength = 0;
if ((lpbyData = HeapAlloc(hHeap,0,nIntLen))) if ((lpbyData = malloc(nIntLen)))
{ {
// get precisition integer object content and decode it // get precisition integer object content and decode it
Npeek(lpbyData,dwAddress+5,nIntLen); Npeek(lpbyData,dwAddress+5,nIntLen);
nLength = RPL_GetZInt(lpbyData,nIntLen,cp,nSize); nLength = RPL_GetZInt(lpbyData,nIntLen,cp,nSize);
HeapFree(hHeap,0,lpbyData); free(lpbyData);
} }
return nLength; return nLength;
} }
@ -551,7 +552,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize)) == NULL) if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize)) == NULL)
goto error; goto error;
if ((lpbyData = GlobalLock(hClipObj))) if ((lpbyData = (LPBYTE) GlobalLock(hClipObj)))
{ {
// copy data to memory // copy data to memory
CopyMemory(lpbyData,cBuffer,dwSize); CopyMemory(lpbyData,cBuffer,dwSize);
@ -572,7 +573,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL) if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL)
goto error; goto error;
if ((lpbyData = GlobalLock(hClipObj))) // lock memory if ((lpbyData = (LPBYTE) GlobalLock(hClipObj))) // lock memory
{ {
// copy data into clipboard buffer // copy data into clipboard buffer
for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpbyData) for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpbyData)
@ -580,8 +581,8 @@ LRESULT OnStackCopy(VOID) // copy data from stack
*lpbyData = 0; // set EOS *lpbyData = 0; // set EOS
GlobalUnlock(hClipObj); // unlock memory GlobalUnlock(hClipObj); // unlock memory
uClipboardFormat = CF_TEXT; // always text
} }
uClipboardFormat = CF_TEXT; // always text
break; break;
default: default:
MessageBeep(MB_OK); // error beep MessageBeep(MB_OK); // error beep
@ -737,7 +738,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack
// any other format // any other format
{ {
DWORD dwSize = lstrlen(lpstrClipdata); DWORD dwSize = lstrlen(lpstrClipdata);
if ((lpbyData = HeapAlloc(hHeap,0,dwSize * 2))) if ((lpbyData = malloc(dwSize * 2)))
{ {
LPBYTE lpbySrc,lpbyDest; LPBYTE lpbySrc,lpbyDest;
DWORD dwLoop; DWORD dwLoop;
@ -776,7 +777,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack
// push object to stack // push object to stack
RPL_Push(1,dwAddress); RPL_Push(1,dwAddress);
} }
HeapFree(hHeap,0,lpbyData); free(lpbyData);
} }
} }
} }

View file

@ -171,7 +171,7 @@ BOOL RplLoadTable(LPCTSTR lpszFilename)
*pcPtr = 0; // set EOS *pcPtr = 0; // set EOS
// allocate symbol memory // allocate symbol memory
VERIFY(pData = HeapAlloc(hHeap,0,sizeof(RefData))); VERIFY(pData = malloc(sizeof(RefData)));
pData->lpszName = DuplicateString(szSymbolName); pData->lpszName = DuplicateString(szSymbolName);
pData->dwAddr = GetBigEndian(byPage+dwPageIndex+38,sizeof(DWORD)); pData->dwAddr = GetBigEndian(byPage+dwPageIndex+38,sizeof(DWORD));
@ -209,8 +209,8 @@ VOID RplDeleteTable(VOID)
while (ppsBase[i] != NULL) // walk through all datasets while (ppsBase[i] != NULL) // walk through all datasets
{ {
pData = ppsBase[i]->pNext; pData = ppsBase[i]->pNext;
HeapFree(hHeap,0,ppsBase[i]->lpszName); free(ppsBase[i]->lpszName);
HeapFree(hHeap,0,ppsBase[i]); free(ppsBase[i]);
ppsBase[i] = pData; ppsBase[i] = pData;
} }
} }

View file

@ -244,7 +244,6 @@ static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_
UNREFERENCED_PARAMETER(dw2); UNREFERENCED_PARAMETER(dw2);
} }
VOID SetHP48Time(VOID) // set date and time VOID SetHP48Time(VOID) // set date and time
{ {
SYSTEMTIME ts; SYSTEMTIME ts;
@ -257,7 +256,7 @@ VOID SetHP48Time(VOID) // set date and time
GetLocalTime(&ts); // local time, _ftime() cause memory/resource leaks GetLocalTime(&ts); // local time, _ftime() cause memory/resource leaks
// calculate days until 01.01.1970 // calculate days until 01.01.0000 (Erlang BIF localtime/0)
dw = (DWORD) ts.wMonth; dw = (DWORD) ts.wMonth;
if (dw > 2) if (dw > 2)
dw -= 3L; dw -= 3L;
@ -269,17 +268,18 @@ VOID SetHP48Time(VOID) // set date and time
dw = (DWORD) ts.wDay + (153L * dw + 2L) / 5L; dw = (DWORD) ts.wDay + (153L * dw + 2L) / 5L;
dw += (146097L * (((DWORD) ts.wYear) / 100L)) / 4L; dw += (146097L * (((DWORD) ts.wYear) / 100L)) / 4L;
dw += (1461L * (((DWORD) ts.wYear) % 100L)) / 4L; dw += (1461L * (((DWORD) ts.wYear) % 100L)) / 4L;
dw -= 719469L; dw += (-719469L + 719528L); // days from year 0
ticks = (ULONGLONG) dw; // convert to 64 bit
// convert into seconds and add time // convert into seconds and add time
dw = dw * 24L + (DWORD) ts.wHour; ticks = ticks * 24L + (ULONGLONG) ts.wHour;
dw = dw * 60L + (DWORD) ts.wMinute; ticks = ticks * 60L + (ULONGLONG) ts.wMinute;
dw = dw * 60L + (DWORD) ts.wSecond; ticks = ticks * 60L + (ULONGLONG) ts.wSecond;
// create timerticks = (s + ms) * 8192 // create timerticks = (s + ms) * 8192
ticks = ((ULONGLONG) dw << 13) | (((ULONGLONG) ts.wMilliseconds << 10) / 125); ticks = (ticks << 13) | (((ULONGLONG) ts.wMilliseconds << 10) / 125);
ticks += UNIX_0_TIME; // add offset ticks from year 0
ticks += Chipset.t2; // add actual timer2 value ticks += Chipset.t2; // add actual timer2 value
time = ticks; // save for calc. timeout time = ticks; // save for calc. timeout

85
Sources/Emu48/UDP.C Normal file
View file

@ -0,0 +1,85 @@
/*
* udp.c
*
* This file is part of Emu48
*
* Copyright (C) 2011 Christoph Gießelink
*
*/
#include "pch.h"
#include "Emu48.h"
TCHAR szUdpServer[1024] = _T("localhost");
WORD wUdpPort = 5025; // scpi-raw
static IN_ADDR ip_addr = { 255, 255, 255, 255 };
VOID ResetUdp(VOID)
{
ip_addr.s_addr = INADDR_NONE; // invalidate saved UDP address
return;
}
BOOL SendByteUdp(BYTE byData)
{
WSADATA wsd;
SOCKET sClient;
SOCKADDR_IN sServer;
BOOL bErr = TRUE;
VERIFY(WSAStartup(MAKEWORD(1,1),&wsd) == 0);
if (ip_addr.s_addr == INADDR_NONE) // IP address not specified
{
LPSTR lpszIpAddr;
#if defined _UNICODE
DWORD dwLength = lstrlen(szUdpServer) + 1;
if ((lpszIpAddr = (LPSTR) malloc(dwLength)) == NULL)
return TRUE; // server not found
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szUdpServer, dwLength,
lpszIpAddr, dwLength, NULL, NULL);
#else
lpszIpAddr = szUdpServer;
#endif
ip_addr.s_addr = inet_addr(lpszIpAddr);
// not a valid ip address -> try to get ip address from name server
if (ip_addr.s_addr == INADDR_NONE)
{
PHOSTENT host = gethostbyname(lpszIpAddr);
if (host == NULL)
{
#if defined _UNICODE
free(lpszIpAddr);
#endif
return TRUE; // server not found
}
ip_addr.s_addr = ((PIN_ADDR) host->h_addr_list[0])->s_addr;
}
#if defined _UNICODE
free(lpszIpAddr);
#endif
}
// create UDP socket
if ((sClient = socket(AF_INET, SOCK_DGRAM, 0)) != INVALID_SOCKET)
{
sServer.sin_family = AF_INET;
sServer.sin_port = htons(wUdpPort);
sServer.sin_addr.s_addr = ip_addr.s_addr;
// transmit data byte
bErr = sendto(sClient, (LPCCH) &byData, sizeof(byData), 0, (LPSOCKADDR) &sServer, sizeof(sServer)) == SOCKET_ERROR;
closesocket(sClient);
}
WSACleanup(); // cleanup network stack
return bErr;
}

View file

@ -77,12 +77,40 @@ BEGIN
BOTTOMMARGIN, 145 BOTTOMMARGIN, 145
END END
IDD_SETTINGS, DIALOG IDD_SET_GENERAL, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 160 RIGHTMARGIN, 244
TOPMARGIN, 4 VERTGUIDE, 14
BOTTOMMARGIN, 280 VERTGUIDE, 161
VERTGUIDE, 168
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
END
IDD_SET_MEMORY, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 244
VERTGUIDE, 14
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
END
IDD_SET_PERIPHERAL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 244
VERTGUIDE, 14
VERTGUIDE, 147
VERTGUIDE, 154
VERTGUIDE, 161
VERTGUIDE, 237
TOPMARGIN, 7
BOTTOMMARGIN, 127
HORZGUIDE, 82
END END
IDD_CHOOSEKML, DIALOG IDD_CHOOSEKML, DIALOG
@ -157,6 +185,22 @@ BEGIN
BOTTOMMARGIN, 74 BOTTOMMARGIN, 74
END END
IDD_DEBUG_MEMSAVE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 257
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
IDD_DEBUG_MEMLOAD, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 257
TOPMARGIN, 7
BOTTOMMARGIN, 58
END
IDD_DEBUG_SETTINGS, DIALOG IDD_DEBUG_SETTINGS, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
@ -252,69 +296,88 @@ FONT 8, "MS Sans Serif"
BEGIN BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2010 Christoph Gießelink && Sébastien Carlier", LTEXT "Copyright © 2012 Christoph Gießelink && Sébastien Carlier",
IDC_STATIC,29,18,181,8 IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14 DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL | EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY ES_READONLY
END END
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287 IDD_SET_GENERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Settings" CAPTION "General"
FONT 8, "MS Sans Serif" FONT 8, "MS Sans Serif"
BEGIN BEGIN
CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button", CONTROL "Authentic Calculator Speed",IDC_REALSPEED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,13,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,17,133,10
CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button", CONTROL "Enable Virtual LCD Delay",IDC_GRAYSCALE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,28,133,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button", CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX |
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10 WS_TABSTOP,14,40,133,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE, CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,"Button",
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,52,133,10
CONTROL "Single Instance",IDC_SINGLEINSTANCE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,14,64,133,10
CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button", CONTROL "Automatically Save Files",IDC_AUTOSAVE,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,76,133,10
CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT, CONTROL "Automatically Save Files On Exit",IDC_AUTOSAVEONEXIT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,73,114,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,88,133,10
CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button", CONTROL "Show Load Object Warning",IDC_OBJECTLOADWARNING,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,100,133,10
CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG, CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10 "Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,112,133,10
GROUPBOX "General",IDC_STATIC,7,4,153,107 GROUPBOX "General",IDC_STATIC,7,7,148,120
CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON | CONTROL "HP Mnemonics",IDC_DISASM_HP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,13,125,65,11 WS_GROUP | WS_TABSTOP,168,21,69,11
CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button", CONTROL "Class Mnemonics",IDC_DISASM_CLASS,"Button",
BS_AUTORADIOBUTTON,84,125,70,11 BS_AUTORADIOBUTTON,168,35,69,11
GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28 GROUPBOX "Disassembler",IDC_STATIC,161,7,83,120
LTEXT "Volume",IDC_STATIC,13,158,24,8 END
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18 IDD_SET_MEMORY DIALOG DISCARDABLE 0, 0, 251, 134
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON | STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
WS_GROUP | WS_TABSTOP,111,152,43,10 CAPTION "Memory"
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111, FONT 8, "MS Sans Serif"
163,43,10 BEGIN
GROUPBOX "Sound",IDC_STATIC,7,144,153,34
CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX | CONTROL "Port 1 is Plugged",IDC_PORT1EN,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,13,189,67,10 WS_TABSTOP,14,20,67,10
CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button", CONTROL "Port 1 is Writeable",IDC_PORT1WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10 BS_AUTOCHECKBOX | WS_TABSTOP,124,20,69,10
CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button", CONTROL "Port 2 is Shared",IDC_PORT2ISSHARED,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,201,65,10 BS_AUTOCHECKBOX | WS_TABSTOP,14,32,65,10
CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button", CONTROL "Port 2 is Writeable",IDC_PORT2WR,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10 BS_AUTOCHECKBOX | WS_TABSTOP,124,32,69,10
LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8 LTEXT "Port 2 File :",IDC_STATIC,14,47,37,8
EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL EDITTEXT IDC_PORT2,52,45,175,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12 PUSHBUTTON "...",IDC_PORT2LOAD,227,45,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51 GROUPBOX "Memory Cards",IDC_STATIC,7,7,237,58
LTEXT "Wire:",IDC_STATIC,13,245,17,8 END
COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
IDD_SET_PERIPHERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Peripheral"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Volume",IDC_STATIC,14,21,24,8
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,40,16,84,18
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,135,20,43,10
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,194,20,
43,10
GROUPBOX "Sound",IDC_STATIC,7,7,237,34
LTEXT "IP Address:",IDC_STATIC,14,60,37,8
LTEXT "Port:",IDC_STATIC,119,60,16,8
EDITTEXT IDC_IR_ADDR,14,70,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_IR_PORT,119,70,28,12,ES_NUMBER
GROUPBOX "Infrared Printer",IDC_STATIC,7,43,147,50
LTEXT "Wire:",IDC_STATIC,168,58,17,8
COMBOBOX IDC_WIRE,189,56,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
LTEXT "IR:",IDC_STATIC,89,245,9,8 LTEXT "IR:",IDC_STATIC,168,74,9,8
COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL | COMBOBOX IDC_IR,189,72,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27 GROUPBOX "Serial Ports",IDC_STATIC,161,43,83,50
DEFPUSHBUTTON "OK",IDOK,9,266,50,14
PUSHBUTTON "Cancel",IDCANCEL,107,266,50,14
END END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66 IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
@ -362,17 +425,10 @@ BEGIN
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14 PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14 PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,144,47,14
PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14 PUSHBUTTON "Cancel",IDCANCEL,201,144,47,14
LTEXT "Mapping Mode:",IDC_DISASM_MODE_TEXT,12,17,45,8
COMBOBOX IDC_DISASM_MODE,60,14,35,90,CBS_DROPDOWNLIST |
WS_TABSTOP
GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26 GROUPBOX "Module",IDC_DISASM_MODULE,7,5,241,26
CONTROL "Map",IDC_DISASM_MAP,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,14,16,37,10
CONTROL "ROM",IDC_DISASM_ROM,"Button",BS_AUTORADIOBUTTON,61,16,
37,10
CONTROL "RAM",IDC_DISASM_RAM,"Button",BS_AUTORADIOBUTTON,108,16,
37,10
CONTROL "Port 1",IDC_DISASM_PORT1,"Button",BS_AUTORADIOBUTTON,
155,16,37,10
CONTROL "Port 2",IDC_DISASM_PORT2,"Button",BS_AUTORADIOBUTTON,
202,16,37,10
LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY | LISTBOX IDC_DISASM_WIN,7,37,241,100,NOT LBS_NOTIFY |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL | LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP WS_TABSTOP
@ -404,7 +460,7 @@ BEGIN
LTEXT "PC=00000",IDC_REG_PC,236,108,33,8 LTEXT "PC=00000",IDC_REG_PC,236,108,33,8
LTEXT "OUT=000",IDC_REG_OUT,192,119,29,8 LTEXT "OUT=000",IDC_REG_OUT,192,119,29,8
LTEXT "IN=0000",IDC_REG_IN,240,119,29,8 LTEXT "IN=0000",IDC_REG_IN,240,119,29,8
LTEXT "ST=0000",IDC_REG_ST,192,130,29,8 LTEXT "ST=0000",IDC_REG_ST,192,130,29,8
LTEXT "CY=0",IDC_REG_CY,224,130,17,8 LTEXT "CY=0",IDC_REG_CY,224,130,17,8
LTEXT "Mode=H",IDC_REG_MODE,244,130,25,8 LTEXT "Mode=H",IDC_REG_MODE,244,130,25,8
LTEXT "MP=0",IDC_REG_MP,192,140,17,8 LTEXT "MP=0",IDC_REG_MP,192,140,17,8
@ -543,6 +599,36 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14 PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14
END END
IDD_DEBUG_MEMSAVE DIALOG DISCARDABLE 0, 0, 264, 65
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Save Memory Data"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "File:",IDC_STATIC,7,10,14,8
EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14
LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8
EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14
LTEXT "End Address (hexadecimal):",IDC_STATIC,7,46,88,8
EDITTEXT IDC_DEBUG_DATA_ENDADDR,101,44,37,14
PUSHBUTTON "OK",IDOK,207,27,50,14
PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14
END
IDD_DEBUG_MEMLOAD DIALOG DISCARDABLE 0, 0, 264, 65
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Load Memory Data"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "File:",IDC_STATIC,7,10,14,8
EDITTEXT IDC_DEBUG_DATA_FILE,25,7,181,14,ES_AUTOHSCROLL
PUSHBUTTON "Browse",IDC_DEBUG_DATA_BUT,207,7,50,14
LTEXT "Start Address (hexadecimal):",IDC_STATIC,7,30,90,8
EDITTEXT IDC_DEBUG_DATA_STARTADDR,101,27,37,14
PUSHBUTTON "OK",IDOK,207,27,50,14
PUSHBUTTON "Cancel",IDCANCEL,207,44,50,14
END
IDD_DEBUG_SETTINGS DIALOG DISCARDABLE 0, 0, 184, 116 IDD_DEBUG_SETTINGS DIALOG DISCARDABLE 0, 0, 184, 116
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger Settings" CAPTION "Debugger Settings"
@ -630,8 +716,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,0 FILEVERSION 1,5,3,0
PRODUCTVERSION 1,5,0,0 PRODUCTVERSION 1,5,3,0
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -646,14 +732,14 @@ BEGIN
BEGIN BEGIN
BLOCK "04090000" BLOCK "04090000"
BEGIN BEGIN
VALUE "CompanyName", "Sebastien Carlier & Christoph Gießelink\0" VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0" VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 5, 0, 0\0" VALUE "FileVersion", "1, 5, 3, 0\0"
VALUE "InternalName", "Emu48\0" VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2010\0" VALUE "LegalCopyright", "Copyright © 2012\0"
VALUE "OriginalFilename", "Emu48.exe\0" VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0" VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 5, 0, 0\0" VALUE "ProductVersion", "1, 5, 3, 0\0"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"
@ -819,7 +905,10 @@ BEGIN
, GRAYED , GRAYED
END END
MENUITEM SEPARATOR MENUITEM SEPARATOR
MENUITEM "RPL Object Viewer...", ID_DEBUG_MEM_RPLVIEW MENUITEM "&Load Memory Data...", ID_DEBUG_MEM_LOAD
MENUITEM "S&ave Memory Data...", ID_DEBUG_MEM_SAVE
MENUITEM SEPARATOR
MENUITEM "&RPL Object Viewer...", ID_DEBUG_MEM_RPLVIEW
END END
END END
@ -860,6 +949,13 @@ END
#endif // APSTUDIO_INVOKED #endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// 24
//
1 24 MOVEABLE PURE "Emu48.xml"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// //
// Accelerator // Accelerator
@ -890,14 +986,6 @@ BEGIN
ID_BREAKPOINTS_CODEEDIT "Breakpoint List" ID_BREAKPOINTS_CODEEDIT "Breakpoint List"
END END
/////////////////////////////////////////////////////////////////////////////
//
// Manifest
//
1 24 MOVEABLE PURE "Emu48.xml"
#endif // English (U.S.) resources #endif // English (U.S.) resources
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -22,13 +22,13 @@ TARGET=$(PRJ).exe
RSRC=$(PRJ).rc RSRC=$(PRJ).rc
RSRCOBJ=$(PRJ).o RSRCOBJ=$(PRJ).o
OBJS=cursor.o ddeserv.o debugger.o disasm.o display.o disrpl.o \ OBJS=cursor.o ddeserv.o debugger.o disasm.o dismem.o display.o disrpl.o \
emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \ emu48.o engine.o external.o fetch.o files.o i28f160.o keyboard.o \
keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o rpl.o serial.o \ keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o redeye.o \
settings.o stack.o symbfile.o timer.o \ rpl.o serial.o settings.o stack.o symbfile.o timer.o udp.o \
$(RSRCOBJ) $(RSRCOBJ)
LIBS=-lwinmm -lcomctl32 LIBS=-lwinmm -lcomctl32 -lws2_32
all: $(TARGET) all: $(TARGET)
@ -58,6 +58,9 @@ debugger.o: debugger.c pch.h resource.h emu48.h \
disasm.o: disasm.c pch.h emu48.h types.h disasm.o: disasm.c pch.h emu48.h types.h
$(CC) $(CFLAGS) $(DEFINES) -c -o disasm.o disasm.c $(CC) $(CFLAGS) $(DEFINES) -c -o disasm.o disasm.c
dismem.o: dismem.c pch.h emu48.h
$(CC) $(CFLAGS) $(DEFINES) -c -o dismem.o dismem.c
display.o: display.c pch.h resource.h emu48.h \ display.o: display.c pch.h resource.h emu48.h \
types.h io.h kml.h types.h io.h kml.h
$(CC) $(CFLAGS) $(DEFINES) -c -o display.o display.c $(CC) $(CFLAGS) $(DEFINES) -c -o display.o display.c
@ -112,6 +115,9 @@ opcodes.o: opcodes.c pch.h emu48.h types.h opcodes.h \
# pch.o: pch.c pch.h # pch.o: pch.c pch.h
# $(CC) $(CFLAGS) $(DEFINES) -c -o pch.o pch.c # $(CC) $(CFLAGS) $(DEFINES) -c -o pch.o pch.c
redeye.o: redeye.c pch.h emu48.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o redeye.o redeye.c
rpl.o: rpl.c pch.h emu48.h types.h io.h rpl.o: rpl.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o rpl.o rpl.c $(CC) $(CFLAGS) $(DEFINES) -c -o rpl.o rpl.c
@ -130,6 +136,9 @@ symbfile.o: symbfile.c pch.h emu48.h
timer.o: timer.c pch.h emu48.h types.h io.h timer.o: timer.c pch.h emu48.h types.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o timer.o timer.c $(CC) $(CFLAGS) $(DEFINES) -c -o timer.o timer.c
udp.o: udp.c pch.h io.h
$(CC) $(CFLAGS) $(DEFINES) -c -o udp.o udp.c
$(RSRCOBJ): $(RSRC) resource.h emu48.ico dbgtool.bmp checkbox.bmp Emu48.xml $(RSRCOBJ): $(RSRC) resource.h emu48.ico dbgtool.bmp checkbox.bmp Emu48.xml
windres $(DEFINES) -i $(RSRC) -o $(RSRCOBJ) windres $(DEFINES) -i $(RSRC) -o $(RSRCOBJ)

View file

@ -45,3 +45,4 @@ int __cdecl _outp(unsigned short, int);
#if !defined _ASSERT #if !defined _ASSERT
#define _ASSERT(a) #define _ASSERT(a)
#endif #endif
#define _CrtDumpMemoryLeaks() ((int)0)

View file

@ -2,7 +2,7 @@
* Emu48 GCC Version * * Emu48 GCC Version *
********************* *********************
Emu48 is normally compiled with the Microsoft Visual C++ V6.0 compiler. An Emu48 is normally compiled with the Microsoft Visual C++ 2005 compiler. An
alternative is the GCC compiler from the GNU project. A great distribution alternative is the GCC compiler from the GNU project. A great distribution
of the compiler and the necessary files is MinGW at www.mingw.org. of the compiler and the necessary files is MinGW at www.mingw.org.
@ -23,6 +23,20 @@ mingw32-make-3.81-20080326.tar.gz
binutils-2.18.50-20080109-2.tar.gz binutils-2.18.50-20080109-2.tar.gz
gcc-core-3.4.5-20060117-1.tar.gz gcc-core-3.4.5-20060117-1.tar.gz
or
gcc-core-4.6.2-1-mingw32-bin.tar.lzma
binutils-2.22-1-mingw32-bin.tar.lzma
libgmp-5.0.1-1-mingw32-dll-10.tar.lzma
libmpc-0.8.1-1-mingw32-dll-2.tar.lzma
libmpfr-2.4.1-1-mingw32-dll-1.tar.lzma
libpthreadgc-2.9.0-mingw32-pre-20110507-2-dll-2.tar.lzma
mingwrt-3.20-mingw32-dev.tar.gz
mingwrt-3.20-mingw32-dll.tar.gz
pthreads-w32-2.9.0-mingw32-pre-20110507-2-dev.tar.lzma
w32api-3.17-2-mingw32-dev.tar.lzma
mingw32-make-3.81-20080326.tar.gz
Older versions of the MinGW package might not work, because there are several 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. bug fixes, especially in the header files, made in the last time.
@ -34,4 +48,4 @@ Many thanks to Pedro A. Arranda Guti
compatible. compatible.
07/27/10 (c) by Christoph Gießelink 05/03/12 (c) by Christoph Gießelink

Binary file not shown.