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
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...
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
@ -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.
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;}
{\*\generator Msftedit 5.41.15.1515;}\viewkind4\uc1\pard\nowidctlpar\qc\lang1033\f0\fs56 EmuXY and KML 2.0\par
\pard\nowidctlpar\fs24\par
\b\fs28 Introduction\b0\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
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
\b\fs40 Index\fs28\par
\b0\fs24\par
@ -18,8 +18,8 @@ Digit\tab Page 9\par
\lang1040 Annunciator\tab Page 10\par
Button\tab Page 11\par
\lang1036 OutIn Codes\tab Page 13\par
Scancode\tab Page 21\par
Conclusion\b\fs28\tab\b0\fs24 Page 24\par
Scancode\tab Page 22\par
Conclusion\b\fs28\tab\b0\fs24 Page 25\par
\pard\nowidctlpar\b\fs28\par
\lang1033 Basics\b0\par
\fs24\par
@ -54,13 +54,15 @@ End\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 Emu10:\par
\f1\fs16\tab\lang1031 Hardware \ldblquote Bert\rdblquote\par
\f1\fs16\tab Hardware \ldblquote Bert\rdblquote\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
\f1\fs16\tab Hardware \ldblquote Lewis\rdblquote\par
\f0\fs24 Emu48:\par
\f1\fs16\tab Hardware \ldblquote Yorke\rdblquote\par
\f0\fs24 Emu71:\par
\f1\fs16\tab Hardware \ldblquote Saturn\rdblquote\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
Emu10:\par
@ -85,8 +87,10 @@ Emu10:\par
\ldblquote G\rdblquote = HP48G, HP48G+ or HP48GX\par
\ldblquote S\rdblquote = HP48S or HP48SX\par
\ldblquote X\rdblquote = HP49G\cf1\par
\pard\nowidctlpar\qj\cf0 Example:\par
\pard\nowidctlpar\f1\fs16\tab Model \ldblquote G\rdblquote\par
\pard\nowidctlpar\qj Emu71:\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
\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
@ -159,13 +163,13 @@ End\par
\lang1031\f1\fs16 Lcd\par
\tab Zoom INTEGER\par
\tab Zoomxy INTEGER INTEGER\par
\tab Vertical INTEGER\par
\tab\lang1033 Vertical INTEGER\par
\tab Offset INTEGER INTEGER\par
\tab Color INTEGER INTEGER INTEGER INTEGER\par
\lang1033 End\par
End\par
\f0\fs24\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
\f1\fs16\tab Zoom 2\par
\f0\fs24\par
@ -177,19 +181,22 @@ Example:\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Offset 20 20\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
\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
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), Emu48:\par
\pard\nowidctlpar\qj Emu28, Emu42 (Lewis):\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 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
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
\f1\fs16\tab Color 0 255 255 255\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 32 255 255 255\tab # optional background color for contrast setting\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
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
@ -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 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\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
Reset\tab : contrast value after calculator reset\par
Min\tab : min. adjustable contrast value by keyboard\par
Max\tab : max. adjustable contrast value by keyboard\par
\par
\pard\nowidctlpar On Emu28 and Emu42 (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
\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
@ -237,12 +245,12 @@ Max\tab : max. adjustable contrast value by keyboard\par
\f0\fs24\par
\page\b\fs28 Digit\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
\lang1031\f1\fs16 Digit\par
\tab Offset INTEGER INTEGER\par
\tab\lang1033 Size INTEGER INTEGER\par
\tab Distance INTEGER\par
\tab Size INTEGER INTEGER\par
\tab\lang1033 Distance INTEGER\par
\tab Bitmap STRING\par
End\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
\f0\fs24\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
Size is the size of one pixel in the LCD screen. Width Height.\par
Example:\par
@ -280,17 +288,17 @@ Example:\par
\f0\fs24\par
\b\fs28\page Annunciator\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
\par
\lang1031\f1\fs16 Annunciator INTEGER\par
\f1\fs16 Annunciator INTEGER\par
\tab Size INTEGER INTEGER\par
\tab Offset INTEGER INTEGER\par
\tab\lang1033 Down INTEGER INTEGER\par
\tab Down INTEGER INTEGER\par
End\par
\f0\fs24\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\fi720\f1\fs16 Annunciator 1\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
\f1\fs16\tab Offset 61 4\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
\f1\fs16\tab Down 16 485\par
\f0\fs24\par
@ -310,11 +318,11 @@ Example:\par
\b0\fs24\par
\tab Button sets the position of the button and what the button does.\par
\par
\lang1031\f1\fs16 Button INTEGER\par
\f1\fs16 Button INTEGER\par
\tab Type INTEGER\par
\tab Size 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 Virtual\par
\tab NoHold\par
@ -327,8 +335,8 @@ Example:\par
End\par
\f0\fs24\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 Example:\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\cf1 Example:\par
\cf0\f1\fs16\tab Button 11\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
@ -345,7 +353,7 @@ Type 4 is copying a part of the background bitmap with the dimension Size from t
\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
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
\cf0\f1\fs16\tab Type 0\par
\f0\fs24\par
@ -361,7 +369,7 @@ Example:\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Down 302 25\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\qj\f1\fs16\tab OutIn 1 16\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\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\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\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\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\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
\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
@ -703,16 +735,16 @@ or\par
\tab\tab <COMMANDS>\par
\tab End\par
Or\par
\tab\lang1031 IfMem INTEGER INTEGER INTEGER\par
\tab\tab\lang1033 <COMMANDS>\par
\tab IfMem INTEGER INTEGER INTEGER\par
\tab\tab <COMMANDS>\par
\tab Else\par
\tab\tab <COMMANDS>\par
\tab End\par
or\par
\tab\lang1031 SetFlag INTEGER\par
\tab SetFlag INTEGER\par
or\par
\tab ResetFlag INTEGER\par
\lang1033 or\par
or\par
\tab NotFlag INTEGER\par
or\par
\tab IfFlag INTEGER\par
@ -789,6 +821,7 @@ EDIT_BACKUP_SAVE 14\par
EDIT_BACKUP_RESTORE 15\par
EDIT_BACKUP_DELETE 16\par
VIEW_SCRIPT 17\par
EDIT_PORT_CONFIGURATION 18\par
EDIT_COPY_STRING 19\par
EDIT_PASTE_STRING 20\par
TOOL_DISASM 21\par
@ -814,6 +847,6 @@ The latest updates are available at:\par
http://hp.giesselink.com/\par
\pard\nowidctlpar\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)
@ -12,8 +12,7 @@ Known bugs and restrictions of Emu48 V1.50
SRQ1 (0x118) [ISQR]
SRQ2 (0x119) [LSRQ]
IRC (0x11A) [IRI EIRU EIRI IRE]
LCR (0x11C) [LED ELBE LBZ LBF]
LBR (0x11D) [LBO]
LCR (0x11C) [LBZ LBF]
- the baudrates 1920, 3840, 7680 and 15360 aren't emulated on most
operating systems
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
use the "=makebeep" subroutine, like alarm wake up, have no sound
- beeper emulation, ATTN key doesn't work
- no infrared printer support
- Shell OS: clock isn't synchronized with real time
- HP49G: the flash memory is emulated now with some restrictions
- 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,
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
DEBUGGER.C

View file

