mirror of
https://github.com/Wiimpathy/HatariWii.git
synced 2024-11-25 11:06:59 +01:00
4310 lines
160 KiB
HTML
4310 lines
160 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Hatari User's Manual</title>
|
||
|
<meta name="description"
|
||
|
content="User's manual for the Atari ST emulator Hatari" />
|
||
|
<meta name="author" content="Hatari development team" />
|
||
|
<meta name="keywords" content="hatari, documentation, manual, linux" />
|
||
|
<meta name="viewport" content="width=device-width; initial-scale=1.0;" />
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||
|
<style type="text/css">
|
||
|
<!--
|
||
|
body { background:#FFFFFF;
|
||
|
color:#000000;
|
||
|
margin-left:10px;
|
||
|
margin-right:10px;
|
||
|
font-family:Verdana,Arial,Helvetica,sans-serif;
|
||
|
}
|
||
|
|
||
|
h2 { border-bottom:solid thin black;}
|
||
|
h4.gui { clear:right }
|
||
|
h5 { margin-bottom:2px; margin-left:1em; }
|
||
|
hr { width: 100%; height: 2px; margin-top:4ex; margin-bottom: 2ex; }
|
||
|
|
||
|
pre { color: black;
|
||
|
background:#eeeeee;
|
||
|
margin: 0px 20px 8px 20px;
|
||
|
padding: 2px 8px 1px 8px;
|
||
|
border: solid thin #ccaa88;
|
||
|
}
|
||
|
|
||
|
th { text-align:center; }
|
||
|
td { font-family:Verdana,Arial,Helvetica,sans-serif; }
|
||
|
|
||
|
a:link { color:#000099; background:#ffffff; text-decoration:none; }
|
||
|
a:visited { color:#cc0000; background:#ffffff; text-decoration:none;}
|
||
|
a:hover { color:#0000ff; background:#ffffff; text-decoration:none; }
|
||
|
a:active { color:#993399; background:#ffffff; text-decoration:none; }
|
||
|
|
||
|
.pageheader { text-align:center; }
|
||
|
.commandline { font-family:Courier,monospace; font-size:90% }
|
||
|
.file { color: #000088;}
|
||
|
.button { color:#000000; background:#c0c0c0; border:outset thin gray; font-family:Courier,monospace; padding-left:1em; padding-right:1em;}
|
||
|
.key { color:#550000; font-family:Courier,monospace; font-size:90% }
|
||
|
.backdropped { background:#ffffee; }
|
||
|
.image {margin-left: 5px; margin-right: 5px; border-width:2px; border-style:solid; border-color:#eeeeff; padding:1cm; text-align:center; }
|
||
|
.floatimage { clear:right; float:right; margin-left:0.5cm; border-width:2px; border-style:solid; border-color:#eeeeff; padding:0.5cm; }
|
||
|
.clearboth { clear:both; }
|
||
|
|
||
|
table.keytable { border:1px solid; }
|
||
|
table.keytable tbody { text-align:center; }
|
||
|
table.keytable th { border:1px solid; padding:3px; }
|
||
|
table.keytable td { border:1px solid; padding:3px; }
|
||
|
|
||
|
p.parameter { margin: 1px 1em 1px 11%; font-weight:bold; }
|
||
|
p.paramdesc { margin: 1px 1em 1px 22%; }
|
||
|
-->
|
||
|
</style>
|
||
|
<script type="text/javascript" src="toc.js"></script>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
|
||
|
<h1 class="pageheader">Hatari User's Manual</h1>
|
||
|
|
||
|
<p class="pageheader">
|
||
|
Version 1.9.0, September 2015
|
||
|
</p>
|
||
|
<p class="pageheader">
|
||
|
Manual written by: <strong>Thomas Huth</strong>, <strong>Matthias Arndt</strong>
|
||
|
& <strong>Eero Tamminen</strong>
|
||
|
</p>
|
||
|
<p class="pageheader">
|
||
|
Hatari on the WWW:
|
||
|
<strong>
|
||
|
<a href="http://hatari.tuxfamily.org/">http://hatari.tuxfamily.org/</a>
|
||
|
</strong>
|
||
|
</p>
|
||
|
|
||
|
<h2 class="no-TOC">Index</h2>
|
||
|
|
||
|
<div id="generated-toc">
|
||
|
<!-- The TOC is generated automatically via JavaScript -->
|
||
|
</div>
|
||
|
|
||
|
<h2>Introduction</h2>
|
||
|
|
||
|
<h3>General description</h3>
|
||
|
<p>
|
||
|
Hatari is an Atari ST, STE, TT and Falcon emulator for Linux, OSX,
|
||
|
Windows and other Systems which are supported by the SDL library.
|
||
|
The emulator is open source software and is distributed under the terms of the
|
||
|
<a href="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html">GNU General
|
||
|
Public License (GPL)</a>.
|
||
|
</p>
|
||
|
<p>
|
||
|
The Atari ST was a 16/32 bit computer system which was first released by Atari
|
||
|
in 1985. Using the Motorola 68000 CPU, it was a very popular computer having
|
||
|
quite a lot of CPU power at that time. See Appendix B for details on emulation
|
||
|
in general.
|
||
|
</p>
|
||
|
<p>
|
||
|
Unlike many other Atari ST emulators which try to give you a good
|
||
|
environment for running GEM applications, Hatari tries to emulate the hardware
|
||
|
of a ST as close as possible so that it is able to run most of the old ST games
|
||
|
and demos. Of course you can run normal GEM applications with Hatari, too.
|
||
|
Recent versions of Hatari even feature STE, Falcon and basic TT emulation.
|
||
|
</p>
|
||
|
|
||
|
<h3>Features</h3>
|
||
|
<ul>
|
||
|
<li>68000 - 68040 emulation via the UAE CPU core
|
||
|
(68060 and MMU emulation only with the WinUAE CPU core)</li>
|
||
|
<li>ST RAM size variable (from 512kiB up to 14MiB are possible)</li>
|
||
|
<li>TT RAM size variable (from 0 up to 256MiB are possible)</li>
|
||
|
<li>optional cartridge images for the ST ROM port</li>
|
||
|
<li>most of the ST specific hardware</li>
|
||
|
<li>ST Shifter with ST-High, ST-Medium and ST-Low resolutions,
|
||
|
overscan effects for all borders in color resolutions</li>
|
||
|
<li>512 color ST palette</li>
|
||
|
<li>Spec512 mode support for low and medium resolutions</li>
|
||
|
<li>many raster effects </li>
|
||
|
<li>scaling of low resolutions by factor two</li>
|
||
|
<li>interleaved lines rendering of ST-medium and (scaled) ST-low
|
||
|
resolutions for the TV "monitor type"</li>
|
||
|
<li>Blitter chip emulation</li>
|
||
|
<li>PSG YM2149 emulation (soundchip) including STFM samples</li>
|
||
|
<li>Printer port emulation on hardware level (print to file)</li>
|
||
|
<li>RS232 emulation</li>
|
||
|
<li>MIDI input/output/through emulation</li>
|
||
|
<li>Mega ST real time clock</li>
|
||
|
<li>IKBD emulation (keyboard, mouse and joystick) with custom
|
||
|
keyboard mapping</li>
|
||
|
<li>joystick emulation via cursor keys and joystick emulation via a
|
||
|
connected PC joystick</li>
|
||
|
<li>FDC (floppy disk controller) emulation using floppy disk images
|
||
|
in standard formats (*.ST, *.MSA, *.DIM and *.STX)</li>
|
||
|
<li>FDC emulation via the IPF support library for using
|
||
|
*.IPF, *.RAW and *.CTR images</li>
|
||
|
<li>support for packed disk images (PkZip and Gzip)</li>
|
||
|
<li>optional write-protection for floppy disk images</li>
|
||
|
<li>ACSI emulation for hard drive support (with basic support for extended
|
||
|
host adapter protocol to access disks > 1 GB)</li>
|
||
|
<li>GEMDOS interface driver to mount directories as hard drives
|
||
|
with optional write-protection</li>
|
||
|
<li>support for memory snapshots (save whole system state)</li>
|
||
|
<li>driver for extended VDI resolutions</li>
|
||
|
<li>recording of sound as .WAV and .YM files</li>
|
||
|
<li>screenshots in PNG or BMP format</li>
|
||
|
<li>AVI animation capturing with sound</li>
|
||
|
<li>TOS versions 1.00, 1.02, 1.04 and 2.06 (and EmuTOS) can be used in ST mode.</li>
|
||
|
</ul>
|
||
|
|
||
|
<h4>STE hardware emulation</h4>
|
||
|
<p>There is support for following additional STE features:</p>
|
||
|
<ul>
|
||
|
<li>horizontal and vertical hardware fine scrolling</li>
|
||
|
<li>split screen techniques / in-screen video address manipulations</li>
|
||
|
<li>(STE specific) left border opening</li>
|
||
|
<li>4096 colors STE palette</li>
|
||
|
<li>Stereo DMA sample sound</li>
|
||
|
<li>Microwire/LMC1992 emulation</li>
|
||
|
<li>STE joypads</li>
|
||
|
<li>TOS versions 1.06, 1.62, 2.05 and 2.06 (and EmuTOS) can be used in STE mode.</li>
|
||
|
</ul>
|
||
|
|
||
|
<h4>Experimental TT hardware emulation</h4>
|
||
|
<p>There is support for following additional TT features:</p>
|
||
|
<ul>
|
||
|
<li>TT low/med/high resolution support</li>
|
||
|
<li>ST/TT palette switching and video shifter</li>
|
||
|
<li>RAM up to 14MiB (ST-RAM) and up to 256 MiB (TT-RAM)</li>
|
||
|
<li>Only TOS version 3.06 (and EmuTOS) can be used in TT mode.</li>
|
||
|
</ul>
|
||
|
|
||
|
<h4>Falcon hardware emulation</h4>
|
||
|
<p>There is support for following additional Falcon features:</p>
|
||
|
<ul>
|
||
|
<li>Partial Videl and Videl borders emulation for all Falcon screen modes</li>
|
||
|
<li>Aspect correction and scaling of small resolutions by an integer factor</li>
|
||
|
<li>STE/Falcon palette switching and shifter</li>
|
||
|
<li>Mono/RGB/VGA/TV monitor types</li>
|
||
|
<li>DSP co-processor emulation</li>
|
||
|
<li>RAM up to 14MiB (ST-RAM) and up to 256 MiB (TT-RAM)</li>
|
||
|
<li>Experimental microphone (jack) emulation</li>
|
||
|
<li>Experimental Crossbar sound matrix (ADC (mic & PSG), DAC, DMA, DSP)
|
||
|
interconnect emulation + support for the additional DMA sound
|
||
|
sample rates</li>
|
||
|
<li>Experimental IDE master and slave emulation for hard drive support</li>
|
||
|
<li>TOS versions 4.00, 4.02, 4.04 and 4.92 (and EmuTOS) can be used in Falcon mode.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>See the developers' <span class="file">doc/todo.txt</span> file
|
||
|
(included with Hatari sources) for the details on the few remaining
|
||
|
emulation gaps and the <a href="compatibility.html">Hatari Atari
|
||
|
Software Compatibility List</a> for which Atari programs are known
|
||
|
to be affected by them.</p>
|
||
|
|
||
|
|
||
|
<h3>System requirements</h3>
|
||
|
|
||
|
<p> Hatari currently has the following minimum system requirements:</p>
|
||
|
<ul>
|
||
|
<li>a fast PC (>500MHz, for Falcon and TT emulation
|
||
|
<a href="#Performance">even faster</a>)</li>
|
||
|
<li>some sort of Unix (preferable <a href="http://www.linux.org/">GNU/Linux</a>)
|
||
|
</li>
|
||
|
<li>the SDL library (<a href="http://www.libsdl.org/">http://www.libsdl.org/</a>)</li>
|
||
|
<li>the zLib (<a href="http://www.gzip.org/zlib/">http://www.gzip.org/zlib/</a>)
|
||
|
for support of ZIP-packed disk images (*.zip and *.gz)</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
In the course of time Hatari has successfully been tested by various people on
|
||
|
the following systems:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>Linux/i86 with Kernel 2.4.x and 2.6.x</li>
|
||
|
<li>Linux/PPC with Kernel 2.4.x and 2.6.x</li>
|
||
|
<li>BeOS/i86</li>
|
||
|
<li>Apple Mac OS X on PowerPC and i86</li>
|
||
|
<li>NetBSD 1.6 on i86</li>
|
||
|
<li>NetBSD on a Digital Alpha</li>
|
||
|
<li>FreeBSD 4.1 on an i486, FreeBSD 4.8 on a Pentium 4 and FreeBSD 5.1</li>
|
||
|
<li>OpenBSD 3.5 and 5.0</li>
|
||
|
<li>Solaris 8 on a SUN UltraSparc 1</li>
|
||
|
<li>Linux/ARM (oabi) on Sharp Zaurus SL-C760 PDA</li>
|
||
|
<li>Linux/ARM (eabi) on Nokia Maemo Internet Tablets and N900 phone</li>
|
||
|
<li>Windows XP</li>
|
||
|
</ul>
|
||
|
|
||
|
<h2>Compiling and running</h2>
|
||
|
|
||
|
<h3>Compiling Hatari</h3>
|
||
|
|
||
|
<p>Required:</p>
|
||
|
<ul>
|
||
|
<li>A C compiler. Preferably GCC, but others have worked too.</li>
|
||
|
<li>A working CMake installation. See
|
||
|
<a href="http://www.cmake.org/">http://www.cmake.org/</a> for details.
|
||
|
<li>The SDL library v1.2.10 or newer. You can get it from
|
||
|
<a href="http://www.libsdl.org/">http://www.libsdl.org/</a>.
|
||
|
</li>
|
||
|
<li>The zLib compression library. You can get it from
|
||
|
<a href="http://www.gzip.org/zlib/">http://www.gzip.org/zlib/</a>.
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Optional:</p>
|
||
|
<ul>
|
||
|
<li>The PNG image library for PNG format screenshots and to
|
||
|
decrease AVI video recording file sizes. You can get it from
|
||
|
<a href="http://www.libpng.org/">http://www.libpng.org/</a>.</li>
|
||
|
<li>The GNU Readline library for Hatari debugger command line editing.</li>
|
||
|
<li>The Xlib library to support Hatari Python UI window embedding
|
||
|
on systems with the X window system (Linux and other unixes).</li>
|
||
|
<li>The portaudio library for Falcon microphone recording support</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
The versions available in your Linux distribution will be sufficient
|
||
|
in most cases, but make sure you have also the header files installed
|
||
|
for the libraries as well! Typically they're in a corresponding -dev
|
||
|
package.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
After you've verified that you have the required libraries and their
|
||
|
development files, change to the <span class="file">hatari/</span>
|
||
|
directory. Create a <span class="file">build/</span> directory under
|
||
|
it and configure the build system for your environment:
|
||
|
<pre>
|
||
|
mkdir -p build
|
||
|
cd build
|
||
|
cmake ..
|
||
|
</pre>
|
||
|
<p>
|
||
|
Then compile Hatari by typing <span class="commandline">make</span>.
|
||
|
If all works fine, you'll get the executable <span class="commandline">hatari</span>
|
||
|
in the src/ subdirectory.
|
||
|
</p>
|
||
|
<p>
|
||
|
Note: Instead of calling CMake directly, you can also use the supplied
|
||
|
configure script to run CMake and to give the arguments (like install
|
||
|
prefix) in a format familiar from GNU Autotools using programs. Type
|
||
|
"<span class="commandline">./configure --help</span>"
|
||
|
to see all the options supported by this script.
|
||
|
</p>
|
||
|
|
||
|
<h3>Installation of a TOS ROM</h3>
|
||
|
|
||
|
<p>
|
||
|
Before you can start Hatari, you have to copy a TOS ROM image to the data
|
||
|
directory (<span class="file"><prefix>/share/hatari/</span>, by
|
||
|
default <span class="file">/usr/local/share/hatari/</span>) and
|
||
|
rename it to <span class="commandline">tos.img</span>, or use the
|
||
|
<span class="commandline">--tos</span> command line option to tell
|
||
|
Hatari where to find a TOS ROM.
|
||
|
Hatari needs a TOS ROM image because this contains the operating system
|
||
|
of the emulated Atari.
|
||
|
</p>
|
||
|
<p>
|
||
|
Unfortunately it is not possible to ship an original ROM
|
||
|
image with the Hatari package since these images are still copyrighted.
|
||
|
But you can easily create an image with a real ST and one of those various
|
||
|
ROM-image programs for the ST (search for "TOSDUMP" with your
|
||
|
favourite internet search engine). If your old ST does not work anymore, you
|
||
|
can also try to search the internet directly for corresponding TOS ROM image,
|
||
|
but don't ask the Hatari team where to get one. </p>
|
||
|
<p> Another solution is EmuTOS, which is also shipped with the official
|
||
|
release versions of Hatari. EmuTOS is an open-source TOS clone. You can find
|
||
|
it at:
|
||
|
<a href="http://emutos.sourceforge.net/">http://emutos.sourceforge.net/</a>.
|
||
|
It is not the best solution for playing games or running other old software
|
||
|
due to compatibility issues (see <span class="file">emutos.txt</span> for
|
||
|
more details), but it's free and compatible with Hatari.</p>
|
||
|
<p>If you do not specify a TOS image on the commandline nor can Hatari
|
||
|
find a suitable TOS image in the default dir, you'll get the chance to
|
||
|
select a TOS image file from the GUI. </p>
|
||
|
|
||
|
<h3>Installation of the binary</h3>
|
||
|
|
||
|
<p> Type <span class="commandline">make install</span> as "root" user to
|
||
|
do a systemwide installation.</p>
|
||
|
<p>Assuming you didn't change the default installation prefix and that
|
||
|
<span class="file">/usr/local/bin/</span> is in your PATH, you should
|
||
|
be now able to start the Hatari executable from anywhere.</p>
|
||
|
<p> When you finally have got a TOS image, try starting Hatari with the
|
||
|
option <span class="commandline">--help</span> to find out more about
|
||
|
its command line parameters. </p>
|
||
|
|
||
|
<h3>Running Hatari for the first time</h3>
|
||
|
|
||
|
<p> Now type <span class="commandline">hatari</span> to run the
|
||
|
emulator for the first time. If all goes
|
||
|
well, you should now be presented with a window showing you the
|
||
|
familiar
|
||
|
little green desktop of the Atari ST. Press <span class="key">F12</span>
|
||
|
to turn on the GUI to
|
||
|
configure Hatari to suit your needs, press <span class="key">F11</span>
|
||
|
to toggle windowed and fullscreen mode. </p>
|
||
|
|
||
|
<h3>Configuration options precedence</h3>
|
||
|
|
||
|
<p>Hatari settings can come from several sources, with later ones
|
||
|
overriding the earlier given ones:
|
||
|
<ul>
|
||
|
<li>Builtin Hatari default options (which are different for old UAE and WinUAE
|
||
|
CPU core builds, former defaults to ST, latter to Falcon)</li>
|
||
|
<li>Global <span class="commandline">/etc/hatari.cfg</span>
|
||
|
(or <span class="commandline">/usr/local/etc/hatari.cfg</span>)
|
||
|
configuration file</li>
|
||
|
<li>User specific <span class="commandline">~/.hatari/hatari.cfg</span>
|
||
|
configuration file</li>
|
||
|
<li>Command line arguments
|
||
|
<li>Option changes done at run-time in Hatari options GUI, with debugger "setopt"
|
||
|
command or through the (optionally enabled) Hatari control socket.
|
||
|
</ul>
|
||
|
|
||
|
<p>Some of the run-time changes require emulation to be reset for them
|
||
|
to take effect.</p>
|
||
|
|
||
|
|
||
|
<h2>Command line options and arguments</h2>
|
||
|
|
||
|
<p>Usage:</p>
|
||
|
<pre>
|
||
|
hatari [options] [disk image | directory | Atari program ]
|
||
|
</pre>
|
||
|
|
||
|
<p>As an argument one can give either a name of:</p>
|
||
|
<ul>
|
||
|
<li>A floppy disk image,
|
||
|
<li>A directory that should be emulated as a virtual GEMDOS HD, or</li>
|
||
|
<li>An Atari program that should be autostarted. In this case
|
||
|
the program's directory will be used as the C: drive from
|
||
|
where this program will be started.
|
||
|
(Note that autostarting a program might not work if you've also
|
||
|
specified a floppy image for drive A: on command line or in config
|
||
|
file which contains a desktop.inf/newdesk.inf/emutos.inf file on
|
||
|
it.)</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Booting will be done from the disk image or directory that's given
|
||
|
last on the command line as an option or the argument (and which
|
||
|
corresponds to A: or C:).</p>
|
||
|
|
||
|
<p>Hatari command line options are split into several categories:</p>
|
||
|
|
||
|
<!--
|
||
|
Generated from hatari.1 options section by changing subheaders to h3
|
||
|
and removing extra paragraphs:
|
||
|
groff -man -Thtml hatari.1 | sed -e 's/−/-/g' | tidy | awk '
|
||
|
/h2.OPTIONS/ { out = 1; next }
|
||
|
/COMMANDS/ { out = 0; next }
|
||
|
{ if(out) print }' \
|
||
|
| sed -e 's/h2/h3/g' -e 's/<b>//' -e 's/<\/b>//' \
|
||
|
-e 's/style="margin-left:11%;[^"]*"/class="parameter"/g' \
|
||
|
-e 's/style="margin-left:22%;"/class="paramdesc"/g'
|
||
|
-->
|
||
|
|
||
|
<h3>General options</h3>
|
||
|
<p class="parameter">-h,
|
||
|
--help</p>
|
||
|
<p class="paramdesc">Print command line options and
|
||
|
terminate</p>
|
||
|
<p class="parameter">-v,
|
||
|
--version</p>
|
||
|
<p class="paramdesc">Print version information and
|
||
|
terminate</p>
|
||
|
<p class="parameter">--confirm-quit
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Whether Hatari confirms quitting</p>
|
||
|
<p class="parameter">-c, --configfile
|
||
|
<filename></p>
|
||
|
<p class="paramdesc">Read additional configuration values from
|
||
|
<file>, these override values read from the global and
|
||
|
user configuration files
|
||
|
</p>
|
||
|
<p class="parameter">-k, --keymap
|
||
|
<file></p>
|
||
|
<p class="paramdesc">load keyboard mapping from
|
||
|
<file></p>
|
||
|
<p class="parameter">--fast-forward
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">On fast machine helps skipping (fast
|
||
|
forwarding) Hatari output</p>
|
||
|
|
||
|
<h3>Common display options</h3>
|
||
|
<p class="parameter">-m,
|
||
|
--mono</p>
|
||
|
<p class="paramdesc">Start in monochrome mode instead of
|
||
|
color</p>
|
||
|
<p class="parameter">--monitor
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Select monitor type (x =
|
||
|
mono/rgb/vga/tv)</p>
|
||
|
<p class="parameter">-f,
|
||
|
--fullscreen</p>
|
||
|
<p class="paramdesc">Start the emulator in fullscreen
|
||
|
mode</p>
|
||
|
<p class="parameter">-w, --window</p>
|
||
|
<p class="paramdesc">Start the emulator in windowed mode</p>
|
||
|
<p class="parameter">--grab</p>
|
||
|
<p class="paramdesc">Grab mouse (also) in windowed mode</p>
|
||
|
<p class="parameter">--borders <bool></p>
|
||
|
<p class="paramdesc">Show ST/STE/Falcon screen borders
|
||
|
(for low/med resolution overscan demos)</p>
|
||
|
<p class="parameter">--frameskips
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Skip <x> frames after each
|
||
|
displayed frame to accelerate emulation (0=disabled, >4 uses
|
||
|
automatic frameskip with given value as maximum)</p>
|
||
|
<p class="parameter">--slowdown <x></p>
|
||
|
<p class="paramdesc">Slow down emulation by factor of x
|
||
|
(used as multiplier for VBL wait time)</p>
|
||
|
<p class="parameter">--statusbar
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Show statusbar (with floppy leds etc
|
||
|
etc)</p>
|
||
|
<p class="parameter">--drive-led
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Show overlay drive led when statusbar
|
||
|
isn’t shown</p>
|
||
|
<p class="parameter">--max-width
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Preferred / maximum window width
|
||
|
for borders / zooming</p>
|
||
|
<p class="parameter">--max-height
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Preferred / maximum window height
|
||
|
for borders / zooming</p>
|
||
|
<p class="parameter">--bpp
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Force internal bitdepth (x =
|
||
|
8/15/16/32, 0=disable)</p>
|
||
|
|
||
|
<h3>ST/STE specific display options</h3>
|
||
|
<p class="parameter">--desktop-st
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Whether fullscreen mode uses desktop
|
||
|
resolution to avoid: messing multi-screen setups, several seconds
|
||
|
delay needed by LCD monitors resolution switching and the resulting
|
||
|
sound break. As Hatari ST/E display code doesn’t support
|
||
|
zooming (except low-rez doubling), it doesn’t get scaled (by
|
||
|
Hatari or monitor) when this is enabled. Therefore this is mainly
|
||
|
useful only if you suffer from the described effects, but still
|
||
|
want to grab mouse and remove other distractions from the screen
|
||
|
just by toggling fullscreen mode. (disabled by default)</p>
|
||
|
<p class="parameter">--spec512
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Hatari uses this threshold to decide
|
||
|
when to render a screen with the slower but more accurate
|
||
|
Spectrum512 screen conversion functions (0 <= x <= 512,
|
||
|
0=disable)</p>
|
||
|
<p class="parameter">-z, --zoom
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Zoom (double) low resolution (1=no,
|
||
|
2=yes)</p>
|
||
|
|
||
|
<h3>TT/Falcon specific display options</h3>
|
||
|
<p>
|
||
|
Zooming to sizes specified below is internally done using integer scaling
|
||
|
factors. This means that different Atari resolutions may show up with
|
||
|
different sizes, but they are never blurry.
|
||
|
<p class="parameter">--desktop <bool></p>
|
||
|
<p class="paramdesc">Whether to use desktop resolution on
|
||
|
fullscreen to avoid issues related to resolution switching.
|
||
|
Otherwise fullscreen will use a resolution that is closest to the
|
||
|
Hatari window size. (enabled by default)</p>
|
||
|
<p class="parameter">--force-max
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Hatari window size is forced to
|
||
|
specified maximum size and black borders used when Atari resolution
|
||
|
doesn’t scale evenly to it. This is most useful when
|
||
|
recording videos of Falcon demos that change their resolution.
|
||
|
(disabled by default)</p>
|
||
|
<p class="parameter">--aspect
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Whether to do monitor aspect ratio
|
||
|
correction (enabled by default)</p>
|
||
|
|
||
|
<h3>VDI options</h3>
|
||
|
<p class="parameter">--vdi
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Whether to use VDI screen mode</p>
|
||
|
<p class="parameter">--vdi-planes
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Use extended VDI resolution with bit
|
||
|
depth <x> (x = 1, 2 or 4)</p>
|
||
|
<p class="parameter">--vdi-width
|
||
|
<w></p>
|
||
|
<p class="paramdesc">Use extended VDI resolution with width
|
||
|
<w> (320 < w <= 1280)</p>
|
||
|
<p class="parameter">--vdi-height
|
||
|
<h></p>
|
||
|
<p class="paramdesc">Use extended VDI resolution with height
|
||
|
<h> (200 < h <= 960)</p>
|
||
|
|
||
|
<h3>Screen capture options</h3>
|
||
|
<p class="parameter">--crop
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Remove statusbar from the screen
|
||
|
captures</p>
|
||
|
<p class="parameter">--avirecord</p>
|
||
|
<p class="paramdesc">Start AVI recording. Note: recording will
|
||
|
automatically stop when emulation resolution changes.</p>
|
||
|
<p class="parameter">--avi-vcodec <x></p>
|
||
|
<p class="paramdesc">Select AVI video codec (x = bmp/png).
|
||
|
PNG compression can be <em>much</em> slower than using the uncompressed BMP
|
||
|
format, but uncompressed video content takes huge amount of space.</p>
|
||
|
<p class="parameter">--png-level <x></p>
|
||
|
<p class="paramdesc">Select PNG compression level for AVI video (x = 0-9).
|
||
|
Both compression efficiency and speed depend on the compressed
|
||
|
screen content. Highest compression level (9) can be <em>really</em>
|
||
|
slow with some content. Levels 3-6 should compress nearly as well
|
||
|
with clearly smaller CPU overhead.</p>
|
||
|
<p class="parameter">--avi-fps <x></p>
|
||
|
<p class="paramdesc">Force AVI frame rate (x = 50/60/71/...)</p>
|
||
|
<p class="parameter">--avi-file <file></p>
|
||
|
<p class="paramdesc">Use <file> to record AVI</p>
|
||
|
|
||
|
<h3>Devices options</h3>
|
||
|
<p class="parameter">-j,
|
||
|
--joystick <port></p>
|
||
|
<p class="paramdesc">Emulate joystick with cursor keys in
|
||
|
given port (0-5)</p>
|
||
|
<p class="parameter">--joy<port>
|
||
|
<type></p>
|
||
|
<p class="paramdesc">Set joystick type (none/keys/real) for
|
||
|
given port</p>
|
||
|
<p class="parameter">--printer
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Enable printer support and write data
|
||
|
to <file></p>
|
||
|
<p class="parameter">--midi-in
|
||
|
<filename></p>
|
||
|
<p class="paramdesc">Enable MIDI support and write MIDI data
|
||
|
to <file></p>
|
||
|
<p class="parameter">--midi-out
|
||
|
<filename></p>
|
||
|
<p class="paramdesc">Enable MIDI support and read MIDI data
|
||
|
from <file></p>
|
||
|
<p class="parameter">--rs232-in
|
||
|
<filename></p>
|
||
|
<p class="paramdesc">Enable serial port support and use
|
||
|
<file> as the input device</p>
|
||
|
<p class="parameter">--rs232-out
|
||
|
<filename></p>
|
||
|
<p class="paramdesc">Enable serial port support and use
|
||
|
<file> as the output device</p>
|
||
|
|
||
|
<h3>Disk options</h3>
|
||
|
<p class="parameter">--drive-a
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Enable/disable drive A (default is on)</p>
|
||
|
<p class="parameter">--drive-b
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Enable/disable drive B (default is on)</p>
|
||
|
<p class="parameter">--drive-a-heads
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Set number of heads for drive A (1=single sided, 2=double sided)</p>
|
||
|
<p class="parameter">--drive-b-heads
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Set number of heads for drive B (1=single sided, 2=double sided)</p>
|
||
|
<p class="parameter">--disk-a
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Set disk image for floppy drive A</p>
|
||
|
<p class="parameter">--disk-b
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Set disk image for floppy drive B</p>
|
||
|
<p class="parameter">--protect-floppy
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Write protect floppy image contents
|
||
|
(on/off/auto). With "auto" option write protection is according to
|
||
|
the disk image file attributes</p>
|
||
|
<p class="parameter">--protect-hd
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Write protect hard drive <dir>
|
||
|
contents (on/off/auto). With "auto" option the protection can be
|
||
|
controlled by setting individual files attributes as it disables
|
||
|
the file attribute modifications for the GEMDOS HD
|
||
|
emulation</p>
|
||
|
<p class="parameter">--gemdos-case <x></p>
|
||
|
<p class="paramdesc">Specify whether new dir/filenames are forced to be
|
||
|
in upper or lower case with the GEMDOS HD emulation. Off/upper/lower, off by default
|
||
|
</p>
|
||
|
<p class="parameter">-d, --harddrive
|
||
|
<dir></p>
|
||
|
<p class="paramdesc">Emulate hard disk partition(s) with
|
||
|
<dir> contents. If directory contains only single letter
|
||
|
(C-Z) subdirectories, each of these subdirectories will be treated
|
||
|
as a separate partition, otherwise the given directory itself will
|
||
|
be assigned to drive "C:". In the multiple partition case, the
|
||
|
letters used as the subdirectory names will determine to which
|
||
|
drives/partitions they’re assigned. If <dir> is
|
||
|
an empty string, then harddrive's emulation is disabled</p>
|
||
|
<p class="parameter">--acsi
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Emulate an ACSI hard drive with an image
|
||
|
<file></p>
|
||
|
<p class="parameter">--ide-master
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Emulate an IDE master hard drive with an
|
||
|
image <file></p>
|
||
|
<p class="parameter">--ide-slave
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Emulate an IDE slave hard drive with an
|
||
|
image <file></p>
|
||
|
<p class="parameter">--fastfdc
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Speed up FDC emulation (can cause
|
||
|
incompatibilities)</p>
|
||
|
|
||
|
<h3>Memory options</h3>
|
||
|
<p class="parameter">
|
||
|
--memstate <file></p>
|
||
|
<p class="paramdesc">Load memory snap-shot <file></p>
|
||
|
<p class="parameter">-s, --memsize
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Set amount of emulated RAM, x = 1 to 14
|
||
|
MiB, or 0 for 512 KiB</p>
|
||
|
|
||
|
<h3>ROM options</h3>
|
||
|
<p class="parameter">-t,
|
||
|
--tos <imagefile></p>
|
||
|
<p class="paramdesc">Specify TOS ROM image to use</p>
|
||
|
<p class="parameter">--patch-tos
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Use this option to enable/disable TOS
|
||
|
ROM patching. Experts only! Leave this enabled unless you know what
|
||
|
you are doing!</p>
|
||
|
<p class="parameter">--cartridge
|
||
|
<imagefile></p>
|
||
|
<p class="paramdesc">Use ROM cartridge image <file>
|
||
|
(only works if GEMDOS HD emulation and extended VDI resolution are
|
||
|
disabled)</p>
|
||
|
|
||
|
<h3>CPU options</h3>
|
||
|
<p class="parameter">
|
||
|
--cpulevel <x></p>
|
||
|
<p class="paramdesc">Specify CPU (680x0) to use (use x >=
|
||
|
1 with EmuTOS or TOS >= 2.06 only!)</p>
|
||
|
<p class="parameter">--cpuclock
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Set the CPU clock (8, 16 or 32 Mhz)</p>
|
||
|
<p class="parameter">--compatible
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Use a more compatible, but slower 68000
|
||
|
CPU mode with better prefetch accuracy and cycle counting</p>
|
||
|
|
||
|
<h3>Misc system options</h3>
|
||
|
<p class="parameter">
|
||
|
--machine <x></p>
|
||
|
<p class="paramdesc">Select machine type (x = st, ste, tt or
|
||
|
falcon)</p>
|
||
|
<p class="parameter">--blitter
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Enable blitter emulation (ST only)</p>
|
||
|
<p class="parameter">--dsp <x></p>
|
||
|
<p class="paramdesc">Falcon DSP emulation (x = none, dummy
|
||
|
or emu, Falcon only)</p>
|
||
|
<p class="parameter">--timer-d
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Patch redundantly high Timer-D
|
||
|
frequency set by TOS. This about doubles Hatari speed (for ST/e
|
||
|
emulation) as the original Timer-D frequency causes most of the
|
||
|
interrupts.</p>
|
||
|
<p class="parameter">--fast-boot
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Patch TOS and initialize the so-called
|
||
|
"memvalid" system variables to by-pass the memory test of TOS, so
|
||
|
that the system boots faster.</p>
|
||
|
<p class="parameter">--rtc
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Enable real-time clock</p>
|
||
|
|
||
|
<h3>Sound options</h3>
|
||
|
<p class="parameter">--mic
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">Enable/disable (Falcon only)
|
||
|
microphone</p>
|
||
|
<p class="parameter">--sound
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Sound frequency: 6000-50066. "off"
|
||
|
disables the sound and speeds up the emulation. To prevent extra
|
||
|
sound artifacts, the frequency should be selected so that it either
|
||
|
matches evenly with the STE/TT/Falcon sound DMA (6258, 12517,
|
||
|
250033, 50066 Hz) or your sound card frequencies (11025, 22050,
|
||
|
44100 or 6000...48000 Hz). Check what your sound card supports.</p>
|
||
|
<p class="parameter">--sound-buffer-size
|
||
|
<x></p>
|
||
|
<p class="paramdesc">SDL’s sound buffer size: 10-100,
|
||
|
or 0 to use default buffer size. By default Hatari uses an SDL
|
||
|
buffer size of 1024 samples, which gives approximatively 20-30 ms
|
||
|
of sound depending on the chosen sound frequency. Under some OS or
|
||
|
with not fully supported sound card, this default setting can cause
|
||
|
a bigger delay at lower frequency (nearly 0.5 sec). In that case,
|
||
|
you can use this option to force the size of the sound buffer to a
|
||
|
fixed number of milliseconds of sound (using 20 is often a good
|
||
|
choice if you have such problems). Most users will not need this
|
||
|
option.</p>
|
||
|
<p class="parameter">--sound-sync
|
||
|
<bool></p>
|
||
|
<p class="paramdesc">The emulation rate is nudged by +100 or
|
||
|
0 or -100 micro-seconds on occasion. This prevents the sound buffer
|
||
|
from overflowing (long latency and lost samples) or underflowing
|
||
|
(short latency and repeated samples). The emulation rate smoothly
|
||
|
deviates by a maximum of 0.58% until synchronized, while the
|
||
|
emulator continuously generates every sound sample and the crystal
|
||
|
controlled sound system consumes every sample.<br />
|
||
|
(on|off, off=default)</p>
|
||
|
<p class="parameter">--ym-mixing
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Select a method for mixing the three
|
||
|
YM2149 voice volumes together. "model" uses a mathematical model of
|
||
|
the YM voices, "table" uses a lookup table of audio output voltage
|
||
|
values measured on STF and "linear" just averages the 3 YM
|
||
|
voices.</p>
|
||
|
|
||
|
<h3>Debug options</h3>
|
||
|
<p class="parameter">-W, --wincon</p>
|
||
|
<p class="paramdesc">Open console window (Windows only)</p>
|
||
|
<p class="parameter">-D,
|
||
|
--debug</p>
|
||
|
<p class="paramdesc">Toggle whether CPU exceptions invoke
|
||
|
the debugger</p>
|
||
|
<p class="parameter">--debug-except <flags></p>
|
||
|
<p class="paramdesc">Specify which exceptions invoke debugger, see
|
||
|
"--debug-except help" for available (comma separated) exception
|
||
|
flags.</p>
|
||
|
<p class="parameter">--bios-intercept</p>
|
||
|
<p class="paramdesc">
|
||
|
Toggle XBios command parsing. Allows Atari programs to use all Hatari
|
||
|
functionality and change Hatari state through Hatari specifit
|
||
|
XBios(255) calls. XBios(20) printscreen calls produce also Hatari
|
||
|
screenshots.</p>
|
||
|
<p class="parameter">--conout <device></p>
|
||
|
<p class="paramdesc">Enable console (xconout vector functions) output
|
||
|
redirection for given <device> to host terminal. Device 2 is for
|
||
|
the (CON:) VT52 console, which vector function catches also EmuTOS panic
|
||
|
messages and MiNT console output, not just normal BIOS console output.</p>
|
||
|
<p class="parameter">--disasm <x></p>
|
||
|
<p class="paramdesc">Set disassembly options. 'uae' and 'ext' select
|
||
|
the dissasembly engine to use, bitmask sets output options for the
|
||
|
external disassembly engine and 'help' lists them.</p>
|
||
|
<p class="parameter">--natfeats <bool></p>
|
||
|
<p class="paramdesc">Enable/disable (basic) Native Features support.
|
||
|
E.g. EmuTOS uses it for debug output.</p>
|
||
|
<p class="parameter">--trace
|
||
|
<flags></p>
|
||
|
<p class="paramdesc">Activate debug traces, see
|
||
|
"--trace help" for available tracing flags</p>
|
||
|
<p class="parameter">--trace-file
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Save trace output to <file>
|
||
|
(default=stderr)</p>
|
||
|
<p class="parameter">--parse
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Parse/execute debugger commands from
|
||
|
<file></p>
|
||
|
<p class="parameter">--saveconfig</p>
|
||
|
<p class="paramdesc">Save Hatari configuration and exit.
|
||
|
Hatari UI needs Hatari configuration file to start, this can be
|
||
|
used to create it automatically.</p>
|
||
|
<p class="parameter">--no-parachute</p>
|
||
|
<p class="paramdesc">Disable SDL parachute to get Hatari
|
||
|
core dumps. SDL parachute is enabled by default to restore video
|
||
|
mode in case Hatari terminates abnormally while using non-standard
|
||
|
screen resolution.</p>
|
||
|
<p class="parameter">--control-socket
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Hatari reads options from given socket
|
||
|
at run-time</p>
|
||
|
<p class="parameter">--log-file
|
||
|
<file></p>
|
||
|
<p class="paramdesc">Save log output to <file>
|
||
|
(default=stderr)</p>
|
||
|
<p class="parameter">--log-level
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Log output level
|
||
|
(x=debug/todo/info/warn/error/fatal)</p>
|
||
|
<p class="parameter">--alert-level
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Show dialog for log messages above
|
||
|
given level</p>
|
||
|
<p class="parameter">--run-vbls
|
||
|
<x></p>
|
||
|
<p class="paramdesc">Exit after X VBLs</p>
|
||
|
|
||
|
<p>Type <span class="commandline">hatari --help</span> to list all
|
||
|
the command line options supported by a given version of Hatari.</p>
|
||
|
|
||
|
|
||
|
<h2>Using the emulated system</h2>
|
||
|
|
||
|
<p> Once you've started Hatari successfully, you can use the emulator as
|
||
|
an almost complete Atari ST computer system. </p>
|
||
|
|
||
|
<h3>The GUI</h3>
|
||
|
|
||
|
<p>Press <span class="key">F12</span> to enter the GUI. Navigate it
|
||
|
with the mouse.
|
||
|
The GUI is rather self explanatory.</p>
|
||
|
|
||
|
<h4 class="gui">The Main Menu</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/main.png" width="500" height="304"
|
||
|
alt="Hatari's GUI - the main menu" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
You can reach the other setup dialogs from the main menu by clicking on
|
||
|
the appropriate buttons.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can load the current settings from a configuration file by clicking
|
||
|
on <span class="button">Load config.</span> and you can save
|
||
|
the current settings to a configuration file by clicking on
|
||
|
<span class="button">Save config.</span>.
|
||
|
</p>
|
||
|
<p>
|
||
|
Click <span class="button">OK</span> to go back and continue the emulation.
|
||
|
All changed options will be applied.
|
||
|
</p>
|
||
|
<p>
|
||
|
Select the <span class="button">Reset machine</span> option if you
|
||
|
want the emulated machine to perform a cold reset. This is equal to
|
||
|
switching the power off and on again on a real Atari machine.
|
||
|
</p>
|
||
|
<p>
|
||
|
Click <span class="button">Quit</span> to terminate Hatari
|
||
|
and return to the host OS.
|
||
|
</p>
|
||
|
<p>
|
||
|
Click <span class="button">Cancel</span> to abandon any
|
||
|
changes that you have made.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The File Selector Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/fileselector.png" width="640" height="400"
|
||
|
alt="Hatari's GUI - the fileselector" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
The file selector dialog appears whenever you are prompted to choose a file
|
||
|
or folder.
|
||
|
</p>
|
||
|
<p>
|
||
|
To enter a folder or choose a file, simply click on the entry in the
|
||
|
main box of the dialog. To navigate in the file list, you can use the
|
||
|
scrollbar on the right with mouse, or use keyboard up + down arrow,
|
||
|
page up + down, Home and End keys.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can use the three buttons in the upper right corner for additional folder
|
||
|
navigation. Click the <span class="button">..</span> button to go up one level
|
||
|
in the directory tree. Click the <span class="button">~</span> button to return
|
||
|
to your home directory. The <span class="button">/</span> button can be clicked
|
||
|
to go to the root directory of the file system.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The System Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/system.png" width="600" height="400"
|
||
|
alt="Hatari's GUI - the system dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
The system dialog can be used to define the basic hardware attributes of
|
||
|
the machine that should be emulated.
|
||
|
</p>
|
||
|
<p>
|
||
|
The machine type option is used to select the type of Atari computer to
|
||
|
be emulated. The ST was the very first 16/32-bit computer from Atari.
|
||
|
Most older games and demos require an ST. The STE was introduced some years
|
||
|
later and had some more advanced hardware features. There are not that many
|
||
|
demos or games that really require an STE but since most normal ST games/demos
|
||
|
also work with an STE, it's normally safe to always work in STE mode.
|
||
|
<br />
|
||
|
TT and Falcon are more advanced, but they are not as compatible to the ST as
|
||
|
the STE was. Therefore many old games and demos do not work with these machine
|
||
|
types anymore. There were only very few programs that were made for the TT
|
||
|
exclusively, while there were some interesting games and demos specially made
|
||
|
for the Falcon.
|
||
|
<br />
|
||
|
<em>Note:</em> Falcon and especially TT emulation are still considered as
|
||
|
experimental and incomplete.
|
||
|
Quite a bunch of programs do not work very well yet.
|
||
|
</p>
|
||
|
<p>
|
||
|
For STE emulation a STE compatible TOS image, e.q. version 1.06, 1.62 or
|
||
|
2.x, is strongly recommended. For TT emulation you need TOS 3.0x and for Falcon
|
||
|
emulation you need TOS 4.0x. EmuTOS can be used on all machine types.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
The CPU type option can be used to select the level of the central processing
|
||
|
unit. If you are not sure what to use, simply select 68000 for ST and STE
|
||
|
machines and 68030 for TT and Falcon emulation, since this were the original
|
||
|
configurations used in the Atari computers. In case you want to vary
|
||
|
the CPU type, you have got to be aware of some constraints:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
Atari ST and STE have only been shipped with a 68000 CPU, so for best
|
||
|
compatibility with old programs, you should choose this CPU type.
|
||
|
</li>
|
||
|
<li>
|
||
|
If you are going to use TOS 1.0x, you also have to select the 68000 CPU,
|
||
|
since these TOS versions are not aware of the higher CPU levels yet.
|
||
|
If you want to use a higher CPU level with the ST or STE machine type,
|
||
|
you've got to use TOS 2.0x instead.
|
||
|
</li>
|
||
|
<li>
|
||
|
Atari TT and Falcon computers were using the 68030 CPU, so you should select
|
||
|
the 68030 CPU type for these machines.
|
||
|
</li>
|
||
|
<li>
|
||
|
TOS 3.0x and 4.0x also only work with a CPU >= 68020.
|
||
|
</li>
|
||
|
<li>
|
||
|
68010 and 68040, 68060 have never been used in official Atari computers,
|
||
|
so don't use these CPU types unless you've got some good reasons.
|
||
|
</li>
|
||
|
<li>
|
||
|
The 68060 option is only available in the "WinUAE" builds of
|
||
|
Hatari, and is currently also considered as experimental, so do not use
|
||
|
this option unless you know what you are doing.
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
The CPU clock option can be used to select the frequency that is used
|
||
|
to clock the CPU. 8 Mhz is the standard for ST and STE and the most
|
||
|
compatible frequency for old software.
|
||
|
Use 16 MHz for Mega STE and Falcon emulation.
|
||
|
The CPU in the TT was clocked with 32 MHz.
|
||
|
</p>
|
||
|
<p>
|
||
|
For Falcon mode, you can choose whether you want to disable DSP emulation,
|
||
|
fake it or enable full emulation. Most Falcon programs only play sound or work
|
||
|
correctly when you enable the DSP emulation, but it needs a lot of host CPU
|
||
|
power (more than 2 GHz) for full emulation. So if you have a slow host CPU,
|
||
|
you can try if your Falcon program also runs with DSP disabled or in
|
||
|
the "dummy" fake mode.
|
||
|
Note that you can not change this option while the DSP based program already
|
||
|
runs.
|
||
|
</p>
|
||
|
<p>
|
||
|
The check boxes in the "CPU and system parameters" section can
|
||
|
be used to fine-tune the machine and CPU types.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you enable the "Real time clock emulation" switch, a RTC (like the ones
|
||
|
that could be found in the Mega-ST and Mega-STE computers) will be emulated
|
||
|
based on the time of the host computer.
|
||
|
This option is only affects the emulation of ST and STE machines. TT and
|
||
|
Falcon used a different kind of RTC (which is not optional and thus always
|
||
|
enabled in Hatari).
|
||
|
Note: You need at least TOS 1.02 for proper RTC emulation, TOS 1.00 does
|
||
|
not support this.
|
||
|
</p>
|
||
|
<p>
|
||
|
The next check box can be used to enable/disable Blitter emulation.
|
||
|
The Blitter is a custom chip that accelerates some graphical operations.
|
||
|
This switch only toggles the Blitter in plain ST mode. In STE and Falcon mode,
|
||
|
the Blitter is always enabled (since these machines have always been sold
|
||
|
with a Blitter chip). The TT was always shipped without the Blitter chip.
|
||
|
</p>
|
||
|
<p>
|
||
|
The "Patch Timer-D" option changes the Timer-D initialization from
|
||
|
TOS. TOS uses the MFP timer D as a baudrate generator for RS232. However, the
|
||
|
TOS default value slows down the emulation. The patch gives you a better
|
||
|
performance. It is normally safe to enable the patch, but if you encounter a
|
||
|
program that does not work, you can try to disable the patch to see if it
|
||
|
works better.
|
||
|
</p>
|
||
|
<p>
|
||
|
With the "Boot faster" option, Hatari patches the TOS ROM and some
|
||
|
system variables, to speed up the boot process of the emulated system, e.g.
|
||
|
by simulating a warm reset. This is a convenient option, but some very few old
|
||
|
programs rely on an unmodified boot process, so in rare cases this option has
|
||
|
to be switched off to get those programs running.
|
||
|
</p>
|
||
|
<p>
|
||
|
The "Prefetch mode" option is used to enable the emulation of 68k
|
||
|
address errors and the so-called CPU prefetch buffer. This is needed for best
|
||
|
compatibility, but it slows down emulation a little bit so you can disable it
|
||
|
if you don't need it and if you have a slow host system.
|
||
|
</p>
|
||
|
<p>
|
||
|
The "Cycle exact", the "MMU emulation" and
|
||
|
"24-bit addressing" option are only available in the
|
||
|
"WinUAE" builds
|
||
|
of Hatari. They are considered as experimental and should be switched off
|
||
|
unless you know what you are doing.
|
||
|
</p>
|
||
|
<p>
|
||
|
The FPU settings are also only available with the "WinUAE" builds
|
||
|
of Hatari. They can be used to select the type of floating point unit of CPUs
|
||
|
>= 68020. In the normal builds of Hatari, the FPU is always enabled for
|
||
|
68030 and 68040 CPUs.
|
||
|
</p>
|
||
|
<p>
|
||
|
<em>NOTE:</em> The emulated Atari system is very very sensitive to all of
|
||
|
these options and it is strongly recommended to reset the emulation after
|
||
|
changing them (for most things that's done automatically).
|
||
|
The correct CPU type and clock are automatically selected when one uses the
|
||
|
<span class="commandline">--machine</span> command line option.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Floppy Disks Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/floppydisks.png" width="640" height="320"
|
||
|
alt="Hatari's GUI - the floppy disks dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
This dialog can be used to choose which floppy disks should be emulated
|
||
|
in the disk drives. You can use most standard Atari ST disk image files.
|
||
|
You may select and browse also zipped disk images. See the chapter
|
||
|
<a href="#Floppy_disk_images">"Floppy disk images"</a> for details.
|
||
|
</p>
|
||
|
<p>
|
||
|
Each drive can be enabled or disabled (as if it was not connected or turned
|
||
|
off). You can also choose to emulate a single sided drive instead of a double
|
||
|
sided one (some games or demos will have a different behaviour in single sided
|
||
|
mode).
|
||
|
</p>
|
||
|
<p>
|
||
|
Click on the button <span class="button">Browse</span> next to the
|
||
|
A: and B: option to go to the fileselector to choose a disk image for the
|
||
|
corresponding drive.
|
||
|
</p>
|
||
|
<p>Click on <span class="button">Eject</span> to eject a disk image
|
||
|
from the emulated drive. The emulated ST will act as if had no floppy
|
||
|
disk in its drive.</p>
|
||
|
<p>You can specify a default directory where Hatari will start to
|
||
|
browse the filesystem.</p>
|
||
|
<p>
|
||
|
Check the "Auto insert B" option if you want Hatari to be smart and
|
||
|
insert the second disk of a two disk game automatically.
|
||
|
Some games then use the second drive automatically.
|
||
|
In the case that a game is not able to find the disk in the second drive,
|
||
|
you have to insert the second disk in drive A: manually when prompted.
|
||
|
<br />
|
||
|
<em>NOTE:</em> This option only works properly if the file name of the
|
||
|
first disks ends with an 'a' before the extension and the second disk name
|
||
|
ends with a 'b'.
|
||
|
</p>
|
||
|
<p>
|
||
|
Select if you want to use fast FDC (Floppy Disk Controller) emulation.
|
||
|
|
||
|
"Fast floppy access" option will speed up disk accesses, but this can
|
||
|
cause incompatibilities with programs that expect correct delays
|
||
|
(some games/demos don't expect data to be read too fast from the
|
||
|
disk). For example, when using STX images, most protections will fail
|
||
|
if fast floppy access is enabled.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you want, you can set Hatari to write-protect your disks. Atari ST
|
||
|
virii can spread on disk images, so that can be a good idea. However,
|
||
|
note that some programs won't work correctly (or at all) with write
|
||
|
protected disks, and things like saving highscores in games will fail.
|
||
|
</p>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/newfloppy.png" width="290" height="224"
|
||
|
alt="Hatari's GUI - the new floppy dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
If you need to create a new blank disk image, click on
|
||
|
<span class="button">Create blank image</span>.
|
||
|
Parameters for the new image can be set in the following dialog. HD
|
||
|
and ED disk sector counts are for larger, non-Atari disk sizes, they
|
||
|
can be useful with programs that don't work from hard drive, or with
|
||
|
with GEMDOS HD emulation.
|
||
|
Click on <span class="button">Create</span> to save the new image or on
|
||
|
<span class="button">Back</span> to return to the disk dialog.
|
||
|
</p>
|
||
|
<p>
|
||
|
After clicking <span class="button">Create</span>, a fileselector
|
||
|
appears. You can browse the filesystem now. Select the target directory,
|
||
|
click beside "File:" and type in a name for the new disk image.
|
||
|
The name should terminate with .st or .msa.
|
||
|
</p>
|
||
|
<p>
|
||
|
Hatari can currently create plain .ST and .MSA disk images exclusively.
|
||
|
<span class="commandline">hmsa</span> command line utility can be used
|
||
|
to convert disk images between .ST and .MSA formats.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Hard Disks Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/harddisks.png" width="640" height="304"
|
||
|
alt="Hatari's GUI - the hard disks dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
This dialog can be used to change the hard disk settings.
|
||
|
</p>
|
||
|
<p>
|
||
|
Here you can select a hard disk image file for ACSI, IDE master or
|
||
|
slave hard drive emulation, or you can select a host directory to be
|
||
|
emulated as the Atari hard drive.
|
||
|
</p>
|
||
|
<p>
|
||
|
Check "Boot from HD" if you want Hatari to execute the AUTO folder on
|
||
|
the hard disk. This option is checked by default if you specify a
|
||
|
hard disk image or a directory via the command line.
|
||
|
</p>
|
||
|
<p>
|
||
|
Removing the check from the "Allow GEMDOS drive modification" option
|
||
|
will prevent Atari programs from modifying the files in GEMDOS HD
|
||
|
emulation directory or creating new files under it.
|
||
|
</p>
|
||
|
<p>
|
||
|
Note that you need TOS version >= 2.05 to boot from IDE hard drive.
|
||
|
And ACSI hard drive emulation does not work with TOS 4.0x in Falcon mode.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Memory Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/memory.png" width="398" height="349"
|
||
|
alt="Hatari's GUI - the memory dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>You can select the amount of RAM for the emulated ST here. Only
|
||
|
amounts that were valid on a real unmodified STFM can be selected.</p>
|
||
|
<p><em>Note:</em> This option is critical and you are strongly advised
|
||
|
to reset the emulated ST
|
||
|
when changing this option.</p>
|
||
|
<p>Here you will find the options to save memory snapshots as well.</p>
|
||
|
<p>Click on <span class="button">Save</span> to save a memory snapshot
|
||
|
to file. You can select a new filename here.</p>
|
||
|
<p>Click on <span class="button">Restore</span> to restore a memory
|
||
|
snapshot from a file. Use the fileselector to select the snapshot to be
|
||
|
restored.</p>
|
||
|
<p><em>NOTE:</em> Memory snapshots are not interchangeable between
|
||
|
different versions of Hatari. E.q. if you compile a newer Hatari, you
|
||
|
cannot load your old memory snapshots back.</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The ROM Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/tos.png" width="519" height="367"
|
||
|
alt="Hatari's GUI - the ROM dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>Here you can select the TOS image to use. Click on <span
|
||
|
class="button">Browse</span> to select it via the fileselector.
|
||
|
You can also select an optional cartridge image to use. Click on <span
|
||
|
class="button">Browse</span> to select one via the fileselector. Click on <span
|
||
|
class="button">Eject</span> to disconnect the custom cartridge image.
|
||
|
</p>
|
||
|
<p>
|
||
|
For ST mode, use TOS 1.00, 1.02, 1.04 or 2.06.
|
||
|
For STE mode, use TOS 1.06, 1.62, 2.05 or 2.06.
|
||
|
If you want to use the TT mode, you must specify a TOS 3.06 image here.
|
||
|
And in Falcon mode, you have to use either TOS 4.00, 4.02, 4.04 or 4.92.
|
||
|
However, you should always use TOS 4.04 for Falcon mode, it's the most common one.
|
||
|
Also note that TOS 4.92 can not be booted from a boot disk (like it's done on a
|
||
|
real Falcon), you have to specify it directly in the TOS ROM setup dialog here.
|
||
|
</p>
|
||
|
<p>
|
||
|
Keep in mind that any custom cartridge image will not work together with
|
||
|
GEMDOS HD emulation or the VDI extended resolution emulation
|
||
|
since some additional driver code will be used in the cartridge memory
|
||
|
space for these emulations.
|
||
|
</p>
|
||
|
<p>
|
||
|
<em>Note:</em> These options are critical and you are strongly
|
||
|
advised to reset the emulated ST
|
||
|
when changing one of these option.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Joystick Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/joystick.png" width="320" height="288"
|
||
|
alt="Hatari's GUI - the joystick dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>In this dialog, you can configure the emulated joysticks.
|
||
|
With the upper two arrows, you can choose the joystick which you want to
|
||
|
configure.</p>
|
||
|
<p>Joystick 1 is the normal ST joystick port and 99.9% of all ST games
|
||
|
use this port.
|
||
|
Joystick 0 emulates a joystick plugged into the ST mouse port
|
||
|
and is often used in games for two players.</p>
|
||
|
<p>With STE joypad A and B, you can enable the emulation of Jaguar joypads
|
||
|
which are plugged in the enhanced joystick ports of the Atari STE.
|
||
|
Only very few STE games support these joypads, so you often won't need this.</p>
|
||
|
<p>Finally, Hatari also emulates joysticks which were plugged on the parallel
|
||
|
port with a special adapter on a real ST. These were used in some few
|
||
|
multi-player games like "Gauntlet 2".</p>
|
||
|
<p>For each ST joystick, choose whether you want to disable it,
|
||
|
use the keyboard for emulation or use a real PC joystick.</p>
|
||
|
<p>For keyboard emulation, you can select the keys by pressing the
|
||
|
<span class="button">Define keys</span> button. You will be prompted to press
|
||
|
the keys for up, down, left, right and fire.</p>
|
||
|
<p>If you want to use a real PC joystick for the emulation, you should connect
|
||
|
it to your PC before you start Hatari. Then you can choose the joystick with
|
||
|
the two lower arrows.</p>
|
||
|
<p>Check the "Enable autofire" option if you are too lazy to pound
|
||
|
on the fire button in shoot'em-up games. However, this option only works with
|
||
|
certain games. In some other games, it gets worse if you enable this option.</p>
|
||
|
<p>See also the chapter "Emulated Joystick" for details.</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Atari Monitor Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/monitor.png" width="340" height="304"
|
||
|
alt="Hatari's GUI - the Atari monitor dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
Here you control the video output of the emulated Atari.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can select which sort of monitor to use. This option depends on
|
||
|
the machine type which you have selected in the "System options"
|
||
|
dialog. In ST and STE mode, you can choose between monochrome mode
|
||
|
(select "Mono") and color mode (select one of the other monitor types).
|
||
|
Note that when you select "TV" and use zoomed low resolution or
|
||
|
switch to ST medium resolution, you will get a TV-like screen rendering
|
||
|
which is a little bit faster but darker compared to the normal "RGB"
|
||
|
monitor mode. Switching between mono and a color monitor acts like a monitor
|
||
|
switch on a real ST - so beware, this will reboot your emulated system!<br />
|
||
|
In TT mode, you can only choose between TT-high resolution ("Mono")
|
||
|
and normal modes (select one of the other monitor types).
|
||
|
Finally the Falcon mode supports all four types of monitors. Note that most
|
||
|
Falcon demos/games require a RGB or TV mode, and do not work with
|
||
|
VGA, although there are also few VGA-only games and demos.
|
||
|
</p>
|
||
|
<p>
|
||
|
"Show ST/STE borders" toggles the displaying of the borders around the ST /
|
||
|
STE. Some demos and games use the screen borders for displaying
|
||
|
additional graphics. As enabling this option increases CPU computing time,
|
||
|
don't enable it if you have a very slow computer.
|
||
|
Borders are shown also in Falcon emulation, but Videl emulation doesn't
|
||
|
yet support palette effects.
|
||
|
This option doesn't affect TT screen mode or extended VDI resolutions.
|
||
|
</p>
|
||
|
<p>
|
||
|
Extended VDI resolutions will emulate a sort of extended graphics card
|
||
|
in the emulated machine, which gives you larger (2-16 color)
|
||
|
resolutions for GEM. Select a resolution and color depth. Check to
|
||
|
activate. This mode isn't affect by the other video options mentioned
|
||
|
above. Uncheck to get back to a normal ST behaviour.<br />
|
||
|
</p>
|
||
|
<p><em>Note that there are several gotches with extended VDI
|
||
|
resolutions:</em></p>
|
||
|
<ul>
|
||
|
<li>Only GEM conformant applications work with them, 99% of all games
|
||
|
and demos don't.</li>
|
||
|
<li>Several GEM programs accessing screen directly (like NVDI) crash
|
||
|
with large enough screen sizes.</li>
|
||
|
<li>Memory reserved for (larger) extended resolutions breaks TOS v3 memory
|
||
|
detection, so you need to interrupt boot up memory detection.</li>
|
||
|
<li>TOS v4 isn't compatible with them. In Falcon emulation you need to
|
||
|
use EmuTOS with extended resolutions.</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
Because TT and Falcon support natively larger resolutions,
|
||
|
VDI mode is most useful with ST / STE emulation.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Hatari Screen Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/screen.png" width="520" height="320"
|
||
|
alt="Hatari's GUI - the Hatari screen dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>
|
||
|
Here you control how the video output of the emulated Atari appears
|
||
|
on your screen.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Check "Fullscreen" to run Hatari in fullscreen. By default Hatari
|
||
|
runs in windowed mode.
|
||
|
</p>
|
||
|
<p>
|
||
|
The "Frame Skip" option can be used to speed up the emulator
|
||
|
if it is running too slow on your system. Disable frame-skip if you have
|
||
|
a fast computer. When selecting 1, 2 or 4, drawing of corresponding number
|
||
|
of frames will be skipped after each frame actually shown by Hatari.
|
||
|
Select "Auto" to let the emulator to decide whether, and
|
||
|
how many frames will be skipped.<br />
|
||
|
<em>Note:</em> The frameskip option also affects the frame rate of the
|
||
|
screen animation recording!
|
||
|
</p>
|
||
|
<p>
|
||
|
Indicators that you can have on the Hatari window:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>"Statusbar" at the bottom of the screen.
|
||
|
The statusbar shows the floppy drive LEDs, the current frameskip value,
|
||
|
the machine type including TOS version and memory size, and whether
|
||
|
recording is currently active.</li>
|
||
|
<li>"Drive led" is a colored rectangle shown on top of the Hatari window
|
||
|
contents. It will show any disk (floppy or hard drive) activity.</li>
|
||
|
<li>"None" turns both of above options off.</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
"Keep desktop resolution" option will use your desktop resolution
|
||
|
for fullscreen to avoid issues related to resolution switching,
|
||
|
especially on LCD monitors (they're slow). If this isn't enabled,
|
||
|
values from the "Max zoomed win" option are used in selecting
|
||
|
a suitable resolution.
|
||
|
<p>
|
||
|
"Max zoomed win" option controls up to which size Hatari tries to scale
|
||
|
the Atari resolutions and how much of the borders (enabled in Atari
|
||
|
Monitor dialog) will be shown. Note that there are several limitations
|
||
|
in this and the "Keep desktop resolution" option, partly because Hatari
|
||
|
has different implementations for different video modes:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>VDI resolutions (selectable in Atari Monitor dialog) aren't scaled.</li>
|
||
|
<li>ST and STE video emulation supports only doubling of the ST-low
|
||
|
resolution.</li>
|
||
|
<li>Hatari doesn't support downscaling. If the original Atari resolution
|
||
|
is larger than the specified size (e.g. TT-high), the Hatari screen
|
||
|
size will also be larger than requested. Hatari Falcon/TT window size
|
||
|
will be limited to the Desktop size though.</li>
|
||
|
<li>TT and Falcon resolutions support only <em>integer</em> scaling ratios.
|
||
|
If the scaling ratio cannot match the requested size exactly, Hatari
|
||
|
will use a ratio that will produce smaller size closest to the
|
||
|
requested one.</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
You should set these values to a size that suits best your monitor
|
||
|
resolution. It's intended to help in getting Hatari to best use your
|
||
|
monitor space on a windowed mode and in fullscreen avoiding "fuzzy"
|
||
|
scaling done by your LCD monitor.
|
||
|
</p>
|
||
|
<p>
|
||
|
Giving "-z 2" option on command line will reset max zoomed size to
|
||
|
default values and "-z 1" will disable all zooming.
|
||
|
Note that zooming takes additional CPU computing time and should
|
||
|
not be enabled on very slow computers.
|
||
|
</p>
|
||
|
<p>Click the <span class="button">Screenshot</span> button to create
|
||
|
a screenshot in PNG (or BMP) format to the current working directory
|
||
|
or click the <span class="button">Record AVI</span> button to
|
||
|
record an AVI format video of Hatari screen (and audio) output.
|
||
|
</p>
|
||
|
<p>
|
||
|
Selecting "Crop statusbar" option will leave statusbar out from
|
||
|
the screenshots and recorded videos.
|
||
|
</p>
|
||
|
|
||
|
<h4 class="gui">The Keyboard Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/keyboard.png" width="459" height="223"
|
||
|
alt="Hatari's GUI - the keyboard dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>Here you can select the keyboard mapping to use. Two different mappings
|
||
|
called "Symbolic" and "Scancode" are predefined.</p>
|
||
|
<p>"Symbolic" tries to map the symbolic values of your PC keys
|
||
|
to the ST keys. It should be working pretty good on all systems as long
|
||
|
as your keyboard layout looks close to the standard english keyboard
|
||
|
layout. However, you might experience some problems with special keys like
|
||
|
brackets etc.</p>
|
||
|
<p>"Scancode" uses the scancode values of your PC keys for keyboard
|
||
|
mapping. This only works on certain architectures like Linux where the
|
||
|
scancodes are similar to the ST scancodes (e.g. it does not work on Mac OS X).
|
||
|
If it works on your system, this often gives better results than the symbolic
|
||
|
mapping. Note that you also need a TOS version with the right language
|
||
|
(e.g. use a French TOS if you are using a French keyboard).</p>
|
||
|
<p>You can also load a custom keyboard mapping file here if you wish. Please
|
||
|
note that the custom keyboard mapping will use the "symbolic"
|
||
|
mapping for all keys that are not defined by your map file. Have a look
|
||
|
at the supplied example mapfile (keymap-sample.txt) to see how to create
|
||
|
your own keyboard mapping.</p>
|
||
|
<p>
|
||
|
When the emulator runs in fast forward mode, and you want to type text,
|
||
|
it can be annoying that the emulated system detects multiple key events
|
||
|
due to the key repetition of the emulated system. To avoid this you can
|
||
|
disable the key repetition in fast forward mode here.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Sound Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/sound.png" width="400" height="400"
|
||
|
alt="Hatari's GUI - the sound dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>Here you can control the sound subsystem.</p>
|
||
|
<p>Check "Enabled" if you want emulated sound at all. Emulation is faster if
|
||
|
sound emulation is turned off.</p>
|
||
|
<p>If you experiment latency issues with your OS audio's output, you
|
||
|
can check the "Synchronize" option to adjust Hatari's video emulation to match
|
||
|
your OS audio.</p>
|
||
|
<p>
|
||
|
Nine frequencies from low to high quality are available. Experiment a
|
||
|
little bit to find out which fits best for your setup.
|
||
|
For most modern computers, 44100 Hz or 48000 Hz should be fine.
|
||
|
For older or slower host systems, you should use a lower frequency.
|
||
|
12517, 250033 and 50066 Hz are frequencies supported by
|
||
|
the STE/TT/Falcon sound DMA.
|
||
|
</p>
|
||
|
<p>
|
||
|
YM voices volume mixing "ST table" method uses a lookup table of audio output
|
||
|
voltage values measured on STF, "Math model" uses a complex model to mix the
|
||
|
3 YM voices and "Linear" just averages the 3 YM voices. Use "ST table" or "Math model"
|
||
|
for accurate sound's emulation.
|
||
|
</p>
|
||
|
<p>
|
||
|
You can select to record a piece of sound here.
|
||
|
Use the <span class="button">Browse</span> button to choose a file.
|
||
|
The file name extension that you use (.WAV or .YM) determines in which format
|
||
|
the sound is recorded in. The <span class="button">Record sound</span> button
|
||
|
is a toggle so you will need to return to the GUI to switch sound recording off
|
||
|
again (or to use the keyboard shortcut for that).
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 class="gui">The Devices Dialog</h4>
|
||
|
|
||
|
<div class="floatimage">
|
||
|
<img src="images/devices.png" width="520" height="383"
|
||
|
alt="Hatari's GUI - the device dialog" />
|
||
|
</div>
|
||
|
|
||
|
<p>Check the first checkmark to enable printer support.
|
||
|
See the <a href="#Emulated_printer">Emulated printer</a> section for
|
||
|
details.</p>
|
||
|
|
||
|
<p>As Hatari currently only supports printing to file, click on <span
|
||
|
class="button">Browse</span> to select the file to print to. You can
|
||
|
enter a new filename as well.</p>
|
||
|
<p>Check the second checkmark to enable RS232 support.
|
||
|
The RS232 device is configured according to the settings of
|
||
|
the emulated RS232 of the Atari ST. This means Hatari will
|
||
|
automatically use baudrate and handshaking as configured for the
|
||
|
emulated ST.</p>
|
||
|
<p>Click on <span class="button">Browse</span> to select suitable
|
||
|
device files for serial input and output. On Linux a good choice is
|
||
|
/dev/ttyS0 or /dev/ttyS1.
|
||
|
</p>
|
||
|
<p>Check the third checkmark to enable MIDI support.
|
||
|
Click on <span class="button">Browse</span> to select a suitable
|
||
|
MIDI device files for MIDI input and output.</p>
|
||
|
<p><span class="file">midi-linux.txt</span> file explains how to
|
||
|
select the correct MIDI device file, how to set up software sound
|
||
|
synthetizing on Linux (using Alsa) if your sound card/driver doesn't
|
||
|
support MIDI, and how to set up MIDI networking e.g. between multiple
|
||
|
Hatari instances.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3 class="clearboth">Keyboard shortcuts for the SDL GUI</h3>
|
||
|
|
||
|
<p>There are multiple ways to interact with the SDL GUI.</p>
|
||
|
|
||
|
<p>TAB and cursor keys change focus between UI elements. Additionally
|
||
|
Home key moves focus to first item, End key to last one. Initially
|
||
|
focus is on default UI element, but focus changes are remembered
|
||
|
between dialog invocations. Enter and Space invoke focused item. UI
|
||
|
elements with underlined characters can be invoked directly with Alt +
|
||
|
key with that character. Alt + arrow keys will act on arrow
|
||
|
buttons.</p>
|
||
|
|
||
|
<p>Most importantly:</p>
|
||
|
<ul>
|
||
|
<li><em>Options GUI main view</em>: Enter accepts configuration, ESC
|
||
|
cancels it.</li>
|
||
|
<li><em>Options GUI dialogs</em>: Enter (or End+Enter if focus was moved)
|
||
|
returns back to main view.</li>
|
||
|
<li><em>Fileselector</em>: Page up and down keys scroll the file list.
|
||
|
Enter on focused file name selects it. Enter on OK button accepts
|
||
|
the selected file. ESC cancels the dialog/selection.</li>
|
||
|
<li><em>Alert dialogs</em>: Enter accepts and ESC cancels the dialog.</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h3>Keyboard shortcuts during emulation</h3>
|
||
|
|
||
|
<p> While the emulator is running, you can activate or toggle various
|
||
|
features via Hatari keyboard shortcuts. Below are listed the default
|
||
|
shortcut key bindings:</p>
|
||
|
<table class="keytable">
|
||
|
<thead>
|
||
|
<tr class="backdropped">
|
||
|
<th>Shortcut</th>
|
||
|
<th>Purpose</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+a</span></td>
|
||
|
<td>record animation</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+g</span></td>
|
||
|
<td>grab a screenshot</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+i</span></td>
|
||
|
<td>boss key: leave full screen mode, pause Hatari
|
||
|
and iconify its window</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+m</span></td>
|
||
|
<td>(un-)lock the mouse into the window</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+r</span></td>
|
||
|
<td>(warm) reset the ST</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+c</span></td>
|
||
|
<td>coldreset the ST (same as the original power switch)</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+d</span></td>
|
||
|
<td>open dialog to select/change disk A</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+s</span></td>
|
||
|
<td>enable/disable sound</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+q</span></td>
|
||
|
<td>quit the emulator</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+x</span></td>
|
||
|
<td>toggle normal speed/fast forward</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+y</span></td>
|
||
|
<td>enable/disable sound recording</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+k</span></td>
|
||
|
<td>save memory snapshot</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+l</span></td>
|
||
|
<td>load memory snapshot</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+j</span></td>
|
||
|
<td>toggle joystick emulation via cursor keys
|
||
|
on/off between ports 0 and 1</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+F1</span></td>
|
||
|
<td>switch joystick type on joy port 0</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+F2</span></td>
|
||
|
<td>switch joystick type on joy port 1</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+F3</span></td>
|
||
|
<td>switch joystick type for joypad A</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+F4</span></td>
|
||
|
<td>switch joystick type for joypad B</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+f or F11</span></td>
|
||
|
<td>toggle between fullscreen and windowed mode</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">ALTGR+o or F12</span></td>
|
||
|
<td>activate the options GUI</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">PAUSE</span></td>
|
||
|
<td>pause emulation</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">AltGr+PAUSE</span></td>
|
||
|
<td>invoke the internal Hatari debugger</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
|
||
|
<p>You can change the key bindings from the Hatari configuration file.
|
||
|
See keymap-sample.txt file for instructions.</p>
|
||
|
|
||
|
|
||
|
<h3>Emulated Atari ST keyboard</h3>
|
||
|
|
||
|
<p> All other keys on the keyboard act as the normal Atari ST keys so
|
||
|
pressing SPACE on your PC will result in an emulated press of the SPACE
|
||
|
key on the ST. The following keys have special meanings: </p>
|
||
|
|
||
|
<table class="keytable">
|
||
|
<thead>
|
||
|
<tr class="backdropped">
|
||
|
<th>Key</th>
|
||
|
<th>Meaning</th>
|
||
|
</tr>
|
||
|
</thead>
|
||
|
<tbody>
|
||
|
<tr>
|
||
|
<td><span class="key">Alt</span></td>
|
||
|
<td>will act as the ST's ALTERNATE key</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">left CTRL</span></td>
|
||
|
<td>will act as the ST's CONTROL key</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">Print Screen</span></td>
|
||
|
<td>will emulate the ST's HELP key</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">Scroll Lock</span></td>
|
||
|
<td>will emulate the ST's UNDO key</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">Page Up</span></td>
|
||
|
<td>will emulate the ST's ( key in the keypad</td>
|
||
|
</tr>
|
||
|
<tr>
|
||
|
<td><span class="key">Page Down</span></td>
|
||
|
<td>will emulate the ST's ) in the keypad</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
|
||
|
<p>If joystick emulation via keyboard is enabled, by default cursor keys
|
||
|
are used for the directions and <span class="key">right CTRL</span> key
|
||
|
as the fire button. Otherwise they act as corresponding keys of the emulated
|
||
|
Atari ST.</p>
|
||
|
|
||
|
<p>NOTE: Problems with simultenous keypresses most likely aren't an
|
||
|
issue in Hatari as many modern keyboards report/support only three
|
||
|
simultenous key presses (or even just two depending on which keys
|
||
|
are in question). Expensive gaming keyboards support more.</p>
|
||
|
|
||
|
|
||
|
<h3>Emulated mouse</h3>
|
||
|
|
||
|
<p>For obvious reasons your PC mouse will act as the emulated Atari ST
|
||
|
mouse. In fullscreen mode it will act as expected, directly controlling
|
||
|
the ST mouse pointer. </p>
|
||
|
<p>However it is a little bit different in windowed mode as
|
||
|
mouse cursor positions between host and emulated Atari can get
|
||
|
out of sync. This can be worked around by constraining the mouse
|
||
|
to the Hatari window. Pressing the <span class="key">ALTGR+m</span>
|
||
|
hotkey combination or starting Hatari with the
|
||
|
<span class="commandline">--grab</span> command line option
|
||
|
grabs the mouse i.e. locks its movements to the Hatari window.
|
||
|
Press the shortcut key (again) to go back to normal mouse behaviour
|
||
|
which allows you to move mouse outside outside the Hatari window while
|
||
|
Hatari is up and running. Note: pausing the emulation will also
|
||
|
(temporarily) release the mouse grab.</p>
|
||
|
<p>Middle button click emulates double click, which is very useful
|
||
|
in Fast Forward mode (where normal double clicking is nearly
|
||
|
impossible).</p>
|
||
|
<p>Mouse scrollwheel will act as cursor up and down keys. </p>
|
||
|
|
||
|
<h3>Emulated joystick</h3>
|
||
|
|
||
|
<p>The Atari ST joysticks are emulated ofcourse allowing you to play
|
||
|
your favourite games with Hatari. </p>
|
||
|
<p>The default mode is to use a connected PC joystick. You can use any
|
||
|
joystick that is supported by your kernel / SDL library. If your joystick works
|
||
|
with other applications, it will likely work with Hatari as well. Make sure
|
||
|
it is calibrated and then off you go. Move the stick to point into the
|
||
|
desired direction. Please note that Hatari will not detect analogue
|
||
|
movement as the Atari ST only had digital joysticks. The first
|
||
|
firebutton will act as the normal firebutton on the Atari ST while the
|
||
|
second
|
||
|
firebutton will emulate a keypress of the <span class="key">SPACE</span>
|
||
|
key on the ST as many ST
|
||
|
games utilize the SPACE bar for secondary game functions. (Xenon for
|
||
|
example)</p>
|
||
|
<p>If you do not have a PC joystick or joypad, then you do not need to
|
||
|
desperate. You can emulate one of the two Atari ST joysticks via the
|
||
|
cursor keys. Just activate it in the GUI. Then the cursor keys will act
|
||
|
as the joystick directions, the right CTRL key will act as the
|
||
|
firebutton. You can still use the cursor keys as the ST's
|
||
|
cursorkeys in this mode as long as you press <span class="key">SHIFT</span>
|
||
|
along with the cursorkeys. You can also configure these keys from the
|
||
|
joystick options.</p>
|
||
|
|
||
|
<h3>Emulated video</h3>
|
||
|
|
||
|
<p>Hatari emulates all screen modes of the original machine.</p>
|
||
|
<p>
|
||
|
ST/STE shifter overscan effects are emulated, but due to the fact
|
||
|
that these effects are achieved by using quirks and glitches in the
|
||
|
original chips to do things beyond their specification, emulation is
|
||
|
a bit tricky for these effects. As a result, some demos using these
|
||
|
techniques might not be displayed correctly in Hatari, known ones are
|
||
|
listed in the <span class="file">compatibility.html</span> file.
|
||
|
</p>
|
||
|
<p>Beside that you can setup extended VDI modes. These only work with
|
||
|
GEM-compliant applications and they are equal to fitting a videocard
|
||
|
into your Mega ST.</p>
|
||
|
<p>Make sure to disable extended VDI modes for playing games as 99% of
|
||
|
all ST games will not be able to make use of higher resolutions.</p>
|
||
|
|
||
|
<h3 id="Emulated_printer">Emulated printer</h3>
|
||
|
|
||
|
<p>Due to the fact that printer handling is different on Atari and
|
||
|
current machines, emulation of the printer is achieved by writing all
|
||
|
printer output to a file.</p>
|
||
|
<p>The file will contain a sequence of data, the same that would appear
|
||
|
on the data pins of the Atari ST printer port.
|
||
|
That would include control characters and commands for graphic
|
||
|
printing. Clicking "Print desktop" on the GEM desktop would result
|
||
|
in a messy data dump in the printer output.</p>
|
||
|
<p>Printer emulation works best for plain text files or programs that
|
||
|
do not format the output for a specific printer.
|
||
|
The file contents can be used with your favourite text editor for
|
||
|
further processing and printing to a real printer.</p>
|
||
|
<p>To get real direct printing out of Hatari you may set up a suitable
|
||
|
(e.g. PostScript) GDOS or NVDI printer driver on the emulated Atari and
|
||
|
set your printer device file as Hatari's printer output.<br />
|
||
|
<em>NOTE:</em> If the driver doesn't match or there's some other problem,
|
||
|
this can cause your printer to print out hundreds of pages of garbage.</p>
|
||
|
|
||
|
<h3>Emulated RS232</h3>
|
||
|
|
||
|
<p>Serial communications in Hatari is designed to directly use a serial
|
||
|
port on your PC.</p>
|
||
|
<p>Communications parameters are set automatically upon the settings of
|
||
|
the emulated ST. This means all you do is to set
|
||
|
the communication parameters like baudrate from your ST communications
|
||
|
software. Hatari will do the rest and handle
|
||
|
the serial input and output for you.</p>
|
||
|
|
||
|
<h2 id="Floppy_disk_images">Floppy disk images</h2>
|
||
|
|
||
|
<p>Hatari does not use floppy disks directly but disk images due to
|
||
|
differences between the floppy disk controllers of the ST and the PC.
|
||
|
Several types of disk images are currently supported :
|
||
|
</p>
|
||
|
|
||
|
<ul>
|
||
|
<li>
|
||
|
the raw "ST" type
|
||
|
</li>
|
||
|
<li>
|
||
|
the similar "DIM" type (not widely used)
|
||
|
</li>
|
||
|
<li>
|
||
|
the compressed "MSA" (Magic-Shadow-Archiver) type
|
||
|
</li>
|
||
|
<li>
|
||
|
the "STX" type that can store low level disk layout. This format is mainly
|
||
|
used to dump original games with their protection. Those images are created
|
||
|
on a real ST using pasti.prg
|
||
|
</li>
|
||
|
<li>
|
||
|
the "IPF", "RAW" and "CTR" types require the caps library. Similar to STX, they
|
||
|
record disk layout, but at a much precise level by storing MFM data. Most of
|
||
|
these dumps are made with the Kryoflux board
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p> The raw type (file suffix should be "*.st") is simply a sector by
|
||
|
sector image of a real floppy disk. You can easily create such an image
|
||
|
with the <span class="commandline">dd</span> program which should
|
||
|
normally be pre-installed on every
|
||
|
Unix-like system. Simply type something like <span class="commandline">dd
|
||
|
if=/dev/fd0 of=myimage.st</span> to create a disk image. Of course you
|
||
|
need access to
|
||
|
/dev/fd0, and depending on your system and the type of floppy disk you
|
||
|
might have to use another device name here (for example I use
|
||
|
/dev/fd0u720 for 720kB disks). However, if the disk is copy-protected
|
||
|
or
|
||
|
doesn't use a MSDOS compatible file system, this might fail. So be very
|
||
|
careful if you are not sure about the disk format. </p>
|
||
|
<p> The other possibility is to image the disk on a real Atari ST.
|
||
|
For non-protected disk, there
|
||
|
are programs like the Magic Shadow Archiver for this task. Hatari
|
||
|
supports this slightly compressed MSA disk images, too. Note that
|
||
|
Hatari
|
||
|
only supports the "old" MSA format, there are some Magic Shadow
|
||
|
Archiver
|
||
|
clones (like Jay-MSA) that create better compressed but
|
||
|
Hatari-incompatible disk images. However, if you have got such a MSA
|
||
|
disk and want to use it with Hatari, you can still run the
|
||
|
corresponding
|
||
|
MSA program within Hatari to extract the incompatible disk image to a
|
||
|
normal floppy disk image.
|
||
|
<p>
|
||
|
For protected disk, the most widely used method is to run pasti.prg on
|
||
|
a real Atari ST and get a .STX image.
|
||
|
<br>
|
||
|
For more complex protections or altered disk, one can use *.IPF or *.CTR
|
||
|
which include tools to check MFM data and possible problems when dumping a disk.
|
||
|
</p>
|
||
|
<p> While *.ST, *.MSA and *.STX are more or less the "standard" types of Atari
|
||
|
disk images, you might sometimes also find STT or ADF images on the
|
||
|
internet. These currently do not work with Hatari. </p>
|
||
|
<p>Hatari can now also utilize *.DIM images just as *.ST ones without
|
||
|
any problems.
|
||
|
Note that DIM images are nearly the same as the raw ST images
|
||
|
(they only have an additional 32 bytes header), so you can easily
|
||
|
transform
|
||
|
the DIM images into ST images by stripping the header from the files.
|
||
|
For example try something like:
|
||
|
<span class="commandline">dd if=input.dim of=output.st bs=32 skip=1</span>
|
||
|
</p>
|
||
|
<p> If you've got a disk image that has been created with the old ST
|
||
|
emulator PaCifiST (for DOS) or with early versions of the program
|
||
|
Makedisk, and the disk image does not work with Hatari, then the disk
|
||
|
probably suffers from the "PaCifiST bootsector bug" (Hatari will
|
||
|
display a
|
||
|
warning message then). In this case, the bootsector of the disk
|
||
|
contains some illegal data, so that the disk even does not work on a
|
||
|
real ST any more. However, if it is a .ST and not a .MSA disk, you can
|
||
|
easily fix it by using a hex-editor to change the byte at offset $D
|
||
|
(13)
|
||
|
from 0 to 1 (don't forget to backup your disk image first, since you
|
||
|
can also easily destroy your disk image when changing a wrong byte
|
||
|
there). If the disk contains a bootsector program, you probably have to
|
||
|
adjust the boot sector check sum, too (it can be found at offset $1FE +
|
||
|
$1FF). </p>
|
||
|
<p>Hatari supports disk images that are compressed with (Pk-)ZIP
|
||
|
(file suffix must be ".zip") or GZip (file suffix must be ".st.gz" or
|
||
|
".msa.gz"), so you can archive your disk images into zip archives.
|
||
|
You can also directly run the zip archives you may download from the
|
||
|
net as long as the archive contains a disk image in .ST or .MSA format.</p>
|
||
|
<p><em>Note:</em> Hatari does not save disk images back to *.ZIP files
|
||
|
so
|
||
|
your highscores and savegames are lost if you load the game from such
|
||
|
a zipped disk image.</p>
|
||
|
|
||
|
|
||
|
<h2>Hard disk support</h2>
|
||
|
|
||
|
<p>
|
||
|
Hatari supports three ways of emulating Atari hard drives: The
|
||
|
low-level ACSI and IDE hard drive emulation and a GEMDOS based HD
|
||
|
emulation. In most cases the GEMDOS HD emulation is best as it allows
|
||
|
exchanging files easily between the emulated and the host environment.
|
||
|
</p>
|
||
|
<p>
|
||
|
Please note that changing the HD-image or the GEMDOS HD-folder will reset
|
||
|
the emulated Atari since it is not possible to switch the hard drive
|
||
|
while the emulator is running.
|
||
|
</p>
|
||
|
<p>
|
||
|
On a 32-bit host system, the size of a hard disk image is limited to 2 GB.
|
||
|
On 64-bit host systems, bigger images might be possible but the support
|
||
|
for bigger images is not tested very well yet.
|
||
|
</p>
|
||
|
<p>
|
||
|
The maximum size of partitions inside the hard disk (images) depends on the
|
||
|
TOS version. TOS 1.00 and 1.02 support up to 256 MB, TOS 1.04 to 3.06 up to
|
||
|
512 MB and TOS 4.0x supports up to 1 GB partitions.
|
||
|
</p>
|
||
|
<p>
|
||
|
NOTE: you need to be careful when mounting device files. Depending on
|
||
|
the system setup (e.g. udev settings) partitions on memory cards etc.
|
||
|
can be mounted automatically. When Hatari is started and uses a device
|
||
|
file with partitions that are already mounted, data can be destroyed
|
||
|
(when several programs independently write to the same device).
|
||
|
Disable your desktop automount, or remember to manually unmount
|
||
|
devices before giving them to Hatari.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>GEMDOS based hard drive emulation</h3>
|
||
|
<p>
|
||
|
With the GEMDOS HD emulation, you can easily "mount" a folder from the
|
||
|
host file system to a drive of the emulated Atari.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you provide Hatari a directory containing only single letter (C-Z)
|
||
|
subdirectories, each of these subdirectories will be treated as a
|
||
|
separate partition, otherwise the given directory itself will be
|
||
|
assigned to drive "C:". In the multiple partition case, the letters
|
||
|
used as the subdirectory names will determine to which
|
||
|
drives/partitions they're assigned. For example following
|
||
|
directory setup:
|
||
|
</p>
|
||
|
<pre>
|
||
|
partitions/
|
||
|
+ C/
|
||
|
+ D/
|
||
|
</pre>
|
||
|
<p>
|
||
|
That is given to Hatari as "hatari -d partitions", will give you
|
||
|
GEMDOS HD emulated C: and D: drives.
|
||
|
</p>
|
||
|
<p>
|
||
|
GEMDOS HD emulation is an easy way to share files between the
|
||
|
host system and the emulated Atari, but there are also some known
|
||
|
limitations which are due to the way the GEMDOS HD emulation is
|
||
|
implemented:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>Directory entries are returned in a (case-insensitively) sorted
|
||
|
order, for consistency. E.g. moving files to a different directory and
|
||
|
back (without changing their names) like AUTOSORT does, doesn't change
|
||
|
that order. You need to rename the files.</li>
|
||
|
<li>Names which aren't valid TOS directory or file names, are converted
|
||
|
to a valid format. If there are multiple files which converted
|
||
|
names are identical in TOS-format, you see only one of those.</li>
|
||
|
<li>It is not possible to use a cartridge image at the same time
|
||
|
with the GEMDOS HD emulation (Hatari has its own cartridge code
|
||
|
that is used for GEMDOS HD emulation).</li>
|
||
|
<li>Anything that installs its own GEMDOS handler, like MiNT, doesn't work
|
||
|
with the GEMDOS HD emulation. Such things need to be run from a real
|
||
|
hard disk image.</li>
|
||
|
<li>GEMDOS HD C: drive conflicts with the ACSI and IDE hard drives.
|
||
|
If you want to use GEMDOS HD directory and ACSI/IDE disk images together,
|
||
|
either use the GEMDOS HD option for skipping ACSI & IDE partitions, or
|
||
|
use a multiple partition GEMDOS HD emulation setup and select the partition
|
||
|
subdirectories (see above) so that they don't conflict with the ACSI/IDE
|
||
|
partitions (drive letters). With HD Driver you have also another option,
|
||
|
see <a href="#Using_HD_Driver_with_GEMDOS_partitions">Using HD Driver
|
||
|
with GEMDOS HD partitions</a>.</li>
|
||
|
<li><em>The GEMDOS HD emulation does not work (very well) with TOS
|
||
|
1.00 and 1.02</em>. Use at least TOS 1.04 if you want the GEMDOS HD
|
||
|
emulation to work properly.</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
If your programs complain that they could not find/read/write
|
||
|
files on the GEMDOS emulated drive, you can copy and use them
|
||
|
from a floppy disk image or a real hard disk image instead.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>ACSI & IDE hard drive emulation with EmuTOS</h3>
|
||
|
|
||
|
<p>
|
||
|
Accessing HD image files is easiest with EmuTOS. It supports both
|
||
|
ASCI and IDE interfaces, regardless of emulated machine type, and
|
||
|
understands DOS partition tables without additional drivers.
|
||
|
<span class="commandline">atari-hd-image.sh</span> script coming
|
||
|
with Hatari can be used to create such image files and to copy
|
||
|
initial data to them.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you have an hard drive (image) with Atari format partition table,
|
||
|
that should already have hard disk driver on it and work fine.
|
||
|
Partitioning/formatting them is the problem. Creating such images
|
||
|
from scratch is described in following sections.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3 id="ACSI_hard_drive_emulation">ACSI hard drive emulation</h3>
|
||
|
<p>
|
||
|
To use the ACSI hard drive emulation, you need a hard disk image file
|
||
|
with a pre-installed HD driver in it. You can try to get an image of
|
||
|
your old ST hard disk or grab one from the internet (e.g. from the
|
||
|
Hatari website).
|
||
|
Please note that the size of ACSI hard drive is normally limited to 1 GB
|
||
|
due to some addressing constraints of the ACSI bus. Bigger disks were only
|
||
|
possible with certain host adapters – this behaviour is emulated by
|
||
|
Hatari, too, but you need a hard disk driver that supports these extensions.
|
||
|
</p>
|
||
|
<p>
|
||
|
To create a <em>new</em> ACSI hard disk image, you can start with an empty
|
||
|
image that you have created for example with the following command:
|
||
|
<span class="commandline">dd if=/dev/zero of=hd.img bs=512 count=xxx</span>
|
||
|
(where 'xxx' is size in 512 byte blocks). Copy the complete AHDI 5.0
|
||
|
package to a floppy disk image, then boot Hatari with this floppy disk
|
||
|
image and the fresh hard disk image like this:
|
||
|
<span class="commandline">--acsi hd.img ahdi.st</span>.
|
||
|
Then start HDX.PRG from the floppy disk and format + partition the hard
|
||
|
disk image with it.
|
||
|
</p>
|
||
|
<p>
|
||
|
Formatting and partitioning works currently only with AHDI 5, but you
|
||
|
can install the AHDI 6 driver to the hard disk after it's formatted.
|
||
|
Restart the emulated system, run AHDI.PRG from the floppy disk to access
|
||
|
the hard disk image from the emulated Atari and then run HINSTALL.PRG.
|
||
|
After installing the hard disk driver to the fresh HD image with
|
||
|
HINSTALL.PRG, you can boot directly from the hard disk image.
|
||
|
</p>
|
||
|
<p>
|
||
|
HD Driver (v9) partitioning is also compatible with Hatari ACSI
|
||
|
emulation. CBHD and ICDPro AdSCSI drivers work on images which have
|
||
|
been partitioned elsewhere.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>IDE hard drive emulation</h3>
|
||
|
<p>
|
||
|
<p>
|
||
|
As the IDE disk format (little endian) differs from the ACSI disk format
|
||
|
(big endian), you need separate disk images for them. Hatari doesn't
|
||
|
currently support partitioning IDE disks with AHDI, but you can do it with
|
||
|
<em>Cecile</em>.
|
||
|
</p>
|
||
|
<p>
|
||
|
First create an empty image file with the size of your choice with:
|
||
|
<span class="commandline">dd if=/dev/zero of=hd.img bs=1k count=xxx</span>.
|
||
|
Then get the Cecile hard disk driver from
|
||
|
<a href="http://centek.free.fr/atari/softs/s_cecile.htm">http://centek.free.fr/atari/softs/s_cecile.htm</a>
|
||
|
and put it on a floppy disk image (e.g. to one named "cecile.st" using:
|
||
|
<span class="commandline">zip2st.sh cecile.zip</span>).
|
||
|
</p>
|
||
|
<p>
|
||
|
Run Hatari with
|
||
|
<span class="commandline">hatari --machine falcon --tos tos404.rom
|
||
|
--ide-master hd.img cecile.st</span>, switch to larger color resolution
|
||
|
and warm up your French language skills. Then start the Cecile hard
|
||
|
disk driver CECILE.PRG and run CC_TOOLS.APP to partition your hard
|
||
|
disk image. Click the "Partition" button, select "Hatari IDE disk" and set
|
||
|
suitable partition size with the arrows (below type field). Then click
|
||
|
"Valider".
|
||
|
</p>
|
||
|
<p>
|
||
|
If you only want to use your HD image in Falcon mode, you can install
|
||
|
the Cecile hard disk driver to the image from the Cecile CC_TOOLS.APP:
|
||
|
Click the "Installer" button and save the Cecile driver to the
|
||
|
1st partition on "Hatari IDE disk". If you want to also use your HD
|
||
|
image in ST/STE mode, you need to get and install either HD Driver or
|
||
|
AHDI 6 driver on it instead (see <a href="#ACSI_hard_drive_emulation">ASCI
|
||
|
hard drive emulation</a> section).
|
||
|
</p>
|
||
|
<p>
|
||
|
Then you can boot from your hard disk image by simply specifying it
|
||
|
with the <span class="commandline">--ide-master</span> parameter.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h2>Moving files to/from hard disk images</h2>
|
||
|
|
||
|
<p>Moving files to and from Atari hard disk images can be done
|
||
|
either through GEMDOS HD partitions (host directories mounted inside
|
||
|
Hatari emulation) or accessing the images directly on the host
|
||
|
(outside the emulation). Both have their own limitations.</p>
|
||
|
|
||
|
<p>If it's fine for the IDE/ACSI partitions to be first, you can
|
||
|
either use ACSI/IDE partition skip option, or a multipartition GEMDOS
|
||
|
HD setup as described in above sections.
|
||
|
</p>
|
||
|
|
||
|
<p>If you want to boot from a GEMDOS HD partition i.e. such to be
|
||
|
before hard disk image partitions, and still to be able to access all
|
||
|
the IDE/ACSI partitions, you need to use HD Driver. Note: this is the
|
||
|
preferred method with EmuTOS (v0.9.x), because it doesn't run/use
|
||
|
driver installed to the IDE/ACSI image directly although its own
|
||
|
partition table/type support is very limited.</p>
|
||
|
|
||
|
<h3 id="Using_HD_Driver_with_GEMDOS_partitions">Using HD Driver with GEMDOS partitions</h3>
|
||
|
|
||
|
<p>Uwe Seimet's <a href="http://www.seimet.de/atari/en/hddriver.html">HD
|
||
|
Driver</a> works fine with both the Hatari GEMDOS HD partitions and normal
|
||
|
hard disk images.
|
||
|
</p>
|
||
|
|
||
|
<p>First copy the HDDRIVER.PRG binary into your GEMDOS HD emulation
|
||
|
directory AUTO folder. Then start the HDDRUTIL.APP configuration utility,
|
||
|
locate HDDRIVER.PRG, open the
|
||
|
<a href="http://www.seimet.de/atari/en/hddriverscreenshots.html">"Devices
|
||
|
and Partitions" dialog</a> and select the "Preserve Existing Partitions"
|
||
|
option. Then you can just start Hatari with your hard disk image and
|
||
|
this GEMDOS HD directory, for example like this:
|
||
|
"<span class="commandline">hatari --harddrive gemdos-hd/ --ide-master
|
||
|
ide-hd.image</span>".</p>
|
||
|
|
||
|
<p>If you're using
|
||
|
the <a href="http://hddriver.seimet.de/en/downloads.html">demo version
|
||
|
of HD Driver</a>, you can write files only to the C: partition, i.e. in
|
||
|
above case only copy files from the hard disk image partition to the
|
||
|
GEMDOS HD partition (with some write slowndowns included into the demo
|
||
|
version). If you want to copy files to the hard disk image with
|
||
|
the <em>demo</em> version of the HD Driver, you need to set the hard disk
|
||
|
image as drive C:.</p>
|
||
|
|
||
|
<p>To accomplish this, set the GEMDOS HD partitions to be from D: forward,
|
||
|
i.e. have a directory which contains only single letter subdirectories,
|
||
|
starting from "D" like in "<span class="commandline">mkdir gemdos-hd;
|
||
|
mkdir gemdos-hd/D</span>". Then give Hatari (as the last parameter)
|
||
|
a boot floppy image containing the demo version of HDDRIVER.PRG in
|
||
|
its AUTO folder, like this: "<span class="commandline">hatari
|
||
|
--ide-master ide-hd.image --harddrive gemdos-hd/ hd-driver-floppy.st</span>".
|
||
|
You can convert HD Driver ZIP package to floppy image with the
|
||
|
<span class="commandline">zip2st</span> utility.</p>
|
||
|
|
||
|
|
||
|
<h3>Accessing HDD image partitions outside of Hatari</h3>
|
||
|
|
||
|
<p>
|
||
|
If you want to access the hard disk image partitions also outside
|
||
|
the emulation, the disk image needs to have a DOS partition table.
|
||
|
The <span class="commandline">atari-hd-image</span> script included
|
||
|
with Hatari can be used to create such an image.
|
||
|
</p>
|
||
|
<p>
|
||
|
Inside the Hatari emulator, EmuTOS can access partition(s) on these
|
||
|
kind of images directly without any driver software. Of the Atari HD
|
||
|
drivers mentioned above, Centek's Cecile and Uwe Seimet's HD Driver
|
||
|
(demo) work fine with these partitions. E.g. AHDI and CBHD don't.
|
||
|
Cecile works only with TT or Falcon.
|
||
|
</p>
|
||
|
<p>
|
||
|
To summarise; if EmuTOS is enough, use that. Otherwise, if you want to
|
||
|
use TT or Falcon emulation, use Cecile (or full HD Driver version if
|
||
|
you have it), otherwise use HD Driver (demo).
|
||
|
</p>
|
||
|
<p>
|
||
|
To access the content of the partitions on Linux host, there are two
|
||
|
possibilities:
|
||
|
|
||
|
<h4>Using Mtools</h4>
|
||
|
<p>
|
||
|
For this you need to add an entry for the hard disk
|
||
|
image to your <span class="commandline">~/.mtoolsrc</span> and
|
||
|
specify which partition you want to access from the image. For
|
||
|
an image created with the above mentioned script, the line in
|
||
|
the configuration file should look something like this:
|
||
|
</p>
|
||
|
<pre>
|
||
|
MTOOLS_NO_VFAT=1
|
||
|
drive c: file="/home/user/hatari/hd.img" partition=1
|
||
|
</pre>
|
||
|
<p>
|
||
|
Note that Mtools is instructed to use FAT compatibility mode because
|
||
|
EmuTOS cannot deal properly with VFAT file information. If you don't
|
||
|
want this setting for all your Mtools drives, you can set it also via
|
||
|
the environment like this ("::" refers to the drive image given with
|
||
|
the "-i" option):
|
||
|
</p>
|
||
|
<pre>
|
||
|
MTOOLS_NO_VFAT=1 mcopy -spmv -i hd.img files/* ::
|
||
|
</pre>
|
||
|
|
||
|
<h4>Using a loopback device</h4>
|
||
|
<p>
|
||
|
This is recommended even by Mtools documentation, but it's less
|
||
|
convenient as it requires root rights. First you need to "loop"
|
||
|
mount the image:
|
||
|
</p>
|
||
|
<pre>
|
||
|
$ su
|
||
|
# image="hd.img"; mountdir="hd"
|
||
|
# start=$(parted $image unit s print | awk '/ 1 /{print $2}' | tr -d s)
|
||
|
# losetup -f $image -o $((512*$start))
|
||
|
# loop=$(losetup -a | tail -1 | cut -d: -f1)
|
||
|
# mkdir -p $mountdir
|
||
|
# mount -t msdos $loop $mountdir
|
||
|
</pre>
|
||
|
<p>
|
||
|
This uses <span class="commandline">parted</span> to find out the first
|
||
|
partition offset in sectors and then tells <span class="commandline">losetup</span>
|
||
|
to bind the first free loop device to a corresponding offset from
|
||
|
the <span class="commandline">hd.img</span> image.
|
||
|
<span class="commandline">mount</span> is then used to mount the file system
|
||
|
from the loop device on top of the "hd" directory.
|
||
|
</p>
|
||
|
<p>
|
||
|
After you've copied the relevant files to the "hd" directory, you need
|
||
|
unmount the file system and remove the loop device binding before using
|
||
|
the disk image from Hatari:
|
||
|
</p>
|
||
|
<pre>
|
||
|
# umount $mountdir
|
||
|
# losetup -d $loop
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h2 id="The_debugger">The debugger</h2>
|
||
|
|
||
|
<p>
|
||
|
Hatari has a built-in debugging interface which can be used for
|
||
|
analyzing code that runs in the emulated system.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
On Unix (Linux / OSX) debugger uses Hatari's parent console window, so
|
||
|
make sure you run Hatari from the command line when you want to use
|
||
|
the debugger. On Windows you need to use "-W" option to get console
|
||
|
window. You can add an icon to your desktop that does it. On Linux
|
||
|
it should do something like this (replace "xterm" with your favorite
|
||
|
terminal program):
|
||
|
</p>
|
||
|
<pre>
|
||
|
xterm -T "Hatari debug window" -e hatari
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
To run debugger commands at Hatari startup, one can use the "--parse
|
||
|
<file>" command line option. This is useful e.g. for debugging
|
||
|
TOS or some demo startup code, or if you always want to use some
|
||
|
specific debugger setup (breakpoints etc).
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Invoking the debugger</h3>
|
||
|
|
||
|
<p>
|
||
|
You can invoke the debugger manually by pressing the
|
||
|
<span class="key">AltGr + Pause</span> key combination.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
With the "-D" command line option, you can toggle whether m68k
|
||
|
exceptions will also invoke the debugger. Which exceptions cause
|
||
|
this, can be controlled with the "--debug-except" option.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Giving "-D" option at Hatari startup is not advised because TOS HW
|
||
|
checks generate some exceptions at every TOS boot. It's better to
|
||
|
toggle exception catching later from the debugger with the "setopt -D"
|
||
|
command.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Alternatively, you can give "--debug-except" option "autostart" flag
|
||
|
(e.g. "--debug-except all,autostart"). This will enable catching of
|
||
|
(specified) exceptions after TOS boot, when Atari program given on
|
||
|
Hatari command line is <em>autostarted</em>.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>General debugger use</h3>
|
||
|
|
||
|
<p>
|
||
|
At the debugger prompt, type "help" to get a list of all
|
||
|
the available commands and their shortcuts:
|
||
|
</p>
|
||
|
<pre>
|
||
|
Generic commands:
|
||
|
cd ( ) : change directory
|
||
|
evaluate ( e) : evaluate an expression
|
||
|
help ( h) : print help
|
||
|
history (hi) : show last CPU & DSP PC values & executed instructions
|
||
|
info ( i) : show machine/OS information
|
||
|
lock ( ) : specify information to show on entering the debugger
|
||
|
logfile ( f) : open or close log file
|
||
|
parse ( p) : get debugger commands from file
|
||
|
setopt ( o) : set Hatari command line and debugger options
|
||
|
stateload ( ) : restore emulation state
|
||
|
statesave ( ) : save emulation state
|
||
|
trace ( t) : select Hatari tracing settings
|
||
|
quit ( q) : quit emulator
|
||
|
|
||
|
CPU commands:
|
||
|
address ( a) : set CPU PC address breakpoints
|
||
|
breakpoint ( b) : set/remove/list conditional CPU breakpoints
|
||
|
disasm ( d) : disassemble from PC, or given address
|
||
|
profile ( ) : profile CPU code
|
||
|
cpureg ( r) : dump register values or set register to value
|
||
|
memdump ( m) : dump memory
|
||
|
memwrite ( w) : write bytes to memory
|
||
|
loadbin ( l) : load a file into memory
|
||
|
savebin ( ) : save memory to a file
|
||
|
symbols ( ) : load CPU symbols & their addresses
|
||
|
step ( s) : single-step CPU
|
||
|
next ( n) : step CPU, proceeding through subroutine calls
|
||
|
cont ( c) : continue emulation / CPU single-stepping
|
||
|
|
||
|
DSP commands:
|
||
|
dspaddress (da) : set DSP PC address breakpoints
|
||
|
dspbreak (db) : set/remove/list conditional DSP breakpoints
|
||
|
dspdisasm (dd) : disassemble DSP code
|
||
|
dspmemdump (dm) : dump DSP memory
|
||
|
dspsymbols ( ) : load DSP symbols & their addresses
|
||
|
dspprofile (dp) : profile DSP code
|
||
|
dspreg (dr) : read/write DSP registers
|
||
|
dspstep (ds) : single-step DSP
|
||
|
dspnext (dn) : step DSP, proceeding through subroutine calls
|
||
|
dspcont (dc) : continue emulation / DSP single-stepping
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h4 id="Entering_arguments_to_debugger_commands">Entering arguments to debugger commands</h4>
|
||
|
|
||
|
<p>
|
||
|
After writing (with TAB completion) one of the above command names,
|
||
|
pressing TAB will (for most commands) show all the available subcommands.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
If you want to give numbers in other number bases
|
||
|
than the default/selected one, they need to be prefixed with a
|
||
|
character indicating this. For decimals this prefix is "#" (#15),
|
||
|
for hexadecimals "$" ($F), and for binary values it's "%" (%1111).
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
By default debugger expects all numbers without a prefix to be
|
||
|
decimals, but you can change the default number base with the "setopt"
|
||
|
command, just give it the desired default number base (bin/dec/hex).
|
||
|
<em>When using the hexadecimal number base, remember still to prefix
|
||
|
hexadecimal numbers with '$' if they could be confused with register
|
||
|
names (a0-7, d0-7)!</em> Otherwise results from expressions and
|
||
|
conditional breakpoints can be unexpected.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Calculations and immediate evaluation</h4>
|
||
|
|
||
|
<p>
|
||
|
Instead of a number, you can also use an arithmetic expression, by
|
||
|
surrounding it with quotes (""). An expression can contain
|
||
|
calculations with CPU and DSP register, symbol and Hatari variable
|
||
|
values in addition to numbers. For example to give a sum of A0 and
|
||
|
D0 register values to a command, use "a0+d0".
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Within arithmetic expressions parenthesis are used both to change
|
||
|
the order of precendence <em>and</em> to indicate indirect addressing.
|
||
|
Unlike with conditional breakpoint expressions (explained below), you
|
||
|
cannot give size for the indirect addressing, a long value is always
|
||
|
read from the RAM address given within parenthesis. For example to
|
||
|
get a long value pointed by stack pointer + 2, use "(a7+2)".
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Values of arithmetic expressions are always evaluated before being
|
||
|
given to a command. Except for "evaluate" and "address" commands,
|
||
|
they always need to be marked with quotes (""). Besides arithmetics,
|
||
|
this can be used also to give symbol/register/variable values to
|
||
|
commands that don't otherwise interpret them. If command complains
|
||
|
that it didn't recognize e.g. a register name, just put it to quotes
|
||
|
and it will be "evaluated" before being given to the command.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
With command argument completion (see <a href="#Build_notes">build
|
||
|
notes</a>), result from the last "evaluate" command can be inserted
|
||
|
by typing '$' and pressing TAB.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3 id="Inspecting_emulation_state">Inspecting emulation state</h3>
|
||
|
|
||
|
<p>
|
||
|
In the beginning, probably the most interesting commands are "m" and "d"
|
||
|
for dumping and disassembling memory regions. You can use "dm" and "dd"
|
||
|
commands to do the same for the DSP.
|
||
|
</p>
|
||
|
<pre>
|
||
|
> help memdump
|
||
|
'memdump' or 'm' - dump memory
|
||
|
Usage: m [start address-[end address]]
|
||
|
dump memory at address or continue dump from previous address.
|
||
|
</pre>
|
||
|
<pre>
|
||
|
> help disasm
|
||
|
'disasm' or 'd' - disassemble from PC, or given address
|
||
|
Usage: d [start address-[end address]]
|
||
|
If no address is given, this command disassembles from the last
|
||
|
position or from current PC if no last position is available.
|
||
|
</pre>
|
||
|
<pre>
|
||
|
> disasm pc
|
||
|
$00aa6e : 2f08 move.l a0,-(sp)
|
||
|
$00aa70 : 0241 0fff andi.w #$fff,d1
|
||
|
$00aa74 : 207c 00fe 78c0 movea.l #$fe78c0,a0
|
||
|
$00aa7a : 2070 1000 movea.l (a0,d1.w),a0
|
||
|
$00aa7e : 4ed0 jmp (a0)
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
Both commands accept in addition to numeric addresses also register
|
||
|
and symbol names, like in above example. If you don't specify an
|
||
|
address, the commands continue showing from an address that comes
|
||
|
after the previously shown data. "disasm" command default address
|
||
|
will be reset to PC address every time you re-enter the debugger.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Use "setopt --disasm help" if you want to set options controlling
|
||
|
the disassembly output.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
You can use the "info" command to see state of specific sets of HW
|
||
|
registers (e.g. "info videl") and Atari OS structures (e.g. "info gemdos").
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Selecting what information is shown on entering the debugger</h4>
|
||
|
|
||
|
<p>
|
||
|
By using the "lock" command, you can ask Hatari to show specific
|
||
|
information whenever you enter the debugger / hit a breakpoint. For
|
||
|
example to see disassembly from current PC address, use "lock disasm".
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
With the "regaddr" subcommand, you see disassembly or memory
|
||
|
dump of an address pointed by a given register ("lock regaddr disasm
|
||
|
a0"). Of the DSP registers, only Rx ones are valid for this
|
||
|
subcommand.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
"file" subcommand can be used to get (arbitrary number of) commands
|
||
|
parsed and executed from a given debugger input file whenever debugger
|
||
|
is entered. With this you can output any information you need:
|
||
|
</p>
|
||
|
<pre>
|
||
|
lock file debugger.ini
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
To disable showing of this extra information, use "lock default".
|
||
|
Without arguments "lock" command will show the available options
|
||
|
(like the "info" command does).
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Debug symbols</h3>
|
||
|
|
||
|
<p>
|
||
|
You can load debugging symbols to the debugger with the "symbols"
|
||
|
command (and with "dspsymbols" for DSP). These symbolic names can be
|
||
|
used in arithmetic expressions and conditional breakpoint expressions.
|
||
|
They also show up in the "disasm" command output and you can trace
|
||
|
calls to them with "trace cpu_symbols" (and DSP symbols with "trace
|
||
|
dsp_symbols").
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>For a program under GEMDOS HD emulation</h4>
|
||
|
|
||
|
<p>
|
||
|
If currently running program contains symbol table in DRI/GST format,
|
||
|
and it's started from GEMDOS HD emulated drive, its symbol names /
|
||
|
addresses are automatically loaded when debugger is entered, and
|
||
|
removed when program terminates.</p>
|
||
|
|
||
|
<p>
|
||
|
Above happens only if there are no symbols loaded when the program
|
||
|
starts. If there are, you can load program symbol data manually with
|
||
|
the following command, after program has been loaded to the memory by
|
||
|
TOS (see <a href="#Breakpoint_variables">setting breakpoint at program
|
||
|
startup</a>):
|
||
|
</p>
|
||
|
<pre>
|
||
|
symbols prg
|
||
|
</pre>
|
||
|
<p>
|
||
|
|
||
|
<p>
|
||
|
The options you need to add suitable symbol table to your programs,
|
||
|
depend on which toolchain you use to build it:
|
||
|
</p>
|
||
|
<dl>
|
||
|
<dt><em>Devpac</em>:</dt>
|
||
|
<dd>"OPT D+,X+"</dd>
|
||
|
<dt><em>AHCC</em>:</dt>
|
||
|
<dd>"-g", and "-l" option for local symbols, both for linking</dd>
|
||
|
<dt><em>GCC</em>:</dt>
|
||
|
<dd>"-Wl,--traditional-format" option for linking,
|
||
|
and "-g" for compilation to get local symbols</dd>
|
||
|
<dt><em>VBCC</em>:</dt>
|
||
|
<dd>"-g" (can only be used at linking phase), <em>when VBCC
|
||
|
configuration file uses "-bataritos" option for
|
||
|
the linker</em></dd>
|
||
|
</dl>
|
||
|
|
||
|
<p>You can view the generated symbols (and convert them to debugger
|
||
|
ASCII format) with tool installed with Hatari:</p>
|
||
|
<pre>
|
||
|
$ gst2ascii -l -o program.tos > program.sym
|
||
|
</pre>
|
||
|
(Options -l and -o are used to exclude useless symbols from the output.)
|
||
|
|
||
|
|
||
|
<h4>For a program on a (disk) image</h4>
|
||
|
|
||
|
<p>
|
||
|
If the program isn't run from a GEMDOS HD emulated drive, but from a
|
||
|
cartridge, floppy or HD image, you need to have the corresponding
|
||
|
program also as normal host file which location you can give to the
|
||
|
debugger:
|
||
|
</p>
|
||
|
<pre>
|
||
|
symbols /path/to/the/program.tos
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h4>ASCII debug symbol files</h4>
|
||
|
|
||
|
<p>
|
||
|
If Hatari complains that your program doesn't have DRI/GST format
|
||
|
symbol table, or its symbols are in some other format, and you
|
||
|
cannot re-compile it to have them, you have two options:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>Convert the symbols to ASCII format understood by the Hatari debugger.
|
||
|
Writing converters for other ASCII formats is easy, and Hatari already
|
||
|
contains covertors for DSP LOD files, <span class="commandline">nm</span>
|
||
|
output for MiNT/a.out binaries and AHCC map files.
|
||
|
<li>Create the ASCII symbols file by hand while you're debugging a program.
|
||
|
</ul>
|
||
|
|
||
|
<p>ASCII symbols file format is following:</p>
|
||
|
<pre>
|
||
|
e01034 T random
|
||
|
e01076 T kbdvbase
|
||
|
e0107e T supexec
|
||
|
</pre>
|
||
|
<p>
|
||
|
Where 'T' means text (code), 'D' means data and 'B' means BSS section
|
||
|
type of address. The hexadecimal address, address type letter and the
|
||
|
symbol name are separated by white space. Empty lines and lines
|
||
|
starting with '#' (comments) are ignored.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Debugger will automatically "relocate" the symbol addresses when it
|
||
|
loads them from a program binary, but with ASCII symbol files you need
|
||
|
to give the relocation offset(s) separately, unless the symbol names
|
||
|
are for fixed adresses (like is the case e.g. with EmuTOS):
|
||
|
</p>
|
||
|
<pre>
|
||
|
symbols program.sym TEXT DATA BSS
|
||
|
</pre>
|
||
|
<p>
|
||
|
If you're interested only about code symbols, you can leave DATA and
|
||
|
BSS offsets out (the values of the above virtual debugger variables
|
||
|
like TEXT come from the currently loaded program's basepage, they're
|
||
|
set after the program is loaded by TOS, see "info basepage" output).
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Breakpoints</h3>
|
||
|
|
||
|
<p>
|
||
|
There are two ways to specify breakpoints for Hatari. First, there are
|
||
|
the simple address breakpoints which trigger when the CPU (or DSP)
|
||
|
program counter hits a given address. Use "a" (or "da" for the DSP)
|
||
|
to create them, for example:
|
||
|
</p>
|
||
|
<pre>
|
||
|
a $e01034
|
||
|
a some_symbol
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
Note that address breakpoints are just wrappers for conditional
|
||
|
breakpoints so you need to use "b" command to remove or list them.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Then there are the conditional breakpoints which can handle much more
|
||
|
complex break condition expressions; they can track changes to
|
||
|
register and memory values with bitmasks, include multiple conditions
|
||
|
for triggering a breakpoint and so on. Use "b" (or "db" for the DSP)
|
||
|
to manage them.
|
||
|
</p>
|
||
|
|
||
|
<p>Help explains the general syntax:</p>
|
||
|
<pre>
|
||
|
> help b
|
||
|
'breakpoint' or 'b' - set/remove/list conditional CPU breakpoints
|
||
|
Usage: b <condition> [&& <condition> ...] [:<option>] | <index> | help | all
|
||
|
|
||
|
Set breakpoint with given <conditions>, remove breakpoint with
|
||
|
given <index>, remove all breakpoints with 'all' or output
|
||
|
breakpoint condition syntax with 'help'. Without arguments,
|
||
|
lists currently active breakpoints.
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
Unless you give breakpoint one of the pre-defined subcommands ('all',
|
||
|
'help'), index for a breakpoint to remove or no arguments (to list
|
||
|
breakpoints), the arguments are interpreted as a new breakpoint
|
||
|
definition.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Each conditional breakpoint can have (currently up to 4) conditions
|
||
|
which are separated by "&&". All of the breakpoint's
|
||
|
conditions need to be true for a breakpoint to trigger.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4 id="Breakpoint_options">Breakpoint options</h4>
|
||
|
|
||
|
<p>
|
||
|
Normally when a breakpoint is triggered, emulation is stopped and you
|
||
|
get to the debugger. Breakpoint options can be used to affect what
|
||
|
happens when a breakpoint is triggered. These options are given after
|
||
|
the conditions and are prefixed with ':'.
|
||
|
</p>
|
||
|
|
||
|
<dl>
|
||
|
<dt><em><count></em></dt>
|
||
|
<dd>Break only on every <count> hit. For example, to stop
|
||
|
on every other time PC is at given address, use:
|
||
|
<pre>
|
||
|
a $1234 :2
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>once</em></dt>
|
||
|
<dd>
|
||
|
Delete the breakpoint when it's hit i.e. trigger it only once. It may
|
||
|
be useful if you just want to get a specific address. Or if you're on
|
||
|
an instruction that jumps back to a start of the loop and you want to
|
||
|
finish the loop, you could use:
|
||
|
<pre>
|
||
|
b pc > "pc" :once
|
||
|
continue
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>trace</em></dt>
|
||
|
<dd>
|
||
|
Continue emulation without stopping after printing the value that
|
||
|
triggered the breakpoint and doing other possible option actions.
|
||
|
This is most useful when investigating memory or register value
|
||
|
changes (explained below).
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>lock</em></dt>
|
||
|
<dd>
|
||
|
Show the same information on breakpoint hit as you see when entering
|
||
|
the debugger (see the "lock" command in
|
||
|
<a href="#Inspecting_emulation_state">Inspecting emulation state</a>
|
||
|
above). This enables also trace option as you would anyway see this
|
||
|
information if debugger would be entered.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>file <file></em></dt>
|
||
|
<dd>
|
||
|
Execute debugger commands from given <file> when this breakpoint
|
||
|
is hit. With this you have complete control over what information is
|
||
|
show when the debugger is hit, you can even chain breakpoints (as
|
||
|
explained in
|
||
|
<a href="#Chaining_breakpoints">Chaining breakpoints</a> later on)
|
||
|
etc. Use this if "lock" option isn't enough or you want different
|
||
|
information show on breakpoints and when entering the debugger.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>noinit</em></dt>
|
||
|
<dd>
|
||
|
Hitting breakpoint doesn't re-initialize debugger which would e.g.
|
||
|
cause profiling data to be reset. This implies trace option as
|
||
|
entering debugger would also re-initialize debugger state. This option
|
||
|
is mainly intended for breakpoints that use :file option to show
|
||
|
backtraces with "profile stack" command during
|
||
|
<a href="#Profiling">profiling</a>. See
|
||
|
<a href="#Usage_examples">Usage examples</a> section for an example.
|
||
|
</dd>
|
||
|
</dl>
|
||
|
|
||
|
<p>
|
||
|
Note: you can give multiple options for conditional breakpoints, but
|
||
|
for address breakpoints you can give only one these options. And
|
||
|
"file" option is supported only for conditional breakpoints.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Breakpoint conditions</h4>
|
||
|
|
||
|
<p>
|
||
|
"b help" explains very briefly the breakpoint condition syntax:
|
||
|
</p>
|
||
|
<pre>
|
||
|
> b help
|
||
|
condition = <value>[.mode] [& <mask>] <comparison> <value>[.mode]
|
||
|
|
||
|
where:
|
||
|
value = [(] <register/symbol/variable name | number> [)]
|
||
|
number/mask = [#|$|%]<digits>
|
||
|
comparison = '<' | '>' | '=' | '!'
|
||
|
addressing mode (width) = 'b' | 'w' | 'l'
|
||
|
addressing mode (space) = 'p' | 'x' | 'y'
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
For CPU breakpoints, mode is the address width; it can be byte ("b"),
|
||
|
word ("w") or long ("l", default). For DSP breakpoints, mode specifies
|
||
|
the address space: "P", "X" or "Y". Note that on DSP only R0-R7
|
||
|
registers can be used for memory addressing. For example;
|
||
|
<pre>
|
||
|
db (r0).x = 1 && (r0).y = 2
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
If the value is in parenthesis like in '($ff820)' or '(a0)', then the
|
||
|
used value will be read from the memory address pointed by it. Note
|
||
|
that this conditional breakpoint expression value is checked at
|
||
|
run-time whereas quoted arithmetic expressions (mentioned in
|
||
|
<a href="#Entering_arguments_to_debugger_commands">Entering arguments
|
||
|
to debugger commands</a> above) are evaluated already when
|
||
|
adding a breakpoint. For example, to break when a value in an address
|
||
|
(later) pointed by A0 matches the value <em>currently</em> in D0, one
|
||
|
would use:
|
||
|
</p>
|
||
|
<pre>
|
||
|
b (a0) = "d0"
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
If you're interested only on certain bits in the value, you can use
|
||
|
'&' and a numeric mask on either side of comparison operator to
|
||
|
mask the coresponding value, like this:
|
||
|
<pre>
|
||
|
b ($ff820).w & 3 = (a0) && (a1) = d0 & %1100
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
Comparison operators should be familiar and obvious, except for '!'
|
||
|
which indicates inequality ("is not") comparison. For example:
|
||
|
</p>
|
||
|
<pre>
|
||
|
b d0 > $20 && d0 < $40 && d0 ! $30
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h5>Tracking breakpoint conditions</h5>
|
||
|
|
||
|
<p>
|
||
|
As a convenience, if the both sides of the comparison are exactly the
|
||
|
same (i.e. condition is redundant as it's always either true or
|
||
|
false), the <em>right side</em> of the comparison is replaced with
|
||
|
its current value. This way you can give something like this:
|
||
|
</p>
|
||
|
<pre>
|
||
|
b pc > "pc"
|
||
|
</pre>
|
||
|
<p>As:</p>
|
||
|
<pre>
|
||
|
b pc > pc
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
That in itself isn't so useful, but for inequality ('!') comparison,
|
||
|
conditional breakpoint will additionally track and output all further
|
||
|
changes for the given address/register expression. This can be used
|
||
|
for example to find out all value changes in a given memory address,
|
||
|
like this:
|
||
|
</p>
|
||
|
<pre>
|
||
|
b ($ffff9202).w ! ($ffff9202).w :trace
|
||
|
</pre>
|
||
|
<p>
|
||
|
Because tracking breakpoint conditions will print the evaluated
|
||
|
value when it changes, they're typically used with the trace option
|
||
|
to track changes e.g. to some IO register.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h5>Breakpoint condition notes</h5>
|
||
|
|
||
|
<ul>
|
||
|
<li>
|
||
|
Any '!' condition should be given as the first condition. Because
|
||
|
breakpoint evaluation is stopped ("short-circuited") when any of the
|
||
|
conditions fails, the tracked value would not be updated correctly
|
||
|
unless tracking condition is given as the first one.
|
||
|
</li>
|
||
|
|
||
|
<li>
|
||
|
Hatari will internally update some register values without immediately
|
||
|
updating the corresponding IO address range memory addresses. For
|
||
|
example the Busy bit for the internal Blitter control register is
|
||
|
(internally) cleared when Blitter activity stops, but the actual IO
|
||
|
address for that control register gets updated only when something
|
||
|
actually writes or reads that IO address. Many HW registers behave
|
||
|
like this (status registers in FDC, ACIA, MFP, Blitter...).
|
||
|
<br>
|
||
|
For breakpoints that track just a single IO register memory address, or
|
||
|
multiple ones of which <strong>none</strong> are modified by Hatari,
|
||
|
only by emulated code, this is not a problem, they get triggered as
|
||
|
expected.
|
||
|
<br>
|
||
|
However, if you have a breakpoint that tracks multiple IO registers
|
||
|
where some of them are updated by Hatari, for example to check that
|
||
|
other Blitter registers aren't updated while control register
|
||
|
indicates Blitter to be active (busy), things don't work as expected!
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h4>Breakpoint variables</h4>
|
||
|
|
||
|
<p>
|
||
|
In addition to loaded symbols, the debugger supports also setting
|
||
|
conditional breakpoints on values of some "virtual" variables listed
|
||
|
by "b help". For example:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>If you want the emulation to stop on the first instruction of
|
||
|
next program; after TOS desktop is up, set a breakpoint on
|
||
|
the TEXT segment address given in a program basepage:
|
||
|
<pre>
|
||
|
b pc = TEXT :once
|
||
|
</pre>
|
||
|
Note1: It's better to trigger it only once because if you'd leave it on,
|
||
|
during reboot you would get a warning for every instruction until TOS sets
|
||
|
a valid basepage.
|
||
|
<br />
|
||
|
Note2: you cannot use an address breakpoint for this because value of
|
||
|
a variable given to address breakpoint is evaluated when it's set, not
|
||
|
at run-time, so it cannot get the new value that the TEXT variable
|
||
|
gets when you start a program.
|
||
|
</li>
|
||
|
<li>To view current program DATA and BSS segment contents,
|
||
|
use the corresponding variables:
|
||
|
<pre>
|
||
|
m DATA
|
||
|
m BSS
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>If you want to stop at a specific cycle within a frame (that is,
|
||
|
PC relative to the current VBL/HBL in cycles), set breakpoints to
|
||
|
specific "HBL" and "FrameCycles" variable values. If you for
|
||
|
example want to break after 20 HBLs, use:
|
||
|
<pre>
|
||
|
b HBL = "HBL+20"
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>Aes/Bios/Gemdos/LineA/LineF/Vdi/XbiosOpcode variables can be used
|
||
|
to catch AES, BIOS, GEMDOS, Line-A, Line-F, VDI and XBIOS OS-calls.
|
||
|
By default they contain the 0xffff value, so to trace e.g. all AES
|
||
|
calls, instead of a specific one, one needs to use something like this:
|
||
|
<pre>
|
||
|
b AesOpcode ! AesOpcode && AesOpcode < 0xffff :trace
|
||
|
</pre>
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
Hint: "info" command "aes", "bios", "gemdos", "vdi" and "xbios"
|
||
|
subcommands for can be used to list the corresponding OS-call opcodes.
|
||
|
For example, to see the GEMDOS opcodes, use:</p>
|
||
|
<pre>
|
||
|
info gemdos 1
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h4 id="Chaining_breakpoints">Chaining breakpoints and other actions</h4>
|
||
|
|
||
|
<p>
|
||
|
As the file pointed by the breakpoint ":file" option (see
|
||
|
<a href="#Breakpoint_options">Breakpoint options</a>) can contain any
|
||
|
debugger commands, it can also be used to do automatic "chaining" of
|
||
|
debugger and breakpoint actions so that after one breakpoint is hit,
|
||
|
another one is set.
|
||
|
</p>
|
||
|
|
||
|
<p>For example if you have these input files:</p>
|
||
|
<ul>
|
||
|
<li>"break.ini":
|
||
|
<pre>
|
||
|
b GemdosOpcode = 0x3D :trace :once :file program.ini
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>"program.ini":
|
||
|
<pre>
|
||
|
b pc = TEXT :trace :once :file trace.ini
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>"trace.ini":
|
||
|
<pre>
|
||
|
symbols prg
|
||
|
trace gemdos,cpu_symbols
|
||
|
b VBL = "VBL+4" :trace :once :file disable.ini
|
||
|
</pre>
|
||
|
</li>
|
||
|
<li>"disable.ini":
|
||
|
<pre>
|
||
|
trace none
|
||
|
b all
|
||
|
</pre>
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
And then start Hatari with the first debugger input file and a GEMDOS
|
||
|
HD directory containing "desktop.inf" file:
|
||
|
</p>
|
||
|
<pre>
|
||
|
hatari --parse break.ini /path/to/your/program.tos
|
||
|
</pre>
|
||
|
|
||
|
<ol>
|
||
|
<li>"break.ini" input file will break when TOS opens
|
||
|
the "desktop.inf" file (it's the first Fopen() i.e. GEMDOS call
|
||
|
0x3D done by TOS at boot) and the breakpoint will run
|
||
|
the debugger commands from the "symbols.ini" file
|
||
|
<li>"program.ini" will setup breakpoint to program startup
|
||
|
(because TEXT variable cannot be used before TOS has booted)
|
||
|
<li>"trace.ini" input file loads symbols for the run program, sets Hatari
|
||
|
to trace several things (see <a href="#Tracing">Tracing</a> section
|
||
|
below) in the emulated system for few VBLs until breakpoint runs
|
||
|
commands from the "disable.ini" file
|
||
|
<li>"disable.ini" input file will disable tracing and remove
|
||
|
all (remaining) breakpoints
|
||
|
</ol>
|
||
|
|
||
|
<p><em>Note:</em></p>
|
||
|
<ul>
|
||
|
<li>Because debugger input files cannot "continue"
|
||
|
emulation, ":trace" option needs to be used for the breakpoint(s)
|
||
|
if you want emulation to continue after the breakpoint action(s).</li>
|
||
|
<li>In simpler breakpoint chain (like above), new breakpoint just
|
||
|
replaces the previous one, ":once" option tells that breakpoint
|
||
|
isn't needed after it's hit.
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
Hint: It's better to test each input file separate before testing the
|
||
|
whole chain. Besides the ":file" breakpoint option, these debugger
|
||
|
input files can be also read with the debugger "file" command, "lock"
|
||
|
command "file" option and with the Hatari "--parse" command line
|
||
|
option.
|
||
|
</p>
|
||
|
|
||
|
<h3>Stepping through code</h3>
|
||
|
|
||
|
<p>
|
||
|
After analyzing the emulation state and/or setting new breakpoints,
|
||
|
you can continue the emulation with the "c" command. You can continue
|
||
|
for a given number of CPU instructions (or DSP instructions when "dc"
|
||
|
is used), or you can continue forever (until a non-tracing breakpoint
|
||
|
triggers) if you omit the instruction count.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
If you want to continue just to the next instruction, use "s" (step)
|
||
|
command to continue for exactly one instruction, or "n" (next), if you
|
||
|
want to skip subroutine and exception calls. "ds" and "dn" commands
|
||
|
do the same for DSP.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
You can also continue with the "n" until instruction of certain
|
||
|
type is encountered, by giving it the instruction type:
|
||
|
<ul>
|
||
|
<li>"branch" matches branch instructions: BCC, BRA, DBCC, JMP</li>
|
||
|
<li>"subcall" matches subroutine calls: BSR, JSR</li>
|
||
|
<li>"subreturn" matches return from subroutine: RTD, RTR, RTS</li>
|
||
|
<li>"exception" matches exceptions: BKPT, ILLG, STOP, TRAP, TRAPV</li>
|
||
|
<li>"exreturn" matches return from exception: RTE</li>
|
||
|
<li>"return" matches both subroutine and exception returns</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>
|
||
|
For example: "n branch", or "dn branch".
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
(Note: CHK, CHK2, FBCC, FDBCC, & FTRAPCC exception / branch CPU
|
||
|
instructions aren't supported currently.)
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Tracing</h3>
|
||
|
|
||
|
<p>
|
||
|
If you want e.g. to continue with real-time disassembling, you can
|
||
|
enable it with "trace cpu_disasm" (or "trace dsp_disasm" for DSP) at
|
||
|
the debugger prompt before continuing.
|
||
|
</p>
|
||
|
<p>
|
||
|
Disable tracing with "trace none" when you enter the debugger again.
|
||
|
"trace help" (or TAB) can be used to list all the (over 40) supported
|
||
|
traceable things, from HW events to OS functions.
|
||
|
</p>
|
||
|
<p>
|
||
|
Notes:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>
|
||
|
If GEMDOS HD emulation isn't enabled, GEMDOS call tracing needs to be
|
||
|
enabled at Hatari command line, it's not possible to enable it after
|
||
|
TOS has initialized GEMDOS.
|
||
|
</li>
|
||
|
<li>
|
||
|
AES, BIOS, GEMDOS and XBIOS traces show arguments for (most of) the
|
||
|
calls, VDI trace shows only function calls (parsing the arguments
|
||
|
would be too complicated).
|
||
|
</li>
|
||
|
<li>
|
||
|
Tracing options can be set even from a program within the emulation,
|
||
|
if you enable the Hatari "--bios-intercept" option and call XBios 255
|
||
|
from the program with a suitable trace options string.
|
||
|
</li>
|
||
|
<li>
|
||
|
Note that the trace output file can be set only when Hatari starts,
|
||
|
it cannot be changed from within the debugger (or emulation).
|
||
|
</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
If there isn't a trace option for something you'd like to track,
|
||
|
you may be able to use tracing breakpoints, explained above.
|
||
|
For example, following tracks Line-A calls:
|
||
|
</p>
|
||
|
<pre>
|
||
|
b LineAOpcode ! LineAOpcode && LineAOpcode < 0xffff :trace
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h3>Profiling</h3>
|
||
|
|
||
|
<p>
|
||
|
Profiling tells where the emulated code spends most of its (emulated)
|
||
|
time. It can be used to find out where a program is (apparently)
|
||
|
stuck, or what are the largest performance bottlenecks for a program.
|
||
|
</p>
|
||
|
|
||
|
<h4>Collecting the profile data</h4>
|
||
|
|
||
|
<p>
|
||
|
Profiling is used by first enabling the profiler (use "dp" for DSP):
|
||
|
</p>
|
||
|
<pre>
|
||
|
> profile on
|
||
|
Profiling enabled.
|
||
|
</pre>
|
||
|
<p>
|
||
|
And profiling will start once you continue the emulation:
|
||
|
</p>
|
||
|
<pre>
|
||
|
> c
|
||
|
Returning to emulation...
|
||
|
Allocated CPU profile buffer (27 MB).
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
When you get back to the debugger, the collected profiling information
|
||
|
is processed and a summary of in which parts of memory the execution
|
||
|
happened, and how long it took, is shown:
|
||
|
</p>
|
||
|
<pre>
|
||
|
Allocated CPU profile address buffer (57 KB).
|
||
|
ROM TOS (0xE00000-0xE80000):
|
||
|
- active address range:
|
||
|
0xe00030-0xe611a4
|
||
|
- active instruction addresses:
|
||
|
14240 (100.00% of all)
|
||
|
- executed instructions:
|
||
|
4589668 (100.00% of all)
|
||
|
- used cycles:
|
||
|
56898472 (100.00% of all)
|
||
|
= 7.09347s
|
||
|
Cartridge ROM (0xFA0000-0xFC0000):
|
||
|
- no activity
|
||
|
|
||
|
= 7.09347s
|
||
|
</pre>
|
||
|
<p>
|
||
|
(DSP RAM will be shown only as single area in profile information.)
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Investigating the profile data</h4>
|
||
|
|
||
|
<p>
|
||
|
When you're back in debugger, you can inspect the collected profile data:
|
||
|
</p>
|
||
|
<pre>
|
||
|
> h profile
|
||
|
'profile' - profile CPU code
|
||
|
Usage: profile <subcommand> [parameter]
|
||
|
|
||
|
Subcommands:
|
||
|
- on
|
||
|
- off
|
||
|
- counts [count]
|
||
|
- cycles [count]
|
||
|
- misses [count]
|
||
|
- symbols [count]
|
||
|
- addresses [address]
|
||
|
- callers
|
||
|
- stack
|
||
|
- stats
|
||
|
- save <file>
|
||
|
- loops <file> [CPU limit] [DSP limit]
|
||
|
|
||
|
'on' & 'off' enable and disable profiling. Data is collected
|
||
|
until debugger is entered again at which point you get profiling
|
||
|
statistics ('stats') summary.
|
||
|
|
||
|
Then you can ask for list of the PC addresses, sorted either by
|
||
|
execution 'counts', used 'cycles' or cache 'misses'. First can
|
||
|
be limited just to named addresses with 'symbols'. Optional
|
||
|
count will limit how many items will be shown.
|
||
|
|
||
|
'addresses' lists the profiled addresses in order, with the
|
||
|
instructions (currently) residing at them. By default this
|
||
|
starts from the first executed instruction, or you can
|
||
|
specify the starting address.
|
||
|
|
||
|
'callers' shows (raw) caller information for addresses which
|
||
|
had symbol(s) associated with them. 'stack' shows the current
|
||
|
profile stack (this is useful only with :noinit breakpoints).
|
||
|
|
||
|
Profile address and callers information can be saved with
|
||
|
'save' command.
|
||
|
|
||
|
Detailed (spin) looping information can be collected by
|
||
|
specifying to which file it should be saved, with optional
|
||
|
limit(s) on how many bytes first and last instruction
|
||
|
address of the loop can differ (0 = no limit).
|
||
|
</pre>
|
||
|
|
||
|
<p>For example, to see which memory addresses were executed most
|
||
|
and what instructions those have at the end of profiling, use:</p>
|
||
|
<pre>
|
||
|
> profile counts 8
|
||
|
addr: count:
|
||
|
0xe06f10 12.11% 555724 move.l $4ba,d1
|
||
|
0xe06f16 12.11% 555724 cmp.l d1,d0
|
||
|
0xe06f18 12.11% 555724 bgt.s $e06f06
|
||
|
0xe06f06 12.11% 555708 move.b $fffffa01.w,d1
|
||
|
0xe06f0a 12.11% 555708 btst #5,d1
|
||
|
0xe06f0e 12.11% 555708 beq.s $e06f1e
|
||
|
0xe00ed8 1.66% 76001 subq.l #1,d0
|
||
|
0xe00eda 1.66% 76001 bpl.s $e00ed8
|
||
|
8 CPU addresses listed.
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
Then, to see what the executed code and its costs look like
|
||
|
around top addresses:
|
||
|
<pre>
|
||
|
> profile addresses 0xe06f04
|
||
|
# disassembly with profile data:
|
||
|
# <instructions percentage>% (<sum of instructions>, <sum of cycles>, <sum of i-cache misses>)
|
||
|
$e06f04 : bra.s $e06f10 0.00% (48, 576, 0)
|
||
|
$e06f06 : move.b $fffffa01.w,d1 12.11% (555708, 8902068, 0)
|
||
|
$e06f0a : btst #5,d1 12.11% (555708, 6685268, 0)
|
||
|
$e06f0e : beq.s $e06f1e 12.11% (555708, 4457312, 0)
|
||
|
$e06f10 : move.l $4ba,d1 12.11% (555724, 11125668, 0)
|
||
|
$e06f16 : cmp.l d1,d0 12.11% (555724, 4461708, 0)
|
||
|
$e06f18 : bgt.s $e06f06 12.11% (555724, 4455040, 0)
|
||
|
$e06f1a : moveq #1,d0 0.00% (16, 64, 0)
|
||
|
Disassembled 8 (of active 14240) CPU addresses.
|
||
|
</pre>
|
||
|
<p>
|
||
|
Unlike normal disassembly, "profile addresses" command shows only
|
||
|
memory addresses which instructions were executed during profiling.
|
||
|
You get instruction cache misses only when using cycle-accurate 030
|
||
|
emulation with a Hatari version configured to use WinUAE CPU core.
|
||
|
<p>
|
||
|
If you have loaded symbol information, symbol names are shown above
|
||
|
the corresponding addresses. With the "profile symbols" command you
|
||
|
get a list of how many times the code execution passed through the
|
||
|
defined symbol addresses.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Profile data accuracy</h4>
|
||
|
|
||
|
<p>Profile data accuracy depends on Hatari emulation accuracy.
|
||
|
Profile data accuracy from most to least accurate when Hatari's
|
||
|
default emulation options are used is following:</p>
|
||
|
<ul>
|
||
|
<li>Executed CPU and DSP instruction counts are accurate.</li>
|
||
|
<li>DSP cycles counts (and their variance information) should be accurate.
|
||
|
</li>
|
||
|
<li>030 CPU instruction cache miss information (provided by WinUAE CPU core)
|
||
|
is assumed to be accurate.</li>
|
||
|
<li>Cycles used by a given CPU instruction depend to some extent on what
|
||
|
instruction(s), and data in case of 030, was processed before it.
|
||
|
While Hatari has some (instruction pairing) heuristics to take
|
||
|
that into account for 68000, in general instruction cycles are
|
||
|
averages. For 68000, cycles (provided by OldUAE CPU core) should
|
||
|
be fairly accurate, for 68030 they aren't (yet) not very accurate.</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h4>Caller information</h4>
|
||
|
|
||
|
<p>
|
||
|
If you have loaded symbols (see <a href="#Debug_symbols">Debug symbols</a>)
|
||
|
before continuing emulation/profiling, additional caller information
|
||
|
will be collected for all the code symbol addresses which are called
|
||
|
as subroutines. This information includes callstack, call counts,
|
||
|
calling instruction type (subroutine call, branch, return etc), and
|
||
|
costs for those calls, both including costs for further subroutine
|
||
|
calls and without them.
|
||
|
</p>
|
||
|
|
||
|
<p>When debugger is re-entered, current callstack is output before
|
||
|
profiling information:</p>
|
||
|
<pre>
|
||
|
> a <em>_P_LineAttack</em>
|
||
|
CPU condition breakpoint 1 with 1 condition(s) added:
|
||
|
pc = $30f44
|
||
|
$030f44 : 48e7 3820 movem.l d2-d4/a2,-(sp)
|
||
|
> c
|
||
|
...
|
||
|
CPU breakpoint condition(s) matched 1 times.
|
||
|
pc = $30f44
|
||
|
Finalizing costs for 12 non-returned functions:
|
||
|
- 0x32a3c: _P_GunShot (return = 0x32b7e)
|
||
|
- 0x32b18: _A_FireShotgun (return = 0x3229a)
|
||
|
- 0x3223a: _P_SetPsprite (return = 0x32e86)
|
||
|
- 0x32e4e: _P_MovePsprites (return = 0x38070)
|
||
|
- 0x37f44: _P_PlayerThink (return = 0x36ea0)
|
||
|
- 0x36e44: _P_Ticker (return = 0x260e0)
|
||
|
- 0x25dcc: _G_Ticker (return = 0x1e4c6)
|
||
|
- 0x1e29e: _TryRunTics (return = 0x239fa)
|
||
|
- 0x238e8: _D_DoomLoop (return = 0x2556a)
|
||
|
- 0x24d7a: _D_DoomMain (return = 0x44346)
|
||
|
...
|
||
|
</pre>
|
||
|
|
||
|
<p>("profile stack" command can be used in breakpoints with :noinit
|
||
|
option to show backtraces during caller profiling.)</p>
|
||
|
|
||
|
<p>Other information collected during profiling is shown with
|
||
|
following command:</p>
|
||
|
<pre>
|
||
|
> profile callers
|
||
|
# <callee>: <caller1> = <calls> <types>[ <inclusive/totals>[ <exclusive/totals>]], <caller2> ..., <callee name>
|
||
|
# types: s = subroutine call, r = return from subroutine, e = exception, x = return from exception,
|
||
|
# b = branch/jump, n = PC moved to next instruction, u = unknown PC change
|
||
|
# totals: calls/instructions/cycles/misses
|
||
|
0xe00030: 0xffffff = 1 e, _main
|
||
|
0xe000fe: 0xe00a0c = 1 b, memdone
|
||
|
0xe0010a: 0xe04e34 = 1 s 1/5/72 1/5/72, _run_cartridge_applications
|
||
|
0xe00144: 0xe04dbe = 1 s 4/118/1512 1/27/444, _init_acia_vecs
|
||
|
0xe001ea: 0xe00ec6 = 1 b, _int_acia
|
||
|
0xe0038c: 0xe04c28 = 1 s 1/191/2052 1/191/2052, _init_exc_vec
|
||
|
0xe003a6: 0xe04c2e = 1 s 1/388/4656 1/388/4656, _init_user_vec
|
||
|
...
|
||
|
</pre>
|
||
|
|
||
|
<p>
|
||
|
For example, if you don't know all the places from which a certain
|
||
|
function is called, or in what context a certain interrupt handler can
|
||
|
be called during the period you're profiling, profile caller
|
||
|
information will tell you:
|
||
|
</p>
|
||
|
<pre>
|
||
|
callee: caller: calls: calltype:
|
||
|
| | | /
|
||
|
0x379: 0x155 = 144 r, 0x283 = 112 b, 0x2ef = 112 b, 0x378 = 72 s
|
||
|
583236/359708265/1631189180 72/4419020/19123430, dsp_interrupt
|
||
|
| | |
|
||
|
inclusive costs exclusive costs callee name
|
||
|
(of calls from 0x378)
|
||
|
|
||
|
Calltypes:
|
||
|
- b: jump/branch
|
||
|
- n: PC just moved to next address
|
||
|
- r: subroutine return
|
||
|
- s: subroutine call
|
||
|
</pre>
|
||
|
<p>
|
||
|
(Most "calls" to "dsp_interrupt" were subroutine call returns (=r)
|
||
|
to it from address 0x155.)
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
With the execution counts in normal profiling data, caller information
|
||
|
can actually be used to have complete picture of what exactly the code
|
||
|
did during profiling. Main/overview work for this analysis is best done
|
||
|
automatically, by the profiler data post-processor (documented below).
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h4>Caller data accuracy</h4>
|
||
|
|
||
|
<p>Everything about profile data accuracy applies also to caller costs,
|
||
|
but there are additional things to take into account, mainly because
|
||
|
profiler cannot determine when exceptions are being handled:</p>
|
||
|
<ul>
|
||
|
<li>If there are exception(s) during a subroutine call, costs for
|
||
|
the exception handling will also be accounted for that subroutine.
|
||
|
This shouldn't be a problem unless those costs are very large,
|
||
|
i.e. check how much CPU your exception handlers take.</li>
|
||
|
<li>Indicated exception handler call type can be incorrect.</li>
|
||
|
<li>Profiled code doing return address related stack manipulations
|
||
|
confuses call tracking and produces incorrect results (profiler
|
||
|
has special code to handle EmuTOS AES switcher because of this).
|
||
|
Typically this produces large list of functions that are finalized
|
||
|
at profile end, so it should be easy to detect.</li>
|
||
|
<li>Compilicated recursive calls seem to sometimes cause inclusive
|
||
|
costs (ones including costs of further subroutine calls) to be
|
||
|
incorrect. Sometimes this can be noticed by them being even
|
||
|
>100%.</li>
|
||
|
<li>On DSP, profiler heuristics assume (for speed reasons) that
|
||
|
<em>conditional</em> subroutine calls never call the very next
|
||
|
instruction (as that would be very bad/inefficient code).</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h4>Saving profile data to a file</h4>
|
||
|
|
||
|
<p>It's useful to save the profile data to a file:
|
||
|
<pre>
|
||
|
> profile save program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>With the saved profile disassembly (and optional caller information)
|
||
|
you can more easily investigate what your program did during
|
||
|
profiling, search symbols & addresses in it, and compare the
|
||
|
results to profiles you've saved from earlier versions of your code.</p>
|
||
|
|
||
|
<p>You may even create your own post-processing tools for
|
||
|
investigating the profiling data more closely, e.g. to
|
||
|
<a href="http://www.atari-forum.com/viewtopic.php?f=68&t=24561&start=75#p226505">find
|
||
|
CPU/DSP communication bottlenecks</a>.</p>
|
||
|
|
||
|
|
||
|
<h3>Profile data post-processing</h3>
|
||
|
|
||
|
<p>Saved profile data can be post-processed with (Python) script
|
||
|
installed by Hatari, to:</p>
|
||
|
<ul>
|
||
|
<li>Get lists of functions/symbols with highest costs.</li>
|
||
|
<li>Get callgraphs of what functions/symbols cause those
|
||
|
costs and what kind of call hierarchy the profiled code
|
||
|
has.</li>
|
||
|
<li>Export profile data in Valgrind's
|
||
|
<a href="http://valgrind.org/docs/manual/cl-format.html">Callgrind format</a>
|
||
|
for viewing it in
|
||
|
<a href="http://kcachegrind.sourceforge.net/">Kcachegrind</a>
|
||
|
GUI.</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h4>Providing symbols for the post-processor</h4>
|
||
|
|
||
|
<p>When the data is post-processed, you should always provide
|
||
|
the post-processor symbols for the profile code! Relying just on the
|
||
|
symbol in the profile data can cause costs to be asssigned to wrong
|
||
|
symbol, if symbol's code wasn't called through symbol's own address,
|
||
|
but by jumping inside its code.</p>
|
||
|
|
||
|
<p>If your code is in fixed location, you should tell
|
||
|
post-processor to handle symbol addresses as absolute (-a):</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py <b>-a</b> etos512k.sym emutos-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>Normal programs are relocated and you should instead give
|
||
|
the symbols as TEXT (code) section relative ones (-r):</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py <b>-r</b> program.sym program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>If symbols are included to your binary in DRI/GST format, first they
|
||
|
need to be extracted to <a href="#Debug_symbols">the ASCII format</a>
|
||
|
understood by the post-processor:</p>
|
||
|
<pre>
|
||
|
$ gst2ascii -l -o program.prg > program.sym
|
||
|
</pre>
|
||
|
|
||
|
<p>If there are some extra symbols that you don't want to see
|
||
|
separately in profiles, because they aren't real functions,
|
||
|
but e.g. loop labels, you can either remove them manually
|
||
|
from the ASCII *.sym file, or filter them out with grep:
|
||
|
</p>
|
||
|
<pre>
|
||
|
$ gst2ascii -l -o program.prg | grep -v -e useless1 -e useless2 > program.sym
|
||
|
</pre>
|
||
|
|
||
|
|
||
|
<h4>Post-processor provided statistics</h4>
|
||
|
|
||
|
<p>Above post-processor examples just parse + verify the given data
|
||
|
and produce output like this:</p>
|
||
|
<pre>
|
||
|
Hatari profile data processor
|
||
|
|
||
|
Parsing TEXT relative symbol address information from program.sym...
|
||
|
[...]
|
||
|
3237 lines with 1550 code symbols/addresses parsed, 0 unknown.
|
||
|
|
||
|
Parsing profile information from program-profile.txt...
|
||
|
[...]
|
||
|
9575 lines processed with 368 functions.
|
||
|
|
||
|
CPU profile information from 'program-profile.txt':
|
||
|
- Hatari v1.6.2+ (May 4 2013), WinUAE CPU core
|
||
|
</pre>
|
||
|
|
||
|
<p>To get statistics (-s) and list of top (-t) CPU users in profile,
|
||
|
add "-st" option:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py <b>-st</b> -r program.sym program-profile.txt
|
||
|
[...]
|
||
|
CPU profile information from 'program-profile.txt':
|
||
|
- Hatari v1.6.2+ (May 4 2013), WinUAE CPU core
|
||
|
|
||
|
Time spent in profile = 34.49539s.
|
||
|
|
||
|
Calls:
|
||
|
- max = 187738, in __toupper at 0x52b88, on line 8286
|
||
|
- 1585901 in total
|
||
|
Executed instructions:
|
||
|
- max = 1900544, in flat_remap_mips+14 at 0x47654, on line 7020
|
||
|
- 64499351 in total
|
||
|
Used cycles:
|
||
|
- max = 15224620, in flat_remap_mips+18 at 0x47658, on line 7022
|
||
|
- 553392132 in total
|
||
|
Instruction cache misses:
|
||
|
- max = 184308, in _BM_T_GetTicks at 0x43b90, on line 4772
|
||
|
- 4941307 in total
|
||
|
|
||
|
Calls:
|
||
|
11.84% 187698 __toupper
|
||
|
11.48% 182105 _BM_T_GetTicks
|
||
|
11.48% 182019 _I_GetTime
|
||
|
[...]
|
||
|
Executed instructions:
|
||
|
34.83% 22462729 flat_generate_mips
|
||
|
14.08% 9080215 flat_remap_mips
|
||
|
8.55% 5515945 render_patch_direct
|
||
|
5.09% 3283328 _TryRunTics
|
||
|
[...]
|
||
|
Used cycles:
|
||
|
23.62% 130702768 flat_generate_mips
|
||
|
12.42% 68735832 flat_remap_mips
|
||
|
9.77% 54041148 _TryRunTics
|
||
|
5.80% 32111536 correct_element
|
||
|
[...]
|
||
|
Instruction cache misses:
|
||
|
37.03% 1829764 _TryRunTics
|
||
|
11.20% 553314 _BM_T_GetTicks
|
||
|
9.44% 466319 _NetUpdate
|
||
|
9.27% 457899 _HGetPacket
|
||
|
[...]
|
||
|
</pre>
|
||
|
|
||
|
<p>If you want to see also symbol addresses and what is per call
|
||
|
cost, add -i option:<p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -st <b>-i</b> -r program.sym program-profile.txt
|
||
|
[...]
|
||
|
Executed instructions:
|
||
|
34.83% 22462729 flat_generate_mips (0x04778a, 774576 / call)
|
||
|
14.08% 9080215 flat_remap_mips (0x047646, 313110 / call)
|
||
|
8.55% 5515945 render_patch_direct (0x047382, 29977 / call)
|
||
|
5.09% 3283328 _TryRunTics (0x042356, 19660 / call)
|
||
|
[...]
|
||
|
Used cycles:
|
||
|
23.62% 8.14728s 130702768 flat_generate_mips (0x04778a, 0.28094s / call)
|
||
|
12.42% 4.28461s 68735832 flat_remap_mips (0x047646, 0.14775s / call)
|
||
|
9.77% 3.36863s 54041148 _TryRunTics (0x042356, 0.02017s / call)
|
||
|
5.80% 2.00165s 32111536 correct_element (0x04a658, 0.00001s / call)
|
||
|
[...]
|
||
|
Instruction cache misses:
|
||
|
37.03% 1829764 _TryRunTics (0x042356, 10956 / call)
|
||
|
11.20% 553314 _BM_T_GetTicks (0x043b90, 3 / call)
|
||
|
9.44% 466319 _NetUpdate (0x041bcc, 5 / call)
|
||
|
9.27% 457899 _HGetPacket (0x041754, 5 / call)
|
||
|
[...]
|
||
|
</pre>
|
||
|
|
||
|
<p>(For cycles the "per call" information is in seconds, not as
|
||
|
a cost count.)</p>
|
||
|
|
||
|
<p>If your profile file contains caller information, you should
|
||
|
add -p option to see it, as that will also help in detecting symbol
|
||
|
issues (see <a href="#Interpreting_the_numbers">Interpreting
|
||
|
the numbers</a>):<p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -st <b>-p</b> -r program.sym program-profile.txt
|
||
|
[...]
|
||
|
9575 lines processed with 368 functions.
|
||
|
[...]
|
||
|
Of all 1570498 switches, ignored 581 for type(s) ['r', 'u', 'x'].
|
||
|
|
||
|
CPU profile information from 'badmood-level-load-CPU.txt':
|
||
|
- Hatari v1.6.2+ (May 4 2013), WinUAE CPU core
|
||
|
[...]
|
||
|
Calls:
|
||
|
11.84% 11.84% 187698 187698 __toupper
|
||
|
11.48% 11.48% 182105 182105 _BM_T_GetTicks
|
||
|
11.48% 22.95% 182019 364038 _I_GetTime
|
||
|
[...]
|
||
|
Executed instructions:
|
||
|
34.83% 34.86% 34.86% 22462729 22484024 22484024 flat_generate_mips
|
||
|
14.08% 14.10% 14.10% 9080215 9091270 9091676 flat_remap_mips
|
||
|
8.55% 5515945 render_patch_direct
|
||
|
5.09% 5.11% 94.96% 3283328 3294022 61247717 _TryRunTics
|
||
|
[...]
|
||
|
Used cycles:
|
||
|
23.62% 23.69% 23.69% 130702768 131100604 131100604 flat_generate_mips
|
||
|
12.42% 12.46% 12.46% 68735832 68928816 68930904 flat_remap_mips
|
||
|
9.77% 9.80% 95.66% 54041148 54238744 529368824 _TryRunTics
|
||
|
5.80% 5.82% 5.82% 32111536 32193664 32193664 correct_element
|
||
|
[...]
|
||
|
Instruction cache misses:
|
||
|
37.03% 37.14% 98.57% 1829764 1835261 4870573 _TryRunTics
|
||
|
11.20% 11.24% 11.24% 553314 555191 555191 _BM_T_GetTicks
|
||
|
9.44% 9.49% 29.13% 466319 468782 1439340 _NetUpdate
|
||
|
9.27% 9.29% 9.37% 457899 459197 463217 _HGetPacket
|
||
|
[...]
|
||
|
</pre>
|
||
|
|
||
|
<p>Now there's a message telling that some of the calls were ignored
|
||
|
because according to their "call type", they were actually returns from
|
||
|
exceptions, not real calls (this is mainly important for callgraph
|
||
|
generation, discussed below).</p>
|
||
|
|
||
|
|
||
|
<h4>Interpreting the results</h4>
|
||
|
|
||
|
<p>In addition to accuracy issues mentioned in previous Profiling
|
||
|
sections, function/symbol level costs have gotchas of their own.</p>
|
||
|
|
||
|
<p>The first cost percentage and count columns are <em>sums for all
|
||
|
the instructions</em> that were in profile data file <em>between
|
||
|
the indicated symbol's address and the address of the next symbol</em>
|
||
|
(= "between-symbols" cost).</p>
|
||
|
|
||
|
<p><strong>NOTE:</strong> If your symbol file doesn't contain addresses
|
||
|
for all the relevant symbols, results from this can be misleading because
|
||
|
instructions costs get assigned to <em>whatever</em> symbol's address
|
||
|
happened to precede those instructions. And you don't see which
|
||
|
caller is causing it from caller info or callgraph either, as entry
|
||
|
point for that time sink lacking a symbol means profiler hadn't
|
||
|
tracked calls to it...</p>
|
||
|
|
||
|
<p>The next two cost percentage and count columns are for <em>subroutine
|
||
|
calls costs</em>, first one for exclusive and latter for inclusive cost
|
||
|
i.e. including costs for further subroutine calls. Values are based on
|
||
|
caller information documented above.</p>
|
||
|
|
||
|
<p>Reasons why between-symbol costs, and subroutine call costs can
|
||
|
differ, are following:</p>
|
||
|
<ul>
|
||
|
<li>Subroutine terminates before next symbol address: exclusive
|
||
|
cost is smaller than in-between cost <em>because of missing
|
||
|
symbol information</em>
|
||
|
(these are indicated with '*' in statistics).</li>
|
||
|
<li>Subroutine is called more through jumps/branches than through
|
||
|
subroutine calls: inclusive call count may be smaller than
|
||
|
in-between call count which includes branches/jumps.</li>
|
||
|
<li>Subroutine jumps/branches to another function instead of
|
||
|
using subroutine call, or function contains additional
|
||
|
(non-function) labels: exclusive cost is larger than
|
||
|
in-between cost.</li>
|
||
|
<li>Exception happening during subroutine call: exclusive cost is
|
||
|
(slightly) larger than in-between cost.</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>In the first case, you should check the profile data to find out
|
||
|
whether there are missing symbols for executed function entry points.
|
||
|
You can notice function entry points as address gap and/or code
|
||
|
retrieving arguments from stack. Exit points can be seen from RTS
|
||
|
instructions.</p>
|
||
|
|
||
|
<p>Second case can also be seen from the profile data. Call count
|
||
|
is same as count for how many times first instruction is executed
|
||
|
(worst case: large loop on subroutine's first instruction).</p>
|
||
|
|
||
|
<p>While subroutine costs should be more accurate and relevant, due to
|
||
|
code optimizations many of the functions are not called as subroutines
|
||
|
(on m68k, using JSR/BSR), but just jumped or branced to. Because of
|
||
|
this, it's useful to compare both subroutine and between-symbols
|
||
|
costs. One should be able to see from the profile disassembly which
|
||
|
of the above cases is cause for the discrepancy in the values.</p>
|
||
|
|
||
|
<p><strong>NOTE:</strong> Before starting to do any serious source
|
||
|
level optimizations, you should <em>always</em> verify from profile
|
||
|
data (disassembly) where exactly the costs are in a function, to make
|
||
|
sure your optimization efforts can actually help the performance.</p>
|
||
|
|
||
|
|
||
|
<h4>Generating and viewing callgraphs</h4>
|
||
|
|
||
|
<p>Callgraphs require that saved profile data contains caller
|
||
|
function address information, i.e. symbols for the code should
|
||
|
be loaded before starting profiling it (see
|
||
|
<a href="#Debug_symbols">loading symbol data</a>).</p>
|
||
|
|
||
|
<p>Separate callgraphs will be created for each of the costs
|
||
|
(0=calls, 1=instructions, 2=cycles) with the -g option:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py <b>-p -g</b> -r program.sym program-profile.txt
|
||
|
[...]
|
||
|
Generating 'program-profile-0.dot' DOT callgraph file...
|
||
|
|
||
|
Generating 'program-profile-1.dot' DOT callgraph file...
|
||
|
|
||
|
Generating 'program-profile-2.dot' DOT callgraph file...
|
||
|
[...]
|
||
|
</pre>
|
||
|
|
||
|
<p>Callgraphs are saved in <a href="http://www.graphviz.org/">GraphViz</a>
|
||
|
"dot" format. Dot files can be viewed:</p>
|
||
|
<ul>
|
||
|
<li>With "dotty" program included with GraphViz</li>
|
||
|
<li>With <a href="http://code.google.com/p/jrfonseca/wiki/XDot">XDot</a>
|
||
|
Python GUI (best option on Linux), or some platform specific viewer</li>
|
||
|
<li>By converting dot file to PostScript or SVG format before
|
||
|
viewing it with viewers for those:
|
||
|
<pre>
|
||
|
$ dot -Tsvg program-profile-1.dot > program-profile-1.svg
|
||
|
</pre>
|
||
|
(problem with most PS/PDF and SVG viewers is that either they
|
||
|
don't allow zooming large callgraphs enough or they use huge
|
||
|
amounts of memory and get very slow)
|
||
|
</li>
|
||
|
</ul>
|
||
|
|
||
|
<p>Produced callgraph will look like this:</p>
|
||
|
<div style="text-align:center">
|
||
|
<a href="images/callgraph.svg">
|
||
|
<img src="images/callgraph.png" width="953" height="589"
|
||
|
alt="Part of callgraph" />
|
||
|
</a>
|
||
|
</div>
|
||
|
|
||
|
<p>Interpreting the callgraph:</p>
|
||
|
<ul>
|
||
|
<li>Diamond shaped nodes are symbols called as subroutines.
|
||
|
Values listed in them are subroutine call costs; inclusive
|
||
|
(total) cost with exclusive (own) cost in parenthesis,
|
||
|
followed by inclusive cost count. Exclusive cost is
|
||
|
shown only if it differs from inclusive one.</li>
|
||
|
<li>Ellipse shaped nodes are for other symbols (functions
|
||
|
called using jumps/branches, loop labels etc). Values
|
||
|
listed in them are between-symbols costs, i.e. normally
|
||
|
they're included to inclusive (total) costs shown in
|
||
|
subroutine call node somewhere higher in call hierarchy.</li>
|
||
|
<li>Nodes which exclusive (own) or between-symbols costs
|
||
|
exceed default or explicitly given threshold value,
|
||
|
have gray background.</li>
|
||
|
<li>Both nodes, which inclusive or between-symbols cost exceeds
|
||
|
the threshold value, and the arrows to & from them,
|
||
|
are marked red.
|
||
|
<li>Arrow types indicate call types; normal arrows subroutine
|
||
|
calls, circles branches/jumps, backarrows returns.
|
||
|
Exception calls and returns are indicated with dashed lines,
|
||
|
unknown calls with dotted lines.</li>
|
||
|
<li>Arrow text tells from which address (within the caller)
|
||
|
the call originated. If symbol had multiple callers, text
|
||
|
includes count of calls from that particular address, and its
|
||
|
percentage is of all calls done to that symbol.</li>
|
||
|
</ul>
|
||
|
|
||
|
|
||
|
<h4>Making large callgraphs readable</h4>
|
||
|
|
||
|
<p>If profile is for larger and more varied amount of code
|
||
|
(e.g. program startup), the resulting callgraph can be so
|
||
|
huge it's unreadable.</p>
|
||
|
|
||
|
<p>If your code has interrupt handlers, they can get called
|
||
|
at any point, which can show in callgraph as "explicit" calls
|
||
|
from the interrupted functions. To get rid of such incorrect
|
||
|
calls, give interrupt handler names to --ignore-to option:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -p -g <b>--ignore-to handler1,handler2</b> -r program.sym program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>In large callgraph most of the functions aren't really interesting,
|
||
|
because their contribution to the cost is insignificant. You can
|
||
|
remove large number of them with --no-leafs and --no-intermediate
|
||
|
options, those options act <em>only</em> on on nodes which costs are below
|
||
|
given threshold. Leaf nodes are ones which don't have any parents
|
||
|
and/or children. Intermediate ones have only single parent and
|
||
|
children (node calling itself is not taken into account).
|
||
|
|
||
|
<p>Threshold for this is given with the --limit (-l) option. With
|
||
|
that it typically makes also sense to change the node emphasis
|
||
|
threshold with --emph-limit (-e) option:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -p -g <b>-l 0.5 -e 2.0</b> -r program.sym program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>If you're not interested in from how many different addresses
|
||
|
a given function calls another function, use --compact option. If you
|
||
|
still see multiple calls between two nodes with it, the reason is that
|
||
|
they happened through different call paths which were removed from
|
||
|
the callgraph after --compact option was applied:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -p -g -l 1.0 -e 2.0 <b>--no-leafs --no-intermediate --compact</b> -r program.sym program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>If even this doesn't help, you can remove all nodes below
|
||
|
the given cost threshold limit with --no-limited option, but this
|
||
|
often doesn't leave much of a call hierarchy. Instead you may
|
||
|
consider removing all nodes except for subroutine call ones, with the
|
||
|
--only-subroutines option.</p>
|
||
|
|
||
|
<p>If you have trouble locating nodes you're specially interested
|
||
|
about, you can either color them differently with the --mark option,
|
||
|
or exclude everything else from the callgraph except those nodes and
|
||
|
their immediate callers & callees, with the --only option:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py -p -g <b>--only func1,func2</b> -r program.sym program-profile.txt
|
||
|
</pre>
|
||
|
|
||
|
<p>Last option for reading the callgraph is using -k option to
|
||
|
export the data for use in (Linux) Kcachegrind UI. Kcachegrind generates
|
||
|
callgraphs on the fly, and just for the area around the function
|
||
|
you selected, so navigating in callgraph may be easier. It also
|
||
|
shows the related profile disassembly, which can make verifying
|
||
|
matters easier:</p>
|
||
|
<pre>
|
||
|
$ hatari_profile.py <b>-p -k</b> -r program.sym program-profile.txt
|
||
|
[...]
|
||
|
Generating callgrind file 'program-profile.cg'...
|
||
|
[...]
|
||
|
$ kcachegrind program-profile.cg
|
||
|
</pre>
|
||
|
<div style="text-align:center">
|
||
|
<img src="images/kcachegrind.png" width="887" height="442"
|
||
|
alt="Kcachegrind screenshot" />
|
||
|
</div>
|
||
|
|
||
|
|
||
|
<h3>Usage examples</h3>
|
||
|
|
||
|
<p>
|
||
|
Here's a list of some common debugging tasks and how to do them
|
||
|
with the Hatari debugger:
|
||
|
</p>
|
||
|
|
||
|
<dl>
|
||
|
<dt><em>Stopping on program startup and examining its data</em></dt>
|
||
|
<dd>Please see <a href="#Breakpoint_variables">Breakpoint variables</a>
|
||
|
and <a href="#Inspecting_emulation_state">Inspecting emulation state</a>
|
||
|
sections.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Tracing specific things in the system</em></dt>
|
||
|
<dd>To trace e.g. all GEMDOS calls and IO operations, use:
|
||
|
<pre>
|
||
|
trace gemdos,io_all
|
||
|
</pre>
|
||
|
Please see <a href="#Tracing">Tracing</a> section for more information
|
||
|
on tracing, what's possible with it and what are its limitations.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when certain PC address is passed Nth time</em></dt>
|
||
|
<dd>To stop e.g. after function/subroutine at $12345 is called for
|
||
|
the 6th time:
|
||
|
<pre>
|
||
|
a $12345 :6
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when specific exception happens</em></dt>
|
||
|
<dd>Hatari's -D option doesn't invoke debugger on all exceptions and
|
||
|
doesn't allow invoking debugger just for specific exceptions. To
|
||
|
stop at specific exception, one can check when it's called.
|
||
|
At the start of memory is the CPU exception table for exception
|
||
|
handler addresses, so to stop e.g. at bus error with some extra
|
||
|
information, one can use following:
|
||
|
<pre>
|
||
|
history on
|
||
|
b pc=($8)
|
||
|
</pre>
|
||
|
After bus error invokes debugger, 'history' command can then be used
|
||
|
to see (executed memory addresses with their current) instructions
|
||
|
leading to the error. The most interesting vector addresses are:
|
||
|
$8 (Bus error), $C (Address error), $10 (Illegal instruction),
|
||
|
$14 (Division by zero). See also --debug-except option.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when register has a specific value</em></dt>
|
||
|
<dd>To stop when e.g. D1 register contains value 5, set a breakpoint on:
|
||
|
<pre>
|
||
|
b d1 = 5
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when a register value changes</em></dt>
|
||
|
<dd>To stop when e.g. D1 register value changes, set a breakpoint on:
|
||
|
<pre>
|
||
|
b d1 ! d1
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when register value is within some range</em></dt>
|
||
|
<dd>To stop when e.g. D1 register value is within range of 10-30,
|
||
|
set a breakpoint on:
|
||
|
<pre>
|
||
|
b d1 > 9 && d1 < 31
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when memory location has a specific value</em></dt>
|
||
|
<dd>To stop when e.g. bit 1 of the Video Shifter Sync Mode byte at
|
||
|
IO address $ff820a is set i.e. video frequency is 60Hz, set
|
||
|
a breakpoint on:
|
||
|
<pre>
|
||
|
b ($ff820a).b & 2 = 2
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping when a memory value changes</em></dt>
|
||
|
<dd>To stop when above bit changes, set a breakpoint on its value
|
||
|
being different from the current value ('!' compares for inequality):
|
||
|
<pre>
|
||
|
b ($ff820a).b & 2 ! ($ff820a).b & 2
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Tracing all changes in specific memory location</em></dt>
|
||
|
<dd>To see the new values and continue without stopping, add
|
||
|
the ":trace" breakpoint option:
|
||
|
<pre>
|
||
|
b ($ff820a).b & 2 ! ($ff820a).b & 2 :trace
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping at specific screen position</em></dt>
|
||
|
<dd>To stop e.g. when VBL is 100, HBL is 40 and line cycles is 5,
|
||
|
use the corresponding debugger variables:
|
||
|
<pre>
|
||
|
b VBL = 100 && HBL = 40 && FrameCycles = 5
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Stopping after value increases/decreases by certain amount</em></dt>
|
||
|
<dd>To stop e.g. after D0 value has increased by 10, set breakpoint on:
|
||
|
<pre>
|
||
|
b d0 = "d0 + 10"
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Examining specific system call return value</em></dt>
|
||
|
<dd>To check e.g. what's the Fopen() GEMDOS call return value,
|
||
|
check with "info gemdos 1" its opcode, set a breakpoint for that
|
||
|
and step to next (n) instruction from the trap call when breakpoint
|
||
|
is hit. GEMDOS call return value is then in register D0:
|
||
|
<pre>
|
||
|
> trace gemdos
|
||
|
> b GemdosOpcode = $3D
|
||
|
> c
|
||
|
[...continue until breakpoint...]
|
||
|
1. CPU breakpoint condition(s) matched 1 times.
|
||
|
GemdosOpcode = $3D
|
||
|
> n
|
||
|
GEMDOS 0x3D Fopen("TEST.TXT", read-only)
|
||
|
> e d0
|
||
|
= %1000000 (bin), #64 (dec), $40 (hex)
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Seeing code leading to a breakpoint</em></dt>
|
||
|
<dd>To see CPU instructions executed before debugger was entered,
|
||
|
you need to enabled history tracking <em>before</em> it. Whenever
|
||
|
debugger is entered, you can then request given number (here 16) of
|
||
|
past instructions to be shown:
|
||
|
<pre>
|
||
|
history cpu
|
||
|
c
|
||
|
[breakpoint is hit and debugger entered]
|
||
|
history 16
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Getting instruction execution history for every breakpoint</em></dt>
|
||
|
<dd>
|
||
|
To see last 16 instructions for both CPU and DSP whenever
|
||
|
(a normal or tracing) breakpoint is hit:
|
||
|
<pre>
|
||
|
history on
|
||
|
lock history 16
|
||
|
c
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Single stepping so that new register values are shown after each step</em></dt>
|
||
|
<dd>
|
||
|
<pre>
|
||
|
lock registers
|
||
|
s
|
||
|
[new register values]
|
||
|
s
|
||
|
[new register values]
|
||
|
...
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Showing current stack contents</em></dt>
|
||
|
<dd>To see first 64 bytes on top of the stack, use:
|
||
|
<pre>
|
||
|
m "a7-64"-a7
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Seeing specific information each time debugger is entered</em></dt>
|
||
|
<dd>To see above information whenever some breakpoint is hit,
|
||
|
you enter debugger manually etc, write that command to e.g.
|
||
|
<span class="file">stack.ini</span> file and then use:
|
||
|
<pre>
|
||
|
lock file stack.ini
|
||
|
</pre>
|
||
|
Please see also <a href="#Chaining_breakpoints">Chaining breakpoints</a>
|
||
|
section for more examples on what you can do with the debugger input files.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Finding where a program or the OS is stuck</em></dt>
|
||
|
<dd>Profiling tells from which addresses CPU is executing the instructions:
|
||
|
<pre>
|
||
|
profile on
|
||
|
c
|
||
|
[after a while, use AltGr+Pause to get back to debugger]
|
||
|
profile counts
|
||
|
</pre>
|
||
|
Please see <a href="#Profiling">Profiling</a> section for more info.
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Seeing program callstack when breakpoint is hit</em></dt>
|
||
|
<dd><a href="#Caller_information">Profiler caller data</a> includes
|
||
|
callstack information (with some limitations).
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Seeing call backtraces whenever given function is called</em></dt>
|
||
|
<dd>Enable profiling, load symbols for the program and set breakpoint
|
||
|
for the function you're interested about, in the following way:
|
||
|
<pre>
|
||
|
profile on
|
||
|
symbols prg
|
||
|
b pc = _my_function :quiet :noinit :file showstack.ini
|
||
|
</pre>
|
||
|
I.e. whenever 'my_function' address is called, quietly trigger a
|
||
|
breakpoint without reseting profiling (callstack) information and run
|
||
|
debugger command(s) from the 'showstack.ini' debugger script file,
|
||
|
which contains following command:
|
||
|
<pre>
|
||
|
profile stack
|
||
|
</pre>
|
||
|
</dd>
|
||
|
|
||
|
<dt><em>Seeing how program functions/symbols call each other</em></dt>
|
||
|
<dd><a href="#Profile_data_post-processing">Profile data
|
||
|
post-processing</a> can provide execution callgraphs.
|
||
|
</dd>
|
||
|
|
||
|
</dl>
|
||
|
|
||
|
<p>
|
||
|
Hint: for most of the above commands, one just needs to prefix them with
|
||
|
"d" (or "dsp" when using full command names) to do similar operation on
|
||
|
the DSP.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3 id="Build_notes">Build notes</h3>
|
||
|
|
||
|
<p>
|
||
|
Lastly, the debugger is much nicer to use with the command line
|
||
|
history, editing and especially the completion support for the
|
||
|
command, command argument and symbol names.
|
||
|
</p>
|
||
|
<p>
|
||
|
If you're building Hatari yourself, please make sure that you have the
|
||
|
GNU readline development files installed (on Debian / Ubuntu these
|
||
|
come from the libreadline5-dev package). Otherwise the name completion
|
||
|
and other features don't get enabled when you configure Hatari.
|
||
|
</p>
|
||
|
<p>
|
||
|
ENABLE_TRACING define needs to be set for tracing to work.
|
||
|
By default it should be enabled.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h2 id="Performance">Performance</h2>
|
||
|
|
||
|
<p>Hatari performance varies between Atari programs, depending on what
|
||
|
features Hatari needs to emulate for them. Less accurate Atari
|
||
|
emulators may be faster as emulation accuracy has a performance
|
||
|
overhead.</p>
|
||
|
|
||
|
<p>The operating system and libraries below Hatari can also sometimes
|
||
|
have a noticeable effect on performance.</p>
|
||
|
|
||
|
|
||
|
<h3>Improving Hatari performance</h3>
|
||
|
|
||
|
<p>
|
||
|
Hatari currently runs best in 16 or 32 bits per pixel color depth
|
||
|
mode, so try to avoid 24 bits per pixel display modes if possible.
|
||
|
16-bit mode is fastest.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<em>On OSX, frame skipping, zooming and drive LED options (listed below)
|
||
|
seem to have a large effect on performance in the windowed mode</em>.
|
||
|
This is apparently due to issues in the SDL OSX backend and how OSX
|
||
|
itself composites non-fullscreen window contents. OSX uses always
|
||
|
32-bit mode.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Unless you've disabled compiler optimizations (like GCC's -O2 or -O3
|
||
|
options) in the Hatari build, the extra optimization flags (like GCC's
|
||
|
"-mtune=i686") don't seem to have very large effect on Hatari
|
||
|
performance. Using GCC -O3 option instead of -O2 can give minor
|
||
|
(5-10%) performance improvements for things (demos) that use very
|
||
|
heavily interrupts.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
However, Hatari can be sped up considerably by giving up some
|
||
|
emulation or emulator accuracy. Except for DSP, these options
|
||
|
should be needed only on very slow devices like handhelds. See below.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
If nothing else helps, try an earlier Hatari version. More accurate
|
||
|
emulation or emulator output in newer Hatari versions means that they
|
||
|
can be slower despite optimizations.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Emulation options</h3>
|
||
|
|
||
|
<p>
|
||
|
Emulation options have the largest impact on performance.
|
||
|
These options can be changed from the Hatari GUI System dialog and
|
||
|
the emulation needs to be rebooted for any of these changes to take
|
||
|
an effect! They're enabled by default.
|
||
|
</p>
|
||
|
|
||
|
<h4>DSP</h4>
|
||
|
<p>
|
||
|
Emulating the Falcon DSP is performance-wise several times more demanding
|
||
|
than emulating the m68k; DSP runs at higher frequency, executes many
|
||
|
instructions for each m68k instruction and emulation isn't as mature
|
||
|
and optimized. Unless some Falcon program needs DSP, <em>none</em> or
|
||
|
<em>dummy</em> DSP emulation mode could be used. Even of the programs
|
||
|
that do use DSP, many use it only for background music and work
|
||
|
fine without the real DSP emulation.
|
||
|
</p>
|
||
|
|
||
|
<h4>Timer-D</h4>
|
||
|
<p>
|
||
|
The single largest factor contributing to general Hatari emulation
|
||
|
performance is the handling of interrupts. Enabling Timer-D patching
|
||
|
option (about) doubles Hatari ST/STE emulation performance as it
|
||
|
significantly reduces the number of interrupts generated by the emulated
|
||
|
Atari machine. Using this has adverse effect only for very rare programs.
|
||
|
</p>
|
||
|
|
||
|
<h4>FDC</h4>
|
||
|
<p>
|
||
|
While accurate FDC emulation doesn't take that much CPU, it slows down
|
||
|
floppy image accesses (and Hatari startup) a lot. Only <em>very</em>
|
||
|
few demos and games require accurate FDC emulation for their copy protection,
|
||
|
so enabling fast floppy access is fairly safe.
|
||
|
</p>
|
||
|
|
||
|
<h4>Compatible CPU</h4>
|
||
|
<p>
|
||
|
After the DSP and interrupts, m68k emulation takes most time.
|
||
|
Disabling the "Slower but more compatible CPU" option will speed up
|
||
|
the emulation a lot, but it won't anymore be cycle accurate. This can
|
||
|
be fine for many games and other programs, but won't work e.g. for demos
|
||
|
using overscan or rasters.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
Roughly speaking, for DSP emulation, one needs at least 2Ghz machine.
|
||
|
For normal (unpatched) Timer-D frequency on some specific cases (like
|
||
|
demos with overscan 512 color animations) one may need over 1GHz
|
||
|
machine, but some rare ST/STE demos may require over 1GHz machine even
|
||
|
with Timer-D patching. For "Compatible CPU" one needs at least 1/2Ghz
|
||
|
machine.
|
||
|
</p>
|
||
|
|
||
|
<p>
|
||
|
<strong>NOTE</strong>: Above options may cause some programs to work in correctly.
|
||
|
The <a href="compatibility.html">Hatari Software Compatibility List</a>
|
||
|
lists programs known to need real real Falcon DSP emulation, Timer-D
|
||
|
frequency or accurate FDC timings. Disabling "Compatible CPU" option
|
||
|
is recommended only as a last resort.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Emulator options</h3>
|
||
|
|
||
|
<p>
|
||
|
Emulator options don't usually have as large effect on performance as
|
||
|
emulation options, but they don't affect the emulated programs at all,
|
||
|
just the quality of the emulation "output". These options can also
|
||
|
be toggled at run-time without rebooting the emulation.
|
||
|
</p>
|
||
|
|
||
|
<h4>Sound</h4>
|
||
|
<p>
|
||
|
Internal Hatari sound handling and the SDL_mixer sound thread
|
||
|
libALSA sound processing can account up to 1/3 of the Hatari CPU usage
|
||
|
in normal ST/STE emulation. Disabling sound will get rid of that.
|
||
|
Using low sound frequency or one matching your sound card may also help.
|
||
|
Best is if you disable also background music from the programs you run
|
||
|
in Hatari as this can significantly reduce the number of generated
|
||
|
interrupts.
|
||
|
</p>
|
||
|
|
||
|
<h4>Frame skipping</h4>
|
||
|
<p>
|
||
|
Screen rendering can take noticeable amount of CPU time. The default
|
||
|
Hatari "auto" frame skipping should be used unless there's a good
|
||
|
reason not to. It will skip converting and showing some of the frames
|
||
|
if there's not enough time for them.
|
||
|
</p>
|
||
|
<p>
|
||
|
Also, if your monitor refresh frequency is lower than the selected
|
||
|
Hatari monitor frequency (e.g. LCD monitors usually use 60Hz whereas
|
||
|
Atari monochrome monitor uses 71Hz), you should use frameskip of one.
|
||
|
The reason is that if your SDL library uses VSync to synchronize the
|
||
|
output to screen (like OSX one?), with zero frame skip that forces the
|
||
|
emulation to run slower than a real Atari. If SDL doesn't use VSync,
|
||
|
Hatari does redundant work to convert frames you can't see.
|
||
|
</p>
|
||
|
|
||
|
<h4>Zooming</h4>
|
||
|
<p>
|
||
|
If you are not using frame skip, disabling zooming can have
|
||
|
noticeable improvement on performance. You can do this by specifying
|
||
|
suitably low "Max zoomed" resolution (<span class="commandline">--zoom
|
||
|
1</span> command line option sets it to 320x200). If you still want to
|
||
|
have a nice fullscreen mode, you should rather add the right resolution
|
||
|
mode-lines (e.g. "320x200") to your xorg.conf file. If you still want
|
||
|
to use zooming, disabling borders may help a bit.
|
||
|
</p>
|
||
|
|
||
|
<h4>Spec512 color handling</h4>
|
||
|
<p>
|
||
|
Handling Spec512 color modes which change the ST/e palette constantly
|
||
|
takes some extra CPU. If you have problems with CPU usage in such
|
||
|
screens and you care more e.g. from the sound quality than visuals, you
|
||
|
can either increase the threshold or disable the Spec512 mode handling
|
||
|
completely by zeroing the threshold for that with the
|
||
|
<span class="commandline">--spec512 0</span> option.
|
||
|
</p>
|
||
|
|
||
|
<h4>Statusbar and drive LED</h4>
|
||
|
<p>
|
||
|
If your version of the SDL library uses VSync to synchronize the screen
|
||
|
output, drawing of the statusbar or the drive LED may have some minor
|
||
|
impact on performance too. Normally they shouldn't.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h3>Measuring the performance</h3>
|
||
|
|
||
|
<p>
|
||
|
There are a couple of ways to monitor and measure Hatari performance.
|
||
|
</p>
|
||
|
<p>
|
||
|
By default Hatari has Statusbar visible and automatic frameskip
|
||
|
enabled. When Hatari has enough time that it can sleep a little each
|
||
|
frame, the statusbar frame skip ("FS") value keeps at zero. If Hatari
|
||
|
is completely busy, it will increase to the maximum specified
|
||
|
(automatic) frame skip value.
|
||
|
</p>
|
||
|
<p>
|
||
|
Hatari has also a facility to measure FPS i.e. Frames Per Second.
|
||
|
Just enable the <span class="commandline">--fast-forward</span> option
|
||
|
on command line (or use the corresponding keyboard shortcut), and
|
||
|
after a while, press the "Pause" key. Whenever Hatari emulation is
|
||
|
paused, Hatari will output on console how many VBLs it could show per
|
||
|
second along with some other numbers.
|
||
|
</p>
|
||
|
<p>
|
||
|
It depends on what you want to measure, but usually it's best to
|
||
|
disable sound and set high frame skip like
|
||
|
<span class="commandline">--sound off --frameskips 60</span> so that
|
||
|
the associated external overheads are minimized. E.g. video output
|
||
|
can on some platforms do VSync and measurements would then show your
|
||
|
monitor refresh frequency instead of the actual Hatari performance.
|
||
|
</p>
|
||
|
<p>
|
||
|
On Unix systems with <span class="commandline">times()</span> function
|
||
|
call, only the time spent by the Hatari process itself is measured.
|
||
|
On other systems, much less accurate SDL "wall clock" timings are
|
||
|
used. To make latter more accurate you could use also
|
||
|
<span class="commandline">--run-vbls</span> option to specify how many
|
||
|
VBLs Hatari should run before it exits. In this case it's best to
|
||
|
either have the test-case run automatically from the AUTO-folder or
|
||
|
given as memory snapshot to Hatari with the frame skip set equal to
|
||
|
the VBL count.
|
||
|
</p>
|
||
|
<p>
|
||
|
Note that these numbers can fluctuate quite a bit, <em>especially</em>
|
||
|
when the SDL timings are used, so for (statistically) reliable numbers
|
||
|
you may need to repeat the measurement several times. You should of
|
||
|
course make also sure that the system doesn't have any other activity
|
||
|
at the same time you're making the measurements.
|
||
|
</p>
|
||
|
|
||
|
|
||
|
<h2>Appendix</h2>
|
||
|
|
||
|
<h3>Copying</h3>
|
||
|
|
||
|
<div class="backdropped">
|
||
|
<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) any later version. </p>
|
||
|
<p>This program is distributed in the hope that it will be useful, but <em>WITHOUT
|
||
|
ANY WARRANTY</em>; without even the implied warranty of <em>MERCHANTABILITY</em>
|
||
|
or <em>FITNESS FOR A PARTICULAR PURPOSE</em>. See the GNU General
|
||
|
Public License for more details. </p>
|
||
|
<p>
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software Foundation,
|
||
|
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||
|
</p>
|
||
|
</div>
|
||
|
<p><a href="http://www.gnu.org/">The GNU Project and the Free Software
|
||
|
Foundation</a> | <a href="http://www.fsf.org/licenses/gpl.html">The
|
||
|
GNU General Public License</a></p>
|
||
|
|
||
|
<h3>Introduction to Emulation</h3>
|
||
|
|
||
|
<p>Emulation via software is an art and Hatari is an example of this.</p>
|
||
|
<p>Emulation is to make a computer behave like a (probably) completely
|
||
|
different machine on the lowest possible niveau.
|
||
|
This includes CPU and custom chip emulation allowing software written
|
||
|
for the emulated machine to be run without notice.
|
||
|
A good emulator will run most of the software intended for the emulated
|
||
|
platform without trouble.
|
||
|
</p>
|
||
|
<p>
|
||
|
The key to emulation is to simply do those things with a software
|
||
|
program, the emulator, that normally chips would perform.
|
||
|
So you have an CPU emulator that basically consists of a large loop
|
||
|
that does exactly what the real thing would do:
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li>fetch an instruction from virtual memory</li>
|
||
|
<li>interpret this instruction</li>
|
||
|
<li>fetch operands from the emulated registers and memory</li>
|
||
|
<li>perform the operation like addition or changing the program
|
||
|
counter on a jump instruction</li>
|
||
|
<li>writes results back into the intended registers or memory
|
||
|
locations</li>
|
||
|
<li>increment of the program counter and loop</li>
|
||
|
</ul>
|
||
|
<p>
|
||
|
The typical von-Neumann CPU can be emulated very fast, stable and
|
||
|
error-free using such a simple loop system.
|
||
|
</p>
|
||
|
<p>
|
||
|
But in most cases the CPU emulation is the simplest part. Correct
|
||
|
emulation of the various custom chips and hardware
|
||
|
parts of the emulated system is much trickier.
|
||
|
</p>
|
||
|
|
||
|
<hr>
|
||
|
|
||
|
</body>
|
||
|
</html>
|