2019-10-16: Updated to version 1.62

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 d67939112f
commit a6d5624a8b
No known key found for this signature in database
GPG key ID: FDFE3669426707A7
23 changed files with 5068 additions and 4215 deletions

View file

@ -177,7 +177,30 @@ If this item is checked, interrupt handler code will be skipped. This option is
You can also use this option if you want to quit the interrupt handler. Just check this option, press F7 for "Step Into" for stopping the debugger behind the RTI instruction, and uncheck this option again.
5.) Menu Info
5.) Menu Trace
- Settings...
This opens a dialog to configure the trace file output.
The "Log File:" editbox contains the log output file. A filename without the file path save the file in the emulator installation directory.
For "File Mode" select "New" for creating a new empty trace file or select "Append" for appending the new trace output when trace is enabled. If you chosen "Append" and the trace file don't exists, a new trace file is created.
The "Logging" checkboxes "Register", "MMU" and "Opcode" determine the output content of the trace file.
"Register" enables printing the CPU register content in front of the disassembled opcode. For some, mainly size output reasons the content of the "Write Only Registers" are not shown.
"MMU" enables printing the MMU register content between register and disassembly.
"Opcode" enables the opcode output in the disassembled and if necessary in the following lines.
- Enable
If this item is checked, the file trace is enabled. Dependent on the "File Mode" setting, a "New" empty trace file is generated or in "Append" Mode additional data is appended to the current log file. Unchecking this item stops logging and flushing the trace file.
6.) Menu Info
- Last Instructions...
@ -192,7 +215,7 @@ This opens a small toolbox window which shows the number of CPU cycles and the c
Some of the display registers have a different meaning on reading and writing. This dialog shows the data written to the write only I/O registers.
6.) Code window
7.) Code window
This windows shows you the disassembled code. The line with the current PC is marked with a "->" or "-R" between the address and the disassembly.
@ -229,14 +252,14 @@ Search for a PCO before the address shown in the first line of the Code window.
Search for a PCO behind the address shown in the first line of the Code window.
7.) Register window
8.) Register window
Here you can see the actual contents of the CPU registers. The values are only updated at a program execution stop. All changed CPU registers are highlighted.
With the left mouse button you change the content of the register. On bit registers, like CY and Mode, the state change immediately without any request.
8.) Memory window
9.) Memory window
This windows shows the memory content in the selected context.
@ -330,7 +353,7 @@ The "Save Memory Data" dialog box allows saving the data of the specified Saturn
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
10.) Stack window
The content of the hardware stack is viewed here. In "1:" is the current return address. A double click on an item shows the address content in the Code window.
@ -349,7 +372,7 @@ Pop the selected element from the stack.
Modifies the stack content of the current selection.
10.) MMU window
11.) MMU window
The configuration of the memory controllers is viewed here. The viewed addresses are the first address of each module area and may differ from the given address in the CONFIG command.
@ -363,11 +386,11 @@ This example
will config a 128KB module at address #80000 and not at the given address. So the MMU viewer will show you the address #80000.
11.) Miscellaneous window
12.) Miscellaneous window
The Miscellaneous window show you the internal state of the interrupt flag, the 1ms keyboard handler and the contents of the Bank Switcher latch. The Bank Switcher item is only enabled on calculators with a latch inside. You see the loaded value of the address lines A6-A0. You have to ignore the last bit (A0), because it isn't wired to the six bit latch.
You can change the values by pressing the left mouse button over the old content.
01/09/13 (c) by Christoph Gießelink
08/12/19 (c) by Christoph Gießelink

View file

@ -87,28 +87,32 @@ h3 { color:red; font-size:1.1em; }
</div>
<div id="main">
<h1><a name=s1>1. General</a></h1>
<p>Emu48 is an emulator for the Hewlett Packard HP38G, HP39G,
HP40G, HP48SX, HP48GX and HP49G calculator hardware. These calculators
are based on the 1LT8 Clarke (HP48SX) and on the Yorke chip.</p>
<p><a href="http://hp.giesselink.com/emu42.htm">Emu48</a> is an
emulator for the Hewlett Packard HP38G, HP39G, HP40G, HP48SX, HP48GX
and HP49G calculator hardware. These calculators are based on the
1LT8 Clarke (HP48SX) and on the Yorke chip.</p>
<h1><a name=s2>2. Acknowledgements</a></h1>
<p>First of all a big thank to S&eacute;bastien Carlier for publishing
Emu48 v1.0 under the GPL. Without this decision newer versions of the
emulator wouldn't have been possible or ports to other similar
calculators wouldn't have been made. Also a big thank to Jean-Yves
Avenard for his technical assistance in the beginning. Lode Vandevenne
spend the PNG image decoder and finally I want to thank all the
spent the PNG image decoder and finally I want to thank all the
unnamed authors for publishing material about these calculators.</p>
<h1><a name=s3>3. ROM Images</a></h1>
<p>Emu48 needs an image of a calculator ROM to be able to run. ROM
images are valid in a packed (even address lower nibble, odd address
higher nibble) or unpacked (one nibble per byte with even address first)
<p>Emu48 needs a <a href="https://en.wikipedia.org/wiki/ROM_image">ROM
image</a> for each calculator model you want to emulate. ROM images
are valid in a packed (even address lower nibble, odd address higher
nibble) or unpacked (one nibble per byte with even address first)
form.</p>
<p>Since fall 2000 the emulator ROM's for the HP38, 39, 40, 48 and 49
are freely available on different Internet sites. Because there's no
license for the distribution of the ROM images, they aren't included
in the Emu48 package. You can still use the classic way extracting
them from your own calculator. But in mostly all cases you have to
convert the ROM files into the Emu48 ROM format.</p>
in the Emu48 package. Since accepting packed ROM images, in most cases
converting the given ROM format (which is regulary a packed ROM image)
into the native Emu48 ROM format is not necessary any more. You can
still use the classic way extracting them from your own calculator.
</p>
<ul>
<li>HP38
<p>To upload the ROM of your HP38G, you will need a special aplet
@ -178,24 +182,24 @@ h3 { color:red; font-size:1.1em; }
<p>To install Emu48 you may use the installer package which contain,
among the binaries, some HP48 KML scripts or just unzip the emulator
and the required emulator skins from archives into an empty directory.
Finally you have to copy your ROM images into this directory and
adjust the ROM image name to the name used in the corresponding KML
script. When you first run Emu48, it will detect the directory in
which you installed it, and will write the configuration to the
registry at <i>HKCU\Software\Emu48</i>.</p>
Finally copy your ROM images into this directory and adjust the ROM
image name to the name used in the corresponding KML script. When you
first run Emu48, it will detect the directory in which you installed
it, and will write the configuration to the registry at
<i>HKCU\Software\Emu48</i>.</p>
<h1><a name=s5>5. How to Start</a></h1>
<p>When Emu48 is installed and you have put valid KML scripts and the
corresponding ROM image(s) into your Emu48 installation directory, you
can start Emu48. You'll see a &quot;Choose Your KML Script&quot;
box.</p>
<p>KML scripts in fact define the visual aspect of Emu48, the behavior of
the buttons, of the keyboard, ... It's a GREAT way to customize your copy
of Emu48.</p>
<p>Check that the path in the &quot;Emu48 Directory&quot; text area is
correct. Modify it if the directory in which you installed Emu48 is not
the directory displayed. Click the refresh button (&quot;V&quot;) after
modifying it to update the list box or use the (&quot;...&quot;) button to
start the directory browser.</p>
<p>KML (Keyboard Mapping Language) scripts define the visual aspect
of Emu48, the behaviour of the buttons, of the keyboard, ... It's a
<b>great</b> way to customize your copy of Emu48.</p>
<p>Check in this dialog that the path in the &quot;Emu48 Directory&quot;
text area points to the directory in which you installed the Emu48 KML
files. Click the refresh button (&quot;V&quot;) after modifying the
directory path manually to update the list box or use the
(&quot;...&quot;) button to start a directory browser.</p>
<p>Choose a KML script in the list box for your calculator ROM you put
into Emu48's directory.</p>
<p>Several HP48 scripts are included in the Emu48 archive:</p>
@ -218,19 +222,21 @@ h3 { color:red; font-size:1.1em; }
</ul>
<p>If you want other great scripts, visit Rechlin's great HP archive
<a href="http://www.hpcalc.org/"></a></p>
<p>And if you are interested in writing new scripts, get the KML 2.0
<p>If you are interested in writing new scripts, get the KML 2.0
documentation from <a href="http://hp.giesselink.com/emu48.htm">the
authors Emu48 page</a>.</p>
<p>Once you have selected a script, press OK to start the emulator. In
most cases, when Emu48 crash after pressing the OK button, you are using
an invalid ROM image. While it's running, you can use the View/Change KML
Script... command to change the visual aspect of Emu48.</p>
<p>Having selected a script, press OK to start the emulator. In most
cases, when Emu48 crash after pressing the OK button, you are using
an invalid ROM image. While it's running, you can use the
&quot;<a href="#ss10.1">View/Change KML Script...</a>&quot; command to
change the visual aspect of Emu48.</p>
<h1><a name=s6>6. Command Line</a></h1>
<p>The command line syntax is &quot;<i>Emu48 [E48file [Port2file]]</i>&quot;.
The first parameter sets the filename for the emulation data
independent from the &quot;LastDocument&quot; setting, the second
parameter the Port2 file. You're not able to set a Port 2 file without
setting the emulation data file. The arguments are optional.</p>
The first parameter sets the filename of the emulation data
independent from the &quot;LastDocument&quot; setting, normally
reponsible for opening the last used state file. The second parameter
the Port2 file. You're not able to set a Port 2 file without setting
the emulation data file. The arguments are optional.</p>
<h1><a name=s7>7. Virtual Keyboard</a></h1>
<p>There are two ways to use the virtual keyboard on the emulated
calculator:</p>
@ -239,38 +245,41 @@ h3 { color:red; font-size:1.1em; }
<li><a href="#keyboard">by PC keyboard</a></li>
</ol>
<p><a name=mouse></a>
The easiest way to use the emulated calculator is using the mouse. The KML
script define buttons with an area where mouse input is active. The mouse
cursor change from an arrow to a hand cursor in these areas. The state of
the virtual key follow the state of your left mouse button. When the mouse
cursor leaves the virtual key area the virtual button automatically
release. In some cases you need to press more than one key on the
emulator. For these cases press the virtual key with the right mouse
button. When you release the mouse button or leave the area of the virtual
key, the key is still hold. To release all hold virtual buttons, just use
the left mouse button again. A single release of a hold virtual key isn't
possible.</p>
The easiest way to use the emulated calculator is by using the mouse. The
KML script defines buttons with an area where mouse clicks take effect.
The active area is indicated by changing the cursor from an arrow to a
hand cursor. Pressing the left mouse button over an active area will
press the virtual button. When the mouse cursor leaves the virtual key
area with still the left mouse button pressed, the virtual button is
automatically released. The visual aspect of a pressed or released
virtual button is defined in the KML script. In some cases you need to
press more than one key on the emulator. For these cases press the
virtual key with the right mouse button. When you release the mouse
button or leave the area of the virtual key, the key is still held.
To release all held virtual buttons, just use the left mouse button
again. A single release of a hold virtual key isn't possible.</p>
<p><a name=keyboard></a>
Another convenient way is using the PC keyboard. The KML script language
support a large variety of commands to implement this feature. So keyboard
usage depends on your used KML script and not on the emulator. Because of
this it's impossible to say what's happen when you press a key on the PC
keyboard. For further details read the KML 2.0 documentation mentioned
before please.</p>
supports a large variety of commands to implement this feature. So
keyboard usage mostly depends on your used KML script and not on the
emulator. Because of this it's impossible to say what's happen when you
press a key on the PC keyboard. Some Windows specific accelerator keys
like F10 cannot be overloaded by the KML script. For further details
read the KML 2.0 documentation mentioned before please.</p>
<h1><a name=s8>8. File Menu</a></h1>
<h2><a name=ss8.1>8.1 New...</a></h2>
<p>Creates a new emulation session. You're asked for a new KML script
where you can select the calculator type and skin to emulate.</p>
<p>Creates a new emulation session. You're asked for a KML script where
you can select the calculator type and skin to emulate.</p>
<h2><a name=ss8.2>8.2 Open...</a></h2>
<p>Opens an existing emulation session. The emulation continues at the
same position where the loaded session was aborted. Loading emulation
<p>Opens a previously saved emulation session. The emulation continues
at the same position where the session was aborted. Loading emulation
sessions made with a different ROM revision may <u>destroy</u> the memory
content or may cause other unpredictable results.</p>
<h2><a name=ss8.3>8.3 Save</a></h2>
<p>Saves the current running session with the actual name.</p>
<p>Saves the current session with the actual name.</p>
<h2><a name=ss8.4>8.4 Save As...</a></h2>
<p>Saves the current running session with a new name. You're also get in
this dialog when you Exit a new session without a state file name.</p>
<p>Saves the current session with a new name. You're also get this
dialog when you Exit a new session without a state file name.</p>
<h2><a name=ss8.5>8.5 Close</a></h2>
<p>Closes the current session without closing the emulator.</p>
<h2><a name=ss8.6>8.6 Settings</a></h2>
@ -294,10 +303,10 @@ h3 { color:red; font-size:1.1em; }
mouse is moved over the emulator window, the emulator is getting the
focus and popping up into foreground.</p></li>
<li><i>Single Instance</i>
<p>When this option is checked, the program is only allowed to run in
a single instance. If another running instance is detected, the detected
<p>When this option is checked, only one instance of the emulator can
be started. If another running instance is detected, the detected
instance is set into foreground as active window and get a request to
change his state file to the given one by the current instance. Finally
change his state file to the given one by the current instance. Then
the current instance is terminated.</p></li>
<li><i>Automatically Save Files</i>
<p>When this option is checked, the current state file will automatically
@ -305,14 +314,15 @@ h3 { color:red; font-size:1.1em; }
emulator program.</p></li>
<li><i>Automatically Save Files On Exit</i>
<p>When this option is checked, the current state file will be saved
automatically at the end when the emulator program is closed.</p></li>
automatically when the emulator program is closed.</p></li>
<li><i>Show Load Object Warning</i>
<p>When this option is checked, you'll get a warning message box when you
try to load an object with the <i>Load Object...</i> menu command. If
this option is unchecked, the warning will be skipped.</p></li>
<li><i>Always Show KML Compilation Result</i>
<p>When this option is checked, you see the results of the KML
(Keyboard Macro Language) interpreter at every KML script load.</p></li>
(Keyboard Mapping Language) interpreter at every KML script load.
</p></li>
</ul>
<h4>8.6.1.2 Section Style</h4>
<ul>
@ -386,20 +396,23 @@ h3 { color:red; font-size:1.1em; }
<h3><a name=ss8.6.3>8.6.3 Settings Peripheral</a></h3>
<h4>8.6.3.1 Section Sound</h4>
<p>A new implementation of the sound engine made ROM patches for sound
output obsolete. The new sound engine emulates the behavior of the beeper
output ports and only work in connection with a sound card. Using the
internal PC speaker isn't possible any more. The old beeper method with a
ROM patch is still working but deprecated, it's strongly recommended to
remove all beep patches from your current KML scripts to enable the new
sound engine. The support of the old sound implementation by a ROM patch
maybe removed in later versions of the emulator and remaining beep
patches will corrupt the ROM with an illegal opcode then.
output obsolete. The new sound engine emulates the behaviour of the
beeper output ports and only work in connection with a sound card.
Using the legacy PC speaker mode isn't possible any more. The old
beeper method with a ROM patch is still working but deprecated, it's
strongly recommended to remove all beep patches from your current KML
scripts to enable the new sound engine. The support of the old sound
implementation by a ROM patch maybe removed in later versions of the
emulator and remaining beep patches will corrupt the ROM with an
illegal opcode then. Actually the program informs you when
detecting ROM beep patches by opening the &quot;KML Script Compilation
Result&quot; dialog. To prevent this, remove the ROM beep patches
from the KML script.
</p>
<p>
For the sound generation the calculator must know his own CPU strobe
<p>For the sound generation the calculator must know his own CPU strobe
frequency. On the real calculator the speed depends on various settings
like component tolerances, actual temperature, humidity and other
variables. The resulting speed is measured by the calculator firmware
variables. The actual speed is measured by the calculator firmware
at a cold- or at a warmstart and stored in the =CSPEED variable. The
content of this calculator variable has direct influence on the
resulting frequency and duration. On the emulator the HP48SX CPU
@ -414,27 +427,24 @@ h3 { color:red; font-size:1.1em; }
frequency registry content has been changed since the last
measurement, the =CSPEED variable of this session file may contain
a wrong frequency value. You easily may discover this by measuring
the real duration of a 10s beep. Is the difference to 10s less
than 1s everything is ok, if not, you should perform a
<u style="color:red">warmstart</u> of the calculator in this
session file. Alternatively you may execute a
<a href=#ss9.6>Reset Calculator</a>. This recalls the measuring
routine and save the result in the speed variable. Both restart
variants purge the stack content!
the real duration of a 10s beep. A deviance less than 1s is ok,
otherwise you should perform a <u style="color:red">warmstart</u>
of the calculator in this session file. Alternatively you may
execute a <a href=#ss9.6>Reset Calculator</a>. This recalls the
measuring routine and save the result in the speed variable. Both
restart variants purge the stack content!
</p>
<ul>
<li><i>Volume</i>
<p>The output volume can be selected with the Volume slider relative to
the Master Volume control.
<p>The output volume can be set with the Volume slider relative to
the Windows Master Volume control.
</p></li>
<li><i>Device</i>
<p>By default the sound device is set to &quot;Standard Audio&quot;, but
you can also manually choose the output device. The device name is
somehow cut since Window Vista, but the method of reading the device
name is used for backwards compatibility to older versions of the
Operating System. When you change the Standard Audio device in the
Operating System settings dialog, the internal device numbering may
change, and so the manually selected audio device.</p></li>
<p>By default the sound device is set to &quot;Standard Audio&quot;,
but you can also manually choose the output device. When you change
the Standard Audio device in the Operating System settings dialog,
the internal device numbering may change, and so the manually selected
audio device.</p></li>
</ul>
<h4>8.6.3.2 Section Infrared Printer</h4>
<p>The emulator has the ability to print data to a HP82240A/B printer
@ -475,33 +485,33 @@ h3 { color:red; font-size:1.1em; }
<h2><a name=ss9.3>9.3 Copy Screen</a></h2>
<p>Copy the screen content as bitmap to the clipboard.</p>
<h2><a name=ss9.4>9.4 Copy Stack</a></h2>
<p>This is only valid for the HP48SX, HP48GX and the HP49G emulation.</p>
<p>This menu item is enabled for the HP48SX, HP48GX and the HP49G
emulation.</p>
<p>Copy a &quot;Real Number&quot;, &quot;Complex Number&quot; or
&quot;String&quot; object in stack level 1 to the clipboard. On all
other objects, the command will be ignored. This prevents sending
binary objects to the clipboard.</p>
<p>The decimal point (radix mark) of &quot;Real Numbers&quot; in the
clipboard is equal to the calculator setting. This point maybe
important when you try to paste the numbers into a program using the
locale settings of the host operating system.</p>
clipboard is equal to the calculator setting. This is important when
you try to paste the numbers into a program using the locale settings
of the host operating system.</p>
<h2><a name=ss9.5>9.5 Paste Stack</a></h2>
<p>This is only valid for the HP48SX, HP48GX and the HP49G emulation.</p>
<p>This menu item is enabled for the HP48SX, HP48GX and the HP49G
emulation.</p>
<p>Paste the text field content of the clipboard to stack level 1 of
the emulated calculator. If the clipboard content is representing a
real number, the number will be saved as &quot;Real Number&quot;
object. Is the content a complex number object, the number will be
saved as &quot;Complex Number&quot; object, in all other cases as
saved as &quot;Complex Number&quot; object, otherwise cases as
&quot;String&quot; object.</p>
<p>To import &quot;Real or Complex Numbers&quot; from the clipboard,
the decimal point (radix mark) of the clipboard and calculator
<u>must</u> be equal. A real or complex number is only detected in the
case of valid real number characters in the clipboard. Especially
heading and tailing white spaces aren't valid number characters
also.</p>
<p>Complex numbers must be in the form <i>(a,b)</i> when using the
point radix mark or in the form <i>(a;b)</i> when using the comma
radix mark. The Cartesian or algebraic form <i>a+bi</i> is not
supported.</p>
<p>To import &quot;Real or Complex Numbers&quot; from the clipboard, the
decimal point (radix mark) of the clipboard and calculator <u>must</u>
match. A real or complex number is only detected in the case of valid
real number characters in the clipboard. Especially heading and tailing
white spaces aren't valid number characters also.</p>
<p>Complex numbers must be in the form <i>(a,b)</i> when using the point
radix mark or in the form <i>(a;b)</i> when using the comma radix mark.
The Cartesian or algebraic form <i>a+bi</i> is not supported.</p>
<h2><a name=ss9.6>9.6 Reset Calculator</a></h2>
<p>This emulates the Reset pin of the internal CPU.</p>
<h2><a name=ss9.7>9.7 Backup</a></h2>
@ -511,7 +521,7 @@ h3 { color:red; font-size:1.1em; }
<h3><a name=ss9.7.2>9.7.2 Backup Restore</a></h3>
<p>This restores a previous saved emulator status without request. If you
changed the calculator model meanwhile, the emulator will switch back to
the old model.</p>
the model used in the backup.</p>
<h3><a name=ss9.7.3>9.7.3 Backup Delete</a></h3>
<p>This deletes the data in the backup slot.</p>
<h1><a name=s10>10. View Menu</a></h1>
@ -525,7 +535,7 @@ h3 { color:red; font-size:1.1em; }
<p>Enter the address to disassemble in hexadecimal into the &quot;Address
(HEX)&quot; field and press &lt;Return&gt;. With the &quot;Next Address&quot;
button the next opcode is disassembled. With the &quot;Copy Data&quot; button
you can copy all selected lines inside the list box to the clipboard.</p>
you can copy all selected lines from the list box to the clipboard.</p>
<h2><a name=ss11.2>11.2 Debugger...</a></h2>
<p>The assembler code debugger of the emulator. For more details refer to the
extra documentation of the debugger please.</p>
@ -537,7 +547,7 @@ h3 { color:red; font-size:1.1em; }
file with it's time information.</p>
<h3><a name=ss11.3.2>11.3.2 Macro Play...</a></h3>
<p>Prompts a dialog box to ask for the keyboard macro file to play. The
replay starts immediately after selecting the file.</p>
replay starts immediately after opening the selected file.</p>
<h3><a name=ss11.3.3>11.3.3 Macro Stop</a></h3>
<p>Stops recording or replaying a keyboard macro file.</p>
<h3><a name=ss11.3.4>11.3.4 Macro Settings...</a></h3>
@ -550,9 +560,9 @@ h3 { color:red; font-size:1.1em; }
</ul>
<h1><a name=s12>12. Help Menu</a></h1>
<h2><a name=ss12.1>12.1 Help Topics</a></h2>
<p>Call this document.</p>
<p>Show this document.</p>
<h2><a name=ss12.2>12.2 About Emu48...</a></h2>
<p>The version, copyright and license message...</p>
<p>Show the version, copyright and license message...</p>
<h1><a name=s13>13. DDE Server</a></h1>
<p>Emu48 has an integrated DDE server to transmit data from and to the HP
stack. Because only the HP48 and HP49 have a stack, all DDE transfers
@ -591,7 +601,7 @@ h3 { color:red; font-size:1.1em; }
</table>
<h1><a name=s14>14. License</a></h1>
<p>Emu48 - A HP38G/39G/40G/48SX/48GX/49G Emulator<br>
Copyright (C) 2018 Christoph Gie&szlig;elink</p>
Copyright (C) 2019 Christoph Gie&szlig;elink</p>
<p>This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)