@ -50,7 +50,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
DdeUnaccessData(hData);
// reserve memory
if ((lpData = HeapAlloc(hHeap,0,dwSize * 2)) == NULL)
if ((lpData = malloc(dwSize * 2)) == NULL)
return (HDDEDATA) DDE_FNOTPROCESSED;
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
{
HeapFree(hHeap,0,lpData); // free memory
free(lpData); // free memory
hReturn = DDE_FNOTPROCESSED;
goto cancel;
}
@ -80,7 +80,7 @@ HDDEDATA CALLBACK DdeCallback(UINT iType,UINT iFmt,HCONV hConv,
dwSize = dwIndex;
dwSize = DdeGetData(hData,lpData+dwSize,dwSize,sizeof(DWORD));
bSuccess = (WriteStack(nStkLvl,lpData,dwSize) == S_ERR_NO);
HeapFree(hHeap,0,lpData); // free memory
free(lpData); // free memory
SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0);
@ -138,7 +138,7 @@ cancel:
dwSize += dwIndex + sizeof(DWORD);
// reserve memory
if ((lpData = HeapAlloc(hHeap,0,dwSize)) == NULL)
if ((lpData = malloc(dwSize)) == NULL)
{
SwitchToState(SM_RUN); // run state
return NULL;
@ -156,7 +156,7 @@ cancel:
// write data
hReturn = DdeCreateDataHandle(idDdeInst,lpData,dwSize,0,hsz2,iFmt,0);
HeapFree(hHeap,0,lpData);
free(lpData);
SwitchToState(SM_RUN); // run state
while (nState!=nNextState) Sleep(0);

View file

@ -53,21 +53,6 @@ typedef struct // type of breakpoint table
DWORD dwAddr; // breakpoint address
} BP_T;
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 int nCol[] =
{
IDC_DEBUG_MEM_COL0, IDC_DEBUG_MEM_COL1, IDC_DEBUG_MEM_COL2, IDC_DEBUG_MEM_COL3,
@ -79,68 +64,6 @@ static CONST TCHAR cHex[] = { _T('0'),_T('1'),_T('2'),_T('3'),
_T('8'),_T('9'),_T('A'),_T('B'),
_T('C'),_T('D'),_T('E'),_T('F') };
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 INT nDbgPosX = 0; // position of debugger window
static INT nDbgPosY = 0;
@ -159,16 +82,12 @@ static UINT uIDFol = ID_DEBUG_MEM_FNONE; // follow mode
static DWORD dwAdrMemFol = 0; // follow address memory window
static UINT uIDMap = ID_DEBUG_MEM_MAP; // current memory view mode
static LPBYTE lbyMapData; // data
static DWORD dwMapDataSize; // data size
static LONG lCharWidth; // width of a character (is a fix font)
static HMENU hMenuCode,hMenuMem,hMenuStack;// handle of context menues
static HWND hWndToolbar; // toolbar handle
static MODEL_MAP_T CONST *pMapping; // model specific memory mapping
static DWORD dwDbgRefCycles; // cpu cycles counter from last opcode
static CHIPSET OldChipset; // old chipset content
@ -189,6 +108,8 @@ static BOOL OnEditBreakpoint(HWND hDlg);
static BOOL OnInfoIntr(HWND hDlg);
static BOOL OnInfoWoRegister(HWND hDlg);
static VOID UpdateProfileWnd(HWND hDlg);
static BOOL OnMemLoadData(HWND hDlg);
static BOOL OnMemSaveData(HWND hDlg);
//################
//#
@ -242,52 +163,53 @@ static VOID DisableMenuKeys(HWND hDlg)
//
static VOID SetMappingMenu(HWND hDlg,UINT uID)
{
enum MEM_MAPPING eMode;
LPTSTR szCaption;
UINT uEnable = MF_GRAYED; // disable Memory Data menu items
CheckMenuItem(hMenuMem,uIDMap,MF_UNCHECKED);
switch (uID)
{
case ID_DEBUG_MEM_MAP:
szCaption = _T("Memory");
lbyMapData = NULL; // data
dwMapDataSize = 512; // data size
eMode = MEM_MMU;
uEnable = MF_ENABLED; // enable Memory Data menu items
break;
case ID_DEBUG_MEM_NCE1:
szCaption = _T("Memory (NCE1)");
lbyMapData = *pMapping->ppbyNCE1;
dwMapDataSize = *pMapping->pdwNCE1Size / 2048; // ROM size is always in nibbles
eMode = MEM_NCE1;
break;
case ID_DEBUG_MEM_NCE2:
szCaption = _T("Memory (NCE2)");
lbyMapData = *pMapping->ppbyNCE2;
dwMapDataSize = *pMapping->pdwNCE2Size;
eMode = MEM_NCE2;
break;
case ID_DEBUG_MEM_CE1:
szCaption = _T("Memory (CE1)");
lbyMapData = *pMapping->ppbyCE1;
dwMapDataSize = *pMapping->pdwCE1Size;
eMode = MEM_CE1;
break;
case ID_DEBUG_MEM_CE2:
szCaption = _T("Memory (CE2)");
lbyMapData = *pMapping->ppbyCE2;
dwMapDataSize = *pMapping->pdwCE2Size;
eMode = MEM_CE2;
break;
case ID_DEBUG_MEM_NCE3:
szCaption = _T("Memory (NCE3)");
lbyMapData = *pMapping->ppbyNCE3;
dwMapDataSize = *pMapping->pdwNCE3Size;
eMode = MEM_NCE3;
break;
default: _ASSERT(0);
}
dwMapDataSize *= 2048; // size in nibble
VERIFY(SetMemMapType(eMode));
if (uIDMap != uID) dwAdrMem = 0; // view from address 0
uIDMap = uID;
CheckMenuItem(hMenuMem,uIDMap,MF_CHECKED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_LOAD,uEnable);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_SAVE,uEnable);
SetDlgItemText(hDlg,IDC_STATIC_MEMORY,szCaption);
return;
};
@ -299,6 +221,7 @@ static DWORD GetMemCurAddr(HWND hDlg)
{
INT i,nPos;
DWORD dwAddr = dwAdrMem;
DWORD dwMapDataMask = GetMemDataMask();
for (i = 0; i < MEMWNDMAX; ++i) // scan all memory cols
{
@ -306,7 +229,7 @@ static DWORD GetMemCurAddr(HWND hDlg)
if ((nPos = (INT) SendDlgItemMessage(hDlg,nCol[i],LB_GETCURSEL,0,0)) != LB_ERR)
{
dwAddr += (DWORD) (nPos * MEMWNDMAX + i) * 2;
dwAddr &= (dwMapDataSize - 1);
dwAddr &= dwMapDataMask;
break;
}
}
@ -331,8 +254,7 @@ static __inline VOID ToggleBreakpoint(DWORD dwAddr)
return;
}
// purge breakpoint
for (++i; i < wBreakpointCount; ++i)
while (++i < wBreakpointCount) // purge breakpoint
sBreakpoint[i-1] = sBreakpoint[i];
--wBreakpointCount;
return;
@ -359,34 +281,23 @@ static __inline VOID ToggleBreakpoint(DWORD dwAddr)
static __inline VOID InitMemMap(HWND hDlg)
{
BOOL bActive;
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
break;
}
}
SetMemRomType(cCurrentRomType); // set current model
_ASSERT(hMenuMem);
// enable menu mappings
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE1,(*pMapping->ppbyNCE1) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE2,(*pMapping->ppbyNCE2) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE1, (*pMapping->ppbyCE1) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE2, (*pMapping->ppbyCE2) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE3,(*pMapping->ppbyNCE3) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE1,GetMemAvail(MEM_NCE1) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE2,GetMemAvail(MEM_NCE2) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE1, GetMemAvail(MEM_CE1) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_CE2, GetMemAvail(MEM_CE2) ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(hMenuMem,ID_DEBUG_MEM_NCE3,GetMemAvail(MEM_NCE3) ? MF_ENABLED : MF_GRAYED);
bActive = (ID_DEBUG_MEM_NCE1 == uIDMap && *pMapping->ppbyNCE1 != NULL)
|| (ID_DEBUG_MEM_NCE2 == uIDMap && *pMapping->ppbyNCE2 != NULL)
|| (ID_DEBUG_MEM_CE1 == uIDMap && *pMapping->ppbyCE1 != NULL)
|| (ID_DEBUG_MEM_CE2 == uIDMap && *pMapping->ppbyCE2 != NULL)
|| (ID_DEBUG_MEM_NCE3 == uIDMap && *pMapping->ppbyNCE3 != NULL);
bActive = (ID_DEBUG_MEM_NCE1 == uIDMap && GetMemAvail(MEM_NCE1))
|| (ID_DEBUG_MEM_NCE2 == uIDMap && GetMemAvail(MEM_NCE2))
|| (ID_DEBUG_MEM_CE1 == uIDMap && GetMemAvail(MEM_CE1))
|| (ID_DEBUG_MEM_CE2 == uIDMap && GetMemAvail(MEM_CE2))
|| (ID_DEBUG_MEM_NCE3 == uIDMap && GetMemAvail(MEM_NCE3));
SetMappingMenu(hDlg,bActive ? uIDMap : ID_DEBUG_MEM_MAP);
return;
@ -452,6 +363,7 @@ static VOID StrToReg(BYTE *pReg, WORD wNib, LPTSTR lpszValue)
//
static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress)
{
enum MEM_MAPPING eMapMode;
LPCTSTR lpszName;
TCHAR szAddress[64];
DWORD dwNxtAddr;
@ -459,7 +371,9 @@ static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress)
nLinePC = -1; // PC not shown (no selection)
_ASSERT(disassembler_map == MEM_MAP); // disassemble in mapped mode
eMapMode = GetMemMapType(); // get current map mode
SetMemMapType(MEM_MMU); // disassemble in mapped mode
dwAddress &= 0xFFFFF; // adjust to Saturn address range
SendMessage(hWnd,WM_SETREDRAW,FALSE,0);
SendMessage(hWnd,LB_RESETCONTENT,0,0);
@ -509,6 +423,7 @@ static INT ViewCodeWnd(HWND hWnd, DWORD dwAddress)
SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM) szAddress);
}
SendMessage(hWnd,WM_SETREDRAW,TRUE,0);
SetMemMapType(eMapMode); // switch back to old map mode
return nLinePC;
}
@ -519,12 +434,14 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress)
{
#define TEXTOFF 32
INT i,j,k;
INT i,j;
TCHAR szBuffer[16],szItem[4];
DWORD dwMapDataMask;
BYTE cChar;
szItem[2] = 0; // end of string
dwAdrMem = dwAddress; // save start address of memory window
dwMapDataMask = GetMemDataMask(); // size mask of data mapping
// purge all list boxes
SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_ADDR,LB_RESETCONTENT,0,0);
@ -538,28 +455,18 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress)
if (ID_DEBUG_MEM_MAP == uIDMap) // mapped memory content
{
// fetch mapping data line
Npeek(byLineData, dwAddress, MAXMEMITEMS);
wsprintf(szBuffer,_T("%05lX"),dwAddress);
}
else // module memory content
{
INT i;
_ASSERT(lbyMapData); // valid module
// fetch modul data line
for (i = 0; i < MAXMEMITEMS; ++i)
{
byLineData[i] = lbyMapData[(dwAddress + i) & (dwMapDataSize - 1)];
}
wsprintf(szBuffer,_T("%06lX"),dwAddress);
}
SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_ADDR,LB_ADDSTRING,0,(LPARAM) szBuffer);
for (k = 0, j = 0; j < MAXMEMITEMS; ++j)
// fetch data line
GetMemPeek(byLineData, dwAddress, MAXMEMITEMS);
for (j = 0; j < MAXMEMITEMS; ++j)
{
// read from fetched data line
szItem[j&0x1] = cHex[byLineData[j]];
@ -579,7 +486,7 @@ static VOID ViewMemWnd(HWND hDlg, DWORD dwAddress)
szBuffer[j/2] = 0; // end of text string
SendDlgItemMessage(hDlg,IDC_DEBUG_MEM_TEXT,LB_ADDSTRING,0,(LPARAM) szBuffer);
dwAddress = (dwAddress + MAXMEMITEMS) & (dwMapDataSize - 1);
dwAddress = (dwAddress + MAXMEMITEMS) & dwMapDataMask;
}
return;
#undef TEXTOFF
@ -1121,7 +1028,7 @@ static BOOL OnMemGoAdr(HWND hDlg)
OnEnterAddress(hDlg, &dwAddress);
if (dwAddress != -1) // not Cancel key
OnMemGoDx(hDlg,dwAddress & (dwMapDataSize - 1));
OnMemGoDx(hDlg,dwAddress & GetMemDataMask());
return -1; // call windows default handler
}
@ -1400,19 +1307,22 @@ static BOOL OnLButtonUp(HWND hDlg, LPARAM lParam)
//
static BOOL OnDblClick(HWND hWnd, WORD wId)
{
HWND hDlg,hWndCode;
TCHAR szBuffer[4];
BYTE byData;
INT i;
DWORD dwAddress;
hDlg = GetParent(hWnd); // dialog window handle
hWndCode = GetDlgItem(hDlg,IDC_DEBUG_CODE);
if (wId == IDC_DEBUG_STACK) // stack list box
{
// get cpu address of selected item
i = (INT) SendMessage(hWnd,LB_GETCURSEL,0,0);
dwAddress = (DWORD) SendMessage(hWnd,LB_GETITEMDATA,i,0);
// show code of this address
ViewCodeWnd(GetDlgItem(GetParent(hWnd),IDC_DEBUG_CODE),dwAddress);
ViewCodeWnd(hWndCode,dwAddress); // show code of this address
return TRUE;
}
@ -1432,11 +1342,12 @@ static BOOL OnDblClick(HWND hWnd, WORD wId)
// enter new value
SendMessage(hWnd,LB_GETTEXT,i,(LPARAM) szBuffer);
OnNewValue(szBuffer);
_stscanf(szBuffer,_T("%2X"), &byData);
byData = (BYTE) _tcstoul(szBuffer,NULL,16);
byData = (byData >> 4) | (byData << 4); // change nibbles for writing
Write2(dwAddress, byData); // write data
ViewMemWnd(GetParent(hWnd),dwAdrMem); // update memory window
Write2(dwAddress,byData); // write data
ViewCodeWnd(hWndCode,dwAdrLine[0]); // update code window
ViewMemWnd(hDlg,dwAdrMem); // update memory window
SendMessage(hWnd,LB_SETCURSEL,i,0);
return FALSE;
}
@ -1543,13 +1454,13 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam)
switch(LOWORD(wParam))
{
case VK_NEXT:
dwAdrMem = (dwAdrMem + MAXMEMITEMS * MAXMEMLINES) & (dwMapDataSize - 1);
dwAdrMem = (dwAdrMem + MAXMEMITEMS * MAXMEMLINES) & GetMemDataMask();
ViewMemWnd(GetParent(hWnd),dwAdrMem);
SendMessage(hWnd,LB_SETCURSEL,wY,0);
return -2;
case VK_PRIOR:
dwAdrMem = (dwAdrMem - MAXMEMITEMS * MAXMEMLINES) & (dwMapDataSize - 1);
dwAdrMem = (dwAdrMem - MAXMEMITEMS * MAXMEMLINES) & GetMemDataMask();
ViewMemWnd(GetParent(hWnd),dwAdrMem);
SendMessage(hWnd,LB_SETCURSEL,wY,0);
return -2;
@ -1557,7 +1468,7 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam)
case VK_DOWN:
if (wY+1 >= MAXMEMLINES)
{
dwAdrMem = (dwAdrMem + MAXMEMITEMS) & (dwMapDataSize - 1);
dwAdrMem = (dwAdrMem + MAXMEMITEMS) & GetMemDataMask();
ViewMemWnd(GetParent(hWnd),dwAdrMem);
SendMessage(hWnd,LB_SETCURSEL,wY,0);
return -2;
@ -1567,7 +1478,7 @@ static __inline BOOL OnKeyUpDown(HWND hWnd, WPARAM wParam)
case VK_UP:
if (wY == 0)
{
dwAdrMem = (dwAdrMem - MAXMEMITEMS) & (dwMapDataSize - 1);
dwAdrMem = (dwAdrMem - MAXMEMITEMS) & GetMemDataMask();
ViewMemWnd(GetParent(hWnd),dwAdrMem);
SendMessage(hWnd,LB_SETCURSEL,wY,0);
return -2;
@ -1599,7 +1510,7 @@ static __inline BOOL OnKeyPlusMinus(HWND hWnd, WPARAM wParam)
dwAdrMem++;
else
dwAdrMem--;
dwAdrMem &= (dwMapDataSize - 1);
dwAdrMem &= GetMemDataMask();
ViewMemWnd(GetParent(hWnd),dwAdrMem); // redraw memory view
SendMessage(hWnd,LB_SETCURSEL,wY,0); // set focus at old position
@ -1822,7 +1733,7 @@ static __inline HWND CreateToolbar(HWND hWnd)
_ASSERT(pData->wVersion == 1); // toolbar resource version
// alloc memory for TBBUTTON stucture
if (!(ptbb = HeapAlloc(hHeap,0,pData->wItemCount*sizeof(TBBUTTON))))
if (!(ptbb = malloc(pData->wItemCount*sizeof(TBBUTTON))))
goto unlock;
// fill TBBUTTON stucture with resource data
@ -1849,7 +1760,7 @@ static __inline HWND CreateToolbar(HWND hWnd)
pData->wWidth,pData->wHeight,pData->wWidth,pData->wHeight,
sizeof(TBBUTTON));
HeapFree(hHeap,0,ptbb);
free(ptbb);
unlock:
FreeResource(hGlobal);
@ -1924,7 +1835,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
SendDlgItemMessage(hDlg,IDC_STATIC_MISC, WM_SETFONT,(WPARAM)GetStockObject(DEFAULT_GUI_FONT),MAKELPARAM(FALSE,0));
// init last instruction circular buffer
pdwInstrArray = HeapAlloc(hHeap,0,INSTRSIZE*sizeof(*pdwInstrArray));
pdwInstrArray = malloc(INSTRSIZE*sizeof(*pdwInstrArray));
wInstrSize = INSTRSIZE; // size of last instruction array
wInstrWp = wInstrRp = 0; // write/read pointer
@ -1937,7 +1848,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
InitBsArea(hDlg); // init bank switcher list box
DisableMenuKeys(hDlg); // set debug menu keys into run state
disassembler_map = MEM_MAP; // disassemble with mapped modules
RplReadNibble = GetMemNib; // get nibble function for RPL object viewer
dwDbgStopPC = -1; // no stop address for goto cursor
dwDbgRplPC = -1; // no stop address for RPL breakpoint
@ -1949,7 +1860,6 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
if (Chipset.Shutdn) // cpu thread stopped
SetEvent(hEventShutdn); // goto debug session
UpdateWindowStatus(); // disable application menu items
OldChipset = Chipset; // save chipset values
return TRUE;
@ -1960,7 +1870,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
SetEvent(hEventDebug);
if (pdwInstrArray) // free last instruction circular buffer
{
HeapFree(hHeap,0,pdwInstrArray);
free(pdwInstrArray);
pdwInstrArray = NULL;
}
CloseHandle(hEventDebug);
@ -1973,8 +1883,6 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
DestroyMenu(hMenuMainCode);
DestroyMenu(hMenuMainMem);
DestroyMenu(hMenuMainStack);
_ASSERT(hWnd);
UpdateWindowStatus(); // enable application menu items
hDlgDebug = NULL; // debugger windows closed
break;
@ -2047,6 +1955,8 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
case ID_DEBUG_MEM_CE1:
case ID_DEBUG_MEM_CE2:
case ID_DEBUG_MEM_NCE3: return OnMemMapping(hDlg,LOWORD(wParam));
case ID_DEBUG_MEM_LOAD: return OnMemLoadData(hDlg);
case ID_DEBUG_MEM_SAVE: return OnMemSaveData(hDlg);
case ID_DEBUG_MEM_RPLVIEW: return OnRplObjView(hDlg);
case ID_DEBUG_STACK_PUSH: return OnStackPush(hDlg);
case ID_DEBUG_STACK_POP: return OnStackPop(hDlg);
@ -2173,16 +2083,18 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast)
{
BYTE *lpbySearch;
INT i,j;
DWORD dwAddr;
DWORD dwAddr,dwMapDataMask;
BOOL bMatch;
HWND hWnd = GetDlgItem(hDlg,IDC_FIND_DATA);
dwMapDataMask = GetMemDataMask(); // size mask of data mapping
i = GetWindowTextLength(hWnd) + 1; // text length incl. EOS
j = bASCII ? 2 : sizeof(*(LPTSTR)0); // buffer width
// allocate search buffer
if ((lpbySearch = HeapAlloc(hHeap,0,i * j)) != NULL)
if ((lpbySearch = malloc(i * j)) != NULL)
{
// get search text and real length
i = GetWindowText(hWnd,(LPTSTR) lpbySearch,i);
@ -2200,7 +2112,7 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast)
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szTmp, -1,
lpbySearch, i+1, NULL, NULL);
HeapFree(hHeap,0,szTmp);
free(szTmp);
}
}
#endif
@ -2245,26 +2157,19 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast)
++dwAddr;
// scan mapping/module until match
for (; i && !bMatch && dwAddr <= dwAdrMem + dwMapDataSize; ++dwAddr)
for (; i && !bMatch && dwAddr <= dwAdrMem + dwMapDataMask + 1; ++dwAddr)
{
BYTE byC;
// i = no. of nibbles that have to match
for (bMatch = TRUE, j = 0;bMatch && j < i; ++j)
{
if (ID_DEBUG_MEM_MAP == uIDMap) // mapped memory content
{
Npeek(&byC,(dwAddr + j) & 0xFFFFF,1);
}
else // module memory content
{
byC = lbyMapData[(dwAddr + j) & (dwMapDataSize - 1)];
}
GetMemPeek(&byC,(dwAddr + j) & dwMapDataMask,1);
bMatch = (byC == lpbySearch[j]);
}
}
dwAddr = (dwAddr - 1) & (dwMapDataSize - 1); // possible matching address
HeapFree(hHeap,0,lpbySearch);
dwAddr = (dwAddr - 1) & dwMapDataMask; // possible matching address
free(lpbySearch);
// check match result
if (bMatch)
@ -2447,10 +2352,13 @@ static VOID UpdateRplObjViewWnd(HWND hDlg, DWORD dwAddr)
if (hDlg == NULL) return; // dialog not open
// show entry point name only in mapped mode
bRplViewName = (GetMemMapType() == MEM_MMU);
// create view string
szObjList = RplCreateObjView(dwAddr,0x100000,TRUE);
szObjList = RplCreateObjView(dwAddr,GetMemDataSize(),TRUE);
SetDlgItemText(hDlg,IDC_RPLVIEW_DATA,szObjList);
HeapFree(hHeap,0,szObjList);
free(szObjList);
return;
}
@ -2480,7 +2388,6 @@ static INT_PTR CALLBACK RplObjView(HWND hDlg, UINT message, WPARAM wParam, LPARA
_ASSERT(FALSE);
}
bRplViewName = TRUE; // show entry point name
bRplViewAddr = TRUE; // show address
bRplViewBin = TRUE; // show binary data
return TRUE;
@ -2535,7 +2442,7 @@ static VOID CopyEditToCombo(HWND hDlg,HWND hWndComboBox)
if ((i = (INT) SendMessage(hWndComboBox,CB_GETCURSEL,0,0)) != CB_ERR)
{
// delete associated name
HeapFree(hHeap,0,(LPVOID) SendMessage(hWndComboBox,CB_GETITEMDATA,i,0));
free((LPVOID) SendMessage(hWndComboBox,CB_GETITEMDATA,i,0));
// append actual name
GetDlgItemText(hDlg,IDC_DEBUG_SET_FILE,szSymbFilename,ARRAYSIZEOF(szSymbFilename));
@ -2700,7 +2607,7 @@ static INT_PTR CALLBACK Settings(HWND hDlg, UINT message, WPARAM wParam, LPARAM
LPTSTR lpszFilename = (LPTSTR) SendMessage(hWnd,CB_GETITEMDATA,i,0);
if (lpszFilename != NULL)
{
HeapFree(hHeap,0,lpszFilename);
free(lpszFilename);
}
}
EndDialog(hDlg,LOWORD(wParam));
@ -3156,7 +3063,7 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L
}
// remove breakpoint from breakpoint table
for (++i; i <= wBreakpointCount; ++i)
while (++i <= wBreakpointCount)
sBreakpoint[i-1] = sBreakpoint[i];
}
}
@ -3346,7 +3253,9 @@ VOID LoadBreakpointList(HANDLE hFile) // NULL = clear breakpoint list
// read number of breakpoints
if (hFile) ReadFile(hFile, &wBreakpointCount, sizeof(wBreakpointCount), &lBytesRead, NULL);
if (lBytesRead) // breakpoints found
// breakpoints found
if (lBytesRead == sizeof(wBreakpointCount) && wBreakpointCount < ARRAYSIZEOF(sBreakpoint))
{
WORD wBreakpointSize;
@ -3363,7 +3272,7 @@ VOID LoadBreakpointList(HANDLE hFile) // NULL = clear breakpoint list
wBreakpointCount = 0; // clear breakpoint list
}
}
else
else // no breakpoints or breakpoint buffer too small
{
wBreakpointCount = 0; // clear breakpoint list
}
@ -3429,3 +3338,232 @@ VOID RestoreBackupBreakpointList(VOID)
}
return;
}
//################
//#
//# Load/Save Memory Data
//#
//################
static BOOL OnBrowseLoadMem(HWND hDlg)
{
TCHAR szBuffer[MAX_PATH];
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter =
_T("Memory Dump Files (*.MEM)\0*.MEM\0")
_T("All Files (*.*)\0*.*\0");
ofn.lpstrDefExt = _T("MEM");
ofn.nFilterIndex = 1;
ofn.lpstrFile = szBuffer;
ofn.lpstrFile[0] = 0;
ofn.nMaxFile = ARRAYSIZEOF(szBuffer);
ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST;
if (GetOpenFileName(&ofn))
{
SetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szBuffer);
}
return 0;
}
static BOOL OnBrowseSaveMem(HWND hDlg)
{
TCHAR szBuffer[MAX_PATH];
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter =
_T("Memory Dump Files (*.MEM)\0*.MEM\0")
_T("All Files (*.*)\0*.*\0");
ofn.lpstrDefExt = _T("MEM");
ofn.nFilterIndex = 1;
ofn.lpstrFile = szBuffer;
ofn.lpstrFile[0] = 0;
ofn.nMaxFile = ARRAYSIZEOF(szBuffer);
ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_CREATEPROMPT|OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn))
{
SetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szBuffer);
}
return 0;
}
//
// write file to memory
//
static BOOL LoadMemData(LPCTSTR lpszFilename,DWORD dwStartAddr)
{
HANDLE hFile;
DWORD dwRead;
BYTE byData;
hFile = CreateFile(lpszFilename,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
return FALSE;
while (TRUE) // read until EOF
{
ReadFile(hFile,&byData,sizeof(byData),&dwRead,NULL);
if (dwRead == 0) break; // EOF
Write2(dwStartAddr,byData); // write byte in map mode
dwStartAddr += 2;
}
CloseHandle(hFile);
return TRUE;
}
//
// write memory data to file
//
static BOOL SaveMemData(LPCTSTR lpszFilename,DWORD dwStartAddr,DWORD dwEndAddr)
{
HANDLE hFile;
DWORD dwAddr,dwWritten;
BYTE byData;
hFile = CreateFile(lpszFilename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
if (hFile == INVALID_HANDLE_VALUE) // error, couldn't create a new file
return FALSE;
for (dwAddr = dwStartAddr; dwAddr <= dwEndAddr; dwAddr += 2)
{
byData = Read2(dwAddr); // read byte in map mode
WriteFile(hFile,&byData,sizeof(byData),&dwWritten,NULL);
}
CloseHandle(hFile);
return TRUE;
}
//
// read edit control and decode content as hex number
//
static BOOL GetAddr(HWND hDlg, INT nID, DWORD *pdwAddr)
{
TCHAR szBuffer[8];
INT i;
HWND hWnd = GetDlgItem(hDlg,nID);
GetWindowText(hWnd,szBuffer,ARRAYSIZEOF(szBuffer));
// test if valid hex address
for (i = 0; i < (LONG) lstrlen(szBuffer); ++i)
{
if (_istxdigit(szBuffer[i]) == 0)
{
SendMessage(hWnd,EM_SETSEL,0,-1);
SetFocus(hWnd); // focus to edit control
return FALSE;
}
}
_stscanf(szBuffer,_T("%6X"),pdwAddr);
return TRUE;
}
//
// memory load data
//
static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szFilename[MAX_PATH];
DWORD dwStartAddr;
switch (message)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_DEBUG_DATA_BUT:
return OnBrowseLoadMem(hDlg);
case IDOK:
// get filename
GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename));
// decode address field
if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr))
return FALSE;
// load memory dump file
if (!LoadMemData(szFilename,dwStartAddr))
return FALSE;
// update memory window
UpdateMemoryWnd(GetParent(hDlg));
// no break
case IDCANCEL:
EndDialog(hDlg,LOWORD(wParam));
return TRUE;
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
static BOOL OnMemLoadData(HWND hDlg)
{
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DEBUG_MEMLOAD), hDlg, (DLGPROC)DebugMemLoad) == -1)
AbortMessage(_T("DebugLoad Dialog Box Creation Error !"));
return -1;
}
//
// memory save data
//
static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
TCHAR szFilename[MAX_PATH];
DWORD dwStartAddr,dwEndAddr;
switch (message)
{
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_DEBUG_DATA_BUT:
return OnBrowseSaveMem(hDlg);
case IDOK:
// get filename
GetDlgItemText(hDlg,IDC_DEBUG_DATA_FILE,szFilename,ARRAYSIZEOF(szFilename));
// decode address fields
if (!GetAddr(hDlg,IDC_DEBUG_DATA_STARTADDR,&dwStartAddr))
return FALSE;
if (!GetAddr(hDlg,IDC_DEBUG_DATA_ENDADDR,&dwEndAddr))
return FALSE;
// save memory dump file
if (!SaveMemData(szFilename,dwStartAddr,dwEndAddr))
return FALSE;
// no break
case IDCANCEL:
EndDialog(hDlg,LOWORD(wParam));
return TRUE;
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
static BOOL OnMemSaveData(HWND hDlg)
{
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_DEBUG_MEMSAVE), hDlg, (DLGPROC)DebugMemSave) == -1)
AbortMessage(_T("DebugSave Dialog Box Creation Error !"));
return -1;
}

View file

@ -16,7 +16,6 @@
BOOL disassembler_mode = HP_MNEMONICS;
BOOL disassembler_symb = FALSE;
WORD disassembler_map = MEM_MAP;
static LPCTSTR hex[] =
{
@ -215,82 +214,13 @@ static LPCTSTR hst_bits[8] =
_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
static BYTE read_nibble (DWORD *p)
{
return GetMemNib(p);
}
static int read_int (DWORD *addr, int n)
{
int i, t;

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

View file

@ -34,7 +34,7 @@ static VOID PutSn(String *str, LPCTSTR szVal, DWORD dwLen)
if (str->dwSize == 0) // no buffer allocated
{
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;
}
@ -51,7 +51,7 @@ static VOID PutSn(String *str, LPCTSTR szVal, DWORD dwLen)
dwMinSize *= ALLOCSIZE;
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));
@ -117,7 +117,7 @@ static DWORD Readx(DWORD *pdwAddr,DWORD n)
DWORD i, t;
for (i = 0, t = 0; i < n; ++i)
t |= read_nibble(pdwAddr) << (i * 4);
t |= RplReadNibble(pdwAddr) << (i * 4);
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
bPflag = FALSE; // show no decimal point
bExpflag = FALSE; // show no exponent
// scan mantissa
for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--)
@ -214,10 +215,10 @@ static BOOL BINx(DWORD *pdwAddr,INT nBinLen,String *str)
LPBYTE pbyNumber;
INT i;
VERIFY(pbyNumber = HeapAlloc(hHeap,0,nBinLen));
VERIFY(pbyNumber = (LPBYTE) malloc(nBinLen));
for (i = 0; i < nBinLen; ++i) // read data
pbyNumber[i] = read_nibble(pdwAddr);
pbyNumber[i] = RplReadNibble(pdwAddr);
// strip leading zeros
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]]);
}
HeapFree(hHeap,0,pbyNumber);
free(pbyNumber);
return FALSE;
}
@ -269,7 +270,7 @@ static BOOL DoHexStream(DWORD *pdwAddr,String *str,UINT *pnLevel)
for (;dwLength > 0; --dwLength)
{
PutC(str,cHex[read_nibble(pdwAddr)]); // write digit
PutC(str,cHex[RplReadNibble(pdwAddr)]); // write digit
}
return FALSE;
}
@ -321,10 +322,10 @@ static BOOL DoIntStream(DWORD *pdwAddr,String *str,UINT *pnLevel)
dwLength -= 5; // object length
VERIFY(pbyData = HeapAlloc(hHeap,0,dwLength));
VERIFY(pbyData = (LPBYTE) malloc(dwLength));
for (i = 0; i < dwLength; ++i) // read data
pbyData[i] = read_nibble(pdwAddr);
pbyData[i] = RplReadNibble(pdwAddr);
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;
}
@ -369,7 +370,7 @@ static BOOL DoReal(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get real object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
return BCDx(byNumber,12,3,str);
}
@ -383,7 +384,7 @@ BOOL DoERel(DWORD *pdwAddr,String *str,UINT *pnLevel)
// get extended real object content
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
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
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
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
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
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
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
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
for (i = 0; i < ARRAYSIZEOF(byNumber); ++i)
byNumber[i] = read_nibble(pdwAddr);
byNumber[i] = RplReadNibble(pdwAddr);
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)
{
byVal = read_nibble(pdwAddr);
byVal = RplReadNibble(pdwAddr);
// remove leading zeros
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)
{
DWORD dwOffset,dwObjStart,dwBufferPos,dwAddr;
BOOL bErr;
BOOL bErr = FALSE;
dwObjStart = *pdwAddr; // remember start position of RRP
dwBufferPos = str->dwPos; // insert address of text
@ -1254,10 +1255,13 @@ static BOOL FetchObj(DWORD *pdwAddr,String *str,UINT *pnLevel)
return bErr;
}
BYTE (*RplReadNibble)(DWORD *p) = NULL; // get nibble function pointer
DWORD RplSkipObject(DWORD dwAddr)
{
UINT nLevel = 1; // nest DOCOL objects
_ASSERT(RplReadNibble != NULL); // get nibble function defined
FetchObj(&dwAddr,NULL,&nLevel); // decode object without output
return dwAddr;
}
@ -1269,12 +1273,14 @@ LPTSTR RplDecodeObject(DWORD dwAddr, DWORD *pdwNxtAddr)
UINT nLevel = 0; // don't nest DOCOL objects
dwNxtAddr = dwAddr; // init next address
_ASSERT(RplReadNibble != NULL); // get nibble function defined
FetchObj(&dwNxtAddr,&str,&nLevel); // decode object
PutC(&str,0); // set EOS
// 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
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
{
c = cHex[read_nibble(&dwStartAddr)];
c = cHex[RplReadNibble(&dwStartAddr)];
}
PutC(str,c); // write data content
@ -1342,6 +1348,10 @@ static VOID PrintTail(DWORD dwStartAddr, DWORD dwEndAddr, String *str)
{
// spaces instead of show address
PutS(str,_T(" "));
// address has 6 digit
if (dwActAddr >= 0x100000)
PutC(str,_T(' '));
}
dwRemain = dwEndAddr - dwActAddr;
@ -1350,7 +1360,7 @@ static VOID PrintTail(DWORD dwStartAddr, DWORD dwEndAddr, String *str)
for (; dwRemain > 0; --dwRemain)
{
// write data content
PutC(str,cHex[read_nibble(&dwActAddr)]);
PutC(str,cHex[RplReadNibble(&dwActAddr)]);
}
PutS(str,_T("\r\n"));
@ -1444,6 +1454,8 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
LPTSTR lpszObject;
DWORD dwLevel,dwAddr,dwNxtAddr;
_ASSERT(RplReadNibble != NULL); // get nibble function defined
lpszObject = NULL; // no memory allocated
dwLevel = 0; // nesting level
@ -1472,8 +1484,7 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
// check for special RRP handling
if (_tcsncmp(lpszObject,_T("DIR\n"),4) == 0)
{
LPCTSTR lpszStart;
LPTSTR lpszEnd;
LPCTSTR lpszStart,lpszEnd;
lpszStart = lpszEnd = lpszObject;
@ -1525,13 +1536,12 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
while (FALSE);
PutS(&str,_T("\r\n"));
// write additional binary data
PrintTail(dwAddr+5,dwNxtAddr,&str);
PrintTail(dwAddr+5,dwNxtAddr,&str); // write additional binary data
if (lstrcmp(lpszObject,_T("::")) == 0)
++dwLevel;
HeapFree(hHeap,0,lpszObject); // free object string
free(lpszObject); // free object string
lpszObject = NULL;
if ( (bSingleObj && dwLevel == 0) // single object decoding?
@ -1554,6 +1564,6 @@ LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj)
PutC(&str,0); // set EOS
// 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;
}