BIN
Emu48.exe

Binary file not shown.

View file

@ -4,9 +4,9 @@
\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 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
\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 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 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
The description of Emu10 and Emu32 has been removed from this document. The development of Emu10 and Emu32 has quit, the emulated calculators are now emulated by Emu42. So Emu42 now emulates three quite different hardware platforms, the High-End Pioneer and Clamshell series with a dot matrix display which base on the Lewis chip, the Mid-Range Pioneer series with a semi dot matrix display which base on the Sacajawea chip and the Low-End Pioneer series with a 7-digit display which base on the Bert chip. To distinguish the three emulation platforms I use, if necessary, Emu42 (Lewis), Emu42 (Sacajawea) and Emu42 (Bert) in the further text.\par
\pard\nowidctlpar\par
\b\fs40 Index\fs28\par
\b0\fs24\par
@ -57,10 +57,8 @@ End\par
\f1\fs16\tab Author \ldblquote John Doe\rdblquote\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
\f0\fs24 Emu28:\par
\f1\fs16\tab\lang1033 Hardware \ldblquote Centipede\rdblquote\par
\pard\nowidctlpar Emu28:\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
@ -69,18 +67,17 @@ End\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
\pard\nowidctlpar\fi720\qj\cf0\ldblquote E\rdblquote = HP10B\par
\ldblquote F\rdblquote = HP20S\par
\ldblquote M\rdblquote = HP21S\par
\pard\nowidctlpar\qj\cf1 Emu28:\par
Emu28:\par
\pard\nowidctlpar\fi720\qj\cf0\ldblquote P\rdblquote = HP28C\par
\pard\nowidctlpar\qj\cf1 Emu42:\par
\pard\nowidctlpar\fi720\qj\cf0\ldblquote I\rdblquote = HP14B\par
\ldblquote T\rdblquote = HP17B\par
\lang1036\ldblquote U\rdblquote = HP17BII\par
\ldblquote Y\rdblquote = HP19BII\par
\lang1033\ldblquote M\rdblquote = HP27S\par
\pard\nowidctlpar\fi720\qj\cf0\lang1040\ldblquote E\rdblquote = HP10B\par
\ldblquote I\rdblquote = HP14B\par
\lang1031\ldblquote T\rdblquote = HP17B\par
\ldblquote U\rdblquote = HP17BII\par
\lang1033\ldblquote Y\rdblquote = HP19BII\par
\ldblquote F\rdblquote = HP20S\par
\ldblquote C\rdblquote = HP21S\par
\ldblquote M\rdblquote = HP27S\par
\ldblquote O\rdblquote = HP28S\par
\ldblquote N\rdblquote = HP32SII\par
\ldblquote D\rdblquote = HP42S\par
@ -113,7 +110,7 @@ Emu42:\par
\cf0 Example:\par
\pard\nowidctlpar\f1\fs16\tab Patch \ldblquote BEEP.48\rdblquote\par
\pard\nowidctlpar\qj\f0\fs24\par
Bitmap is the bitmap file that will be the \ldblquote faceplate\rdblquote . All emulator versions are supporting the BMP file format, the latest versions also the Graphics Interchange Format (GIF).\par
Bitmap is the bitmap file that will be the \ldblquote faceplate\rdblquote . All emulator versions are supporting the BMP file format, more recent versions also the Graphics Interchange Format (GIF) and the latest versions (not Pocket PC) the Portable Network Graphics (PNG). Transparency of PNG is not supported. There are some requirements on the annunciator design of Emu28, Emu42 and Emu71. By default, these emulators use transparent annunciators with a drawing color and a transparent background. Therefore, each annunciator must be drawn in monochrome with a background color pixel at top, left and a different color for the annunciator mask.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Bitmap \ldblquote mygx.bmp\rdblquote\par
\pard\nowidctlpar\qj\f0\fs24\par
@ -122,11 +119,11 @@ Icon is an optional icon file in the icon file format that will be showed instea
\f1\fs16\tab Icon \ldblquote mygx.ico\rdblquote\par
\pard\nowidctlpar\qj\f0\fs24\par
Color is an optional setting to define the transparency color of the background bitmap. It takes effect only when both, title bar and menu bar are not shown. The first integer specifies the maximum tolerance between bitmap pixel and reference for color matching followed by three integers defining the RGB numbers (Red, Green and Blue) of the transparency reference color. Each RGB number range from 0 to 255. The difference between the actual pixel and the transparency color is calculated by the formula:\par
\f2 Difference = |\'c4R| + |\'c4G| + |\'c4B| where the \'c4 are the count differences between the color parts of the pixel and the transparency\f0 reference color. The given tolerance value must be greater or equal to the calculated difference to handle this background bitmap \ul position\ulnone as transparent. Because of setting the bitmap position to transparent it\rquote s quite important that the display area in the background bitmap is not set to transparent, else the complete display area will be transparent even if the colors of the display pixel don\rquote t match with the transparency reference color.\par
\f2 Difference = |\'c4R| + |\'c4G| + |\'c4B| where the \'c4 are the count differences between the color parts of the pixel and the transparency reference color. The given tolerance value must be greater o\f0 r equal to the calculated difference to handle this background bitmap \ul position\ulnone as transparent. Because of setting the bitmap position to transparent it\rquote s quite important that the display area in the background bitmap is not set to transparent, else the complete display area will be transparent even if the colors of the display pixel don\rquote t match with the transparency reference color.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Color 0 255 0 0\par
\pard\nowidctlpar\qj\f0\fs24\par
Scale allows to resize the background bitmap with a factor. Background bitmap dependent positions like the button definitions, the display origin and the display Zoom factor are translated to the new size. Only for the case of an external annunciator bitmap definition, the source annunciator coordinates and size information aren\rquote t translated. The first argument is the \ldblquote multiplier\rdblquote , the second the \ldblquote dividend\rdblquote of the factor.\par
Scale allows to resize the background bitmap with a factor. Background bitmap dependent positions like the button definitions, the display origin and the display Zoom factor are translated to the new size. Only for the case of an external annunciator bitmap definition, the source annunciator coordinates and size information aren\rquote t translated. The first argument is the \ldblquote multiplier\rdblquote , the second the \ldblquote dividend\rdblquote of the factor. Caution: Scaling modifies the bitmap colors, so a transparent color setting for the background may not work anymore.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Scale 2 3\par
\pard\nowidctlpar\qj\f0\fs24\par
@ -152,11 +149,11 @@ Debug sets the emulator to return an information message box telling the scancod
\lang1033 End\par
\f0\fs24\par
\par
\pard\nowidctlpar\qj Offset is how far the top left corner of the bitmap will be offset in the window. Most of the time you should set this to 0 0. The first integer is the amount of pixels to the right and the second is that amount of pixels down.\par
\pard\nowidctlpar\qj Offset is how far the top left corner of the bitmap will be offset in the window. Most of the time you should set this to 0 0. The first integer is the number of pixels to the right and the second is the number of pixels down.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Offset 0 0\par
\f0\fs24\par
\pard\nowidctlpar\qj Size sets the size of the emulator window in pixels. The first integer is the width and the second is the height. This is the width of the window, not the bitmap. It is usually smaller than the bitmap size because the bitmap normally contain the annunciator symbols.\par
\pard\nowidctlpar\qj Size sets the size of the emulator window in pixels. The first integer is the width and the second is the height. This is the width of the window, not the bitmap. It is usually smaller than the bitmap size because the bitmap normally contains the annunciator symbols.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Size 302 485\par
\f0\fs24\par
@ -187,11 +184,11 @@ Debug sets the emulator to return an information message box telling the scancod
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), Emu48 and Emu71 and will be ignored on Emu10 and Emu42 (Sacajawea). Zoom factor two is usually used by the dot matrix LCD types emulated by Emu28, Emu42 (Lewis), Emu48 and Emu71.\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 Emu42 (Bert) and Emu42 (Sacajawea). 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
Zoomxy is a variant of the Zoom command only valid for Emu42 (Lewis) and Emu48. On Emu42 (Lewis) the High-End-Pioneer calculator series has originally a non quadratic rectangle as display pixel. The height of the pixel is normally bound to the zoom factor. But in some circumstances it\rquote s useful to adjust the height of the pixel separately from the width. The first integer is the width and the second integer is the height of the dot matrix pixel.\par
Zoomxy is a variant of the Zoom command only valid for Emu42 (Lewis) and Emu48. On Emu42 (Lewis) the High-End-Pioneer calculator series has originally a non-quadratic rectangle as display pixel. The height of the pixel is normally bound to the zoom factor. But in some circumstances, it\rquote s useful to adjust the height of the pixel separately from the width. The first integer is the width and the second integer is the height of the dot matrix pixel.\par
Example:\par
\f1\fs16\tab Zoomxy 2 3\par
\pard\nowidctlpar\qj\f0\fs24\par
@ -199,17 +196,17 @@ Vertical is a special command only for the Pocket PC versions of Emu42 and Emu48
\pard\nowidctlpar Example:\par
\f1\fs16\tab Vertical 1\par
\f0\fs24\par
\pard\nowidctlpar\qj Offset sets the position of the LCD screen. The first integer is the amount of pixels right and the second is the amount of pixels down.\par
\pard\nowidctlpar\qj Offset sets the position of the LCD screen. The first integer is the number of pixels right and the second is the number of pixels down.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Offset 20 20\par
\f0\fs24\par
\pard\nowidctlpar\qj Bitmap \super (*1) \nosupersub is an optional command for including an external annunciator bitmap instead of using the annunciators in the background bitmap.\par
\pard\nowidctlpar\qj Bitmap is an optional command for including an external annunciator bitmap instead of using the annunciators in the background bitmap. Accept all bitmap formats like Bitmap in the Global section.\par
\pard\nowidctlpar Example:\par
\f1\fs16\tab Bitmap \ldblquote mylcd.bmp\rdblquote\par
\pard\nowidctlpar\qj\f0\fs24\par
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
Emu42 (Bert):\par
\pard\nowidctlpar\fi720\qj 0-7 = 0 is lightest, 7 is darkest\par
\pard\nowidctlpar\qj\par
Emu42 (Sacajawea), Emu71:\par
@ -223,7 +220,7 @@ Emu42 (Sacajawea), Emu71:\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. 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
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 Emu28, Emu42 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
@ -240,13 +237,13 @@ The contrast settings outside these areas (accessible by hardware so it\rquote s
\par
\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs\clbrdrb\brdrw15\brdrs \cellx5812\pard\intbl\nowidctlpar\cell Emulator\cell Range\cell Reset\cell\lang1031 Min\cell Max\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\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl\nowidctlpar HP10B\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\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\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx1243\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx2410\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx3261\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4111\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx4962\clbrdrl\brdrw15\brdrs\clbrdrt\brdrw15\brdrs\clbrdrr\brdrw15\brdrs \cellx5812\pard\intbl\nowidctlpar HP10B\cell Emu42\cell 0-7\cell 4\cell 2\cell 6\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 HP14B\cell Emu42\cell 0-15\cell 6\cell 0\cell 15\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 HP17B\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 HP17BII\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 HP19BII\cell Emu42\cell\lang1033 0-31\cell 22\cell 16\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 HP20S\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\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 HP21S\cell Emu10\cell 0-7\cell 4\cell 2\cell 6\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 HP20S\cell Emu42\cell 0-7\cell 4\cell 2\cell 6\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 HP21S\cell Emu42\cell 0-7\cell 4\cell 2\cell 6\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 HP27S\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 HP28C\cell Emu28\cell 0-31\cell 26\cell 20\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 HP28S\cell Emu42\cell 0-31\cell 22\cell 16\cell 31\cell\row\trowd\trgaph70\trleft-70\trbrdrl\brdrs\brdrw10 \trbrdrt\brdrs\brdrw10 \trbrdrr\brdrs\brdrw10 \trbrdrb\brdrs\brdrw10 \trpaddl70\trpaddr70\trpaddfl3\trpaddfr3
@ -264,7 +261,7 @@ 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 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
\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
@ -272,7 +269,7 @@ 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) are using different methods for creating a numeric value.\b\par
\pard\nowidctlpar\qj\b0\tab This section is only valid for Emu42 (Bert) and Emu42 (Sacajawea) and describes the (alpha-) numeric part of the LCD screen. Emu42 (Bert) 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
@ -281,7 +278,7 @@ Max\tab : max. adjustable contrast value by keyboard\par
\tab Bitmap STRING\par
End\par
\f0\fs24\par
Emu10:\par
Emu42 (Bert):\par
\pard\nowidctlpar\qj The low-end Pioneer series use a classic 7 segment LCD. With the first nine annunciators (segments \lquote a\rquote to \lquote g\rquote , \lquote dp\rquote and \lquote cm\rquote ) one digit is described.\par
\pard\nowidctlpar\par
The commands Offset and Size are unused.\par
@ -315,7 +312,7 @@ 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), 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\qj\tab Annunciators are the 23 (Emu42 (Bert)), 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
@ -338,7 +335,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 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\qj Down is the position of the annunciator in the bitmap when it is on. There are some restrictions on the different emulators. On Emu42 (Bert) 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
@ -412,7 +409,7 @@ NoHold will keep a button from sticking in the down position. It only generates
Example:\par
\tab\f1\fs16 NoHold\par
\cf0\b\f0\fs28\par
\b0\fs24 OnDown and OnUp are used to carryout scancode commands when you press a button. Any Scancode command (see page 21) can be used. OnDown is when the button is pressed down. OnUp is when the button is released.\par
\b0\fs24 OnDown and OnUp are used to carryout scancode commands when you press a button. Any Scancode command (see page 24) can be used. OnDown is when the button is pressed down. OnUp is when the button is released.\par
Example:\par
\f1\fs16\tab OnDown\par
\pard\nowidctlpar\tab\tab Press 81\par
@ -480,24 +477,24 @@ Example:\par
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 v\cell\cell 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 \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 5 4\cell\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 \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 SHIFT\cell\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 \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\lang1036\b0\fs20 5 2\cell\cell 3 2\cell 2 2\cell 1 2\cell 0 2\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 5 2\cell\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 \cellx978\cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 C\cell\cell 0\cell .\cell =\cell +\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 0 32768\cell\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\page OutIn Codes HP19BII\par
\pard\nowidctlpar\par
\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\nowidctlpar\cf2\lang1033\f3\fs24 Key\cell\b0\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\nowidctlpar\cf2\f3\fs24 Key\cell\b0\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\nowidctlpar\cf1\b\fs20 OutIn\cell\b0\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\cellx978\cellx1986\cellx2994\cellx4002\cellx5010\cellx6018\pard\intbl\nowidctlpar\b\fs16\cell\b0\cell\cell\cell\cell\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 A\cell\lang1040 B\cell C\cell D\cell E\cell\lang1033 F\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 A\cell B\cell C\cell D\cell E\cell F\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 6 256\cell 6 2048\cell 6 64\cell 6 32\cell 6 1\cell 6 1024\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 G\cell H\cell\lang1040 I\cell J\cell K\cell\lang1031 L\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 G\cell\lang1040 H\cell I\cell J\cell K\cell L\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 5 256\cell 5 2048\cell 5 64\cell 5 32\cell 5 1\cell 5 1024\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 M\cell N\cell\lang1040 O\cell P\cell Q\cell\lang1033 R\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 M\cell N\cell O\cell\lang1036 P\cell Q\cell R\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 4 256\cell 4 2048\cell 4 64\cell 4 32\cell 4 1\cell 4 1024\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 S\cell T\cell\lang1031 U\cell V\cell W\cell\lang1036 X\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 S\cell T\cell U\cell V\cell W\cell X\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 3 256\cell 3 2048\cell 3 64\cell 3 32\cell 3 1\cell 3 1024\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 Y\cell Z\cell\lang1040 ?\cell $\cell #\cell :\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 Y\cell\lang1040 Z\cell ?\cell $\cell #\cell :\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx978\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 2 256\cell 2 2048\cell 2 64\cell 2 32\cell 2 1\cell 2 1024\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrt\brdrw30\brdrs\clbrdrr\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf2\b\fs24 SPACE\cell INS\cell DEL\cell\lang1033 <-\cell ->\cell\row\trowd\trgaph30\trleft-30\trpaddl30\trpaddr30\trpaddfl3\trpaddfr3
\clbrdrl\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx1986\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx2994\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx4002\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx5010\clbrdrl\brdrw30\brdrs\clbrdrr\brdrw30\brdrs\clbrdrb\brdrw30\brdrs \cellx6018\pard\intbl\nowidctlpar\cf1\b0\fs20 1 2048\cell 1 64\cell 1 32\cell 1 1\cell 1 1024\cell\row\pard\nowidctlpar\cf0\f0\fs24\par
@ -746,13 +743,13 @@ Example:\par
\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 Locale\par
\b0\fs24\par
\tab With the Locale command you can bind Scancode definitions to a keyboard Input Locale ID. An Input Locale ID, also known a Language Identifier Constant, is a 16 bit decimal number consists of a 10 bit primary language and a 6 bit sublanguage identifier.\par
\tab With the Locale command you can bind Scancode definitions to a keyboard Input Locale ID. An Input Locale ID, also known a Language Identifier Constant, is a 16-bit decimal number consists of a 10-bit primary language and a 6 bit sublanguage identifier.\par
\par
\f1\fs16 Locale INTEGER\par
\tab <Scancode blocks>\par
End\par
\f0\fs24\par
For example the Primary Language ID for English is 9, the Sublanguage ID for United States (US) is 1 and the Sublanguage ID for United Kingdom (UK) is 2.\par
For example, the Primary Language ID for English is 9, the Sublanguage ID for United States (US) is 1 and the Sublanguage ID for United Kingdom (UK) is 2.\par
\par
With the formula:\par
\par
@ -761,7 +758,7 @@ Locale ID = 1024 * Sublanguage ID + Primary Language ID\par
Locale ID English(US) = 1024 * 1 + 9 = 1033\par
Locale ID English(UK) = 1024 * 2 + 9 = 2057\par
\par
A special case is the value \ldblquote 0\rdblquote for the Primary Language ID and the Sublanguage ID. \ldblquote 0\rdblquote is standing for Neutral. So if you want to select all English keyboards to one case the Locale ID is\par
A special case is the value \ldblquote 0\rdblquote for the Primary Language ID and the Sublanguage ID. \ldblquote 0\rdblquote is standing for Neutral. So, if you want to select all English keyboards to one case the Locale ID is\par
\par
Locale ID English(Neutral) = 1024 * 0 + 9 = 9\par
\par
@ -906,8 +903,8 @@ 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
EDIT_COPY_STACK 19\par
EDIT_PASTE_STACK 20\par
TOOL_DISASM 21\par
TOOL_DEBUG 22\par
TOOL_MACRO_RECORD 23\par
@ -926,7 +923,7 @@ Example:\par
\pard\nowidctlpar\sa200\sl276\slmult1\f0\fs24\par
\pard\nowidctlpar\b\fs28\page Conclusion\par
\b0\fs24\par
\pard\nowidctlpar\qj This document was originally written by Casey Patterson for the Keyboard Macro Language made by S\'e9bastien Carlier and is now maintained by Christoph Gie\'dfelink.\par
\pard\nowidctlpar\qj This document was originally written by Casey Patterson for the Keyboard Mapping Language made by S\'e9bastien Carlier and is now maintained by Christoph Gie\'dfelink.\par
\pard\nowidctlpar\par
I\rquote m sorry, the authors can\rquote t give any individual support, try the forum at http://www.hpmuseum.org/ please.\par
\par
@ -937,10 +934,10 @@ The latest updates are available at:\par
\pard\nowidctlpar\fi720\b0 c.giesselink@gmx.de\par
\pard\nowidctlpar\par
\pard\nowidctlpar\fi720 Christoph Giesselink Main Page\par
http://hp.giesselink.com/\par
https://hp.giesselink.com/\par
\pard\nowidctlpar\par
\par
Release 19: August 15th, 2017\par
Release 21: July 4th, 2019\par
\par
}