View file

@ -19,6 +19,7 @@ extern BOOL bRplViewName; // show entry point name
extern BOOL bRplViewAddr; // show adress
extern BOOL bRplViewBin; // show binary 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 LPTSTR RplDecodeObject(DWORD dwAddr, DWORD *pdwNxtAddr);
extern LPTSTR RplCreateObjView(DWORD dwStartAddr, DWORD dwEndAddr, BOOL bSingleObj);

View file

@ -13,7 +13,7 @@
#include "kml.h"
#include "debugger.h"
#define VERSION "1.50"
#define VERSION "1.53"
// #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
DWORD idDdeInst; // DDE server id
UINT uCF_HpObj; // DDE clipboard format
HANDLE hHeap;
HANDLE hThread;
DWORD lThreadId;
HANDLE hEventShutdn; // event handle to stop cpu thread
@ -84,7 +83,7 @@ BOOL bAlwaysDisplayLog = TRUE;
BOOL bLoadObjectWarning = TRUE;
BOOL bAlwaysOnTop = FALSE; // emulator window always on top
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)
{
if (szTitle) HeapFree(hHeap,0,szTitle);
if (szTitle) free(szTitle);
_ASSERT(hWnd != NULL);
if (szString)
@ -111,44 +110,6 @@ VOID SetWindowTitle(LPCTSTR szString)
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)
{
// 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)
return; // no items selected
if ((lpnCount = HeapAlloc(hHeap,0,i * sizeof(INT))) != NULL)
if ((lpnCount = malloc(i * sizeof(INT))) != NULL)
{
LPTSTR lpszData;
HANDLE hClipObj;
@ -223,7 +184,7 @@ VOID CopyItemsToClipboard(HWND hWnd) // save selected Listbox Items to Clipboar
GlobalFree(hClipObj);
}
}
HeapFree(hHeap,0,lpnCount); // free item table
free(lpnCount); // free item table
}
return;
}
@ -327,16 +288,11 @@ static VOID SetCommList(HWND hDlg,LPCTSTR szWireSetting,LPCTSTR szIrSetting)
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;
LPCTSTR szActPort2Filename = _T("");
BOOL bPort2CfgChange = FALSE;
BOOL bPort2AttChange = FALSE;
switch (message)
switch (uMsg)
{
case WM_INITDIALOG:
// 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_ALWAYSONTOP,bAlwaysOnTop);
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_AUTOSAVEONEXIT,bAutoSaveOnExit);
CheckDlgButton(hDlg,IDC_OBJECTLOADWARNING,bLoadObjectWarning);
@ -351,24 +313,58 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
// set disassebler mode
CheckDlgButton(hDlg,(disassembler_mode == HP_MNEMONICS) ? IDC_DISASM_HP : IDC_DISASM_CLASS,BST_CHECKED);
// 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);
// set combobox parameter
SetCommList(hDlg,szSerialWire,szSerialIr);
if (bCommInit) // disable when port open
return TRUE;
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
EnableWindow(GetDlgItem(hDlg,IDC_WIRE),FALSE);
EnableWindow(GetDlgItem(hDlg,IDC_IR),FALSE);
case PSN_KILLACTIVE:
// 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
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_PORT2),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;
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;
case IDC_PORT2LOAD:
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));
}
return TRUE;
case IDOK:
}
break;
case WM_NOTIFY:
switch (((LPNMHDR) lParam)->code)
{
case PSN_KILLACTIVE:
if (Chipset.Port1Size && cCurrentRomType!='X')
{
UINT nOldState = SwitchToState(SM_SLEEP);
// save old card status
BYTE bCardsStatus = Chipset.cards_status;
BYTE byCardsStatus = Chipset.cards_status;
// port1 disabled?
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?
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
)
{
@ -504,22 +494,7 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
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
{
UINT nOldState = SwitchToState(SM_INVALID);
@ -563,32 +538,83 @@ static INT_PTR CALLBACK SettingsProc(HWND hDlg, UINT message, WPARAM wParam, LPA
}
SwitchToState(nOldState);
}
// set disassembler mode
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));
return TRUE;
}
break;
}
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;
if (pbyRom == NULL) return IDNO;
if (bDocumentAvail == FALSE) return IDNO;
if (bAuto)
uReply = IDYES;
@ -755,14 +781,50 @@ static LRESULT OnPaint(HWND hWindow)
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
//
static LRESULT OnDropFiles(HANDLE hFilesInfo)
static LRESULT OnDropFiles(HDROP hFilesInfo)
{
TCHAR szFileName[MAX_PATH];
WORD wNumFiles,wIndex;
BOOL bSuccess;
BOOL bSuccess = FALSE;
// get number of files dropped
wNumFiles = DragQueryFile (hFilesInfo,(UINT)-1,NULL,0);
@ -833,7 +895,6 @@ static LRESULT OnFileNew(VOID)
SaveBackup();
}
if (NewDocument()) SetWindowTitle(_T("Untitled"));
UpdateWindowStatus();
cancel:
if (pbyRom) SwitchToState(SM_RUN);
return 0;
@ -1036,13 +1097,13 @@ static LRESULT OnViewCopy(VOID)
GetObject(hPalette,sizeof(WORD),&wBits);
// 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->palNumEntries = wBits;
GetPaletteEntries(hPalette, 0, wBits, ppal->palPalEntry);
SetClipboardData(CF_PALETTE, CreatePalette(ppal));
HeapFree(hHeap,0,ppal);
free(ppal);
}
}
DeleteDC(hBmpDC);
@ -1087,13 +1148,80 @@ static LRESULT OnViewReset(VOID)
//
// 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)
{
PROPSHEETPAGE psp[3];
PROPSHEETHEADER psh;
// not in nState = SM_INVALID or port2 file must be closed from document
_ASSERT(nState != SM_INVALID || pbyPort2 == NULL);
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_SETTINGS), hWnd, (DLGPROC)SettingsProc) == -1)
AbortMessage(_T("Settings Dialog Creation Error !"));
psp[0].dwSize = sizeof(PROPSHEETPAGE);
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();
return 0;
@ -1104,6 +1232,9 @@ static LRESULT OnViewSettings(VOID)
//
static LRESULT OnViewScript(VOID)
{
TCHAR szKmlFile[MAX_PATH];
BOOL bKMLChanged,bSucc;
BYTE cType = cCurrentRomType;
if (nState != SM_RUN)
{
@ -1113,14 +1244,50 @@ static LRESULT OnViewScript(VOID)
}
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
{
if (!DisplayChooseKml(cType)) break;
}
while (!InitKML(szCurrentKml,FALSE));
if (!DisplayChooseKml(cType)) // quit with Cancel
{
if (!bKMLChanged) // KML script not changed
break; // exit loop with current loaded KML script
SetWindowPathTitle(szCurrentFilename); // update window title line
if (pbyRom) SwitchToState(SM_RUN);
// restore KML script file name
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;
}
@ -1271,58 +1438,74 @@ static INT_PTR CALLBACK Disasm(HWND hDlg, UINT message, WPARAM wParam, LPARAM lP
{
static DWORD dwAddress,dwAddressMax;
enum MEM_MAPPING eMode;
LONG i;
DWORD dwNxtAddr;
TCHAR *cpStop,szAddress[256] = _T("0");
TCHAR szAddress[256] = _T("0");
switch (message)
{
case WM_INITDIALOG:
VERIFY(SetMemRomType(cCurrentRomType)); // set current model
// set fonts & cursor
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_ROM,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_DISASM_MODE_TEXT,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_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_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,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);
disassembler_map = MEM_MAP; // disassemble with mapped modules
dwAddress = _tcstoul(szAddress,&cpStop,16);
dwAddressMax = 0x100000; // greatest address (mapped mode)
dwAddressMax = GetMemDataSize();
dwAddress = _tcstoul(szAddress,NULL,16);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
// decode radio buttons
case IDC_DISASM_MAP:
disassembler_map = MEM_MAP;
dwAddressMax = 0x100000;
return TRUE;
case IDC_DISASM_ROM:
disassembler_map = MEM_ROM;
dwAddressMax = dwRomSize;
return TRUE;
case IDC_DISASM_RAM:
disassembler_map = MEM_RAM;
dwAddressMax = Chipset.Port0Size * 2048;
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;
// decode memory mode combo box
case IDC_DISASM_MODE:
// new combo box item selected
if (HIWORD(wParam) == CBN_SELENDOK)
{
HWND hWnd = GetDlgItem(hDlg,IDC_DISASM_MODE);
i = (LONG) SendMessage(hWnd,CB_GETCURSEL,0,0);
eMode = (enum MEM_MAPPING) SendMessage(hWnd,CB_GETITEMDATA,i,0);
VERIFY(SetMemMapType(eMode));
dwAddressMax = GetMemDataSize();
}
break;
case IDOK:
SendDlgItemMessage(hDlg,IDC_DISASM_ADR,EM_SETSEL,0,-1);
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)
return FALSE;
}
dwAddress = _tcstoul(szAddress,&cpStop,16);
dwAddress = _tcstoul(szAddress,NULL,16);
// no break
case IDC_DISASM_NEXT:
if (dwAddress >= dwAddressMax)
@ -1403,7 +1586,7 @@ static LRESULT OnToolDisasm(VOID) // disasm dialogbox call
{
if (pbyRom) SwitchToState(SM_SLEEP);
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);
return 0;
}
@ -1411,7 +1594,7 @@ static LRESULT OnToolDisasm(VOID) // disasm dialogbox call
static LRESULT OnAbout(VOID)
{
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;
}
@ -1479,7 +1662,8 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_CREATE: return OnCreate(hWindow);
case WM_DESTROY: return OnDestroy(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:
if (LOWORD(wParam)==WA_INACTIVE) break;
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)
{
typedef DWORD (WINAPI *LPFN_STIP)(HANDLE hThread,DWORD dwIdealProcessor);
MSG msg;
WNDCLASS wc;
ATOM classAtom;
RECT rectWindow;
HACCEL hAccel;
LPFN_STIP fnSetThreadIdealProcessor;
DWORD dwProcessor;
HSZ hszService, hszTopic; // variables for DDE server
DWORD_PTR dwAffMask;
LPTSTR lpFilePart;
hApp = hInst;
@ -1577,13 +1765,6 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
}
#endif
hHeap = GetProcessHeap();
if (hHeap == NULL)
{
AbortMessage(_T("Heap creation failed."));
return FALSE;
}
wc.style = CS_BYTEALIGNCLIENT;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.cbClsExtra = 0;
@ -1595,7 +1776,7 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU);
wc.lpszClassName = _T("CEmu48");
if (!RegisterClass(&wc))
if (!(classAtom = RegisterClass(&wc)))
{
AbortMessage(
_T("CEmu48 class registration failed.\n")
@ -1603,6 +1784,21 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
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
rectWindow.left = 0;
rectWindow.top = 0;
@ -1610,13 +1806,12 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
rectWindow.bottom = 0;
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,
CW_USEDEFAULT, CW_USEDEFAULT,
rectWindow.right - rectWindow.left,
rectWindow.bottom - rectWindow.top,
NULL,NULL,hApp,NULL
);
NULL,NULL,hApp,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
QueryPerformanceCounter(&lAppStart);
GetCurrentDirectory(ARRAYSIZEOF(szCurrentDirectory), szCurrentDirectory);
szCurrentKml[0] = 0; // no KML file selected
ReadSettings();
SetSpeed(bRealSpeed); // set speed
MruInit(4); // init MRU entries
UpdateWindowStatus();
// create auto event handle
hEventShutdn = CreateEvent(NULL,FALSE,FALSE,NULL);
if (hEventShutdn == NULL)
@ -1656,9 +1848,18 @@ int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nC
DestroyWindow(hWnd);
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()
dwAffMask = SetThreadAffinityMask(hThread,1);
_ASSERT(dwAffMask != 0);
VERIFY(SetThreadAffinityMask(hThread,(DWORD_PTR) (1 << dwProcessor)));
ResumeThread(hThread); // start thread
while (nState!=nNextState) Sleep(0); // wait for thread initialized
@ -1753,6 +1954,7 @@ start:
_ASSERT(pKml == NULL); // KML script not closed
_ASSERT(szTitle == NULL); // freed allocated memory
_ASSERT(hPalette == NULL); // freed resource memory
_CrtDumpMemoryLeaks(); // show memory leaks
return (int) msg.wParam;
UNREFERENCED_PARAMETER(lpCmdLine);

View file

@ -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 BASE MTL /nologo /D "NDEBUG" /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
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 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"
@ -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 BASE MTL /nologo /D "_DEBUG" /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
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 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"
@ -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 BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
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 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"
@ -128,14 +128,15 @@ 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 BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
# SUBTRACT RSC /x
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
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 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
@ -166,6 +167,10 @@ SOURCE=.\disasm.c
# End Source File
# Begin Source File
SOURCE=.\dismem.c
# End Source File
# Begin Source File
SOURCE=.\display.c
# End Source File
# Begin Source File
@ -235,6 +240,10 @@ SOURCE=.\pch.c
# End Source File
# Begin Source File
SOURCE=.\redeye.c
# End Source File
# Begin Source File
SOURCE=.\rpl.c
# End Source File
# Begin Source File
@ -257,6 +266,10 @@ SOURCE=.\symbfile.c
SOURCE=.\timer.c
# End Source File
# Begin Source File
SOURCE=.\udp.c
# End Source File
# End Group
# Begin Group "Header Files"

View file

@ -47,12 +47,6 @@
#define HP_MNEMONICS FALSE // disassembler mnenomics mode
#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_NEW 1
#define MACRO_PLAY 2
@ -62,12 +56,17 @@
#define DISP_MENUE 0x04
#define DISP_ANNUN 0x08
#define ROMPAGESIZE (1<<12) // ROM dirty page size in nibbles
// macro to check for valid calculator model
#define isModelValid(m) (m != 0 && strchr(MODELS,m) != NULL)
// values for mapping area
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
extern HPALETTE hPalette;
extern HPALETTE hOldPalette;
@ -90,7 +89,6 @@ extern LARGE_INTEGER lFreq;
extern LARGE_INTEGER lAppStart;
extern DWORD idDdeInst;
extern UINT uCF_HpObj;
extern HANDLE hHeap;
extern HINSTANCE hApp;
extern HWND hWnd;
extern HWND hDlgDebug;
@ -109,11 +107,11 @@ extern BOOL bAlwaysDisplayLog;
extern BOOL bLoadObjectWarning;
extern BOOL bAlwaysOnTop;
extern BOOL bActFollowsMouse;
extern BOOL bSingleInstance;
extern HANDLE hThread;
extern DWORD lThreadId;
extern VOID SetWindowTitle(LPCTSTR szString);
extern VOID CopyItemsToClipboard(HWND hWnd);
extern VOID UpdateWindowStatus(VOID);
extern VOID ForceForegroundWindow(HWND hWnd);
// mru.c
@ -174,6 +172,7 @@ extern UINT nState;
extern UINT nNextState;
extern BOOL bRealSpeed;
extern BOOL bKeySlow;
extern UINT nOpcSlow;
extern BOOL bCommInit;
extern CHIPSET Chipset;
extern TCHAR szSerialWire[16];
@ -198,6 +197,7 @@ extern WORD wInstrRp;
extern VOID SuspendDebugger(VOID);
extern VOID ResumeDebugger(VOID);
extern VOID CheckSerial(VOID);
extern VOID InitAdjustSpeed(VOID);
extern VOID AdjKeySpeed(VOID);
extern VOID SetSpeed(BOOL bAdjust);
extern VOID UpdateKdnBit(VOID);
@ -217,6 +217,7 @@ extern TCHAR szCurrentFilename[MAX_PATH];
extern TCHAR szBackupFilename[MAX_PATH];
extern TCHAR szBufferFilename[MAX_PATH];
extern TCHAR szPort2Filename[MAX_PATH];
extern BOOL bDocumentAvail;
extern BYTE cCurrentRomType;
extern UINT nCurrentClass;
extern LPBYTE Port0;
@ -225,6 +226,8 @@ extern LPBYTE Port2;
extern LPBYTE pbyRom;
extern BOOL bRomWriteable;
extern DWORD dwRomSize;
extern LPBYTE pbyRomDirtyPage;
extern DWORD dwRomDirtyPageSize;
extern WORD wRomCrc;
extern LPBYTE pbyPort2;
extern BOOL bPort2Writeable;
@ -309,12 +312,22 @@ extern VOID KeyboardEvent(BOOL bPress, UINT out, UINT in);
extern INT nMacroState;
extern INT nMacroTimeout;
extern BOOL bMacroRealSpeed;
extern DWORD dwMacroMinDelay;
extern VOID KeyMacroRecord(BOOL bPress, UINT out, UINT in);
extern LRESULT OnToolMacroNew(VOID);
extern LRESULT OnToolMacroPlay(VOID);
extern LRESULT OnToolMacroStop(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
extern BOOL bDetectClpObject;
extern LRESULT OnStackCopy(VOID);
@ -339,11 +352,19 @@ extern VOID RCKBp(CHIPSET* w);
// DDEserv.c
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
extern BOOL disassembler_mode;
extern BOOL disassembler_symb;
extern WORD disassembler_map;
extern BYTE read_nibble(DWORD *p);
extern DWORD disassemble(DWORD addr, LPTSTR out);
// Symbfile.c
@ -385,7 +406,7 @@ static __inline int YesNoCancelMessage(LPCTSTR szMessage,UINT uStyle) {return Me
static __inline LPTSTR DuplicateString(LPCTSTR szString)
{
UINT uLength = lstrlen(szString) + 1;
LPTSTR szDup = HeapAlloc(hHeap,0,uLength*sizeof(szDup[0]));
LPTSTR szDup = malloc(uLength*sizeof(szDup[0]));
lstrcpy(szDup,szString);
return szDup;
}

View file

@ -77,12 +77,40 @@ BEGIN
BOTTOMMARGIN, 145
END
IDD_SETTINGS, DIALOG
IDD_SET_GENERAL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 160
TOPMARGIN, 4
BOTTOMMARGIN, 280
RIGHTMARGIN, 244
VERTGUIDE, 14
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
IDD_CHOOSEKML, DIALOG
@ -157,6 +185,22 @@ BEGIN
BOTTOMMARGIN, 74
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
BEGIN
LEFTMARGIN, 7
@ -252,69 +296,88 @@ FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2010 Christoph Gießelink && Sébastien Carlier",
LTEXT "Copyright © 2012 Christoph Gießelink && Sébastien Carlier",
IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY
END
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings"
IDD_SET_GENERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "General"
FONT 8, "MS Sans Serif"
BEGIN
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,28,133,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,40,133,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,"Button",
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,76,133,10
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,100,133,10
CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10
GROUPBOX "General",IDC_STATIC,7,4,153,107
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,112,133,10
GROUPBOX "General",IDC_STATIC,7,7,148,120
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",
BS_AUTORADIOBUTTON,84,125,70,11
GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28
LTEXT "Volume",IDC_STATIC,13,158,24,8
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,111,152,43,10
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111,
163,43,10
GROUPBOX "Sound",IDC_STATIC,7,144,153,34
BS_AUTORADIOBUTTON,168,35,69,11
GROUPBOX "Disassembler",IDC_STATIC,161,7,83,120
END
IDD_SET_MEMORY DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Memory"
FONT 8, "MS Sans Serif"
BEGIN
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",
BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10
BS_AUTOCHECKBOX | WS_TABSTOP,124,20,69,10
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",
BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10
LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8
EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51
LTEXT "Wire:",IDC_STATIC,13,245,17,8
COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
BS_AUTOCHECKBOX | WS_TABSTOP,124,32,69,10
LTEXT "Port 2 File :",IDC_STATIC,14,47,37,8
EDITTEXT IDC_PORT2,52,45,175,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,227,45,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,7,237,58
END
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
LTEXT "IR:",IDC_STATIC,89,245,9,8
COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
LTEXT "IR:",IDC_STATIC,168,74,9,8
COMBOBOX IDC_IR,189,72,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27
DEFPUSHBUTTON "OK",IDOK,9,266,50,14
PUSHBUTTON "Cancel",IDCANCEL,107,266,50,14
GROUPBOX "Serial Ports",IDC_STATIC,161,43,83,50
END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
@ -362,17 +425,10 @@ BEGIN
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,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
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 |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP
@ -543,6 +599,36 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14
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
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger Settings"
@ -602,8 +688,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,0
PRODUCTVERSION 1,5,0,0
FILEVERSION 1,5,3,0
PRODUCTVERSION 1,5,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -620,12 +706,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\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 "LegalCopyright", "Copyright © 2010\0"
VALUE "LegalCopyright", "Copyright © 2012\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 5, 0, 0\0"
VALUE "ProductVersion", "1, 5, 3, 0\0"
END
END
BLOCK "VarFileInfo"
@ -791,6 +877,9 @@ BEGIN
, GRAYED
END
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
END
END

View file

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

View file

@ -66,7 +66,7 @@ static __inline VOID BeepWave(DWORD dwFrequency,DWORD dwDuration)
// (samp/sec) * msecs * (secs/msec) = samps
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.dwUser = 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(waveOutClose(hSoundDevice) == MMSYSERR_NOERROR);
HeapFree(hHeap,0,wh.lpData);
free(wh.lpData);
CloseHandle(hEventSound);
return;
}

View file

@ -23,6 +23,8 @@ TCHAR szBackupFilename[MAX_PATH];
TCHAR szBufferFilename[MAX_PATH];
TCHAR szPort2Filename[MAX_PATH];
BOOL bDocumentAvail = FALSE; // document not available
BYTE cCurrentRomType = 0; // Model -> hardware
UINT nCurrentClass = 0; // Class -> derivate
@ -33,6 +35,8 @@ LPBYTE Port2 = NULL;
LPBYTE pbyRom = NULL;
BOOL bRomWriteable = TRUE; // flag if ROM writeable
DWORD dwRomSize = 0;
LPBYTE pbyRomDirtyPage = NULL;
DWORD dwRomDirtyPageSize = 0;
WORD wRomCrc = 0; // fingerprint of patched ROM
LPBYTE pbyPort2 = NULL;
@ -45,7 +49,6 @@ WORD wPort2Crc = 0; // fingerprint of port2
BOOL bBackup = FALSE;
static HANDLE hRomFile = NULL;
static HANDLE hRomMap = NULL;
static HANDLE hPort2File = NULL;
static HANDLE hPort2Map = NULL;
@ -61,6 +64,7 @@ static CHIPSET BackupChipset;
static LPBYTE BackupPort0;
static LPBYTE BackupPort1;
static LPBYTE BackupPort2;
static BOOL bRomPacked;
//################
//#
@ -209,6 +213,7 @@ typedef struct tnode
DWORD dwAddress; // patch address
BYTE byROM; // original ROM value
BYTE byPatch; // patched ROM value
struct tnode *prev; // previous node
struct tnode *next; // next node
} TREENODE;
@ -219,14 +224,17 @@ static BOOL PatchNibble(DWORD dwAddress, BYTE byPatch)
TREENODE *p;
_ASSERT(pbyRom); // ROM defined
if ((p = HeapAlloc(hHeap,0,sizeof(TREENODE))) == NULL)
if ((p = malloc(sizeof(TREENODE))) == NULL)
return TRUE;
p->bPatch = TRUE; // address patched
p->dwAddress = dwAddress; // save current values
p->byROM = pbyRom[dwAddress];
p->byPatch = byPatch;
p->prev = NULL;
p->next = nodePatch; // save node
if (nodePatch) nodePatch->prev = p; // add as previous element
nodePatch = p;
pbyRom[dwAddress] = byPatch; // patch ROM
@ -244,7 +252,7 @@ static VOID RestorePatches(VOID)
pbyRom[nodePatch->dwAddress] = nodePatch->byROM;
p = nodePatch->next; // save pointer to next node
HeapFree(hHeap,0,nodePatch); // free node
free(nodePatch); // free node
nodePatch = p; // new node
}
return;
@ -255,9 +263,14 @@ VOID UpdatePatches(BOOL bPatch)
TREENODE *p = nodePatch;
_ASSERT(pbyRom); // ROM defined
while (p != NULL)
{
if (bPatch) // patch ROM
{
if (p) // something in patch list
{
// goto last element in list
for (; p->next != NULL; p = p->next) {}
do
{
if (!p->bPatch) // patch only if not patched
{
@ -272,15 +285,20 @@ VOID UpdatePatches(BOOL bPatch)
{
_ASSERT(FALSE); // call ROM patch on a patched ROM
}
p = p->prev;
}
while (p != NULL);
}
}
else // restore ROM
{
for (; p != NULL; p = p->next)
{
// restore original data
pbyRom[p->dwAddress] = p->byROM;
p->bPatch = FALSE; // address not patched
}
p = p->next; // next node
}
return;
}
@ -311,7 +329,7 @@ BOOL PatchRom(LPCTSTR szFilename)
CloseHandle(hFile);
return FALSE;
}
lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow+1);
lpBuf = malloc(dwFileSizeLow+1);
if (lpBuf == NULL)
{
CloseHandle(hFile);
@ -360,7 +378,7 @@ BOOL PatchRom(LPCTSTR szFilename)
++nPos;
}
}
HeapFree(hHeap,0,lpBuf);
free(lpBuf);
return TRUE;
}
@ -377,6 +395,8 @@ BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM
DWORD *pdwData,dwSize;
DWORD dwChk = 0;
if (pbyRom == NULL) return TRUE; // ROM CRC isn't available
_ASSERT(pbyRom); // view on ROM
pdwData = (DWORD *) pbyRom;
@ -398,34 +418,34 @@ BOOL CrcRom(WORD *pwChk) // calculate fingerprint of ROM
BOOL MapRom(LPCTSTR szFilename)
{
DWORD dwFileSizeHigh;
DWORD dwSize,dwFileSize,dwRead;
// open ROM for writing
BOOL bWrite = (cCurrentRomType == 'X') ? bRomWriteable : FALSE;
BOOL bRomRW = (cCurrentRomType == 'X') ? bRomWriteable : FALSE;
if (pbyRom != NULL)
{
return FALSE;
}
SetCurrentDirectory(szEmuDirectory);
if (bWrite) // ROM writeable
if (bRomRW) // ROM writeable
{
hRomFile = CreateFile(szFilename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
if (hRomFile == INVALID_HANDLE_VALUE)
{
bWrite = FALSE; // ROM not writeable
bRomRW = FALSE; // ROM not writeable
hRomFile = CreateFile(szFilename,
GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
}
}
@ -436,7 +456,7 @@ BOOL MapRom(LPCTSTR szFilename)
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
FILE_FLAG_SEQUENTIAL_SCAN,
NULL);
}
SetCurrentDirectory(szCurrentDirectory);
@ -445,49 +465,136 @@ BOOL MapRom(LPCTSTR szFilename)
hRomFile = NULL;
return FALSE;
}
dwRomSize = GetFileSize(hRomFile, &dwFileSizeHigh);
if (dwFileSizeHigh != 0)
{ // file is too large.
dwRomSize = GetFileSize(hRomFile, NULL);
if (dwRomSize <= 4)
{ // file is too small.
CloseHandle(hRomFile);
hRomFile = NULL;
dwRomSize = 0;
return FALSE;
}
hRomMap = CreateFileMapping(hRomFile, NULL, bWrite ? PAGE_READWRITE : PAGE_WRITECOPY, 0, dwRomSize, NULL);
if (hRomMap == NULL)
{
CloseHandle(hRomFile);
hRomFile = NULL;
dwRomSize = 0;
return FALSE;
}
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
AbortMessage(_T("Sharing file mapping handle."));
}
pbyRom = MapViewOfFile(hRomMap, bWrite ? FILE_MAP_WRITE : FILE_MAP_COPY, 0, 0, dwRomSize);
// read the first 4 bytes
ReadFile(hRomFile,&dwSize,sizeof(dwSize),&dwRead,NULL);
dwFileSize = dwRomSize; // calculate ROM image buffer size
bRomPacked = (dwSize & 0xF0F0F0F0) != 0; // ROM image packed
if (bRomPacked) dwRomSize *= 2; // unpacked ROM image has double size
pbyRom = VirtualAlloc(NULL,dwRomSize,MEM_RESERVE|MEM_COMMIT,PAGE_READWRITE);
if (pbyRom == NULL)
{
CloseHandle(hRomMap);
CloseHandle(hRomFile);
hRomMap = NULL;
hRomFile = NULL;
dwRomSize = 0;
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;
}
VOID UnmapRom(VOID)
{
if (pbyRom == NULL) return;
RestorePatches(); // restore ROM Patches
UnmapViewOfFile(pbyRom);
CloseHandle(hRomMap);
if (pbyRom == NULL) return; // ROM not mapped
RestorePatches(); // restore ROM patches
if (hRomFile) // ROM file still open (only in R/W case)
{
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);
pbyRom = NULL;
hRomMap = NULL;
pbyRomDirtyPage = NULL;
dwRomDirtyPageSize = 0;
hRomFile = NULL;
}
VirtualFree(pbyRom,0,MEM_RELEASE); // free ROM image
pbyRom = NULL;
dwRomSize = 0;
wRomCrc = 0;
return;
@ -670,13 +777,13 @@ VOID ResetDocument(VOID)
}
szCurrentKml[0] = 0;
szCurrentFilename[0]=0;
if (Port0) { HeapFree(hHeap,0,Port0); Port0 = NULL; }
if (Port1) { HeapFree(hHeap,0,Port1); Port1 = NULL; }
if (Port2) { HeapFree(hHeap,0,Port2); Port2 = NULL; } else UnmapPort2();
if (Port0) { free(Port0); Port0 = NULL; }
if (Port1) { free(Port1); Port1 = NULL; }
if (Port2) { free(Port2); Port2 = NULL; } else UnmapPort2();
ZeroMemory(&Chipset,sizeof(Chipset));
ZeroMemory(&RMap,sizeof(RMap)); // delete MMU mappings
ZeroMemory(&WMap,sizeof(WMap));
UpdateWindowStatus();
bDocumentAvail = FALSE; // document not available
return;
}
@ -746,21 +853,22 @@ BOOL NewDocument(VOID)
// allocate port memory
if (Chipset.Port0Size)
{
Port0 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port0Size*2048);
Port0 = calloc(Chipset.Port0Size*2048,sizeof(*Port0));
_ASSERT(Port0 != NULL);
}
if (Chipset.Port1Size)
{
Port1 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port1Size*2048);
Port1 = calloc(Chipset.Port1Size*2048,sizeof(*Port1));
_ASSERT(Port1 != NULL);
}
if (Chipset.Port2Size)
{
Port2 = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,Chipset.Port2Size*2048);
Port2 = calloc(Chipset.Port2Size*2048,sizeof(*Port1));
_ASSERT(Port2 != NULL);
}
LoadBreakpointList(NULL); // clear debugger breakpoint list
RomSwitch(0); // boot ROM view of HP49G and map memory
bDocumentAvail = TRUE; // document available
return TRUE;
restore:
RestoreBackup();
@ -843,10 +951,13 @@ BOOL OpenDocument(LPCTSTR szFilename)
switch (pbyFileSignature[14])
{
case 0xFE: // Win48 2.1 / Emu4x 0.99.x format
// read length of KML script name
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
{
LPSTR szTmp = HeapAlloc(hHeap,0,nLength);
LPSTR szTmp = malloc(nLength);
if (szTmp == NULL)
{
AbortMessage(_T("Memory Allocation Failure."));
@ -855,7 +966,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
ReadFile(hFile, szTmp, nLength, &lBytesRead, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead,
szCurrentKml, ARRAYSIZEOF(szCurrentKml));
HeapFree(hHeap,0,szTmp);
free(szTmp);
}
#else
{
@ -916,13 +1027,13 @@ BOOL OpenDocument(LPCTSTR szFilename)
goto restore;
}
// reload old button state
ReloadButtons(Chipset.Keyboard_Row,sizeof(Chipset.Keyboard_Row));
ReloadButtons(Chipset.Keyboard_Row,ARRAYSIZEOF(Chipset.Keyboard_Row));
FlashInit(); // init flash structure
if (Chipset.Port0Size)
{
Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048);
Port0 = malloc(Chipset.Port0Size*2048);
if (Port0 == NULL)
{
AbortMessage(_T("Memory Allocation Failure."));
@ -937,7 +1048,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
if (Chipset.Port1Size)
{
Port1 = HeapAlloc(hHeap,0,Chipset.Port1Size*2048);
Port1 = malloc(Chipset.Port1Size*2048);
if (Port1 == NULL)
{
AbortMessage(_T("Memory Allocation Failure."));
@ -969,7 +1080,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
{
if (Chipset.Port2Size)
{
Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048);
Port2 = malloc(Chipset.Port2Size*2048);
if (Port2 == NULL)
{
AbortMessage(_T("Memory Allocation Failure."));
@ -1007,7 +1118,7 @@ BOOL OpenDocument(LPCTSTR szFilename)
if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename);
#endif
SetWindowPathTitle(szCurrentFilename); // update window title line
UpdateWindowStatus();
bDocumentAvail = TRUE; // document available
return TRUE;
read_err:
@ -1058,14 +1169,14 @@ BOOL SaveDocument(VOID)
WriteFile(hCurrentFile, &nLength, sizeof(nLength), &lBytesWritten, NULL);
#if defined _UNICODE
{
LPSTR szTmp = HeapAlloc(hHeap,0,nLength);
LPSTR szTmp = malloc(nLength);
if (szTmp != NULL)
{
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szCurrentKml, nLength,
szTmp, nLength, NULL, NULL);
WriteFile(hCurrentFile, szTmp, nLength, &lBytesWritten, NULL);
HeapFree(hHeap,0,szTmp);
free(szTmp);
}
}
#else
@ -1106,7 +1217,6 @@ BOOL SaveDocumentAs(LPCTSTR szFilename)
if (pEmuDocumentNotify) pEmuDocumentNotify(szCurrentFilename);
#endif
SetWindowPathTitle(szCurrentFilename); // update window title line
UpdateWindowStatus(); // and draw it
return SaveDocument(); // save current content
}
@ -1135,23 +1245,22 @@ BOOL SaveBackup(VOID)
lstrcpy(szBackupFilename, szCurrentFilename);
lstrcpy(szBackupKml, szCurrentKml);
if (BackupPort0) HeapFree(hHeap,0,BackupPort0);
if (BackupPort1) HeapFree(hHeap,0,BackupPort1);
if (BackupPort2) HeapFree(hHeap,0,BackupPort2);
if (BackupPort0) free(BackupPort0);
if (BackupPort1) free(BackupPort1);
if (BackupPort2) free(BackupPort2);
CopyMemory(&BackupChipset, &Chipset, sizeof(Chipset));
BackupPort0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048);
BackupPort0 = malloc(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);
BackupPort2 = NULL;
if (Chipset.Port2Size) // internal port2
{
BackupPort2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048);
BackupPort2 = malloc(Chipset.Port2Size*2048);
CopyMemory(BackupPort2,Port2,Chipset.Port2Size*2048);
}
CreateBackupBreakpointList();
bBackup = TRUE;
UpdateWindowStatus();
return TRUE;
}
@ -1182,13 +1291,13 @@ BOOL RestoreBackup(VOID)
}
}
CopyMemory(&Chipset, &BackupChipset, sizeof(Chipset));
Port0 = HeapAlloc(hHeap,0,Chipset.Port0Size*2048);
Port0 = malloc(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);
if (Chipset.Port2Size) // internal port2
{
Port2 = HeapAlloc(hHeap,0,Chipset.Port2Size*2048);
Port2 = malloc(Chipset.Port2Size*2048);
CopyMemory(Port2,BackupPort2,Chipset.Port2Size*2048);
}
// map port2
@ -1205,7 +1314,7 @@ BOOL RestoreBackup(VOID)
SetWindowLocation(hWnd,Chipset.nPosX,Chipset.nPosY);
RestoreBackupBreakpointList(); // restore the debugger breakpoint list
if (bDbgOpen) OnToolDebug(); // reopen the debugger
UpdateWindowStatus();
bDocumentAvail = TRUE; // document available
return TRUE;
}
@ -1214,12 +1323,11 @@ BOOL ResetBackup(VOID)
if (!bBackup) return FALSE;
szBackupFilename[0] = 0;
szBackupKml[0] = 0;
if (BackupPort0) { HeapFree(hHeap,0,BackupPort0); BackupPort0 = NULL; }
if (BackupPort1) { HeapFree(hHeap,0,BackupPort1); BackupPort1 = NULL; }
if (BackupPort2) { HeapFree(hHeap,0,BackupPort2); BackupPort2 = NULL; }
if (BackupPort0) { free(BackupPort0); BackupPort0 = NULL; }
if (BackupPort1) { free(BackupPort1); BackupPort1 = NULL; }
if (BackupPort2) { free(BackupPort2); BackupPort2 = NULL; }
ZeroMemory(&BackupChipset,sizeof(BackupChipset));
bBackup = FALSE;
UpdateWindowStatus();
return TRUE;
}
@ -1413,7 +1521,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
CloseHandle(hFile);
return FALSE;
}
lpBuf = HeapAlloc(hHeap,0,dwFileSizeLow*2);
lpBuf = malloc(dwFileSizeLow*2);
if (lpBuf == NULL)
{
CloseHandle(hFile);
@ -1433,7 +1541,7 @@ BOOL LoadObject(LPCTSTR szFilename) // separated stack writing part
if (wError == S_ERR_ASCII)
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);
}
@ -1490,7 +1598,7 @@ typedef struct _BmpFile
LPBYTE pbyFile; // buffer
} 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;
@ -1502,7 +1610,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
{
LOGPALETTE* pPal;
HPALETTE hpal = NULL;
UINT nNumColors;
WORD wNumColors;
BYTE red;
BYTE green;
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
pRgb = (RGBQUAD FAR *)((LPBYTE)lpbi + (WORD)lpbi->biSize);
nNumColors = DibNumColors(lpbi);
wNumColors = DibNumColors(lpbi);
if (nNumColors)
if (wNumColors)
{
// Allocate for the logical palette structure
pPal = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
return NULL;
pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY));
if (!pPal) return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = 0x300;
pPal->palNumEntries = wNumColors;
// Fill in the palette entries from the DIB color table and
// 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].peGreen = pRgb[i].rgbGreen;
pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
pPal->palPalEntry[i].peFlags = 0;
}
hpal = CreatePalette(pPal);
HeapFree(hHeap,0,pPal);
free(pPal);
}
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
// number of to the maximum value (256).
nNumColors = 256;
pPal = HeapAlloc(hHeap,0,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
wNumColors = 256;
pPal = malloc(sizeof(LOGPALETTE) + wNumColors * sizeof(PALETTEENTRY));
if (!pPal) return NULL;
pPal->palNumEntries = nNumColors;
pPal->palVersion = 0x300;
pPal->palNumEntries = wNumColors;
red = green = blue = 0;
@ -1570,7 +1677,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
blue += 64;
}
hpal = CreatePalette(pPal);
HeapFree(hHeap,0,pPal);
free(pPal);
}
return hpal;
}
@ -1625,12 +1732,13 @@ static HBITMAP DecodeBmp(LPBMPFILE pBmp)
pBmi, DIB_RGB_COLORS));
if (hBitmap == NULL) return NULL;
_ASSERT(hPalette == NULL); // resource free
if (hPalette == NULL)
{
hPalette = CreateBIPalette(&pBmi->bmiHeader);
// save old palette
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
RealizePalette(hWindowDC);
}
return hBitmap;
}
@ -2118,11 +2226,13 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp)
_ASSERT(bDecoding == FALSE); // decoding successful
// normal decoding exit
_ASSERT(hPalette == NULL); // resource free
if (hPalette == NULL)
{
hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi);
// save old palette
hOldPalette = SelectPalette(hWindowDC, hPalette, FALSE);
RealizePalette(hWindowDC);
}
quit:
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
//
@ -367,8 +412,8 @@ static VOID WrStateE8C(BYTE a, DWORD d)
_ASSERT(d+1 < dwRomSize); // address valid?
// no error set in BWSLBS, because I could alway program a "0"
*(pbyRom+d++) &= (a & 0x0F); // write LSB
*(pbyRom+d++) &= (a >> 4); // write MSB
WriteByte(d,a); // write byte
d += 2; // next address
}
}
else
@ -395,11 +440,8 @@ static VOID WrState40(DWORD d)
// byte/word program data
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"
*(pbyRom+d++) &= (a & 0x0F); // write LSB
*(pbyRom+d) &= (a >> 4); // write MSB
WriteByte(d << 1,a); // write byte
WSMset.byStatusReg |= WSMS; // data written
WSMset.uWrState = WRS_DATA;
return;
@ -433,8 +475,7 @@ static VOID WrState20C(BYTE a, DWORD d)
d &= ~(dwBlockSize-1); // start of block
dwBlockSize *= 2; // block size in nibbles
_ASSERT(d+dwBlockSize <= dwRomSize); // address valid?
// write 128K nibble
FillMemory(pbyRom + (d << 1),dwBlockSize,0x0F);
EraseBlock(d << 1,dwBlockSize); // erase 128K nibble
}
}
else
@ -467,7 +508,7 @@ static VOID WrState30C(BYTE a, DWORD d)
WORD wNoOfBlocks = (byQueryTab[0x2E] << 8) | byQueryTab[0x2D];
DWORD dwBlockSize = ((byQueryTab[0x30] << 8) | byQueryTab[0x2F]) * 256;
LPBYTE pbyBlock = pbyRom;
DWORD dwBlockAddr = 0;
dwBlockSize *= 2; // block size in nibbles
@ -481,11 +522,11 @@ static VOID WrState30C(BYTE a, DWORD d)
// clear block lock bit
WSMset.dwLockCnfg &= ~(1<<i);
// write 128K nibble
FillMemory(pbyBlock,dwBlockSize,0x0F);
// erase 128K nibble
EraseBlock(dwBlockAddr,dwBlockSize);
}
pbyBlock += dwBlockSize; // next block
dwBlockAddr += dwBlockSize; // next block
}
}
else
@ -571,9 +612,7 @@ static VOID WrState60D(BYTE a, DWORD d)
// read array
static BYTE RdStateData(DWORD d)
{
d <<= 1; // nibble address
_ASSERT(d+1 < dwRomSize); // address valid?
return *(pbyRom+d)|(*(pbyRom+d+1)<<4); // get byte
return ReadByte(d << 1); // get byte
}
// read identifier codes

View file

@ -28,6 +28,7 @@
#define SRQ2 0x19 // SRQ2
#define IR_CTRL 0x1a // IR CONTROL
#define LCR 0x1c // Led Control Register
#define LBR 0x1d // Led Buffer Register
#define DISP1CTL 0x20 // Display Start Address
#define LINENIBS 0x25 // Display Line Offset
#define LINECOUNT 0x28 // Display Line Counter
@ -125,6 +126,9 @@
#define LBZ 0x02 // Led Port Busy
#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]
#define LC3 0x08 // LC3 - Line Counter Bit3
#define LC2 0x04 // LC2 - Line Counter Bit2

View file

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

View file

@ -59,7 +59,7 @@ static LPCTSTR szLexDelim[] =
_T(" \t\r") // valid whitespaces for LEX_PARAM
};
static KmlToken pLexToken[] =
static CONST KmlToken pLexToken[] =
{
{TOK_ANNUNCIATOR,000001,11,_T("Annunciator")},
{TOK_BACKGROUND, 000000,10,_T("Background")},
@ -104,7 +104,7 @@ static KmlToken pLexToken[] =
{TOK_VGA, 000001, 3,_T("Vga")}, // for PPC compatibility reasons
{TOK_LCD, 000000, 3,_T("Lcd")},
{TOK_END, 000000, 3,_T("End")},
{0, 000000, 0,_T("")},
{TOK_NONE, 000000, 0,_T("")}
};
static CONST TokenId eIsGlobalBlock[] =
@ -146,7 +146,7 @@ static VOID ClearLog()
nLogLength = 0;
if (szLog != NULL)
{
HeapFree(hHeap,0,szLog);
free(szLog);
szLog = NULL;
}
return;
@ -158,7 +158,7 @@ static VOID AddToLog(LPCTSTR szString)
if (szLog == NULL)
{
nLogLength = nLength + 1; // \0
szLog = HeapAlloc(hHeap,0,nLogLength*sizeof(szLog[0]));
szLog = malloc(nLogLength*sizeof(szLog[0]));
if (szLog==NULL)
{
nLogLength = 0;
@ -168,7 +168,7 @@ static VOID AddToLog(LPCTSTR szString)
}
else
{
LPTSTR szLogTmp = HeapReAlloc(hHeap,0,szLog,(nLogLength+nLength)*sizeof(szLog[0]));
LPTSTR szLogTmp = realloc(szLog,(nLogLength+nLength)*sizeof(szLog[0]));
if (szLogTmp == NULL)
{
ClearLog();
@ -268,9 +268,9 @@ static VOID DestroyKmlList(VOID)
while (pKmlList)
{
pList = pKmlList->pNext;
HeapFree(hHeap,0,pKmlList->szFilename);
HeapFree(hHeap,0,pKmlList->szTitle);
HeapFree(hHeap,0,pKmlList);
free(pKmlList->szFilename);
free(pKmlList->szTitle);
free(pKmlList);
pKmlList = pList;
}
return;
@ -313,7 +313,7 @@ static VOID CreateKmlList(VOID)
FreeBlocks(pBlock);
continue;
}
VERIFY(pScript = HeapAlloc(hHeap,0,sizeof(KmlScript)));
VERIFY(pScript = malloc(sizeof(KmlScript)));
pScript->szFilename = DuplicateString(pFindFileData.cFileName);
szTitle = GetStringParam(pBlock,TOK_GLOBAL,TOK_TITLE,0);
if (szTitle == NULL) szTitle = pScript->szFilename;
@ -497,7 +497,7 @@ static LPTSTR MapKMLFile(HANDLE hFile)
goto fail;
}
lpBuf = HeapAlloc(hHeap,0,(dwFileSizeLow+1)*sizeof(lpBuf[0]));
lpBuf = malloc((dwFileSizeLow+1)*sizeof(lpBuf[0]));
if (lpBuf == NULL)
{
PrintfToLog(_T("Cannot allocate %i bytes."), (dwFileSizeLow+1)*sizeof(lpBuf[0]));
@ -505,17 +505,17 @@ static LPTSTR MapKMLFile(HANDLE hFile)
}
#if defined _UNICODE
{
LPSTR szTmp = HeapAlloc(hHeap,0,dwFileSizeLow+1);
LPSTR szTmp = malloc(dwFileSizeLow+1);
if (szTmp == NULL)
{
HeapFree(hHeap,0,lpBuf);
free(lpBuf);
lpBuf = NULL;
PrintfToLog(_T("Cannot allocate %i bytes."), dwFileSizeLow+1);
goto fail;
}
ReadFile(hFile, szTmp, dwFileSizeLow, &lBytesRead, NULL);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szTmp, lBytesRead, lpBuf, dwFileSizeLow+1);
HeapFree(hHeap,0,szTmp);
free(szTmp);
}
#else
{
@ -637,10 +637,10 @@ static TokenId ParseToken(UINT nMode)
if (bDebug) // token not found
{
// 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
PrintfToLog(_T("%i: Undefined token %s"),nLexLine,szToken);
HeapFree(hHeap,0,szToken);
free(szToken);
}
return TOK_NONE;
}
@ -665,21 +665,33 @@ static LPTSTR ParseString(VOID)
szText++; // skip leading '"'
nLength = 0;
nBlock = 256;
lpszString = HeapAlloc(hHeap,0,nBlock * sizeof(lpszString[0]));
lpszString = malloc(nBlock * sizeof(lpszString[0]));
while (*szText != _T('"'))
{
if (nLength == nBlock - 1) // ran out of buffer space
{
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
{
lpszString[nLength] = 0; // set EOS
PrintfToLog(_T("%i: Invalid string %s."), nLexLine, lpszString);
HeapFree(hHeap,0,lpszString);
free(lpszString);
return NULL;
}
lpszString[nLength++] = *szText++; // save char
@ -688,7 +700,7 @@ static LPTSTR ParseString(VOID)
lpszString[nLength] = 0; // set EOS
// 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)
@ -736,7 +748,7 @@ static KmlLine* ParseLine(TokenId eCommand)
}
if (pLexToken[i].nLen == 0) return NULL;
pLine = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlLine));
pLine = calloc(1,sizeof(KmlLine));
pLine->eCommand = eCommand;
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 (eToken == TOK_STRING) HeapFree(hHeap,0,szLexString);
if (eToken == TOK_STRING) free(szLexString);
nParams = pLexToken[i].nParams; // get argument types of command
for (i = 0; i < j; ++i) // handle all scanned arguments
{
if ((nParams & 7) == TYPE_STRING) // string type
{
HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]);
free((LPVOID)pLine->nParam[i]);
}
nParams >>= 3; // next argument type
}
HeapFree(hHeap,0,pLine);
free(pLine);
return NULL;
}
@ -833,7 +845,7 @@ static KmlLine* IncludeLines(LPCTSTR szFilename)
nLexLine = uOldLine;
szText = szOldText;
HeapFree(hHeap,0,lpbyBuf);
free(lpbyBuf);
return pLine;
}
@ -845,7 +857,7 @@ static KmlLine* ParseLines(VOID)
TokenId eToken;
UINT nLevel = 0;
while ((eToken = Lex(LEX_COMMAND)))
while ((eToken = Lex(LEX_COMMAND)) != TOK_NONE)
{
if (IsGlobalBlock(eToken)) // check for block command
{
@ -871,7 +883,7 @@ static KmlLine* ParseLines(VOID)
{
pLine = pFirst = IncludeLines(szLexString);
}
HeapFree(hHeap,0,szFilename); // free memory
free(szFilename); // free memory
if (pLine == NULL) // parsing error
goto abort;
while (pLine->pNext) pLine=pLine->pNext;
@ -921,7 +933,7 @@ static KmlBlock* ParseBlock(TokenId eType)
nLinesIncludeLevel = 0;
VERIFY(pBlock = HeapAlloc(hHeap,HEAP_ZERO_MEMORY,sizeof(KmlBlock)));
VERIFY(pBlock = calloc(1,sizeof(KmlBlock)));
pBlock->eType = eType;
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
if (eToken != TOK_INTEGER)
{
if (eToken == TOK_STRING) free(szLexString);
PrintfToLog(_T("%i: Block %s parameter must be an integer."), nLexLine, pLexToken[i].szName);
HeapFree(hHeap,0,pBlock);
free(pBlock);
return NULL;
}
@ -949,14 +962,14 @@ static KmlBlock* ParseBlock(TokenId eType)
if (eToken != TOK_EOL)
{
PrintfToLog(_T("%i: Too many parameters for block %s."), nLexLine, pLexToken[i].szName);
HeapFree(hHeap,0,pBlock);
free(pBlock);
return NULL;
}
pBlock->pFirstLine = ParseLines();
if (pBlock->pFirstLine == NULL) // break on ParseLines error
{
HeapFree(hHeap,0,pBlock);
free(pBlock);
pBlock = NULL;
}
@ -1002,7 +1015,7 @@ static KmlBlock* IncludeBlocks(LPCTSTR szFilename)
nLexLine = uOldLine;
szText = szOldText;
HeapFree(hHeap,0,lpbyBuf);
free(lpbyBuf);
return pFirst;
}
@ -1029,7 +1042,7 @@ static KmlBlock* ParseBlocks(VOID)
pBlock = pBlock->pNext = IncludeBlocks(szLexString);
else
pBlock = pFirst = IncludeBlocks(szLexString);
HeapFree(hHeap,0,szFilename); // free memory
free(szFilename); // free memory
if (pBlock == NULL) // parsing error
goto abort;
while (pBlock->pNext) pBlock=pBlock->pNext;
@ -1445,13 +1458,13 @@ static VOID FreeLines(KmlLine* pLine)
{
if ((nParams&7) == TYPE_STRING) // string type
{
HeapFree(hHeap,0,(LPVOID)pLine->nParam[i]);
free((LPVOID)pLine->nParam[i]);
}
i++; // incr. parameter buffer index
nParams >>= 3; // next argument type
}
pLine = pLine->pNext; // get next line
HeapFree(hHeap,0,pThisLine);
free(pThisLine);
}
return;
}
@ -1463,7 +1476,7 @@ VOID FreeBlocks(KmlBlock* pBlock)
KmlBlock* pThisBlock = pBlock;
pBlock = pBlock->pNext;
FreeLines(pThisBlock->pFirstLine);
HeapFree(hHeap,0,pThisBlock);
free(pThisBlock);
}
return;
}
@ -1481,11 +1494,8 @@ VOID KillKML(VOID)
DestroyMainBitmap();
if (hPalette)
{
BOOL err;
if (hWindowDC) SelectPalette(hWindowDC, hOldPalette, FALSE);
err = DeleteObject(hPalette);
_ASSERT(err != FALSE); // freed resource memory
VERIFY(DeleteObject(hPalette));
hPalette = NULL;
}
bClicking = FALSE;
@ -1508,7 +1518,6 @@ VOID KillKML(VOID)
nLcdZoom = 1;
cCurrentRomType = 0;
nCurrentClass = 0;
UpdateWindowStatus();
ResizeWindow();
return;
}
@ -1839,9 +1848,17 @@ VOID ReloadButtons(BYTE *Keyboard_Row, UINT nSize)
for (i=0; i<nButtons; i++) // scan all buttons
{
if (pButton[i].nOut < nSize) // valid out code
{
if (pButton[i].nIn == 0x8000) // ON key
{
// 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?
bKeyPressed = bKeyPressed || pButton[i].bDown;
@ -2109,7 +2126,7 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename)
HANDLE hFile;
LPTSTR lpBuf;
KmlBlock* pBlock;
DWORD eToken;
TokenId eToken;
SetCurrentDirectory(szEmuDirectory);
hFile = CreateFile(szFilename,
@ -2137,7 +2154,7 @@ static KmlBlock* LoadKMLGlobal(LPCTSTR szFilename)
}
CleanLex();
ClearLog();
HeapFree(hHeap,0,lpBuf);
free(lpBuf);
return pBlock;
}
@ -2173,7 +2190,7 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
pKml = ParseBlocks();
CleanLex();
HeapFree(hHeap,0,lpBuf);
free(lpBuf);
if (pKml == NULL) goto quit;
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);
}
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)
{
BOOL bNINT,bNINT2;
@ -1173,8 +1196,13 @@ VOID ReadIO(BYTE *a, DWORD d, DWORD s, BOOL bUpdate)
#endif
break;
case 0x1B: *a = 0; break;
case 0x1C: *a = 0; break; // LED CONTROL
case 0x1D: *a = 0; break; // LED BUFFER
case 0x1C: // LED CONTROL
// 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 0x1F: *a = Chipset.IORam[d]; 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 0x36: *a = 0; break;
case 0x37: *a = ReadT1(); break;
case 0x38: Nunpack(a, ReadT2() , s); return;
case 0x39: Nunpack(a, ReadT2()>> 4, s); return;
case 0x3A: Nunpack(a, ReadT2()>> 8, s); return;
case 0x3B: Nunpack(a, ReadT2()>>12, s); return;
case 0x3C: Nunpack(a, ReadT2()>>16, s); return;
case 0x3D: Nunpack(a, ReadT2()>>20, s); return;
case 0x3E: Nunpack(a, ReadT2()>>24, s); return;
case 0x3F: Nunpack(a, ReadT2()>>28, s); return;
case 0x38: Nunpack(a, ReadT2Acc() , s); return;
case 0x39: Nunpack(a, ReadT2Acc()>> 4, s); return;
case 0x3A: Nunpack(a, ReadT2Acc()>> 8, s); return;
case 0x3B: Nunpack(a, ReadT2Acc()>>12, s); return;
case 0x3C: Nunpack(a, ReadT2Acc()>>16, s); return;
case 0x3D: Nunpack(a, ReadT2Acc()>>20, s); return;
case 0x3E: Nunpack(a, ReadT2Acc()>>24, s); return;
case 0x3F: Nunpack(a, ReadT2Acc()>>28, s); return;
default: *a = Chipset.IORam[d];
}
d++; a++;
@ -1589,12 +1617,27 @@ VOID WriteIO(BYTE *a, DWORD d, DWORD s)
}
#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;
break;
// 0011D = NS:LBR
// 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 @ Scratch pad