View file

@ -1,4 +1,4 @@
Known bugs and restrictions of Emu48 V1.61
Known bugs and restrictions of Emu48 V1.62
------------------------------------------
- the following I/O bits aren't emulated (incomplete)
@ -47,4 +47,4 @@ Known bugs and restrictions of Emu48 V1.61
- quitting the emulator while programming the flash isn't allowed,
because the content of flash state machine isn't saved so far
08/14/18 (c) by Christoph Gießelink, c dot giesselink at gmx dot de
10/15/19 (c) by Christoph Gießelink, c dot giesselink at gmx dot de

View file

@ -1,3 +1,83 @@
Service Pack 62 for Emu48 Version 1.0
DEBUGGER.C
- added enum type, static variables and static function prototypes
for trace implementation
- removed all occurrences of UNREFERENCED_PARAMETER(wParam);
- changed function NotifyDebugger(), added flush trace buffer
- changed function Debugger(), added trace implementation in case
WM_INITDIALOG, WM_DESTROY and WM_COMMAND
- added functions StartTrace(), StopTrace(), FlushTrace(),
PrintTrace(), OutTrace(), OnBrowseTraceSettings(),
TraceSettings(), OnTraceSettings() and OnTraceEnable() for trace
implementation
DISPLAY.C
- changed function CreateMainBitmap(), changed LoadBitmapFile()
function call loading a bitmap with realizing a palette
- changed function CreateAnnunBitmap(), changed LoadBitmapFile()
function call loading a bitmap without realizing a palette
EMU48.C
- added variable bMouseButton saving if mouse button was pressed
when mouse cursor was inside a virtual button hit area
- removed function OnNcHitTest(), replaced by additional
OnLButtonDown() implementation
- changed function OnLButtonDown(), added part for windows movement
when having no title bar prior done over the WM_NCHITTEST message
handler which caused side effects
- changed function OnLButtonUp() and OnKeyDown(), added reset of
variable bMouseButton
- changed function MainWndProc(), added WM_ENDSESSION handler for
document saving, WM_CONTEXTMENU calls the context menu only when
the right mouse button was not pressed over a virtual button hit
area before, removed the WM_NCRBUTTONUP case and removed the
WM_NCHITTEST message handler
EMU48.DSP
- added "LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS" to lodepng.c
definitions
EMU48.H
- changed function prototype
- extern declaration of global functions
EMU48.RC
- added dialog IDD_TRACE
- changed menu IDR_DEBUG, added ID_TRACE_SETTINGS and
ID_TRACE_ENABLE menu items
- changed version and copyright
ENGINE.C
- changed function Debugger(), added function fnOutTrace() call
FILES.C
- added function CheckForBeepPatch() looking for ROM beep patches at
known positions
- bugfix in function NewDocument(), initialize the ROM fingerprint
after loading the KML script
- changed function DecodeBmp(), DecodeGif(), DecodePng() and
LoadBitmapFile(), changed function prototype by adding an argument
if a palette should realized
KML.C
- bugfix in function ParseLines() and ParseBlocks(), if loading of
an include file failed the KML script line number at the error
message was wrong
- changed function InitKML(), added error check ROM beep patches
LODEPNG.C
- changed implementation file to LodePNG version 20190914 with
unmarked typecast patches for x64 compatibility, Copyright (c)
2005-2019 Lode Vandevenne
LODEPNG.H
- changed header file to LodePNG version 20190914
RESOURCE.H
- added definitions
Service Pack 61 for Emu48 Version 1.0
EMU48.DSP

View file