View file

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

View file

@ -48,7 +48,7 @@ static __inline LPBYTE FASTPTR(DWORD d)
if ( !(Chipset.IOCfig && ((d & 0xFFFC0) == Chipset.IOBase))
&& 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
|| (RMap[u] + 0x1000 == RMap[(u+1) & (ARRAYSIZEOF(RMap)-1)])
)
@ -59,7 +59,7 @@ static __inline LPBYTE FASTPTR(DWORD d)
else
{
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;
}

View file

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

View file

@ -390,10 +390,10 @@ DWORD RPL_CreateTemp(DWORD l)
Write5(TEMPTOP, a+l); // adjust new end of top object
Write5(RSKTOP, b+l); // adjust new end of rtn stack
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);
Nwrite(p,a+l,b-a);
HeapFree(hHeap,0,p);
free(p);
Write5(a+l-5,l); // set object length field
return (a+1); // return base address of new object
}

View file

@ -179,6 +179,7 @@ VOID ReadSettings(VOID)
// Emulator
bAlwaysOnTop = ReadInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
bActFollowsMouse = ReadInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
bSingleInstance = ReadInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
bRealSpeed = ReadInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
dwSXCycles = ReadInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
dwGXCycles = ReadInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
@ -187,12 +188,15 @@ VOID ReadSettings(VOID)
bGrayscale = ReadInt(_T("Emulator"),_T("Grayscale"),bGrayscale);
bWaveBeep = ReadInt(_T("Emulator"),_T("WaveBeep"),bWaveBeep);
dwWaveVol = ReadInt(_T("Emulator"),_T("WaveVolume"),dwWaveVol);
SetSpeed(bRealSpeed); // set speed
// LowBat
bLowBatDisable = ReadInt(_T("LowBat"),_T("Disable"),bLowBatDisable);
// Macro
bMacroRealSpeed = ReadInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
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
ReadString(_T("Serial"),_T("Wire"),_T(NO_SERIAL),szSerialWire,ARRAYSIZEOF(szSerialWire));
ReadString(_T("Serial"),_T("Ir"),_T(NO_SERIAL),szSerialIr,ARRAYSIZEOF(szSerialIr));
@ -222,6 +226,7 @@ VOID WriteSettings(VOID)
// Emulator
WriteInt(_T("Emulator"),_T("AlwaysOnTop"),bAlwaysOnTop);
WriteInt(_T("Emulator"),_T("ActivationFollowsMouse"),bActFollowsMouse);
WriteInt(_T("Emulator"),_T("SingleInstance"),bSingleInstance);
WriteInt(_T("Emulator"),_T("RealSpeed"),bRealSpeed);
WriteInt(_T("Emulator"),_T("SXCycles"),dwSXCycles);
WriteInt(_T("Emulator"),_T("GXCycles"),dwGXCycles);
@ -235,6 +240,10 @@ VOID WriteSettings(VOID)
// Macro
WriteInt(_T("Macro"),_T("RealSpeed"),bMacroRealSpeed);
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
WriteString(_T("Serial"),_T("Wire"),szSerialWire);
WriteString(_T("Serial"),_T("Ir"),szSerialIr);

View file

@ -128,6 +128,7 @@ static INT RPL_GetBcd(BYTE CONST *pbyNum,INT nMantLen,INT nExpLen,CONST TCHAR cD
i = 0; // first character
bPflag = FALSE; // show no decimal point
bExpflag = FALSE; // show no exponent
// scan mantissa
for (v = (LONG) nMantLen - 1; v >= 0 || bPflag; v--)
@ -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;
}
@ -460,12 +461,12 @@ static INT DoInt(DWORD dwAddress,LPTSTR cp,INT nSize)
if (nIntLen <= 0) return 0; // error in calculator object
nLength = 0;
if ((lpbyData = HeapAlloc(hHeap,0,nIntLen)))
if ((lpbyData = malloc(nIntLen)))
{
// get precisition integer object content and decode it
Npeek(lpbyData,dwAddress+5,nIntLen);
nLength = RPL_GetZInt(lpbyData,nIntLen,cp,nSize);
HeapFree(hHeap,0,lpbyData);
free(lpbyData);
}
return nLength;
}
@ -551,7 +552,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize)) == NULL)
goto error;
if ((lpbyData = GlobalLock(hClipObj)))
if ((lpbyData = (LPBYTE) GlobalLock(hClipObj)))
{
// copy data to memory
CopyMemory(lpbyData,cBuffer,dwSize);
@ -572,7 +573,7 @@ LRESULT OnStackCopy(VOID) // copy data from stack
if ((hClipObj = GlobalAlloc(GMEM_MOVEABLE,dwSize + 1)) == NULL)
goto error;
if ((lpbyData = GlobalLock(hClipObj))) // lock memory
if ((lpbyData = (LPBYTE) GlobalLock(hClipObj))) // lock memory
{
// copy data into clipboard buffer
for (dwAddress += 5;dwSize-- > 0;dwAddress += 2,++lpbyData)
@ -580,8 +581,8 @@ LRESULT OnStackCopy(VOID) // copy data from stack
*lpbyData = 0; // set EOS
GlobalUnlock(hClipObj); // unlock memory
uClipboardFormat = CF_TEXT; // always text
}
uClipboardFormat = CF_TEXT; // always text
break;
default:
MessageBeep(MB_OK); // error beep
@ -737,7 +738,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack
// any other format
{
DWORD dwSize = lstrlen(lpstrClipdata);
if ((lpbyData = HeapAlloc(hHeap,0,dwSize * 2)))
if ((lpbyData = malloc(dwSize * 2)))
{
LPBYTE lpbySrc,lpbyDest;
DWORD dwLoop;
@ -776,7 +777,7 @@ LRESULT OnStackPaste(VOID) // paste data to stack
// push object to stack
RPL_Push(1,dwAddress);
}
HeapFree(hHeap,0,lpbyData);
free(lpbyData);
}
}
}