@ -35,6 +35,9 @@
#define CODELABEL 0x80000000 // label in code window
// trace log file modes
enum TRACE_MODE { TRACE_FILE_NEW = 0, TRACE_FILE_APPEND };
typedef struct CToolBarData
{
WORD wVersion;
@ -81,6 +84,14 @@ static DWORD dwAdrMemFol = 0; // follow address memory window
static UINT uIDMap = ID_DEBUG_MEM_MAP; // current memory view mode
static BOOL bDbgTrace = FALSE; // enable trace output
static HANDLE hLogFile = NULL; // log file handle
static TCHAR szTraceFilename[MAX_PATH] = _T("trace.log"); // filename for trace file
static UINT uTraceMode = TRACE_FILE_NEW; // trace log file mode
static BOOL bTraceReg = TRUE; // enable register logging
static BOOL bTraceMmu = FALSE; // disable MMU logging
static BOOL bTraceOpc = TRUE; // enable opcode logging
static LONG lCharWidth; // width of a character (is a fix font)
static HMENU hMenuCode,hMenuMem,hMenuStack;// handle of context menues
@ -108,6 +119,12 @@ static BOOL OnInfoWoRegister(HWND hDlg);
static VOID UpdateProfileWnd(HWND hDlg);
static BOOL OnMemLoadData(HWND hDlg);
static BOOL OnMemSaveData(HWND hDlg);
static VOID StartTrace(VOID);
static VOID StopTrace(VOID);
static VOID FlushTrace(VOID);
static VOID OutTrace(VOID);
static BOOL OnTraceSettings(HWND hDlg);
static BOOL OnTraceEnable(HWND hDlg);
//################
//#
@ -1768,6 +1785,7 @@ BOOL CheckBreakpoint(DWORD dwAddr, DWORD dwRange, UINT nType)
VOID NotifyDebugger(INT nType) // update registers
{
nRplBreak = nType; // save breakpoint type
FlushTrace(); // flush trace buffer
_ASSERT(hDlgDebug); // debug dialog box open
PostMessage(hDlgDebug,WM_UPDATE,0,0);
return;
@ -1861,6 +1879,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
HDC hDC;
HFONT hFont;
HMENU hSysMenu;
HMENU hDbgMenu;
INT i;
switch (message)
@ -1870,6 +1889,15 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
if (bAlwaysOnTop) SetWindowPos(hDlg,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE);
SendMessage(hDlg,WM_SETICON,ICON_BIG,(LPARAM) LoadIcon(hApp,MAKEINTRESOURCE(IDI_EMU48)));
bDbgTrace = FALSE; // disable file trace
// load file trace settings
ReadSettingsString(_T("Debugger"),_T("TraceFile"),szTraceFilename,szTraceFilename,ARRAYSIZEOF(szTraceFilename));
uTraceMode = ReadSettingsInt(_T("Debugger"),_T("TraceFileMode"),uTraceMode);
bTraceReg = ReadSettingsInt(_T("Debugger"),_T("TraceRegister"),bTraceReg);
bTraceMmu = ReadSettingsInt(_T("Debugger"),_T("TraceMMU"),bTraceMmu);
bTraceOpc = ReadSettingsInt(_T("Debugger"),_T("TraceOpcode"),bTraceOpc);
// add Settings item to sysmenu
_ASSERT((IDM_DEBUG_SETTINGS & 0xFFF0) == IDM_DEBUG_SETTINGS);
_ASSERT(IDM_DEBUG_SETTINGS < 0xF000);
@ -1879,11 +1907,17 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
VERIFY(AppendMenu(hSysMenu,MF_STRING,IDM_DEBUG_SETTINGS,_T("Debugger Settings...")));
}
hDbgMenu = GetMenu(hDlg); // menu of debugger dialog
hWndToolbar = CreateToolbar(hDlg); // add toolbar
CheckMenuItem(GetMenu(hDlg),ID_BREAKPOINTS_NOP3, bDbgNOP3 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(GetMenu(hDlg),ID_BREAKPOINTS_DOCODE,bDbgCode ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(GetMenu(hDlg),ID_BREAKPOINTS_RPL, bDbgRPL ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(GetMenu(hDlg),ID_INTR_STEPOVERINT, bDbgSkipInt ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hDbgMenu,ID_BREAKPOINTS_NOP3, bDbgNOP3 ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hDbgMenu,ID_BREAKPOINTS_DOCODE,bDbgCode ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hDbgMenu,ID_BREAKPOINTS_RPL, bDbgRPL ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hDbgMenu,ID_INTR_STEPOVERINT, bDbgSkipInt ? MF_CHECKED : MF_UNCHECKED);
CheckMenuItem(hDbgMenu,ID_TRACE_ENABLE, bDbgTrace ? MF_CHECKED : MF_UNCHECKED);
EnableMenuItem(hDbgMenu,ID_TRACE_SETTINGS,bDbgTrace ? MF_GRAYED : MF_ENABLED);
hDlgDebug = hDlg; // handle for debugger dialog
hEventDebug = CreateEvent(NULL,FALSE,FALSE,NULL);
if (hEventDebug == NULL)
@ -1931,6 +1965,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
fnOutTrace = OutTrace; // function for file trace
RplReadNibble = GetMemNib; // get nibble function for RPL object viewer
dwDbgStopPC = -1; // no stop address for goto cursor
@ -1949,6 +1984,7 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
case WM_DESTROY:
// SetHP48Time(); // update time & date
nDbgState = DBG_OFF; // debugger inactive
StopTrace(); // finish trace
bInterrupt = TRUE; // exit opcode loop
SetEvent(hEventDebug);
if (pdwInstrArray) // free last instruction circular buffer
@ -1965,6 +2001,14 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
GetWindowPlacement(hDlg, &wndpl);
nDbgPosX = wndpl.rcNormalPosition.left;
nDbgPosY = wndpl.rcNormalPosition.top;
// save file trace settings
WriteSettingsString(_T("Debugger"),_T("TraceFile"),szTraceFilename);
WriteSettingsInt(_T("Debugger"),_T("TraceFileMode"),uTraceMode);
WriteSettingsInt(_T("Debugger"),_T("TraceRegister"),bTraceReg);
WriteSettingsInt(_T("Debugger"),_T("TraceMMU"),bTraceMmu);
WriteSettingsInt(_T("Debugger"),_T("TraceOpcode"),bTraceOpc);
RplDeleteTable(); // delete rpl symbol table
DeleteObject(hFontBold); // delete bold font
DestroyMenu(hMenuMainCode);
@ -2023,6 +2067,8 @@ static INT_PTR CALLBACK Debugger(HWND hDlg, UINT message, WPARAM wParam, LPARAM
case ID_BREAKPOINTS_NOP3: return OnToggleMenuItem(hDlg,LOWORD(wParam),&bDbgNOP3);
case ID_BREAKPOINTS_DOCODE: return OnToggleMenuItem(hDlg,LOWORD(wParam),&bDbgCode);
case ID_BREAKPOINTS_RPL: return OnToggleMenuItem(hDlg,LOWORD(wParam),&bDbgRPL);
case ID_TRACE_SETTINGS: return OnTraceSettings(hDlg);
case ID_TRACE_ENABLE: return OnTraceEnable(hDlg);
case ID_INFO_LASTINSTRUCTIONS: return OnInfoIntr(hDlg);
case ID_INFO_PROFILE: return OnProfile(hDlg);
case ID_INFO_WRITEONLYREG: return OnInfoWoRegister(hDlg);
@ -2199,7 +2245,7 @@ static __inline BOOL OnFindOK(HWND hDlg,BOOL bASCII,DWORD *pdwAddrLast,INT nSear
#if defined _UNICODE
{
// Unicode to byte translation
LPTSTR szTmp = DuplicateString((LPTSTR) lpbySearch);
LPTSTR szTmp = DuplicateString((LPCTSTR) lpbySearch);
if (szTmp != NULL)
{
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
@ -2711,7 +2757,6 @@ static INT_PTR CALLBACK Settings(HWND hDlg, UINT message, WPARAM wParam, LPARAM
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
@ -2775,7 +2820,6 @@ static INT_PTR CALLBACK NewValue(HWND hDlg, UINT message, WPARAM wParam, LPARAM
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
}
static INT_PTR OnNewValue(LPTSTR lpszValue)
@ -2827,7 +2871,6 @@ static INT_PTR CALLBACK EnterAddr(HWND hDlg, UINT message, WPARAM wParam, LPARAM
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
}
static VOID OnEnterAddress(HWND hDlg, DWORD *dwValue)
@ -2880,7 +2923,6 @@ static INT_PTR CALLBACK EnterBreakpoint(HWND hDlg, UINT message, WPARAM wParam,
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
}
static VOID OnEnterBreakpoint(HWND hDlg, BP_T *sValue)
@ -3175,7 +3217,6 @@ static INT_PTR CALLBACK EditBreakpoint(HWND hDlg, UINT message, WPARAM wParam, L
return TRUE;
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
@ -3561,7 +3602,6 @@ static INT_PTR CALLBACK DebugMemLoad(HWND hDlg, UINT message, WPARAM wParam, LPA
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
@ -3569,7 +3609,6 @@ 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;
}
@ -3617,7 +3656,6 @@ static INT_PTR CALLBACK DebugMemSave(HWND hDlg, UINT message, WPARAM wParam, LPA
}
}
return FALSE;
UNREFERENCED_PARAMETER(wParam);
UNREFERENCED_PARAMETER(lParam);
}
@ -3625,6 +3663,337 @@ 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;
}
//################
//#
//# Trace Log
//#
//################
static VOID StartTrace(VOID)
{
if (hLogFile == NULL)
{
SetCurrentDirectory(szEmuDirectory);
hLogFile = CreateFile(
szTraceFilename,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
(uTraceMode == TRACE_FILE_NEW) ? CREATE_ALWAYS : OPEN_ALWAYS,
0,
NULL);
SetCurrentDirectory(szCurrentDirectory);
if (hLogFile == INVALID_HANDLE_VALUE)
{
InfoMessage(_T("Unable to create trace log file."));
hLogFile = NULL;
return;
}
// goto end of file
SetFilePointer(hLogFile,0L,NULL,FILE_END);
}
return;
}
static VOID StopTrace(VOID)
{
if (hLogFile != NULL)
{
CloseHandle(hLogFile);
}
hLogFile = NULL;
return;
}
static VOID FlushTrace(VOID)
{
if (hLogFile != NULL)
{
VERIFY(FlushFileBuffers(hLogFile));
}
return;
}
static __inline void __cdecl PrintTrace(LPCTSTR lpFormat, ...)
{
TCHAR cOutput[1024];
DWORD dwWritten, dwRead;
va_list arglist;
va_start(arglist,lpFormat);
dwWritten = (DWORD) wvsprintf(cOutput,lpFormat,arglist);
va_end(arglist);
#if defined _UNICODE
{
// Unicode to byte translation
LPTSTR szTmp = DuplicateString(cOutput);
if (szTmp != NULL)
{
WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,
szTmp, -1,
(LPSTR) cOutput, sizeof(cOutput), NULL, NULL);
free(szTmp);
}
}
#endif
WriteFile(hLogFile,cOutput,dwWritten,&dwRead,NULL);
return;
}
static VOID OutTrace(VOID)
{
enum MEM_MAPPING eMapMode;
LPCTSTR lpszName;
LPTSTR s,d;
TCHAR szBuffer[128];
TCHAR szOpc[8];
DWORD dwNxtAddr,dwOpcAddr;
UINT i;
if (hLogFile != NULL) // log file opened
{
if (bTraceReg) // show regs
{
INT nPos;
nPos = wsprintf(szBuffer,_T("\r\n A=%s"),RegToStr(Chipset.A,16));
nPos += wsprintf(&szBuffer[nPos],_T(" B=%s"),RegToStr(Chipset.B,16));
nPos += wsprintf(&szBuffer[nPos],_T(" C=%s"),RegToStr(Chipset.C,16));
wsprintf(&szBuffer[nPos],_T(" D=%s\r\n"),RegToStr(Chipset.D,16));
PrintTrace(szBuffer);
nPos = wsprintf(szBuffer,_T(" R0=%s"),RegToStr(Chipset.R0,16));
nPos += wsprintf(&szBuffer[nPos],_T(" R1=%s"),RegToStr(Chipset.R1,16));
nPos += wsprintf(&szBuffer[nPos],_T(" R2=%s"),RegToStr(Chipset.R2,16));
wsprintf(&szBuffer[nPos],_T(" R3=%s\r\n"),RegToStr(Chipset.R3,16));
PrintTrace(szBuffer);
PrintTrace(_T(" R4=%s D0=%05X D1=%05X P=%X CY=%d Mode=%c OUT=%03X IN=%04X\r\n"),
RegToStr(Chipset.R4,16),Chipset.d0,Chipset.d1,Chipset.P,Chipset.carry,
Chipset.mode_dec ? _T('D') : _T('H'),Chipset.out,Chipset.in);
PrintTrace(_T(" ST=%s MP=%d SR=%d SB=%d XM=%d IntrEn=%d KeyScan=%d BS=%02X\r\n"),
RegToStr(Chipset.ST,4),
(Chipset.HST & MP) != 0,(Chipset.HST & SR) != 0,(Chipset.HST & SB) != 0,(Chipset.HST & XM) != 0,
Chipset.inte,Chipset.intk,Chipset.Bank_FF & 0x7F);
// hardware stack content
PrintTrace(_T(" Stack="));
for (i = 1; i <= ARRAYSIZEOF(Chipset.rstk); ++i)
{
PrintTrace(_T(" %05X"), Chipset.rstk[(Chipset.rstkp-i)&7]);
}
PrintTrace(_T("\r\n"));
}
if (bTraceMmu) // show MMU
{
TCHAR szSize[8],szAddr[8];
if (!bTraceReg) // no regs
{
PrintTrace(_T("\r\n")); // add separator line
}
wsprintf(szAddr, Chipset.IOCfig ? _T("%05X") : _T("-----"),Chipset.IOBase);
PrintTrace(_T(" I/O=%s"),szAddr);
wsprintf(szSize, Chipset.P0Cfg2 ? _T("%05X") : _T("-----"),(Chipset.P0Size^0xFF)<<12);
wsprintf(szAddr, Chipset.P0Cfig ? _T("%05X") : _T("-----"),Chipset.P0Base<<12);
PrintTrace(_T(" NCE2=%s/%s"),szSize,szAddr);
if (cCurrentRomType=='S')
{
wsprintf(szSize, Chipset.P1Cfg2 ? _T("%05X") : _T("-----"),(Chipset.P1Size^0xFF)<<12);
wsprintf(szAddr, Chipset.P1Cfig ? _T("%05X") : _T("-----"),Chipset.P1Base<<12);
}
else
{
wsprintf(szSize, Chipset.BSCfg2 ? _T("%05X") : _T("-----"),(Chipset.BSSize^0xFF)<<12);
wsprintf(szAddr, Chipset.BSCfig ? _T("%05X") : _T("-----"),Chipset.BSBase<<12);
}
PrintTrace(_T(" CE1=%s/%s"),szSize,szAddr);
if (cCurrentRomType=='S')
{
wsprintf(szSize, Chipset.P2Cfg2 ? _T("%05X") : _T("-----"),(Chipset.P2Size^0xFF)<<12);
wsprintf(szAddr, Chipset.P2Cfig ? _T("%05X") : _T("-----"),Chipset.P2Base<<12);
}
else
{
wsprintf(szSize, Chipset.P1Cfg2 ? _T("%05X") : _T("-----"),(Chipset.P1Size^0xFF)<<12);
wsprintf(szAddr, Chipset.P1Cfig ? _T("%05X") : _T("-----"),Chipset.P1Base<<12);
}
PrintTrace(_T(" CE2=%s/%s"),szSize,szAddr);
if (cCurrentRomType=='S')
{
wsprintf(szSize, Chipset.BSCfg2 ? _T("%05X") : _T("-----"),(Chipset.BSSize^0xFF)<<12);
wsprintf(szAddr, Chipset.BSCfig ? _T("%05X") : _T("-----"),Chipset.BSBase<<12);
}
else
{
wsprintf(szSize, Chipset.P2Cfg2 ? _T("%05X") : _T("-----"),(Chipset.P2Size^0xFF)<<12);
wsprintf(szAddr, Chipset.P2Cfig ? _T("%05X") : _T("-----"),Chipset.P2Base<<12);
}
PrintTrace(_T(" NCE3=%s/%s\r\n"),szSize,szAddr);
}
// disassemble line
eMapMode = GetMemMapType(); // get current map mode
SetMemMapType(MEM_MMU); // disassemble in mapped mode
// entry has a name
if (disassembler_symb && (lpszName = RplGetName(Chipset.pc)) != NULL)
{
PrintTrace(_T("=%s\r\n"),lpszName); // print address as label
}
dwNxtAddr = disassemble(Chipset.pc,szBuffer);
// in disassembly replace space characters
// between Opcode and Modifier with one TAB
if ((s = _tcschr(szBuffer,_T(' '))) != NULL)
{
// skip blanks
for (d = s; *d == _T(' '); ++d) { }
if (d == &szBuffer[8]) // on TAB position
{
*s++ = _T('\t'); // replace with TAB
// move the opcode modifier
while ((*s++ = *d++) != 0) { }
}
}
if (bTraceOpc) // show opcode nibbles
{
dwOpcAddr = Chipset.pc; // init address
// show opcode nibbles in a block of 5
for (i = 0; i < 5 && dwOpcAddr < dwNxtAddr; ++i)
{
szOpc[i] = cHex[GetMemNib(&dwOpcAddr)];
}
if (i == 1) // only 1 nibble written
{
szOpc[i++] = _T('\t'); // one additional TAB necessary
}
szOpc[i] = 0; // EOS
PrintTrace(_T("%05lX %s\t%s\r\n"),Chipset.pc,szOpc,szBuffer);
while (dwOpcAddr < dwNxtAddr) // decode rest of opcode
{
// show opcode nibbles in a block of 5
for (i = 0; i < 5 && dwOpcAddr < dwNxtAddr; ++i)
{
szOpc[i] = cHex[GetMemNib(&dwOpcAddr)];
}
szOpc[i] = 0; // EOS
PrintTrace(_T(" %s\r\n"),szOpc);
}
}
else // without opcode nibbles
{
PrintTrace(_T("%05lX\t%s\r\n"),Chipset.pc,szBuffer);
}
SetMemMapType(eMapMode); // switch back to old map mode
}
return;
}
//
// trace settings dialog
//
static BOOL OnBrowseTraceSettings(HWND hDlg)
{
TCHAR szBuffer[MAX_PATH];
OPENFILENAME ofn;
// get current content of file edit box
GetDlgItemText(hDlg,IDC_TRACE_FILE,szBuffer,ARRAYSIZEOF(szBuffer));
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = hDlg;
ofn.lpstrFilter =
_T("Trace Log Files (*.log)\0*.log\0")
_T("All Files (*.*)\0*.*\0");
ofn.lpstrDefExt = _T("log");
ofn.nFilterIndex = 1;
ofn.lpstrFile = szBuffer;
ofn.nMaxFile = ARRAYSIZEOF(szBuffer);
ofn.Flags = OFN_EXPLORER|OFN_HIDEREADONLY|OFN_CREATEPROMPT|OFN_OVERWRITEPROMPT;
if (GetSaveFileName(&ofn))
{
SetDlgItemText(hDlg,IDC_TRACE_FILE,szBuffer);
}
return 0;
}
//
// trace settings
//
static INT_PTR CALLBACK TraceSettings(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
SetDlgItemText(hDlg,IDC_TRACE_FILE,szTraceFilename);
CheckDlgButton(hDlg,(uTraceMode == TRACE_FILE_NEW) ? IDC_TRACE_NEW : IDC_TRACE_APPEND,BST_CHECKED);
CheckDlgButton(hDlg,IDC_TRACE_REGISTER,bTraceReg);
CheckDlgButton(hDlg,IDC_TRACE_MMU,bTraceMmu);
CheckDlgButton(hDlg,IDC_TRACE_OPCODE,bTraceOpc);
return TRUE;
case WM_COMMAND:
switch(LOWORD(wParam))
{
case IDC_TRACE_BROWSE:
return OnBrowseTraceSettings(hDlg);
case IDOK:
// get filename
GetDlgItemText(hDlg,IDC_TRACE_FILE,szTraceFilename,ARRAYSIZEOF(szTraceFilename));
// trace mode
uTraceMode = IsDlgButtonChecked(hDlg,IDC_TRACE_NEW) ? TRACE_FILE_NEW : TRACE_FILE_APPEND;
// trace content
bTraceReg = IsDlgButtonChecked(hDlg,IDC_TRACE_REGISTER);
bTraceMmu = IsDlgButtonChecked(hDlg,IDC_TRACE_MMU);
bTraceOpc = IsDlgButtonChecked(hDlg,IDC_TRACE_OPCODE);
// no break
case IDCANCEL:
EndDialog(hDlg,LOWORD(wParam));
return TRUE;
}
}
return FALSE;
UNREFERENCED_PARAMETER(lParam);
}
static BOOL OnTraceSettings(HWND hDlg)
{
if (DialogBox(hApp, MAKEINTRESOURCE(IDD_TRACE), hDlg, (DLGPROC)TraceSettings) == -1)
AbortMessage(_T("TraceSettings Dialog Box Creation Error !"));
return -1;
}
static BOOL OnTraceEnable(HWND hDlg)
{
OnToggleMenuItem(hDlg,ID_TRACE_ENABLE,&bDbgTrace);
bDbgTrace ? StartTrace() : StopTrace();
EnableMenuItem(GetMenu(hDlg),ID_TRACE_SETTINGS,bDbgTrace ? MF_GRAYED : MF_ENABLED);
return 0;
}

View file

@ -241,7 +241,7 @@ BOOL CreateMainBitmap(LPCTSTR szFilename)
_ASSERT(hWindowDC != NULL);
VERIFY(hMainDC = CreateCompatibleDC(hWindowDC));
if (hMainDC == NULL) return FALSE; // quit if failed
hMainBitmap = LoadBitmapFile(szFilename);
hMainBitmap = LoadBitmapFile(szFilename,TRUE);
if (hMainBitmap == NULL)
{
DeleteDC(hMainDC);
@ -276,7 +276,7 @@ BOOL CreateAnnunBitmap(LPCTSTR szFilename)
_ASSERT(hWindowDC != NULL);
VERIFY(hAnnunDC = CreateCompatibleDC(hWindowDC));
if (hAnnunDC == NULL) return FALSE; // quit if failed
hAnnunBitmap = LoadBitmapFile(szFilename);
hAnnunBitmap = LoadBitmapFile(szFilename,FALSE);
if (hAnnunBitmap == NULL)
{
DeleteDC(hAnnunDC);

View file

@ -13,7 +13,7 @@
#include "kml.h"
#include "debugger.h"
#define VERSION "1.61"
#define VERSION "1.62"
#ifdef _DEBUG
LPCTSTR szNoTitle = _T("Emu48 ")_T(VERSION)_T(" Debug");
@ -41,6 +41,7 @@ static const LPCTSTR szLicence =
static BOOL bOwnCursor = FALSE;
static BOOL bTitleBar = TRUE;
static BOOL bMouseButton = FALSE;
CRITICAL_SECTION csGDILock; // critical section for hWindowDC
@ -1776,28 +1777,19 @@ static VOID OnContextMenu(LPARAM lParam)
return;
}
static BOOL OnNcHitTest(LPARAM lParam)
{
if (!bTitleBar || bClientWinMove) // no title bar or window movement over client enabled
{
POINT pt;
POINTSTOPOINT(pt,MAKEPOINTS(lParam)); // mouse position
VERIFY(ScreenToClient(hWnd,&pt)); // convert mouse into client position
if (pt.y >= 0) // client area
{
// hit area not over a button
return !MouseIsButton(pt.x,pt.y);
}
}
return FALSE;
}
static LRESULT OnLButtonDown(UINT nFlags, WORD x, WORD y)
{
if (nMacroState == MACRO_PLAY) return 0; // playing macro
if (nState == SM_RUN) MouseButtonDownAt(nFlags, x,y);
bMouseButton = MouseIsButton(x,y); // mouse is over button hit area
// no title bar or window movement over client enabled and hit area not over a button
if ((!bTitleBar || bClientWinMove) && nFlags == MK_LBUTTON && !bMouseButton)
{
// move window while holding the left mouse button
PostMessage(hWnd,WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(x,y));
}
return 0;
}
@ -1805,6 +1797,7 @@ static LRESULT OnLButtonUp(UINT nFlags, WORD x, WORD y)
{
if (nMacroState == MACRO_PLAY) return 0; // playing macro
if (nState == SM_RUN) MouseButtonUpAt(nFlags, x,y);
bMouseButton = FALSE;
return 0;
}
@ -1840,6 +1833,7 @@ static LRESULT OnKeyDown(int nVirtKey, LPARAM lKeyData)
// call RunKey() only once (suppress autorepeat feature)
if (nState == SM_RUN && (lKeyData & 0x40000000) == 0)
RunKey((BYTE)nVirtKey, TRUE);
bMouseButton = FALSE;
return 0;
}
@ -1983,12 +1977,18 @@ LRESULT CALLBACK MainWndProc(HWND hWindow, UINT uMsg, WPARAM wParam, LPARAM lPar
case SC_CLOSE: return OnFileExit();
}
break;
case WM_CONTEXTMENU:
case WM_NCRBUTTONUP:
OnContextMenu(lParam);
case WM_ENDSESSION:
// session will end and any auto saving is enabled
if (wParam == TRUE && (bAutoSave || bAutoSaveOnExit))
{
SwitchToState(SM_INVALID); // hold emulation thread
if (szCurrentFilename[0] != 0) // has current filename
SaveDocument();
SwitchToState(SM_RUN); // on cancel restart emulation thread
}
break;
case WM_NCHITTEST:
if (OnNcHitTest(lParam)) return HTCAPTION;
case WM_CONTEXTMENU:
if (!bMouseButton) OnContextMenu(lParam);
break;
case WM_RBUTTONDOWN:
case WM_LBUTTONDOWN: return OnLButtonDown((UINT) wParam, LOWORD(lParam), HIWORD(lParam));

View file

@ -220,7 +220,7 @@ SOURCE=.\kml.c
# Begin Source File
SOURCE=.\lodepng.c
# ADD CPP /D "LODEPNG_NO_COMPILE_ENCODER" /D "LODEPNG_NO_COMPILE_DISK" /D "LODEPNG_NO_COMPILE_ERROR_TEXT" /D "LODEPNG_NO_COMPILE_CPP"
# ADD CPP /D "LODEPNG_NO_COMPILE_ENCODER" /D "LODEPNG_NO_COMPILE_DISK" /D "LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS" /D "LODEPNG_NO_COMPILE_ERROR_TEXT" /D "LODEPNG_NO_COMPILE_CPP"
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File

View file

@ -215,6 +215,7 @@ extern DWORD *pdwInstrArray;
extern WORD wInstrSize;
extern WORD wInstrWp;
extern WORD wInstrRp;
extern VOID (*fnOutTrace)(VOID);
extern VOID SuspendDebugger(VOID);
extern VOID ResumeDebugger(VOID);
extern VOID CheckSerial(VOID);
@ -260,6 +261,7 @@ extern BOOL bBackup;
extern VOID SetWindowLocation(HWND hWnd,INT nPosX,INT nPosY);
extern DWORD GetCutPathName(LPCTSTR szFileName,LPTSTR szBuffer,DWORD dwBufferLength,INT nCutLength);
extern VOID SetWindowPathTitle(LPCTSTR szFileName);
extern BOOL CheckForBeepPatch(VOID);
extern VOID UpdatePatches(BOOL bPatch);
extern BOOL PatchRom(LPCTSTR szFilename);
extern BOOL CrcRom(WORD *pwChk);
@ -285,7 +287,7 @@ extern BOOL LoadObject(LPCTSTR szFilename);
extern BOOL SaveObject(LPCTSTR szFilename);
extern BOOL LoadIconFromFile(LPCTSTR szFilename);
extern VOID LoadIconDefault(VOID);
extern HBITMAP LoadBitmapFile(LPCTSTR szFilename);
extern HBITMAP LoadBitmapFile(LPCTSTR szFilename,BOOL bPalette);
extern HRGN CreateRgnFromBitmap(HBITMAP hBmp,COLORREF color,DWORD dwTol);
// Timer.c

View file

@ -206,6 +206,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 109
END
IDD_TRACE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 240
TOPMARGIN, 7
BOTTOMMARGIN, 106
END
END
#endif // APSTUDIO_INVOKED
@ -295,7 +303,7 @@ 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 © 2018 Christoph Gießelink && Sébastien Carlier",
LTEXT "Copyright © 2019 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 |
@ -654,6 +662,30 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,122,95,50,14
END
IDD_TRACE DIALOG DISCARDABLE 0, 0, 247, 113
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Trace Settings"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Log File:",IDC_STATIC,7,13,28,8
EDITTEXT IDC_TRACE_FILE,39,11,180,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_TRACE_BROWSE,220,11,20,12
CONTROL "&New",IDC_TRACE_NEW,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,16,49,41,10
CONTROL "&Append",IDC_TRACE_APPEND,"Button",BS_AUTORADIOBUTTON,
16,64,41,10
GROUPBOX "File Mode",IDC_STATIC,7,32,113,53
CONTROL "&Register",IDC_TRACE_REGISTER,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,45,43,10
CONTROL "&MMU",IDC_TRACE_MMU,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,57,43,10
CONTROL "&Opcode",IDC_TRACE_OPCODE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,69,43,10
GROUPBOX "Logging",IDC_STATIC,127,32,113,53
DEFPUSHBUTTON "OK",IDOK,62,92,50,14
PUSHBUTTON "Cancel",IDCANCEL,135,92,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
@ -691,8 +723,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,1,0
PRODUCTVERSION 1,6,1,0
FILEVERSION 1,6,2,0
PRODUCTVERSION 1,6,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -709,12 +741,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 6, 1, 0\0"
VALUE "FileVersion", "1, 6, 2, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2018\0"
VALUE "LegalCopyright", "Copyright © 2019\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 6, 1, 0\0"
VALUE "ProductVersion", "1, 6, 2, 0\0"
END
END
BLOCK "VarFileInfo"
@ -896,6 +928,11 @@ BEGIN
BEGIN
MENUITEM "&Step Over Interrupts", ID_INTR_STEPOVERINT
END
POPUP "&Trace"
BEGIN
MENUITEM "&Settings...", ID_TRACE_SETTINGS
MENUITEM "&Enable", ID_TRACE_ENABLE
END
POPUP "&Info"
BEGIN
MENUITEM "&Last Instructions...", ID_INFO_LASTINSTRUCTIONS

View file

@ -55,6 +55,8 @@ WORD wInstrSize = 256; // size of last instruction array
WORD wInstrWp; // write pointer of instruction array
WORD wInstrRp; // read pointer of instruction array
VOID (*fnOutTrace)(VOID) = NULL; // callback function for file trace
static INT nDbgRplBreak = BN_ASM; // flag for RPL breakpoint detection
static INT nDbgOldState = DBG_OFF; // old state of debugger for suspend/resume
@ -95,6 +97,10 @@ static __inline VOID Debugger(VOID) // debugger part
UpdateDbgCycleCounter(); // update 64 bit cpu cycle counter
SaveInstrAddr(Chipset.pc); // save pc in last instruction buffer
if (fnOutTrace != NULL) // has a trace function
{
fnOutTrace(); // write file trace
}
nDbgRplBreak = BN_ASM; // notify ASM breakpoint

View file

@ -192,6 +192,71 @@ VOID SetWindowPathTitle(LPCTSTR szFileName)
//################
//#
//# BEEP Patch check
//#
//################
BOOL CheckForBeepPatch(VOID)
{
typedef struct beeppatch
{
const DWORD dwAddress; // patch address
const BYTE byPattern[4]; // patch pattern
} BEEPPATCH, *PBEEPPATCH;
// known beep patches
const BEEPPATCH s38[] = { { 0x017D0, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s39[] = { { 0x017BC, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s48[] = { { 0x017A6, { 0x8, 0x1, 0xB, 0x1 } } };
const BEEPPATCH s49[] = { { 0x4157A, { 0x8, 0x1, 0xB, 0x1 } }, // 1.18/1.19-5/1.19-6
{ 0x41609, { 0x8, 0x1, 0xB, 0x1 } } }; // 1.24/2.01/2.09
const BEEPPATCH *psData;
UINT nDataItems;
BOOL bMatch;
switch (cCurrentRomType)
{
case '6':
case 'A': // HP38G
psData = s38;
nDataItems = ARRAYSIZEOF(s38);
break;
case 'E': // HP39/40G
psData = s39;
nDataItems = ARRAYSIZEOF(s39);
break;
case 'S': // HP48SX
case 'G': // HP48GX
psData = s48;
nDataItems = ARRAYSIZEOF(s48);
break;
case 'X': // HP49G
psData = s49;
nDataItems = ARRAYSIZEOF(s49);
break;
default:
psData = NULL;
nDataItems = 0;
}
// check if one data set match
for (bMatch = FALSE; !bMatch && nDataItems > 0; --nDataItems)
{
_ASSERT(pbyRom != NULL && psData != NULL);
// pattern matching?
bMatch = (psData->dwAddress + ARRAYSIZEOF(psData->byPattern) < dwRomSize)
&& (memcmp(&pbyRom[psData->dwAddress],psData->byPattern,ARRAYSIZEOF(psData->byPattern))) == 0;
++psData; // next data set
}
return bMatch;
}
//################
//#
//# Patch
@ -788,6 +853,7 @@ BOOL NewDocument(VOID)
if (!DisplayChooseKml(0)) goto restore;
if (!InitKML(szCurrentKml,FALSE)) goto restore;
Chipset.type = cCurrentRomType;
CrcRom(&Chipset.wRomCrc); // save fingerprint of loaded ROM
if (Chipset.type == '6' || Chipset.type == 'A') // HP38G
{
@ -1731,7 +1797,7 @@ static HPALETTE CreateBIPalette(BITMAPINFOHEADER CONST *lpbi)
return hpal;
}
static HBITMAP DecodeBmp(LPBMPFILE pBmp)
static HBITMAP DecodeBmp(LPBMPFILE pBmp,BOOL bPalette)
{
LPBITMAPFILEHEADER pBmfh;
LPBITMAPINFO pBmi;
@ -1781,7 +1847,7 @@ static HBITMAP DecodeBmp(LPBMPFILE pBmp)
pBmi, DIB_RGB_COLORS));
if (hBitmap == NULL) return NULL;
if (hPalette == NULL)
if (bPalette && hPalette == NULL)
{
hPalette = CreateBIPalette(&pBmi->bmiHeader);
// save old palette
@ -1812,7 +1878,7 @@ static BOOL ReadGifWord(LPBMPFILE pGif, INT *n)
return FALSE;
}
static HBITMAP DecodeGif(LPBMPFILE pBmp,DWORD *pdwTransparentColor)
static HBITMAP DecodeGif(LPBMPFILE pBmp,DWORD *pdwTransparentColor,BOOL bPalette)
{
// this implementation base on the GIF image file
// decoder engine of Free42 (c) by Thomas Okken
@ -2306,7 +2372,7 @@ static HBITMAP DecodeGif(LPBMPFILE pBmp,DWORD *pdwTransparentColor)
_ASSERT(bDecoding == FALSE); // decoding successful
// normal decoding exit
if (hPalette == NULL)
if (bPalette && hPalette == NULL)
{
hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi);
// save old palette
@ -2323,7 +2389,7 @@ quit:
return hBitmap;
}
static HBITMAP DecodePng(LPBMPFILE pBmp)
static HBITMAP DecodePng(LPBMPFILE pBmp,BOOL bPalette)
{
// this implementation use the PNG image file decoder
// engine of Copyright (c) 2005-2018 Lode Vandevenne
@ -2348,7 +2414,7 @@ static HBITMAP DecodePng(LPBMPFILE pBmp)
if (uError) goto quit;
ZeroMemory(&bmi,sizeof(bmi)); // init bitmap info
bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi.bmiHeader.biWidth = (LONG) uWidth;
bmi.bmiHeader.biHeight = (LONG) uHeight;
bmi.bmiHeader.biPlanes = 1;
@ -2386,7 +2452,7 @@ static HBITMAP DecodePng(LPBMPFILE pBmp)
_ASSERT((DWORD) (pbyLine - pbyPixels) <= bmi.bmiHeader.biSizeImage);
}
if (hPalette == NULL)
if (bPalette && hPalette == NULL)
{
hPalette = CreateBIPalette((PBITMAPINFOHEADER) &bmi);
// save old palette
@ -2408,7 +2474,7 @@ quit:
return hBitmap;
}
HBITMAP LoadBitmapFile(LPCTSTR szFilename)
HBITMAP LoadBitmapFile(LPCTSTR szFilename,BOOL bPalette)
{
HANDLE hFile;
HANDLE hMap;
@ -2439,7 +2505,7 @@ HBITMAP LoadBitmapFile(LPCTSTR szFilename)
// check for bitmap file header "BM"
if (Bmp.dwFileSize >= 2 && *(WORD *) Bmp.pbyFile == 0x4D42)
{
hBitmap = DecodeBmp(&Bmp);
hBitmap = DecodeBmp(&Bmp,bPalette);
break;
}
@ -2447,14 +2513,14 @@ HBITMAP LoadBitmapFile(LPCTSTR szFilename)
if ( Bmp.dwFileSize >= 6
&& (memcmp(Bmp.pbyFile,"GIF87a",6) == 0 || memcmp(Bmp.pbyFile,"GIF89a",6) == 0))
{
hBitmap = DecodeGif(&Bmp,&dwTColor);
hBitmap = DecodeGif(&Bmp,&dwTColor,bPalette);
break;
}
// check for PNG file header
if (Bmp.dwFileSize >= 8 && memcmp(Bmp.pbyFile,"\x89PNG\r\n\x1a\n",8) == 0)
{
hBitmap = DecodePng(&Bmp);
hBitmap = DecodePng(&Bmp,bPalette);
break;
}

View file

@ -895,6 +895,8 @@ static KmlLine* ParseLines(BOOL bInclude)
if (eToken == TOK_INCLUDE)
{
LPTSTR szFilename;
UINT nLexLineKml;
eToken = Lex(LEX_PARAM); // get include parameter in 'szLexString'
if (eToken != TOK_STRING) // not a string (token don't begin with ")
{
@ -903,6 +905,7 @@ static KmlLine* ParseLines(BOOL bInclude)
}
szFilename = szLexString; // save pointer to allocated memory
szLexString = NULL;
nLexLineKml = nLexLine; // save line number
eToken = Lex(LEX_PARAM); // decode argument
if (eToken != TOK_EOL)
{
@ -925,7 +928,10 @@ static KmlLine* ParseLines(BOOL bInclude)
}
free(szFilename); // free filename string
if (pLine == NULL) // parsing error
{
nLexLine = nLexLineKml; // restore line number
goto abort;
}
while (pLine->pNext) pLine=pLine->pNext;
continue;
}
@ -1096,6 +1102,8 @@ static KmlBlock* ParseBlocks(BOOL bInclude, BOOL bEndTokenEn)
if (eToken == TOK_INCLUDE)
{
LPTSTR szFilename;
UINT nLexLineKml;
eToken = Lex(LEX_PARAM); // get include parameter in 'szLexString'
if (eToken != TOK_STRING) // not a string (token don't begin with ")
{
@ -1104,6 +1112,7 @@ static KmlBlock* ParseBlocks(BOOL bInclude, BOOL bEndTokenEn)
}
szFilename = szLexString; // save pointer to allocated memory
szLexString = NULL;
nLexLineKml = nLexLine; // save line number
eToken = Lex(LEX_PARAM); // decode argument
if (eToken != TOK_EOL)
{
@ -1117,7 +1126,10 @@ static KmlBlock* ParseBlocks(BOOL bInclude, BOOL bEndTokenEn)
pBlock = pFirst = IncludeBlocks(bInclude,szFilename);
free(szFilename); // free filename string
if (pBlock == NULL) // parsing error
{
nLexLine = nLexLineKml; // restore line number
goto abort;
}
while (pBlock->pNext) pBlock = pBlock->pNext;
continue;
}
@ -2614,9 +2626,14 @@ BOOL InitKML(LPCTSTR szFilename, BOOL bNoLog)
if (!CrcRom(&wRomCrc)) // build patched ROM fingerprint and check for unpacked data
{
AddToLog(_T("Error, packed ROM image detected."));
UnmapRom(); // free memory
goto quit;
}
if (CheckForBeepPatch()) // check if ROM contain beep patches
{
AddToLog(_T("Warning, ROM beep patch detected. Remove beep patches please."));
bNoLog = FALSE;
bAlwaysDisplayLog = TRUE;
}
ResizeMainBitmap(nScaleMul,nScaleDiv); // resize main picture
CreateLcdBitmap();

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
/*
LodePNG version 20180611
LodePNG version 20190914
Copyright (c) 2005-2018 Lode Vandevenne
Copyright (c) 2005-2019 Lode Vandevenne
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -44,36 +44,44 @@ the custom_zlib field of the compress and decompress settings*/
#ifndef LODEPNG_NO_COMPILE_ZLIB
#define LODEPNG_COMPILE_ZLIB
#endif
/*png encoder and png decoder*/
#ifndef LODEPNG_NO_COMPILE_PNG
#define LODEPNG_COMPILE_PNG
#endif
/*deflate&zlib decoder and png decoder*/
#ifndef LODEPNG_NO_COMPILE_DECODER
#define LODEPNG_COMPILE_DECODER
#endif
/*deflate&zlib encoder and png encoder*/
#ifndef LODEPNG_NO_COMPILE_ENCODER
#define LODEPNG_COMPILE_ENCODER
#endif
/*the optional built in harddisk file loading and saving functions*/
#ifndef LODEPNG_NO_COMPILE_DISK
#define LODEPNG_COMPILE_DISK
#endif
/*support for chunks other than IHDR, IDAT, PLTE, tRNS, IEND: ancillary and unknown chunks*/
#ifndef LODEPNG_NO_COMPILE_ANCILLARY_CHUNKS
#define LODEPNG_COMPILE_ANCILLARY_CHUNKS
#endif
/*ability to convert error numerical codes to English text string*/
#ifndef LODEPNG_NO_COMPILE_ERROR_TEXT
#define LODEPNG_COMPILE_ERROR_TEXT
#endif
/*Compile the default allocators (C's free, malloc and realloc). If you disable this,
you can define the functions lodepng_free, lodepng_malloc and lodepng_realloc in your
source files with custom allocators.*/
#ifndef LODEPNG_NO_COMPILE_ALLOCATORS
#define LODEPNG_COMPILE_ALLOCATORS
#endif
/*compile the C++ version (you can disable the C++ wrapper here even when compiling for C++)*/
#ifdef __cplusplus
#ifndef LODEPNG_NO_COMPILE_CPP
@ -87,14 +95,19 @@ source files with custom allocators.*/
#endif /*LODEPNG_COMPILE_CPP*/
#ifdef LODEPNG_COMPILE_PNG
/*The PNG color types (also used for raw).*/
typedef enum LodePNGColorType
{
LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/
/*The PNG color types (also used for raw image).*/
typedef enum LodePNGColorType {
LCT_GREY = 0, /*grayscale: 1,2,4,8,16 bit*/
LCT_RGB = 2, /*RGB: 8,16 bit*/
LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/
LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/
LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/
LCT_GREY_ALPHA = 4, /*grayscale with alpha: 8,16 bit*/
LCT_RGBA = 6, /*RGB with alpha: 8,16 bit*/
/*LCT_MAX_OCTET_VALUE lets the compiler allow this enum to represent any invalid
byte value from 0 to 255 that could be present in an invalid PNG file header. Do
not use, compare with or set the name LCT_MAX_OCTET_VALUE, instead either use
the valid color type names above, or numeric values like 1 or 7 when checking for
particular disallowed color type byte values, or cast to integer to print it.*/
LCT_MAX_OCTET_VALUE = 255
} LodePNGColorType;
#ifdef LODEPNG_COMPILE_DECODER
@ -196,8 +209,7 @@ unsigned lodepng_encode24_file(const char* filename,
#ifdef LODEPNG_COMPILE_CPP
namespace lodepng
{
namespace lodepng {
#ifdef LODEPNG_COMPILE_DECODER
/*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype
is the format to output the pixels to. Default is RGBA 8-bit per channel.*/
@ -253,18 +265,17 @@ const char* lodepng_error_text(unsigned code);
#ifdef LODEPNG_COMPILE_DECODER
/*Settings for zlib decompression*/
typedef struct LodePNGDecompressSettings LodePNGDecompressSettings;
struct LodePNGDecompressSettings
{
/* Check LodePNGDecoderSettings for more ignorable errors */
struct LodePNGDecompressSettings {
/* Check LodePNGDecoderSettings for more ignorable errors such as ignore_crc */
unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/
unsigned ignore_nlen; /*ignore complement of len checksum in uncompressed blocks*/
/*use custom zlib decoder instead of built in one (default: null)*/
unsigned (*custom_zlib)(unsigned char**, size_t*,
const unsigned char*, size_t,
const LodePNGDecompressSettings*);
/*use custom deflate decoder instead of built in one (default: null)
if custom_zlib is used, custom_deflate is ignored since only the built in
zlib function will call custom_deflate*/
if custom_zlib is not null, custom_inflate is ignored (the zlib format uses deflate)*/
unsigned (*custom_inflate)(unsigned char**, size_t*,
const unsigned char*, size_t,
const LodePNGDecompressSettings*);
@ -282,13 +293,12 @@ Settings for zlib compression. Tweaking these settings tweaks the balance
between speed and compression ratio.
*/
typedef struct LodePNGCompressSettings LodePNGCompressSettings;
struct LodePNGCompressSettings /*deflate = compress*/
{
struct LodePNGCompressSettings /*deflate = compress*/ {
/*LZ77 related settings*/
unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/
unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/
unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/
unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
unsigned minmatch; /*minimum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/
unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/
unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/
@ -316,8 +326,7 @@ Color mode of an image. Contains all information required to decode the pixel
bits to RGBA colors. This information is the same as used in the PNG file
format, and is used both for PNG and raw image data in LodePNG.
*/
typedef struct LodePNGColorMode
{
typedef struct LodePNGColorMode {
/*header (IHDR)*/
LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/
unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/
@ -342,7 +351,7 @@ typedef struct LodePNGColorMode
transparent color key (tRNS)
This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit.
For greyscale PNGs, r, g and b will all 3 be set to the same.
For grayscale PNGs, r, g and b will all 3 be set to the same.
When decoding, by default you can ignore this information, since LodePNG sets
pixels with this key to transparent already in the raw RGBA output.
@ -350,7 +359,7 @@ typedef struct LodePNGColorMode
The color key is only supported for color types 0 and 2.
*/
unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/
unsigned key_r; /*red/greyscale component of color key*/
unsigned key_r; /*red/grayscale component of color key*/
unsigned key_g; /*green component of color key*/
unsigned key_b; /*blue component of color key*/
} LodePNGColorMode;
@ -360,6 +369,8 @@ void lodepng_color_mode_init(LodePNGColorMode* info);
void lodepng_color_mode_cleanup(LodePNGColorMode* info);
/*return value is error code (0 means no error)*/
unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source);
/* Makes a temporary LodePNGColorMode that does not need cleanup (no palette) */
LodePNGColorMode lodepng_color_mode_make(LodePNGColorType colortype, unsigned bitdepth);
void lodepng_palette_clear(LodePNGColorMode* info);
/*add 1 color to the palette*/
@ -371,7 +382,7 @@ unsigned lodepng_get_bpp(const LodePNGColorMode* info);
/*get the amount of color channels used, based on colortype in the struct.
If a palette is used, it counts as 1 channel.*/
unsigned lodepng_get_channels(const LodePNGColorMode* info);
/*is it a greyscale type? (only colortype 0 or 4)*/
/*is it a grayscale type? (only colortype 0 or 4)*/
unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info);
/*has it got an alpha channel? (only colortype 2 or 6)*/
unsigned lodepng_is_alpha_type(const LodePNGColorMode* info);
@ -393,8 +404,7 @@ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* colo
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*The information of a Time chunk in PNG.*/
typedef struct LodePNGTime
{
typedef struct LodePNGTime {
unsigned year; /*2 bytes used (0-65535)*/
unsigned month; /*1-12*/
unsigned day; /*1-31*/
@ -405,8 +415,7 @@ typedef struct LodePNGTime
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*Information about the PNG image, except pixels, width and height.*/
typedef struct LodePNGInfo
{
typedef struct LodePNGInfo {
/*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/
unsigned compression_method;/*compression method of the original file. Always 0.*/
unsigned filter_method; /*filter method of the original file*/
@ -415,18 +424,30 @@ typedef struct LodePNGInfo
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
/*
suggested background color chunk (bKGD)
This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit.
Suggested background color chunk (bKGD)
For greyscale PNGs, r, g and b will all 3 be set to the same. When encoding
the encoder writes the red one. For palette PNGs: When decoding, the RGB value
will be stored, not a palette index. But when encoding, specify the index of
the palette in background_r, the other two are then ignored.
This uses the same color mode and bit depth as the PNG (except no alpha channel),
with values truncated to the bit depth in the unsigned integer.
The decoder does not use this background color to edit the color of pixels.
For grayscale and palette PNGs, the value is stored in background_r. The values
in background_g and background_b are then unused.
So when decoding, you may get these in a different color mode than the one you requested
for the raw pixels.
When encoding with auto_convert, you must use the color model defined in info_png.color for
these values. The encoder normally ignores info_png.color when auto_convert is on, but will
use it to interpret these values (and convert copies of them to its chosen color model).
When encoding, avoid setting this to an expensive color, such as a non-gray value
when the image is gray, or the compression will be worse since it will be forced to
write the PNG with a more expensive color mode (when auto_convert is on).
The decoder does not use this background color to edit the color of pixels. This is a
completely optional metadata feature.
*/
unsigned background_defined; /*is a suggested background color given?*/
unsigned background_r; /*red component of suggested background color*/
unsigned background_r; /*red/gray/palette component of suggested background color*/
unsigned background_g; /*green component of suggested background color*/
unsigned background_b; /*blue component of suggested background color*/
@ -437,6 +458,10 @@ typedef struct LodePNGInfo
text_strings, while text_keys are keywords that give a short description what
the actual text represents, e.g. Title, Author, Description, or anything else.
All the string fields below including keys, names and language tags are null terminated.
The PNG specification uses null characters for the keys, names and tags, and forbids null
characters to appear in the main text which is why we can use null termination everywhere here.
A keyword is minimum 1 character and maximum 79 characters long. It's
discouraged to use a single line length longer than 79 characters for texts.
@ -469,11 +494,86 @@ typedef struct LodePNGInfo
unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/
/*
unknown chunks
There are 3 buffers, one for each position in the PNG where unknown chunks can appear
each buffer contains all unknown chunks for that position consecutively
The 3 buffers are the unknown chunks between certain critical chunks:
0: IHDR-PLTE, 1: PLTE-IDAT, 2: IDAT-IEND
Color profile related chunks: gAMA, cHRM, sRGB, iCPP
LodePNG does not apply any color conversions on pixels in the encoder or decoder and does not interpret these color
profile values. It merely passes on the information. If you wish to use color profiles and convert colors, please
use these values with a color management library.
See the PNG, ICC and sRGB specifications for more information about the meaning of these values.
*/
/* gAMA chunk: optional, overridden by sRGB or iCCP if those are present. */
unsigned gama_defined; /* Whether a gAMA chunk is present (0 = not present, 1 = present). */
unsigned gama_gamma; /* Gamma exponent times 100000 */
/* cHRM chunk: optional, overridden by sRGB or iCCP if those are present. */
unsigned chrm_defined; /* Whether a cHRM chunk is present (0 = not present, 1 = present). */
unsigned chrm_white_x; /* White Point x times 100000 */
unsigned chrm_white_y; /* White Point y times 100000 */
unsigned chrm_red_x; /* Red x times 100000 */
unsigned chrm_red_y; /* Red y times 100000 */
unsigned chrm_green_x; /* Green x times 100000 */
unsigned chrm_green_y; /* Green y times 100000 */
unsigned chrm_blue_x; /* Blue x times 100000 */
unsigned chrm_blue_y; /* Blue y times 100000 */
/*
sRGB chunk: optional. May not appear at the same time as iCCP.
If gAMA is also present gAMA must contain value 45455.
If cHRM is also present cHRM must contain respectively 31270,32900,64000,33000,30000,60000,15000,6000.
*/
unsigned srgb_defined; /* Whether an sRGB chunk is present (0 = not present, 1 = present). */
unsigned srgb_intent; /* Rendering intent: 0=perceptual, 1=rel. colorimetric, 2=saturation, 3=abs. colorimetric */
/*
iCCP chunk: optional. May not appear at the same time as sRGB.
LodePNG does not parse or use the ICC profile (except its color space header field for an edge case), a
separate library to handle the ICC data (not included in LodePNG) format is needed to use it for color
management and conversions.
For encoding, if iCCP is present, gAMA and cHRM are recommended to be added as well with values that match the ICC
profile as closely as possible, if you wish to do this you should provide the correct values for gAMA and cHRM and
enable their '_defined' flags since LodePNG will not automatically compute them from the ICC profile.
For encoding, the ICC profile is required by the PNG specification to be an "RGB" profile for non-gray
PNG color types and a "GRAY" profile for gray PNG color types. If you disable auto_convert, you must ensure
the ICC profile type matches your requested color type, else the encoder gives an error. If auto_convert is
enabled (the default), and the ICC profile is not a good match for the pixel data, this will result in an encoder
error if the pixel data has non-gray pixels for a GRAY profile, or a silent less-optimal compression of the pixel
data if the pixels could be encoded as grayscale but the ICC profile is RGB.
To avoid this do not set an ICC profile in the image unless there is a good reason for it, and when doing so
make sure you compute it carefully to avoid the above problems.
*/
unsigned iccp_defined; /* Whether an iCCP chunk is present (0 = not present, 1 = present). */
char* iccp_name; /* Null terminated string with profile name, 1-79 bytes */
/*
The ICC profile in iccp_profile_size bytes.
Don't allocate this buffer yourself. Use the init/cleanup functions
correctly and use lodepng_set_icc and lodepng_clear_icc.
*/
unsigned char* iccp_profile;
unsigned iccp_profile_size; /* The size of iccp_profile in bytes */
/* End of color profile related chunks */
/*
unknown chunks: chunks not known by LodePNG, passed on byte for byte.
There are 3 buffers, one for each position in the PNG where unknown chunks can appear.
Each buffer contains all unknown chunks for that position consecutively.
The 3 positions are:
0: between IHDR and PLTE, 1: between PLTE and IDAT, 2: between IDAT and IEND.
For encoding, do not store critical chunks or known chunks that are enabled with a "_defined" flag
above in here, since the encoder will blindly follow this and could then encode an invalid PNG file
(such as one with two IHDR chunks or the disallowed combination of sRGB with iCCP). But do use
this if you wish to store an ancillary chunk that is not supported by LodePNG (such as sPLT or hIST),
or any non-standard PNG chunk.
Do not allocate or traverse this data yourself. Use the chunk traversing functions declared
later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct.
*/
@ -489,12 +589,16 @@ void lodepng_info_cleanup(LodePNGInfo* info);
unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source);
#ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/
void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag,
const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/
void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/
/*replaces if exists*/
unsigned lodepng_set_icc(LodePNGInfo* info, const char* name, const unsigned char* profile, unsigned profile_size);
void lodepng_clear_icc(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/
#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/
/*
@ -517,14 +621,17 @@ unsigned lodepng_convert(unsigned char* out, const unsigned char* in,
Settings for the decoder. This contains settings for the PNG and the Zlib
decoder, but not the Info settings from the Info structs.
*/
typedef struct LodePNGDecoderSettings
{
typedef struct LodePNGDecoderSettings {
LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/
/* Check LodePNGDecompressSettings for more ignorable errors */
/* Check LodePNGDecompressSettings for more ignorable errors such as ignore_adler32 */
unsigned ignore_crc; /*ignore CRC checksums*/
unsigned ignore_critical; /*ignore unknown critical chunks*/
unsigned ignore_end; /*ignore issues at end of file if possible (missing IEND chunk, too large chunk, ...)*/
/* TODO: make a system involving warnings with levels and a strict mode instead. Other potentially recoverable
errors: srgb rendering intent value, size of content of ancillary chunks, more than 79 characters for some
strings, placement/combination rules for ancillary chunks, crc of unknown chunks, allowed characters
in string keys, etc... */
unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/
@ -540,10 +647,14 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings);
#ifdef LODEPNG_COMPILE_ENCODER
/*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/
typedef enum LodePNGFilterStrategy
{
typedef enum LodePNGFilterStrategy {
/*every filter at zero*/
LFS_ZERO,
LFS_ZERO = 0,
/*every filter at 1, 2, 3 or 4 (paeth), unlike LFS_ZERO not a good choice, but for testing*/
LFS_ONE = 1,
LFS_TWO = 2,
LFS_THREE = 3,
LFS_FOUR = 4,
/*Use filter that gives minimum sum, as described in the official PNG filter heuristic.*/
LFS_MINSUM,
/*Use the filter type that gives smallest Shannon entropy for this scanline. Depending
@ -558,36 +669,45 @@ typedef enum LodePNGFilterStrategy
LFS_PREDEFINED
} LodePNGFilterStrategy;
/*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding.
/*Gives characteristics about the integer RGBA colors of the image (count, alpha channel usage, bit depth, ...),
which helps decide which color model to use for encoding.
Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/
typedef struct LodePNGColorProfile
{
unsigned colored; /*not greyscale*/
typedef struct LodePNGColorStats {
unsigned colored; /*not grayscale*/
unsigned key; /*image is not opaque and color key is possible instead of full alpha*/
unsigned short key_r; /*key values, always as 16-bit, in 8-bit case the byte is duplicated, e.g. 65535 means 255*/
unsigned short key_g;
unsigned short key_b;
unsigned alpha; /*image is not opaque and alpha channel or alpha palette required*/
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/
} LodePNGColorProfile;
unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16 or allow_palette is disabled.*/
unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order, only valid when numcolors is valid*/
unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for grayscale only. 16 if 16-bit per channel required.*/
size_t numpixels;
void lodepng_color_profile_init(LodePNGColorProfile* profile);
/*user settings for computing/using the stats*/
unsigned allow_palette; /*default 1. if 0, disallow choosing palette colortype in auto_choose_color, and don't count numcolors*/
unsigned allow_greyscale; /*default 1. if 0, choose RGB or RGBA even if the image only has gray colors*/
} LodePNGColorStats;
/*Get a LodePNGColorProfile of the image.*/
unsigned lodepng_get_color_profile(LodePNGColorProfile* profile,
void lodepng_color_stats_init(LodePNGColorStats* stats);
/*Get a LodePNGColorStats of the image. The stats must already have been inited.*/
void lodepng_compute_color_stats(LodePNGColorStats* stats,
const unsigned char* image, unsigned w, unsigned h,
const LodePNGColorMode* mode_in);
/*The function LodePNG uses internally to decide the PNG color with auto_convert.
Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/
/*Computes a minimal PNG color model that can contain all colors as indicated by the stats and it settings.
The stats should be computed with lodepng_compute_color_stats.
mode_in is raw color profile of the image the stats were computed on, to copy palette order from when relevant.
Minimal PNG color model means the color type and bit depth that gives smallest amount of bits in the output image,
e.g. gray if only grayscale pixels, palette if less than 256 colors, color key if only single transparent color, ...
LodePNG uses this function internally if auto_convert is enabled (it is by default).
*/
unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out,
const unsigned char* image, unsigned w, unsigned h,
const LodePNGColorMode* mode_in);
const LodePNGColorMode* mode_in,
const LodePNGColorMode* stats);
/*Settings for the encoder.*/
typedef struct LodePNGEncoderSettings
{
typedef struct LodePNGEncoderSettings {
LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/
unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/
@ -623,8 +743,7 @@ void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings);
#if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER)
/*The settings, state and information for extended encoding and decoding.*/
typedef struct LodePNGState
{
typedef struct LodePNGState {
#ifdef LODEPNG_COMPILE_DECODER
LodePNGDecoderSettings decoder; /*the decoding settings*/
#endif /*LODEPNG_COMPILE_DECODER*/
@ -657,7 +776,7 @@ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h,
/*
Read the PNG header, but not the actual data. This returns only the information
that is in the header chunk of the PNG, such as width, height and color type. The
that is in the IHDR chunk of the PNG, such as width, height and color type. The
information is placed in the info_png field of the LodePNGState.
*/
unsigned lodepng_inspect(unsigned* w, unsigned* h,
@ -665,6 +784,20 @@ unsigned lodepng_inspect(unsigned* w, unsigned* h,
const unsigned char* in, size_t insize);
#endif /*LODEPNG_COMPILE_DECODER*/
/*
Reads one metadata chunk (other than IHDR) of the PNG file and outputs what it
read in the state. Returns error code on failure.
Use lodepng_inspect first with a new state, then e.g. lodepng_chunk_find_const
to find the desired chunk type, and if non null use lodepng_inspect_chunk (with
chunk_pointer - start_of_file as pos).
Supports most metadata chunks from the PNG standard (gAMA, bKGD, tEXt, ...).
Ignores unsupported, unknown, non-metadata or IHDR chunks (without error).
Requirements: &in[pos] must point to start of a chunk, must use regular
lodepng_inspect first since format of most other chunks depends on IHDR, and if
there is a PLTE chunk, that one must be inspected before tRNS or bKGD.
*/
unsigned lodepng_inspect_chunk(LodePNGState* state, size_t pos,
const unsigned char* in, size_t insize);
#ifdef LODEPNG_COMPILE_ENCODER
/*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/
@ -678,11 +811,23 @@ The lodepng_chunk functions are normally not needed, except to traverse the
unknown chunks stored in the LodePNGInfo struct, or add new ones to it.
It also allows traversing the chunks of an encoded PNG file yourself.
PNG standard chunk naming conventions:
First byte: uppercase = critical, lowercase = ancillary
Second byte: uppercase = public, lowercase = private
Third byte: must be uppercase
Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
The chunk pointer always points to the beginning of the chunk itself, that is
the first byte of the 4 length bytes.
In the PNG file format, chunks have the following format:
-4 bytes length: length of the data of the chunk in bytes (chunk itself is 12 bytes longer)
-4 bytes chunk type (ASCII a-z,A-Z only, see below)
-length bytes of data (may be 0 bytes if length was 0)
-4 bytes of CRC, computed on chunk name + data
The first chunk starts at the 8th byte of the PNG file, the entire rest of the file
exists out of concatenated chunks with the above format.
PNG standard chunk ASCII naming conventions:
-First byte: uppercase = critical, lowercase = ancillary
-Second byte: uppercase = public, lowercase = private
-Third byte: must be uppercase
-Fourth byte: uppercase = unsafe to copy, lowercase = safe to copy
*/
/*
@ -717,10 +862,24 @@ unsigned lodepng_chunk_check_crc(const unsigned char* chunk);
/*generates the correct CRC from the data and puts it in the last 4 bytes of the chunk*/
void lodepng_chunk_generate_crc(unsigned char* chunk);
/*iterate to next chunks. don't use on IEND chunk, as there is no next chunk then*/
/*
Iterate to next chunks, allows iterating through all chunks of the PNG file.
Input must be at the beginning of a chunk (result of a previous lodepng_chunk_next call,
or the 8th byte of a PNG file which always has the first chunk), or alternatively may
point to the first byte of the PNG file (which is not a chunk but the magic header, the
function will then skip over it and return the first real chunk).
Expects at least 8 readable bytes of memory in the input pointer.
Will output pointer to the start of the next chunk or the end of the file if there
is no more chunk after this. Start this process at the 8th byte of the PNG file.
In a non-corrupt PNG file, the last chunk should have name "IEND".
*/
unsigned char* lodepng_chunk_next(unsigned char* chunk);
const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk);
/*Finds the first chunk with the given type in the range [chunk, end), or returns NULL if not found.*/
unsigned char* lodepng_chunk_find(unsigned char* chunk, const unsigned char* end, const char type[5]);
const unsigned char* lodepng_chunk_find_const(const unsigned char* chunk, const unsigned char* end, const char type[5]);
/*
Appends chunk to the data in out. The given chunk should already have its chunk header.
The out variable and outlength are updated to reflect the new reallocated buffer.
@ -818,11 +977,9 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const
#ifdef LODEPNG_COMPILE_CPP
/* The LodePNG C++ wrapper uses std::vectors instead of manually allocated memory buffers. */
namespace lodepng
{
namespace lodepng {
#ifdef LODEPNG_COMPILE_PNG
class State : public LodePNGState
{
class State : public LodePNGState {
public:
State();
State(const State& other);
@ -894,16 +1051,22 @@ TODO:
[.] test if there are no memory leaks or security exploits - done a lot but needs to be checked often
[.] check compatibility with various compilers - done but needs to be redone for every newer version
[X] converting color to 16-bit per channel types
[ ] read all public PNG chunk types (but never let the color profile and gamma ones touch RGB values)
[X] support color profile chunk types (but never let them touch RGB values by default)
[ ] support all public PNG chunk types (almost done except sBIT, sPLT and hIST)
[ ] make sure encoder generates no chunks with size > (2^31)-1
[ ] partial decoding (stream processing)
[X] let the "isFullyOpaque" function check color keys and transparent palettes too
[X] better name for the variables "codes", "codesD", "codelengthcodes", "clcl" and "lldl"
[ ] don't stop decoding on errors like 69, 57, 58 (make warnings)
[ ] allow treating some errors like warnings, when image is recoverable (e.g. 69, 57, 58)
[ ] make warnings like: oob palette, checksum fail, data after iend, wrong/unknown crit chunk, no null terminator in text, ...
[ ] error messages with line numbers (and version)
[ ] errors in state instead of as return code?
[ ] new errors/warnings like suspiciously big decompressed ztxt or iccp chunk
[ ] let the C++ wrapper catch exceptions coming from the standard library and return LodePNG error codes
[ ] allow user to provide custom color conversion functions, e.g. for premultiplied alpha, padding bits or not, ...
[ ] allow user to give data (void*) to custom allocator
[ ] provide alternatives for C library functions not present on some platforms (memcpy, ...)
[ ] rename "grey" to "gray" everywhere since "color" also uses US spelling (keep "grey" copies for backwards compatibility)
*/
#endif /*LODEPNG_H inclusion guard*/
@ -998,8 +1161,10 @@ The following features are supported by the decoder:
*) zlib decompression (inflate)
*) zlib compression (deflate)
*) CRC32 and ADLER32 checksums
*) colorimetric color profile conversions: currently experimentally available in lodepng_util.cpp only,
plus alternatively ability to pass on chroma/gamma/ICC profile information to other color management system.
*) handling of unknown chunks, allowing making a PNG editor that stores custom and unknown chunks.
*) the following chunks are supported (generated/interpreted) by both encoder and decoder:
*) the following chunks are supported by both encoder and decoder:
IHDR: header information
PLTE: color palette
IDAT: pixel data
@ -1011,6 +1176,10 @@ The following features are supported by the decoder:
bKGD: suggested background color
pHYs: physical dimensions
tIME: modification time
cHRM: RGB chromaticities
gAMA: RGB gamma correction
iCCP: ICC color profile
sRGB: rendering intent
1.2. features not supported
---------------------------
@ -1019,10 +1188,10 @@ The following features are _not_ supported:
*) some features needed to make a conformant PNG-Editor might be still missing.
*) partial loading/stream processing. All data must be available and is processed in one call.
*) The following public chunks are not supported but treated as unknown chunks by LodePNG
cHRM, gAMA, iCCP, sRGB, sBIT, hIST, sPLT
Some of these are not supported on purpose: LodePNG wants to provide the RGB values
stored in the pixels, not values modified by system dependent gamma or color models.
*) The following public chunks are not (yet) supported but treated as unknown chunks by LodePNG:
sBIT
hIST
sPLT
2. C and C++ version
@ -1096,7 +1265,7 @@ LodePNGColorMode info_raw
When decoding, here you can specify which color type you want
the resulting raw image to be. If this is different from the colortype of the
PNG, then the decoder will automatically convert the result. This conversion
always works, except if you want it to convert a color PNG to greyscale or to
always works, except if you want it to convert a color PNG to grayscale or to
a palette with missing colors.
By default, 32-bit color is used for the result.
@ -1192,7 +1361,7 @@ can encode the colors of all pixels without information loss.
An important thing to note about LodePNG, is that the color type of the PNG, and
the color type of the raw image, are completely independent. By default, when
you decode a PNG, you get the result as a raw image in the color type you want,
no matter whether the PNG was encoded with a palette, greyscale or RGBA color.
no matter whether the PNG was encoded with a palette, grayscale or RGBA color.
And if you encode an image, by default LodePNG will automatically choose the PNG
color type that gives good compression based on the values of colors and amount
of colors in the image. It can be configured to let you control it instead as
@ -1200,10 +1369,10 @@ well, though.
To be able to do this, LodePNG does conversions from one color mode to another.
It can convert from almost any color type to any other color type, except the
following conversions: RGB to greyscale is not supported, and converting to a
following conversions: RGB to grayscale is not supported, and converting to a
palette when the palette doesn't have a required color is not supported. This is
not supported on purpose: this is information loss which requires a color
reduction algorithm that is beyong the scope of a PNG encoder (yes, RGB to grey
reduction algorithm that is beyond the scope of a PNG encoder (yes, RGB to gray
is easy, but there are multiple ways if you want to give some channels more
weight).
@ -1224,10 +1393,10 @@ decoding to have another color type, a conversion is done by LodePNG.
The PNG specification gives the following color types:
0: greyscale, bit depths 1, 2, 4, 8, 16
0: grayscale, bit depths 1, 2, 4, 8, 16
2: RGB, bit depths 8 and 16
3: palette, bit depths 1, 2, 4 and 8
4: greyscale with alpha, bit depths 8 and 16
4: grayscale with alpha, bit depths 8 and 16
6: RGBA, bit depths 8 and 16
Bit depth is the amount of bits per pixel per color channel. So the total amount
@ -1276,15 +1445,22 @@ To avoid some confusion:
the raw image correctly before encoding.
-both encoder and decoder use the same color converter.
The function lodepng_convert does the color conversion. It is available in the
interface but normally isn't needed since the encoder and decoder already call
it.
Non supported color conversions:
-color to greyscale: no error is thrown, but the result will look ugly because
only the red channel is taken
-anything to palette when that palette does not have that color in it: in this
case an error is thrown
-color to grayscale when non-gray pixels are present: no error is thrown, but
the result will look ugly because only the red channel is taken (it assumes all
three channels are the same in this case so ignores green and blue). The reason
no error is given is to allow converting from three-channel grayscale images to
one-channel even if there are numerical imprecisions.
-anything to palette when the palette does not have an exact match for a from-color
in it: in this case an error is thrown
Supported color conversions:
-anything to 8-bit RGB, 8-bit RGBA, 16-bit RGB, 16-bit RGBA
-any grey or grey+alpha, to grey or grey+alpha
-any gray or gray+alpha, to gray or gray+alpha
-anything to a palette, as long as the palette has the requested colors in it
-removing alpha channel
-higher to smaller bitdepth, and vice versa
@ -1297,10 +1473,6 @@ false.
as the PNG has, by setting the color_convert setting to false. Settings in
info_raw are then ignored.
The function lodepng_convert does the color conversion. It is available in the
interface but normally isn't needed since the encoder and decoder already call
it.
6.3. padding bits
-----------------
@ -1309,7 +1481,7 @@ have a bit amount that isn't a multiple of 8, then padding bits are used so that
scanline starts at a fresh byte. But that is NOT true for the LodePNG raw input and output.
The raw input image you give to the encoder, and the raw output image you get from the decoder
will NOT have these padding bits, e.g. in the case of a 1-bit image with a width
of 7 pixels, the first pixel of the second scanline will the the 8th bit of the first byte,
of 7 pixels, the first pixel of the second scanline will the 8th bit of the first byte,
not the first bit of a new byte.
6.4. A note about 16-bits per channel and endianness
@ -1426,7 +1598,7 @@ The LodePNGInfo struct contains fields with the unknown chunk in it. It has 3
buffers (each with size) to contain 3 types of unknown chunks:
the ones that come before the PLTE chunk, the ones that come between the PLTE
and the IDAT chunks, and the ones that come after the IDAT chunks.
It's necessary to make the distionction between these 3 cases because the PNG
It's necessary to make the distinction between these 3 cases because the PNG
standard forces to keep the ordering of unknown chunks compared to the critical
chunks, but does not force any other ordering rules.
@ -1509,7 +1681,7 @@ C and C++.
*) Other Compilers
If you encounter problems on any compilers, feel free to let me know and I may
try to fix it if the compiler is modern and standards complient.
try to fix it if the compiler is modern and standards compliant.
10. examples
@ -1524,8 +1696,7 @@ examples can be found on the LodePNG website.
#include "lodepng.h"
#include <iostream>
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
const char* filename = argc > 1 ? argv[1] : "test.png";
//load and decode
@ -1544,8 +1715,7 @@ int main(int argc, char *argv[])
#include "lodepng.h"
int main(int argc, char *argv[])
{
int main(int argc, char *argv[]) {
unsigned error;
unsigned char* image;
size_t width, height;
@ -1614,6 +1784,18 @@ yyyymmdd.
Some changes aren't backwards compatible. Those are indicated with a (!)
symbol.
Not all changes are listed here, the commit history in github lists more:
https://github.com/lvandeve/lodepng
*) 14 aug 2019: around 25% faster decoding thanks to huffman lookup tables.
*) 15 jun 2019 (!): auto_choose_color API changed (for bugfix: don't use palette
if gray ICC profile) and non-ICC LodePNGColorProfile renamed to LodePNGColorStats.
*) 30 dec 2018: code style changes only: removed newlines before opening braces.
*) 10 sep 2018: added way to inspect metadata chunks without full decoding.
*) 19 aug 2018 (!): fixed color mode bKGD is encoded with and made it use
palette index in case of palette.
*) 10 aug 2018 (!): added support for gAMA, cHRM, sRGB and iCCP chunks. This
change is backwards compatible unless you relied on unknown_chunks for those.
*) 11 jun 2018: less restrictive check for pixel size integer overflow
*) 14 jan 2018: allow optionally ignoring a few more recoverable errors
*) 17 sep 2017: fix memory leak for some encoder input error cases
@ -1624,6 +1806,7 @@ symbol.
*) 08 dec 2015: Made load_file function return error if file can't be opened.
*) 24 okt 2015: Bugfix with decoding to palette output.
*) 18 apr 2015: Boundary PM instead of just package-merge for faster encoding.
*) 24 aug 2014: Moved to github
*) 23 aug 2014: Reduced needless memory usage of decoder.
*) 28 jun 2014: Removed fix_png setting, always support palette OOB for
simplicity. Made ColorProfile public.
@ -1766,5 +1949,5 @@ Domain: gmail dot com.
Account: lode dot vandevenne.
Copyright (c) 2005-2018 Lode Vandevenne
Copyright (c) 2005-2019 Lode Vandevenne
*/

View file

@ -33,6 +33,7 @@
#define IDD_DEBUG_MEMSAVE 127
#define IDD_DEBUG_MEMLOAD 128
#define IDD_DEBUG_SETTINGS 129
#define IDD_TRACE 130
#define IDC_REALSPEED 1000
#define IDC_GRAYSCALE 1001
#define IDC_ALWAYSONTOP 1002
@ -169,6 +170,13 @@
#define IDC_MACRO_MANUAL 1133
#define IDC_SOUND_SLIDER 1134
#define IDC_SOUND_DEVICE 1135
#define IDC_TRACE_FILE 1136
#define IDC_TRACE_BROWSE 1137
#define IDC_TRACE_NEW 1138
#define IDC_TRACE_APPEND 1139
#define IDC_TRACE_REGISTER 1140
#define IDC_TRACE_MMU 1141
#define IDC_TRACE_OPCODE 1142
#define ID_FILE_NEW 40001
#define ID_FILE_OPEN 40002
#define ID_FILE_SAVE 40003
@ -239,15 +247,17 @@
#define ID_INFO_LASTINSTRUCTIONS 40069
#define ID_INFO_PROFILE 40070
#define ID_INFO_WRITEONLYREG 40071
#define ID_TRACE_SETTINGS 40072
#define ID_TRACE_ENABLE 40073
#define ID_FILE_MRU_FILE1 40100
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 130
#define _APS_NEXT_COMMAND_VALUE 40072
#define _APS_NEXT_CONTROL_VALUE 1136
#define _APS_NEXT_RESOURCE_VALUE 131
#define _APS_NEXT_COMMAND_VALUE 40074
#define _APS_NEXT_CONTROL_VALUE 1143
#define _APS_NEXT_SYMED_VALUE 109
#endif
#endif

View file

@ -206,6 +206,14 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 109
END
IDD_TRACE, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 240
TOPMARGIN, 7
BOTTOMMARGIN, 106
END
END
#endif // APSTUDIO_INVOKED
@ -295,7 +303,7 @@ 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 © 2018 Christoph Gießelink && Sébastien Carlier",
LTEXT "Copyright © 2019 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 |
@ -654,6 +662,30 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,122,95,50,14
END
IDD_TRACE DIALOG DISCARDABLE 0, 0, 247, 113
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Trace Settings"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Log File:",IDC_STATIC,7,13,28,8
EDITTEXT IDC_TRACE_FILE,39,11,180,12,ES_AUTOHSCROLL
PUSHBUTTON "...",IDC_TRACE_BROWSE,220,11,20,12
CONTROL "&New",IDC_TRACE_NEW,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,16,49,41,10
CONTROL "&Append",IDC_TRACE_APPEND,"Button",BS_AUTORADIOBUTTON,
16,64,41,10
GROUPBOX "File Mode",IDC_STATIC,7,32,113,53
CONTROL "&Register",IDC_TRACE_REGISTER,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,45,43,10
CONTROL "&MMU",IDC_TRACE_MMU,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,57,43,10
CONTROL "&Opcode",IDC_TRACE_OPCODE,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,140,69,43,10
GROUPBOX "Logging",IDC_STATIC,127,32,113,53
DEFPUSHBUTTON "OK",IDOK,62,92,50,14
PUSHBUTTON "Cancel",IDCANCEL,135,92,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
@ -720,8 +752,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,6,1,0
PRODUCTVERSION 1,6,1,0
FILEVERSION 1,6,2,0
PRODUCTVERSION 1,6,2,0
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@ -738,12 +770,12 @@ BEGIN
BEGIN
VALUE "CompanyName", "Christoph Gießelink & Sebastien Carlier\0"
VALUE "FileDescription", "HP38/39/40/48/49 Emulator\0"
VALUE "FileVersion", "1, 6, 1, 0\0"
VALUE "FileVersion", "1, 6, 2, 0\0"
VALUE "InternalName", "Emu48\0"
VALUE "LegalCopyright", "Copyright © 2018\0"
VALUE "LegalCopyright", "Copyright © 2019\0"
VALUE "OriginalFilename", "Emu48.exe\0"
VALUE "ProductName", "Emu48\0"
VALUE "ProductVersion", "1, 6, 1, 0\0"
VALUE "ProductVersion", "1, 6, 2, 0\0"
END
END
BLOCK "VarFileInfo"
@ -925,6 +957,11 @@ BEGIN
BEGIN
MENUITEM "&Step Over Interrupts", ID_INTR_STEPOVERINT
END
POPUP "&Trace"
BEGIN
MENUITEM "&Settings...", ID_TRACE_SETTINGS
MENUITEM "&Enable", ID_TRACE_ENABLE
END
POPUP "&Info"
BEGIN
MENUITEM "&Last Instructions...", ID_INFO_LASTINSTRUCTIONS

View file

@ -13,6 +13,7 @@ DEFINES= -DIDC_STATIC=-1 \
LODEPNGDEFINES= -DLODEPNG_NO_COMPILE_ENCODER \
-DLODEPNG_NO_COMPILE_DISK \
-DLODEPNG_NO_COMPILE_ANCILLARY_CHUNKS \
-DLODEPNG_NO_COMPILE_ERROR_TEXT \
-DLODEPNG_NO_COMPILE_CPP

View file

@ -67,4 +67,4 @@ Many thanks to Pedro A. Arranda Guti
compatible.
02/21/18 (c) by Christoph Gießelink
10/15/19 (c) by Christoph Gießelink

View file

@ -1,2 +1 @@
;01477:6300; disable 10 min auto off (internal, undocumented)
;017A6:81B1; =makebeep

Binary file not shown.