View file

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

View file

@ -244,7 +244,6 @@ static void CALLBACK TimeProc(UINT uEventId, UINT uMsg, DWORD_PTR dwUser, DWORD_
UNREFERENCED_PARAMETER(dw2);
}
VOID SetHP48Time(VOID) // set date and time
{
SYSTEMTIME ts;
@ -257,7 +256,7 @@ VOID SetHP48Time(VOID) // set date and time
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;
if (dw > 2)
dw -= 3L;
@ -269,17 +268,18 @@ VOID SetHP48Time(VOID) // set date and time
dw = (DWORD) ts.wDay + (153L * dw + 2L) / 5L;
dw += (146097L * (((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
dw = dw * 24L + (DWORD) ts.wHour;
dw = dw * 60L + (DWORD) ts.wMinute;
dw = dw * 60L + (DWORD) ts.wSecond;
ticks = ticks * 24L + (ULONGLONG) ts.wHour;
ticks = ticks * 60L + (ULONGLONG) ts.wMinute;
ticks = ticks * 60L + (ULONGLONG) ts.wSecond;
// 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
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
END
IDD_SETTINGS, DIALOG
IDD_SET_GENERAL, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 160
TOPMARGIN, 4
BOTTOMMARGIN, 280
RIGHTMARGIN, 244
VERTGUIDE, 14
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
IDD_CHOOSEKML, DIALOG
@ -157,6 +185,22 @@ BEGIN
BOTTOMMARGIN, 74
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
BEGIN
LEFTMARGIN, 7
@ -252,69 +296,88 @@ FONT 8, "MS Sans Serif"
BEGIN
ICON IDI_EMU48,IDC_STATIC,7,6,20,20,SS_REALSIZEIMAGE
LTEXT "",IDC_VERSION,29,6,151,8,NOT WS_GROUP
LTEXT "Copyright © 2010 Christoph Gießelink && Sébastien Carlier",
LTEXT "Copyright © 2012 Christoph Gießelink && Sébastien Carlier",
IDC_STATIC,29,18,181,8
DEFPUSHBUTTON "OK",IDOK,215,12,39,14
EDITTEXT IDC_LICENSE,7,33,247,112,ES_MULTILINE | ES_AUTOHSCROLL |
ES_READONLY
END
IDD_SETTINGS DIALOG DISCARDABLE 0, 0, 167, 287
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Settings"
IDD_SET_GENERAL DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "General"
FONT 8, "MS Sans Serif"
BEGIN
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,25,100,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,37,65,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,49,100,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,28,133,10
CONTROL "Always On Top",IDC_ALWAYSONTOP,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,14,40,133,10
CONTROL "Activation Follows Mouse",IDC_ACTFOLLOWSMOUSE,"Button",
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,61,89,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,76,133,10
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",
BS_AUTOCHECKBOX | WS_TABSTOP,13,85,102,10
BS_AUTOCHECKBOX | WS_TABSTOP,14,100,133,10
CONTROL "Always Show KML Compilation Result",IDC_ALWAYSDISPLOG,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,97,133,10
GROUPBOX "General",IDC_STATIC,7,4,153,107
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,112,133,10
GROUPBOX "General",IDC_STATIC,7,7,148,120
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",
BS_AUTORADIOBUTTON,84,125,70,11
GROUPBOX "Disassembler",IDC_STATIC,7,114,153,28
LTEXT "Volume",IDC_STATIC,13,158,24,8
CONTROL "Slider1",IDC_SOUND_SLIDER,"msctls_trackbar32",
TBS_AUTOTICKS | WS_TABSTOP,39,153,68,18
CONTROL "Speaker",IDC_SOUND_SPEAKER,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,111,152,43,10
CONTROL "Wave",IDC_SOUND_WAVE,"Button",BS_AUTORADIOBUTTON,111,
163,43,10
GROUPBOX "Sound",IDC_STATIC,7,144,153,34
BS_AUTORADIOBUTTON,168,35,69,11
GROUPBOX "Disassembler",IDC_STATIC,161,7,83,120
END
IDD_SET_MEMORY DIALOG DISCARDABLE 0, 0, 251, 134
STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
CAPTION "Memory"
FONT 8, "MS Sans Serif"
BEGIN
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",
BS_AUTOCHECKBOX | WS_TABSTOP,84,189,69,10
BS_AUTOCHECKBOX | WS_TABSTOP,124,20,69,10
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",
BS_AUTOCHECKBOX | WS_TABSTOP,84,201,69,10
LTEXT "Port 2 File :",IDC_STATIC,13,216,37,8
EDITTEXT IDC_PORT2,51,214,94,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,145,214,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,180,153,51
LTEXT "Wire:",IDC_STATIC,13,245,17,8
COMBOBOX IDC_WIRE,31,243,48,42,CBS_DROPDOWNLIST | WS_VSCROLL |
BS_AUTOCHECKBOX | WS_TABSTOP,124,32,69,10
LTEXT "Port 2 File :",IDC_STATIC,14,47,37,8
EDITTEXT IDC_PORT2,52,45,175,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_PORT2LOAD,227,45,10,12
GROUPBOX "Memory Cards",IDC_STATIC,7,7,237,58
END
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
LTEXT "IR:",IDC_STATIC,89,245,9,8
COMBOBOX IDC_IR,107,243,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
LTEXT "IR:",IDC_STATIC,168,74,9,8
COMBOBOX IDC_IR,189,72,48,43,CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
GROUPBOX "Serial Ports",IDC_STATIC,7,233,153,27
DEFPUSHBUTTON "OK",IDOK,9,266,50,14
PUSHBUTTON "Cancel",IDCANCEL,107,266,50,14
GROUPBOX "Serial Ports",IDC_STATIC,161,43,83,50
END
IDD_CHOOSEKML DIALOG DISCARDABLE 0, 0, 195, 66
@ -362,17 +425,10 @@ BEGIN
PUSHBUTTON "&Next Address",IDC_DISASM_NEXT,99,144,47,14
PUSHBUTTON "&Copy Data",IDC_DISASM_COPY,150,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
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 |
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP
@ -543,6 +599,36 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,93,60,50,14
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
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Debugger Settings"
@ -630,8 +716,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,5,0,0
PRODUCTVERSION 1,5,0,0
FILEVERSION 1,5,3,0
PRODUCTVERSION 1,5,3,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -646,14 +732,14 @@ BEGIN
BEGIN
BLOCK "04090000"
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 "FileVersion", "1, 5, 0, 0\0"
VALUE "FileVersion", "1, 5, 3, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2010\0"
VALUE "LegalCopyright", "Copyright © 2012\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 5, 0, 0\0"
VALUE "ProductVersion", "1, 5, 3, 0\0"
END
END
BLOCK "VarFileInfo"
@ -819,7 +905,10 @@ BEGIN
, GRAYED
END
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
@ -860,6 +949,13 @@ END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// 24
//
1 24 MOVEABLE PURE "Emu48.xml"
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
@ -890,14 +986,6 @@ BEGIN
ID_BREAKPOINTS_CODEEDIT "Breakpoint List"
END
/////////////////////////////////////////////////////////////////////////////
//
// Manifest
//
1 24 MOVEABLE PURE "Emu48.xml"
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////

View file

@ -22,13 +22,13 @@ TARGET=$(PRJ).exe
RSRC=$(PRJ).rc
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 \
keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o rpl.o serial.o \
settings.o stack.o symbfile.o timer.o \
keymacro.o kml.o lowbat.o mru.o mops.o opcodes.o redeye.o \
rpl.o serial.o settings.o stack.o symbfile.o timer.o udp.o \
$(RSRCOBJ)
LIBS=-lwinmm -lcomctl32
LIBS=-lwinmm -lcomctl32 -lws2_32
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
$(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 \
types.h io.h kml.h
$(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
# $(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
$(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
$(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
windres $(DEFINES) -i $(RSRC) -o $(RSRCOBJ)

View file

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

View file

@ -2,7 +2,7 @@
* 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
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
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
bug fixes, especially in the header files, made in the last time.
@ -34,4 +48,4 @@ Many thanks to Pedro A. Arranda Guti
compatible.
07/27/10 (c) by Christoph Gießelink
05/03/12 (c) by Christoph Gießelink

Binary file not shown.