3954 lines
252 KiB
HTML
3954 lines
252 KiB
HTML
<!DOCTYPE html><html lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>SjASMPlus 1.20.3 Documentation [2023-06-23]</title><link rel="stylesheet" type="text/css" href="docbook.css"><meta name="generator" content="DocBook XSL Stylesheets V1.79.2"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book"><div class="titlepage"><div><div><h1 class="title"><a name="sjasmplus_manual"></a>SjASMPlus 1.20.3 Documentation [2023-06-23]</h1></div></div><hr></div><div class="toc"><dl class="toc"><dt><span class="chapter"><a href="#introduction">1. Introduction</a></span></dt><dd><dl><dt><span class="section"><a href="#license">License</a></span></dt><dt><span class="section"><a href="#about">What is it?</a></span></dt><dt><span class="section"><a href="#features">Main Features</a></span></dt><dt><span class="section"><a href="#credits">Credits</a></span></dt><dt><span class="section"><a href="#feedback">Feedback</a></span></dt><dt><span class="section"><a href="#news">What's new?</a></span></dt></dl></dd><dt><span class="chapter"><a href="#where_to_get">2. Where to get and how to use</a></span></dt><dd><dl><dt><span class="section"><a href="#s_packages">Packages</a></span></dt><dt><span class="section"><a href="#s_cli">Command line</a></span></dt><dt><span class="section"><a href="#s_id_warnings">Warnings with id</a></span></dt><dt><span class="section"><a href="#s_source_format">Source file format</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_labels">3. Labels</a></span></dt><dd><dl><dt><span class="section"><a href="#s_labels">Labels</a></span></dt><dt><span class="section"><a href="#s_local_labels">Local labels</a></span></dt><dt><span class="section"><a href="#s_at_labels">@ Labels</a></span></dt><dt><span class="section"><a href="#s_temp_labels">Temporary labels</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_constants">4. Constants, expressions and other features</a></span></dt><dd><dl><dt><span class="section"><a href="#s_numeric">Numeric constants</a></span></dt><dt><span class="section"><a href="#s_strings">Character and string constants</a></span></dt><dt><span class="section"><a href="#s_expressions">Expressions</a></span></dt><dt><span class="section"><a href="#s_asm_lang">Assembly language</a></span></dt><dt><span class="section"><a href="#s_fake_instructions">Fake instructions</a></span></dt><dt><span class="section"><a href="#s_realdevice">Real device emulation mode</a></span></dt><dt><span class="section"><a href="#s_predefined">Predefined defines</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_directives">5. Pseudo-ops (aka Pseudo-instructions, Directives etc)</a></span></dt><dd><dl><dt><span class="section"><a href="#s_directive_usage">Simple example of usage</a></span></dt><dt><span class="section"><a href="#s_pseudoops">Pseudo-ops</a></span></dt><dt><span class="section"><a href="#s_conditional_assembly">Conditional assembly</a></span></dt><dt><span class="section"><a href="#s_macros">Macros</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_structures">6. Structures</a></span></dt><dd><dl><dt><span class="section"><a href="#s_structures_about">What is it?</a></span></dt><dt><span class="section"><a href="#s_define_structure">Defining structure</a></span></dt><dt><span class="section"><a href="#s_structure_instructions">STRUCT instructions</a></span></dt><dt><span class="section"><a href="#st_usage">Usage of defined structure</a></span></dt><dt><span class="section"><a href="#s_structure_examples">Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_lua_scripting">7. Lua scripting</a></span></dt><dd><dl><dt><span class="section"><a href="#s_lua_oh_why">Why?</a></span></dt><dt><span class="section"><a href="#s_lua_how_to">How to use?</a></span></dt><dt><span class="section"><a href="#s_lua_sjasmplus_bindings">SjASMPlus functions bindings to Lua</a></span></dt><dt><span class="section"><a href="#s_lua_third_party_libs">Third-party embedded library(ies)</a></span></dt><dt><span class="section"><a href="#s_lua_examples">Example</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_savenex">8. SAVENEX guide</a></span></dt><dd><dl><dt><span class="section"><a href="#s_savenex_file_format">NEX File Format</a></span></dt><dt><span class="section"><a href="#s_savenex_commands">Detailed description of each SAVENEX command</a></span></dt><dt><span class="section"><a href="#s_savenex_examples">Examples</a></span></dt></dl></dd><dt><span class="chapter"><a href="#c_sld_data">9. Source Level Debugging (SLD) data</a></span></dt><dd><dl><dt><span class="section"><a href="#s_sld_intro">What is it?</a></span></dt><dt><span class="section"><a href="#s_sld_cli">Usage</a></span></dt><dt><span class="section"><a href="#s_sld_source_advice">How to write "non tricky" source</a></span></dt><dt><span class="section"><a href="#s_sld_file_format">SLD File Format definition (version "1")</a></span></dt></dl></dd><dt><span class="index"><a href="#index">Index</a></span></dt></dl></div>
|
||
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="introduction"></a>Chapter 1. Introduction</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="license"></a>License</h2></div></div></div>
|
||
|
||
|
||
<p>SjASMPlus is licensed under BSD license.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="about"></a>What is it?</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
SjASMPlus is Z80 Assembly Language Cross Compiler. It is available
|
||
for Win32, Linux and FreeBSD (mainly 5.x) systems. It is based on SjASM
|
||
source code by Sjoerd Mastijn (<a class="ulink" href="http://xl2s.tk" target="_top">http://xl2s.tk</a>).
|
||
</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="features"></a>Main Features</h2></div></div></div>
|
||
|
||
|
||
<div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p>Full source of assembler available under BSD license, modify and extend as you wish</p>
|
||
</li><li class="listitem">
|
||
<p>Z80/R800/Z80N/i8080/LR35902 documented and undocumented opcodes support</p>
|
||
</li><li class="listitem">
|
||
<p>Macro language, defines, array of defines</p>
|
||
</li><li class="listitem">
|
||
<p>Built-in Lua scripting engine</p>
|
||
</li><li class="listitem">
|
||
<p>Conditional assembly, block repeating</p>
|
||
</li><li class="listitem">
|
||
<p>Modules (namespaces), local and temporary labels</p>
|
||
</li><li class="listitem">
|
||
<p>Source and binary file inclusion, include paths</p>
|
||
</li><li class="listitem">
|
||
<p>Multi file output, file updating, various types of exports</p>
|
||
</li><li class="listitem">
|
||
<p>Structures to work easily with structured data in memory</p>
|
||
</li><li class="listitem">
|
||
<p>Relocation data generator to support SymbOS-like relocation of executables</p>
|
||
</li><li class="listitem">
|
||
<p>Virtual device mode for common machines: ZX 128, ZX Next, Amstrad CPC, … (pseudo op DEVICE)</p>
|
||
</li><li class="listitem">
|
||
<p>ZX Spectrum specific directives and pseudo ops (SAVESNA, SAVETAP, SAVEHOB, INCHOB, INCTRD…)</p>
|
||
</li><li class="listitem">
|
||
<p>ZX Spectrum Next specific features and directives (Z80N, 8ki memory paging, SAVENEX)</p>
|
||
</li><li class="listitem">
|
||
<p>Amstrad CPC 464/6128 specific directives (SAVECPCSNA)</p>
|
||
</li><li class="listitem">
|
||
<p>Correctness is assured by <a class="ulink" href="https://cirrus-ci.com/github/z00m128/sjasmplus/master" target="_top">
|
||
Cirrus-CI with 400+ automated tests</a> (that's also 400+ examples of usage!)</p>
|
||
</li><li class="listitem">
|
||
<p>Fake instructions as LD HL,DE (LD H,D:LD L,E) and more</p>
|
||
</li><li class="listitem">
|
||
<p>Code inlining through colon (LD A,C:INC A:PUSH AF:IFDEF FX:LD A,D:ENDIF…)</p>
|
||
</li><li class="listitem">
|
||
<p>Very fast compilation: 1 million lines by 2-3 seconds on modern computer</p>
|
||
</li><li class="listitem">
|
||
<p>Multiline block comments and user’s messages</p>
|
||
</li></ul></div>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="credits"></a>Credits</h2></div></div></div>
|
||
|
||
|
||
<p>Special thanks to <span class="emphasis"><em>Sjoerd Mastijn</em></span>, the author of SjASM.</p>
|
||
|
||
<p><span class="emphasis"><em>Aprisobal </em></span>- main programming, documentation, etc.</p>
|
||
|
||
<p>Thanks to:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p><span class="emphasis"><em>Kurles/HS/CPU, Alexander Kovalenko, Ped7g, Dart Alver, Oli Wilkinson</em></span> - additional
|
||
programming;</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>Krystian Wlosek
|
||
<kwlosek(at)gmail.com></em></span> - bug fix patches, Linux
|
||
makefile;</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>Ric Horne <Ric.Hohne@eads-ts.com></em></span>
|
||
- bug fix patches.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>breeze <breeze@tut.by></em></span> - bug fix
|
||
patches.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>psndcj <psndcj.tbk@gmail.com></em></span> -
|
||
bug reporting, beta-testing.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>elfh <elphecy@gmail.com></em></span> - bug
|
||
reporting.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>bugsy <bugsy@ya.ru></em></span> - bug
|
||
reporting.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>skrju <sq-@mail.ru></em></span> - bug
|
||
reporting.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>Tygrys, UB880D, Cizo, mborik, z00m, otis</em></span> -
|
||
compilation errors and warnings clean up, makefiles, testing.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>Antipod, boo_boo, PulkoMandy, Busy, Liniya, LVD</em></span> -
|
||
bug fix patches, testing.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>CKirby</em></span> - SLD export and support in his tools.</p>
|
||
</li><li class="listitem">
|
||
<p><span class="emphasis"><em>Simon Brattel</em></span> - for creating mother of all assemblers Zeus
|
||
and bringing all the good and peace to the mankind, giving infinite inspiration
|
||
to sjasmplus contributors who stole his tremendously amazing features without
|
||
even crediting him - till now, fixed (not sure what the particular list of features
|
||
was copied from Zeus, I guess DG/DH, I believe some other similarities are rather
|
||
copied from the ALASM which had many features before Zeus, but who knows, too late
|
||
to track it all precisely, what happened in 90's and when).</p>
|
||
</li></ul></div>
|
||
|
||
<p>Big thanks to all people, who helped on development of the compiler!</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="feedback"></a>Feedback</h2></div></div></div>
|
||
|
||
|
||
<p>WWW: <a class="ulink" href="https://github.com/z00m128/sjasmplus" target="_top">https://github.com/z00m128/sjasmplus</a>
|
||
(newer versions maintained by z00m and others)</p>
|
||
|
||
<p>WWW: <a class="ulink" href="https://sourceforge.net/projects/sjasmplus/" target="_top">https://sourceforge.net/projects/sjasmplus/</a>
|
||
(original Aprisobal's source)</p>
|
||
|
||
<p>E-Mail: zoom@centrum.sk, my@aprisobal.by</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="news"></a>What's new?</h2></div></div></div>
|
||
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term">23.6.2023 - 1.20.3</span></dt><dd>
|
||
<pre class="synopsis">- added alias <a class="link" href="#s_cli" title="Command line">`--define`</a> for `-D`
|
||
- added <a class="link" href="#s_strings" title="Character and string constants">string-literals</a> suffixes Z and C to add zero or set high bit of last char
|
||
- end of line backslash continues source line (<a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/parsing/escape_eol.asm" target="_top">limited support</a>, not recommended)
|
||
- Lua: minor version upgrade to 5.4.6 (from 5.4.4)
|
||
- minor updates to Makefile
|
||
</pre>
|
||
</dd><dt><span class="term">14.2.2023 - 1.20.2</span></dt><dd>
|
||
<pre class="synopsis">- added optional second argument for <a class="link" href="#po_dup">`DUP`</a> to have index variable
|
||
- option `--exp` will create file even when no `EXPORT` is used
|
||
- fixing variable name-clash when compiling against musl-clib
|
||
- LuaBridge updated, CMake and Makefile updated a bit
|
||
- minor bugfixes/improvements in parser in specific edge cases
|
||
</pre>
|
||
</dd><dt><span class="term">29.7.2022 - 1.20.1</span></dt><dd>
|
||
<pre class="synopsis">- parse decimal <a class="link" href="#s_numeric" title="Numeric constants">numeric constants</a> with warning (for easier Lua 5.4 life)
|
||
- added <a class="link" href="#po_saveamsdos">`SAVEAMSDOS`</a> (like SAVEBIN with AMSDOS header)
|
||
- added "smart" <a class="link" href="#s_labels" title="Labels">SMC offset</a> syntax for self-modify-code labels: `abc+*: or 123`
|
||
- added <a class="link" href="#po_defdevice">`DEFDEVICE`</a> to define custom devices
|
||
- Makefile cleanup
|
||
</pre>
|
||
</dd><dt><span class="term">13.6.2022 - 1.20.0</span></dt><dd>
|
||
<pre class="synopsis">- Lua: <a class="link" href="#c_lua_scripting" title="Chapter 7. Lua scripting">upgrade to 5.4</a>, replacing tolua++ bindings with LuaBridge2.6 library, extending some bindings
|
||
- Lua: bindings slightly modified (required by upgrade), refreshed docs, added test coverage
|
||
- Lua: the 3rd party extensions (BTW not working for many years) are obsolete in 5.4 and removed
|
||
- Lua: more accurate errors/warning location reported even in complex cases
|
||
- warnings: added -Wall, --help=warnings shows on/off status, rdlow off by default
|
||
- Added HIGH mode to <a class="link" href="#po_relocate_start">relocation data generator</a> (MSB-only relocation mode)
|
||
- many open-file "fatal" errors become "non-fatal", assembling will continue
|
||
- deprecated features removed: --syntax=m, label `abs` in expressions
|
||
- `--color=auto` will stay no-color when <a class="ulink" href="https://no-color.org/" target="_top">env.var. `NO_COLOR`</a> is defined
|
||
- refactorings, improving some error messages and parsing, small fixes in parsing logic
|
||
- fix listing of Lua's sj.parse_code (eol-comments), minor memory leaks fixed
|
||
- fix relocation of temporary labels in expressions
|
||
- invalid CLI options are reported as regular errors (also changing exit code)
|
||
- errors are colored similarly to gcc (only keyword has color), console input name is `<stdin>`
|
||
</pre>
|
||
</dd><dt><span class="term">31.3.2022 - 1.19.0</span></dt><dd>
|
||
<pre class="synopsis">- added Amstrad CPC devices (<a class="link" href="#po_device">"AMSTRADCPC464", "AMSTRADCPC6128"</a>) - by Oli Wilkinson
|
||
- added Amstrad CPC save snapshot and CDT (<a class="link" href="#po_savecpcsna">`SAVECPCSNA`</a>, <a class="link" href="#po_savecdt">`SAVECDT`</a>) - by Oli Wilkinson
|
||
- added <a class="link" href="#po_save3dos">`SAVE3DOS`</a> (like SAVEBIN with +3DOS header)
|
||
- the deprecated "ok" warning suppression is removed, use "<warning-id>-ok" comment or -Wno-...
|
||
- new <a class="link" href="#s_temp_labels" title="Temporary labels">temporary label</a> suffix syntax "_b" and "_f", enabling them for all expressions
|
||
- fix `--longptr` mode to keep 32b address when `DS 0` is used
|
||
- added fake instructions adc|add|sbc|sub de,bc|de|hl|sp
|
||
- dec|inc|pop|push will accept also single-comma multiarg in --syntax=a mode
|
||
- DUP/REPT will now accept also zero count (skipping the block)
|
||
- DEFL labels can be defined even as late as in last pass
|
||
- bugfixes (macros, listing, file names in errors, SLD reversepop data)
|
||
</pre>
|
||
</dd><dt><span class="term">29.8.2021 - 1.18.3</span></dt><dd>
|
||
<pre class="synopsis">- added <a class="link" href="#s_cli" title="Command line">`--color`</a> to enable/disable ANSI coloring of errors/warnings
|
||
- added <a class="link" href="#s_cli" title="Command line">`--syntax=s`</a> mode to disable sub-word substitutions of DEFINEs
|
||
- added at-sign prefix for <a class="link" href="#s_local_labels" title="Local labels">macro local labels</a> to act as non-macro local label
|
||
- <a class="link" href="#po_savetrd">`SAVETRD`</a> accepts names containing dot ("z.x.B" is "z.x" with extension "B") - by Dart Alver
|
||
- <a class="link" href="#po_savetrd">`SAVETRD`</a> has optional argument to save BASIC with variables (length_minus_variables)
|
||
- minor bugfixes (conditional block parser)
|
||
</pre>
|
||
</dd><dt><span class="term">14.2.2021 - 1.18.2</span></dt><dd>
|
||
<pre class="synopsis">- [may break old sources] new <a class="link" href="#s_expressions" title="Expressions">exist operator</a> to check label existence
|
||
- the --syntax=i mode makes now also register parsing case insensitive
|
||
- minor bugfixes (predefined values, savenex BMP loader less strict about "colors used" content)
|
||
</pre>
|
||
</dd><dt><span class="term">23.1.2021 - 1.18.1</span></dt><dd>
|
||
<pre class="synopsis">- Big-Endian hosts support (experimental and not tested continuously)
|
||
- added "listall", "listact" commands to <a class="link" href="#po_opt">OPT</a> - to switch between listing types
|
||
- <a class="link" href="#po_while">`WHILE`</a> has optional argument to set explicit guardian-counter
|
||
- <a class="link" href="#po_assert">`ASSERT`</a> has optional argument (to add description/notes for expression)
|
||
- <a class="link" href="#po_slot">`SLOT`</a> and <a class="link" href="#po_mmu">`MMU`</a> will now accept also starting address of slot instead of its number
|
||
- fix: option --sym was not exporting labels starting with underscore
|
||
- fix: SAVENEX BMP-loader bug when certain builds of sjasmplus were unable to open BMP files
|
||
- fix: after STRUCT instance the "main" label is not polluted by last field of STRUCT
|
||
- minor bugfixes in parser, windows cmake-builds have now icon
|
||
- docs: adding "Index" section
|
||
- docs: adding some missing information (__DATE__, __TIME__), fixing HTML anchor names
|
||
</pre>
|
||
</dd><dt><span class="term">12.12.2020 - 1.18.0</span></dt><dd>
|
||
<pre class="synopsis">- [may break old sources] the colon between end of EQU/DEFL/= expression and instruction is mandatory
|
||
- [may break old sources] new <a class="link" href="#s_expressions" title="Expressions">abs operator</a> for absolute integer value
|
||
- new <a class="link" href="#s_id_warnings" title="Warnings with id">system of warnings</a> (and suppression), the "; ok" comments are now deprecated
|
||
- <a class="link" href="#po_display">`DISPLAY`</a> has now also binary and char formatting
|
||
- <a class="link" href="#po_define">`DEFINE+`</a> added to [re]define identifier without error
|
||
- <a class="link" href="#ca_elseif">`ELSEIF`</a> added to conditional assembling arsenal
|
||
- <a class="link" href="#po_while">`WHILE`</a> added for conditional loops
|
||
- added <a class="link" href="#po_device">"NOSLOT64K" device</a> with 2MiB of virtual memory
|
||
- <a class="link" href="#po_labelslist">`LABELSLIST`</a> has new optional argument to dump 16bit "virtual labels"
|
||
- <a class="link" href="#po_cspectmap">`CSPECTMAP`</a> exports STRUCT symbols with more detail (instance labels with physical address)
|
||
- <a class="link" href="#s_labels" title="Labels">SMC offset</a> syntax for self-modify-code labels for source brevity
|
||
- added exclamation mark prefix for <a class="link" href="#s_local_labels" title="Local labels">labels</a> to not affect following local labels
|
||
- added "listmc" command to <a class="link" href="#po_opt">OPT</a> - to list only lines with machine code bytes
|
||
- added <a class="link" href="#s_cli" title="Command line">`--lstlab=sort`</a> variant to have symbols in listings in predictable order
|
||
- minor bugfixes in parser and listing-line-numbering, refactored symbols/labels implementation
|
||
- Added <a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/examples/chargfx2asm" target="_top">example (chargfx2asm)</a> how to use sjasmplus as byte-processor for binary files
|
||
- <a class="link" href="#c_sld_data" title="Chapter 9. Source Level Debugging (SLD) data">SLD data</a> improvements based on Maziac's feedback and <a class="ulink" href="https://github.com/maziac/DeZog" target="_top">DeZog</a>'s needs
|
||
</pre>
|
||
</dd><dt><span class="term">8.8.2020 - 1.17.0</span></dt><dd>
|
||
<pre class="synopsis">- `STRUCT` has new <a class="link" href="#st_text">`TEXT`</a> pseudo-instruction to define "DB-like" data (<a class="ulink" href="https://github.com/z00m128/sjasmplus/issues/93" target="_top">Issue #93</a>)
|
||
- <a class="link" href="#st_usage" title="Usage of defined structure">`STRUCT` initializer block</a> can be now multi-line (when correctly enclosed in curly braces)
|
||
- <a class="link" href="#po_equ">`EQU`</a> now allows for optional override of page number assigned to the new symbol
|
||
- new <a class="link" href="#s_expressions" title="Expressions">$$$ and $$$$ operators</a> to retrieve "physical" address/page inside DISP block
|
||
- instruction `out (c),0` now emits warning (can be suppressed by the "; ok" comment)
|
||
- fixed listing of structures using long BLOCK fields (machine code was correct, but listing not)
|
||
- fixed some memory leaks, undefined behaviour and unaligned memory access
|
||
</pre>
|
||
</dd><dt><span class="term">27.7.2020 - 1.16.0</span></dt><dd>
|
||
<pre class="synopsis">- <a class="link" href="#po_lua">`LUA`</a> the new emit warning (v1.15.1) is now suppressible
|
||
- <a class="link" href="#s_predefined" title="Predefined defines">Predefined defines</a> extended and renamed (following gcc/clang ones)
|
||
- Added <a class="link" href="#po_relocate_end">relocation data generator</a> (similar to WinAPE feature), check also <a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/examples/relocation" target="_top">example</a>
|
||
- bugfixes/improvements in parser like: operators `not`, `low`, `high` can be followed also by "("
|
||
</pre>
|
||
</dd></dl></div>
|
||
|
||
<p>See <a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/CHANGELOG.md" target="_top">CHANGELOG.md</a> for full list of changes.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="where_to_get"></a>Chapter 2. Where to get and how to use</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_packages"></a>Packages</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
The <span class="strong"><strong>latest release</strong></span> of this sjasmplus variant is
|
||
<span class="strong"><strong>available at <a class="ulink" href="https://github.com/z00m128/sjasmplus/releases/latest" target="_top">
|
||
https://github.com/z00m128/sjasmplus/releases/latest</a></strong></span>
|
||
- there is available zip archive with <span class="strong"><strong>windows binary</strong></span>
|
||
(toward <span class="strong"><strong>bottom of the page</strong></span>), and zip archives with
|
||
<span class="strong"><strong>full source code</strong></span> of the sjasmplus.
|
||
</p>
|
||
|
||
<p>Win32 package has:</p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p>sjasmplus.exe - the Win32 executable.</p>
|
||
</li><li class="listitem">
|
||
<p>examples directory - some examples of use</p>
|
||
</li><li class="listitem">
|
||
<p>documentation directory - documentation in various
|
||
formats</p>
|
||
</li></ul></div><p>
|
||
</p>
|
||
|
||
<p>
|
||
You may want to download also the full source package, as it contains more than 400
|
||
<span class="strong"><strong>automated tests</strong></span> used to verify correctness of executable,
|
||
and these can be often helpful to better understand how specific feature of sjasmplus works,
|
||
and <span class="strong"><strong>how to use it</strong></span> effectively.
|
||
</p>
|
||
|
||
<p>
|
||
<span class="strong"><strong>Linux, Unix, MacOS</strong></span> and <span class="strong"><strong>BSD</strong></span>
|
||
version can be built from the full source archive. You can compile it using <span class="emphasis"><em>GCC</em></span>
|
||
and included <span class="emphasis"><em>Makefile</em></span>. There is an option to use <span class="emphasis"><em>CMake</em></span>
|
||
for compilation. See
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/INSTALL.md" target="_top">INSTALL.md</a> for details.
|
||
</p>
|
||
|
||
<p>Windows binaries are compiled with <span class="emphasis"><em>MinGW</em></span> environment and included
|
||
<span class="emphasis"><em>Makefile.win</em></span> file.</p>
|
||
|
||
<p>You can grab older (up to v1.07) binaries and sources at SourceForge project page:
|
||
<a class="ulink" href="https://sourceforge.net/projects/sjasmplus/" target="_top">https://sourceforge.net/projects/sjasmplus/</a></p>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_cli"></a>Command line</h2></div></div></div>
|
||
|
||
|
||
<p>Usage:</p>
|
||
|
||
<pre class="synopsis">sjasmplus [options] sourcefile(s)</pre>
|
||
|
||
<p>Option flags as follows:</p>
|
||
|
||
<pre class="synopsis"> -h or --help[=warnings] Help information
|
||
--version Basic info (with --nologo only raw version string)
|
||
--zxnext[=cspect] Enable ZX Next Z80 extensions (CSpect emulator has
|
||
extra "exit" DD00 and "break" DD01 fake instructions)
|
||
--i8080 Limit valid instructions to i8080 only (+ no fakes)
|
||
--lr35902 Sharp LR35902/SM83 CPU instructions mode (+ no fakes)
|
||
--outprefix=<path> Prefix for save/output/.. filenames in directives
|
||
Note: if prefix is folder, it must already exist and add trailing slash. Prefix
|
||
is applied only to filenames defined in source (not to CLI arguments).
|
||
-i<path> or -I<path> or --inc=<path> ( --inc without "=" to empty the list)
|
||
Include path (later defined have higher priority)
|
||
--lst[=<filename>] Save listing to <filename> (<source>.lst is default)
|
||
--lstlab[=sort] Append [sorted] symbol table to listing
|
||
--sym=<filename> Save symbol table to <filename>
|
||
--exp=<filename> Save exports to <filename> (see EXPORT pseudo-op)
|
||
--raw=<filename> Machine code saved also to <filename> (- is STDOUT)
|
||
--sld[=<filename>] Save Source Level Debugging data to <filename>
|
||
Default name is: "<first input filename>.sld.txt"
|
||
Note: use OUTPUT,LUA/ENDLUA and other pseudo-ops to control output
|
||
Logging:
|
||
--nologo Do not show startup message
|
||
--msg=[all|war|err|none|lst|lstlab] Stderr messages verbosity ("all" is default)
|
||
Note: "lst" or "lstlab" will turn STDERR into listing file (this will clash with
|
||
`--lst`, use only one of the options) and some diagnostic messages of "all"
|
||
are omitted, as they are not part of listing files. "lstlab" does sort symbols.
|
||
--fullpath Show full path to file in errors
|
||
Note: the "fullpath" starts from current working directory, not from file system
|
||
root (the MS_VS build was fixed to behave this way since v1.15.0)
|
||
--color=[on|off|auto] Enable or disable ANSI coloring of warnings/errors
|
||
Note: auto detection checks for existence of environment variable TERM, and its
|
||
content is scanned for sub-string "color" (like "xterm-256color")
|
||
Other:
|
||
-D<NAME>[=<value>] or --define <NAME>[=<value>]
|
||
Define <NAME> as <value> (--define since v1.20.3)
|
||
-W[no-]<warning_id> Disables/enabled particular warning type
|
||
- Reads STDIN as source (even in between regular files)
|
||
--longptr No device: program counter $ can go beyond 0x10000
|
||
--reversepop Enable reverse POP order (as in base SjASM version)
|
||
--dirbol Enable directives processing from the beginning of line
|
||
--nofakes Disable fake instructions (same as --syntax=F)
|
||
--dos866 Encode from Windows codepage to DOS 866 (Cyrillic)
|
||
--syntax=<...> Adjust parsing syntax, read details below.</pre>
|
||
|
||
<p>
|
||
The option <code class="code">--lstlab=sort</code> will cause also other symbol dumps being sorted (along
|
||
listing): <code class="code">--sym</code>, <code class="code">CSPECTMAP</code> and <code class="code">LABELSLIST</code>.
|
||
The <code class="code">--msg=lstlab</code> sets always sorting "on" (no "unsorted" option).
|
||
</p>
|
||
<p>Value for <code class="code">--syntax</code> option may consist of multiple letters, omitting letter
|
||
for particular feature will use the default setting:
|
||
</p><pre class="synopsis"> a Multi-argument delimiter ",," (default is ",") (but dec|inc|pop|push accept also ",")
|
||
b Whole expression parentheses are legal for memory access only (default = immediate or memory)
|
||
B memory access brackets [] required (default = relaxed syntax, [] allowed as extra)
|
||
f F Fake instructions: warning / disabled (default = enabled)
|
||
i Case insensitive instructions/directives (default = same case required)
|
||
† <span class="emphasis"><em>l L Keyword labels (registers, instructions, ...): warning / error (default = silent)</em></span>
|
||
M Alias "m" and "M" for "(hl)" to cover 8080-like syntax: ADD A,M
|
||
s Use only "simple" whole-word substitutions, no sub-words (since v1.18.3)
|
||
w Warnings option: report warnings as errors
|
||
m *REMOVED* in v1.20.0, use -Wno-rdlow</pre><p>
|
||
† work in progress: options "l" and "L" are not implemented yet, following example is then
|
||
not working correctly either.
|
||
</p>
|
||
<p>
|
||
I.e. <code class="code">--syntax=faBil</code> will modify parser to process source line
|
||
</p><pre class="programlisting">hl: Ld a,(hl),,de,hl</pre><p>
|
||
in a way to produce warnings about keyword "hl" being used for label, about fake instruction
|
||
being used (ld de,hl) and assemble <code class="code">(hl)</code> as numeric expression, not memory access.
|
||
Warnings on fake instructions can be suppressed for particular line by adding any end-of-line
|
||
comment containing string "fake", i.e. "<code class="code">ld de,hl ; fake DE=HL</code>" will assemble
|
||
without warning. The "F" option is identical to "--nofakes" and preferred.
|
||
</p>
|
||
|
||
<p>
|
||
The recommended setup for new projects is <code class="code">--syntax=abfw</code> which makes syntax less relaxed,
|
||
so some typos and mistakes are easier to catch, for example:
|
||
</p><pre class="programlisting"> OPT reset --syntax=abfw
|
||
label: dw 15
|
||
ld b,(label)
|
||
sub a,b</pre><p> will produce "error: Illegal instruction
|
||
(can't access memory): (label)" message for the <code class="code">ld b,(label)</code> and the <code class="code">sub a,b</code>
|
||
will produce only the <code class="code">sub b</code> instruction (to give the <code class="code">sub</code> multi-argument
|
||
with syntax option "a" the line would have to be <code class="code">sub a,,b</code>).
|
||
</p>
|
||
|
||
<p>
|
||
The assembler will also read the environment variable <code class="code">SJASMPLUSOPTS</code> (if available),
|
||
and process its content as part of command line options (before the actual options), so you
|
||
can pre-configure certain options in your environment, for example:
|
||
</p><pre class="programlisting">export SJASMPLUSOPTS="--zxnext=cspect --msg=war"
|
||
sjasmplus --lst --lstlab example.asm</pre><p>
|
||
will execute the assembling as if command line "<code class="code">sjasmplus --zxnext=cspect --msg=war --lst --lstlab example.asm</code>"
|
||
was used. Known issue: parser of environment variable delimits each option on any white-space character, so
|
||
option containing space character will be incorrectly parsed (like "-Ifile-path with space" = fails and
|
||
there is no way to escape/quote the path in the SJASMPLUSOPTS variable to make it work).
|
||
</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_id_warnings"></a>Warnings with id</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
Some warnings have own "id" - these can be switched off or suppressed for particular line.
|
||
The line suppression mechanism requires you to add end-of-line comment with "id-ok" string
|
||
somewhere in the comment (exception: for fake instructions and --syntax=f mode the word
|
||
"fake" is enough without -ok suffix) (the "ok" comment suppression mechanism from previous
|
||
versions of sjasmplus is removed since v1.19.0).
|
||
</p>
|
||
<p>
|
||
The id-warning is emitted together with its id in brackets:
|
||
</p><pre class="programlisting"> ld a,(10-2) ; read memory address 8 - emits warning "rdlow"
|
||
ld a,(10-2) ; same instruction, but suppress warning: rdlow-ok
|
||
|
||
file.asm(1): warning[rdlow]: Reading memory at low address: 8</pre><p>
|
||
To list all warning-ids, their on/off state and short description of each use:
|
||
</p><pre class="programlisting"><command line>$ sjasmplus --help=warnings</pre><p>
|
||
Most of the extra warnings are by default enabled, but to enable/disable all of them you can use (also in source with OPT directive):
|
||
</p><pre class="programlisting"><command line>$ sjasmplus -Wall
|
||
<command line>$ sjasmplus -Wno-all</pre><p>
|
||
To disable particular warning globally you can use option <code class="code">-Wno-<id></code>,
|
||
either on command line, or from source by using <code class="code"><a class="link" href="#po_opt">OPT</a></code>:
|
||
</p><pre class="programlisting"><command line>$ sjasmplus -Wno-out0
|
||
|
||
; in source code:
|
||
OPT -Wno-trdext -Wno-trdext3 ; disable "trdext" and "trdext3" warnings
|
||
SAVETRD "image.trd", "file.txt", 30000, 100
|
||
OPT -Wtrdext3 ; re-enable "trdext3" warning for following code
|
||
; ...</pre><p>
|
||
</p>
|
||
<p>
|
||
Warnings without id can't be suppressed and generally should happen only when the source
|
||
code has actual bug (in our opinion) and can be modified to fix the warning, or when you
|
||
are hitting limits of sjasmplus architecture and/or implementation.
|
||
</p>
|
||
<p>
|
||
If you believe you are hitting warning without id on correct code, which can be safely
|
||
ignored (the machine code produced is stable and as expected), open issue on github with
|
||
example source, so we can assign the warning new id (or explain why it is problematic :) ).
|
||
</p>
|
||
<p>
|
||
Warnings with id usually signal bug in the code (in common scenarios), but may be misleading
|
||
in more specialized cases - the decision is left to the author, whether to modify
|
||
the code to avoid the warning or suppress it and use the resulting machine code "as is".
|
||
</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_source_format"></a>Source file format</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
Lines in the source file should have the following form:
|
||
</p><pre class="programlisting">Label Operator Operand Comment</pre><p>
|
||
<span class="strong"><strong>Lines without label must start with whitespace.</strong></span>
|
||
All fields are optional.
|
||
End of line backslash continues source line (since 1.20.3, <a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/parsing/escape_eol.asm" target="_top">limited support</a>, not recommended).
|
||
Operators and operands can be inlined with colon:
|
||
</p><pre class="programlisting"> Operator Operand:Operator Operand:Operator Operand... Comment</pre><p>
|
||
Comments should start with '<code class="code">;</code>' or '<code class="code">//</code>'.
|
||
Comment blocks start with '<code class="code">/*</code>' and end with '<code class="code">*/</code>' (work in "nested" way,
|
||
i.e. comment block started inside comment block must be also ended, before main block ends).
|
||
|
||
</p><div class="example"><a name="idp309"></a><p class="title"><b>Example 2.1. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">; comment
|
||
// comment
|
||
ld /* comment */ a,80
|
||
/*
|
||
comment /* nested comment block */
|
||
*/
|
||
ld /*
|
||
but this won't be ld a,3!
|
||
*/ a,3</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_labels"></a>Chapter 3. Labels</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_labels"></a>Labels</h2></div></div></div>
|
||
|
||
|
||
<p>Labels are case-sensitive and may be of any reasonable length,
|
||
that is: up to about 70 characters. Label definitions must start on
|
||
the beginning of a line, but don't have to be followed by a colon ':'.
|
||
Generally labels should start with a letter or a underscore ('_'), the
|
||
following characters may be chosen from letters, numbers and the
|
||
following special symbols: '_', '.', '!', '?', '#' and '@'. Note that
|
||
the '.' has special meaning, as it is used between module names, labels
|
||
and local labels. The following are all legal and distinct
|
||
labels:</p><pre class="programlisting">Kip
|
||
KIP
|
||
Kip@@
|
||
MAIN.loop?</pre><p>It is possible to use mnemonics, pseudo-ops and
|
||
register names as labels but it is not advised to do so (expression operator keyword used
|
||
as label will emit warning, and is also not advised). Also note that
|
||
the identifiers defined with the DEFINE pseudo-op use another name
|
||
space.</p>
|
||
|
||
<p>(since v1.18.0) Right after label (before the optional colon) you
|
||
can write extra "SMC offset" (Self Modify Code offset) in the form of plus
|
||
sign and single decimal digit. The defined label will become equal to current
|
||
address plus the SMC offset:
|
||
</p><pre class="programlisting"> ; SMC-offset syntax is very strict, no spacing, single '+', single digit
|
||
answer+1: ld a,13 ; "answer" points second opcode byte
|
||
; this helps to keep the SMC-label together with the target instruction
|
||
ld hl,answer
|
||
ld (hl),42 ; fix immediate in `ld a,*` to correct answer
|
||
; compare with classic syntax:
|
||
classic equ $+1 : ld a,7 ; often even split to two lines</pre><p>
|
||
</p>
|
||
|
||
<p>(since v1.20.1) Smart SMC labels: you can write "plus asterisk" to let sjasmplus adjust
|
||
self-modify label by most likely offset for following instruction. This works only
|
||
for instructions with "obvious" target immediate value:
|
||
</p><pre class="programlisting"> ; smart-SMC syntax is very strict, no spacing, single '+', single '*'
|
||
answer+*: ld a,13 ; "answer" points second opcode byte
|
||
; this helps to keep the SMC-label together with the target instruction
|
||
ld hl,answer
|
||
ld (hl),42 ; fix immediate in `ld a,*` to correct answer
|
||
; few more examples which byte the "smart SMC" will target in the opcode
|
||
jptarget+*: jp nz,12345 ; "jptarget" points at second opcode byte (word value 12345)
|
||
ixvalue+*: ld ix,12345 ; "ixvalue" points at third opcode byte (word value 12345)
|
||
nxtrval+*: nextreg $44,123 ; "nxtrval" points at fourth opcode byte (byte value 123)
|
||
; unsupported situations, will cause error
|
||
invalid1+*: inc (ix+123) ; IXY displacements are not considered (not significant enough)
|
||
invalid2+*: cpl : ld a,14 ; only first instruction after label is considered</pre><p>
|
||
</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_local_labels"></a>Local labels</h2></div></div></div>
|
||
|
||
|
||
<p>When there is a <a class="link" href="#po_module">module definition</a> all
|
||
labels (except those starting with a '@') are local to that module. To
|
||
use a label from outside the module use modulename.labelname, in this
|
||
example: 'vdp.Cls'. Labels starting with a '.' are also local to the
|
||
previous non-local label.</p>
|
||
|
||
<p>(since v1.18.0) If you start the label with an ! (exclamation mark), it will not
|
||
affect following local labels (same syntax as <a class="ulink" href="http://www.xl2s.tk/" target="_top">sjasm</a>).</p>
|
||
|
||
<p>(since v1.18.3) Local label inside macro prefixed with @ (at sign) acts as regular local label,
|
||
otherwise (older behaviour) the local label is local to each macro's instance.</p>
|
||
|
||
<div class="example"><a name="idp330"></a><p class="title"><b>Example 3.1. docs_examples/s_local_labels.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MODULE main ; module "main"
|
||
Main: ; main.Main
|
||
CALL SetScreen ; SetScreen
|
||
CALL vdp.Cls ; main.vdp.Cls
|
||
.loop: ; main.Main.loop
|
||
LD A,(.event) ; main.Main.event
|
||
CALL ProcessEvent ; label not found: main.ProcessEvent
|
||
DJNZ .loop ; main.Main.loop
|
||
|
||
MODULE vdp ; module "main.vdp"
|
||
@SetScreen: ; SetScreen
|
||
.loop: ; main.vdp.SetScreen.loop
|
||
RET
|
||
Cls: ; main.vdp.Cls
|
||
!KeepClsForLocal: ; main.vdp.KeepClsForLocal (since v1.18.0)
|
||
.loop: DJNZ .loop ; main.vdp.Cls.loop
|
||
RET
|
||
ENDMODULE
|
||
|
||
Main.event DB 0 ; main.Main.event
|
||
ENDMODULE</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
|
||
<div class="example"><a name="idp335"></a><p class="title"><b>Example 3.2. local labels inside macro</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> macro test
|
||
.kip0 ; this is local to every instance of macro
|
||
@.kip1 ; syntax added in v1.18.3
|
||
endm
|
||
|
||
module main
|
||
hoi test ; produce labels: main.hoi, 0>kip0, main.hoi.kip1
|
||
endmodule</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_at_labels"></a>@ Labels</h2></div></div></div>
|
||
|
||
|
||
<p>Labels starting with a '@' are not touched by the label processing
|
||
and used 'as-is'. See 'SetScreen' in the previous example code. </p><div class="example"><a name="idp341"></a><p class="title"><b>Example 3.3. docs_examples/s_at_labels.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MODULE xxx
|
||
Label ; xxx.Label
|
||
.Local ; xxx.Label.Local
|
||
@Label ; Label
|
||
.Local ; xxx.Label.Local => duplicate label error
|
||
@Label2 ; Label2
|
||
.Local ; xxx.Label2.Local
|
||
@yyy.Local ; yyy.Local
|
||
yyy.Local ; xxx.yyy.Local</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_temp_labels"></a>Temporary labels</h2></div></div></div>
|
||
|
||
|
||
<p>To keep the number of used labels reasonable it is possible to use
|
||
numbers as labels. These labels can only be used as labels to jump to.
|
||
To jump to these labels, use the number followed by an 'F' for forward
|
||
branches or a 'B' for backward branches. Temporary labels should be defined
|
||
in the same order during every pass of assembling, but they can be used
|
||
within macro, or repeating blocks (old sjasmplus versions didn't allow usage within macro).</p>
|
||
|
||
<p>Since v1.19.0 there is alternative syntax using underscore before 'B' and 'F', this
|
||
alternative underscored suffix enables temporary labels also for regular instructions
|
||
(in all expressions, same way as other labels).</p>
|
||
|
||
<div class="example"><a name="idp350"></a><p class="title"><b>Example 3.4. docs_examples/s_temp_labels.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ADD A,E
|
||
JR NC,1F
|
||
INC D
|
||
1 LD E,A
|
||
2 LD B,4
|
||
LD A,(DE)
|
||
OUT (152),A
|
||
DJNZ 2B
|
||
|
||
MACRO zing
|
||
DUP 2
|
||
JR 1F
|
||
1 DJNZ 1B
|
||
EDUP
|
||
ENDM
|
||
|
||
.4 zing
|
||
|
||
; since v1.19.0
|
||
ld hl,1B ; *old* HL = binary 1, NOT temporary label
|
||
ld hl,1_B ; *new* HL = previous temporary label 1
|
||
ld hl,1_B*3 ; *new* works also in expressions</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_constants"></a>Chapter 4. Constants, expressions and other features</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_numeric"></a>Numeric constants</h2></div></div></div>
|
||
|
||
|
||
<p>Numeric constants should always start with a digit or $, # or %.
|
||
The following formats are supported:</p>
|
||
|
||
<pre class="programlisting">12 decimal
|
||
12d decimal
|
||
0xc hexadecimal
|
||
$c hexadecimal
|
||
#c hexadecimal
|
||
0ch hexadecimal
|
||
0b1100 binary (v1.12.1)
|
||
%1100 binary
|
||
1100b binary
|
||
0q14 octal (v1.12.1)
|
||
14q octal
|
||
14o octal</pre>
|
||
|
||
<p>(v1.12.1) Optional single quotes(') may be inserted between the digits as a separator
|
||
(example: <code class="computeroutput"> ld a,%11'01'11'00 </code>).
|
||
They are ignored by the assembler.</p>
|
||
|
||
<p>(v1.20.1) decimal parts are now parsed and ignored (with optional warning), instead of
|
||
causing syntax error - this should make life easier when formatting values from Lua script.
|
||
It is also possible to fix all Lua scripts to produce only integer values, but if you prefer
|
||
to silently ignore the extra decimal part, you can.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_strings"></a>Character and string constants</h2></div></div></div>
|
||
|
||
|
||
<p>Character constants are characters surrounded by single quotes. It
|
||
is possible to use double quotes in some cases, but in general it is
|
||
better to use single quotes. String constants are characters surrounded
|
||
by double quotes. When double quotes are used, the following escape
|
||
sequences are recognized:</p>
|
||
<pre class="programlisting">\\ 92
|
||
\? 63
|
||
\' 39
|
||
\" 34
|
||
\0 0 ; since v1.11
|
||
\A 7
|
||
\B 8
|
||
\D 127
|
||
\E 27
|
||
\F 12
|
||
\N 10
|
||
\R 13
|
||
\T 9
|
||
\V 11</pre><p>Inside single quotes two quotes after each other are
|
||
parsed as the apostrophe itself (since v1.11).</p><p>
|
||
</p><p>Adding Z or C after quotes/apostrophes will make string zero-terminated or set top bit of last character (since v1.20.3).</p><div class="example"><a name="idp371"></a><p class="title"><b>Example 4.1. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> BYTE "stringconstant\n" ; escape sequence assembles to newline
|
||
BYTE 'stringconstant\n' ; \n assembles literally as two bytes: '\', 'n'
|
||
LD HL,'hl' ; hl = 0x686C = 'l', 'h'
|
||
LD HL,"hl" ; hl = 0x686C = 'l', 'h'
|
||
LD A,"7" ; not recommended (but works)
|
||
LD A,'8' ; recommended
|
||
LD A,'\E' ; warning + truncating value to 'E' (0x45)
|
||
LD A,'"' ; A = 0x22
|
||
LD A,"'" ; A = 0x27
|
||
LD A,'''' ; A = 0x27 ; since v1.11
|
||
BYTE "AB"Z, "CD"C, 'E'Z, 'F'C ; hex: 41 42 00 43 C4 45 00 C6</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_expressions"></a>Expressions</h2></div></div></div>
|
||
|
||
|
||
<p>Expressions are evaluated in signed 32 bits in this version of SjASMPlus (unless explicitly
|
||
specified as unsigned, like ">>>" operator), so intermediate values have range -2147483648
|
||
to +2147483647. True for boolean results is equal to value -1, false is equal to 0 (so
|
||
result of compare or logical operators can be used as all-bit-mask further). </p>
|
||
|
||
<p>'$' represents the current program counter. '$$' represents the
|
||
current page in the current slot in the <a class="link" href="#s_realdevice" title="Real device emulation mode">real device emulation mode</a>, '$$label' evaluates to number of page
|
||
where the "label" was defined (only regular labels have meaningful value, labels defined
|
||
under DISP mode may return the page specified in DISP itself, EQU/DEFL/... will produce mostly
|
||
irrelevant values). '$$$' and '$$$$' can be used inside DISP block to retrieve the "physical"
|
||
memory address and page (where the displaced machine code is written to). '{address}' can be used
|
||
to read WORD from virtual device memory (correct value is read only in last pass of assembling,
|
||
in early passes the zero value is always returned), '{b address}' reads only BYTE.</p>
|
||
|
||
<p>It is possible to use parenthesis '(' and ')' to override the
|
||
precedence of the operators. The following operators may be used in
|
||
expressions:</p>
|
||
|
||
<pre class="programlisting">norel norel L <a class="indexterm" name="op_norel"></a>Label/symbol L will be treated as non-relocatable
|
||
exist exist L <a class="indexterm" name="op_exist"></a>is label/symbol L defined in source (even when not used) (since v1.18.2)
|
||
|
||
! !x <a class="indexterm" name="op_log_not"></a>logical not
|
||
~ ~x <a class="indexterm" name="op_cpl"></a>complement
|
||
+ +x does "nothing", can be used to make "+(...)" parse as value (not as memory)
|
||
- -x minus
|
||
low low x <a class="indexterm" name="op_low"></a>low 8 bits of 16 bit value or lower part of register pair
|
||
high high x <a class="indexterm" name="op_high"></a>high 8 bits of 16 bit value or higher part of register pair
|
||
not not x <a class="indexterm" name="op_log_not2"></a>logical not
|
||
abs abs x <a class="indexterm" name="op_abs"></a>absolute value (since v1.18.0)
|
||
|
||
* x*y <a class="indexterm" name="op_mul"></a>multiplication
|
||
/ x/y <a class="indexterm" name="op_div"></a>division
|
||
% x%y <a class="indexterm" name="op_mod"></a>modulo
|
||
mod x mod y <a class="indexterm" name="op_mod2"></a>modulo
|
||
|
||
+ x+y <a class="indexterm" name="op_add"></a>addition
|
||
- x-y <a class="indexterm" name="op_sub"></a>subtraction
|
||
|
||
<< x<<y <a class="indexterm" name="op_sla"></a>shift left
|
||
>> x>>y <a class="indexterm" name="op_sra"></a>shift right signed
|
||
>>> x>>>y <a class="indexterm" name="op_srl"></a>shift right unsigned
|
||
shl x shl y <a class="indexterm" name="op_shl"></a>shift left
|
||
shr x shr y <a class="indexterm" name="op_shr"></a>shift right signed
|
||
|
||
<? x<?y <a class="indexterm" name="op_min"></a>minimum
|
||
>? x>?y <a class="indexterm" name="op_max"></a>maximum
|
||
|
||
< x<y <a class="indexterm" name="op_lt"></a>less than
|
||
> x>y <a class="indexterm" name="op_gt"></a>greater than
|
||
<= x<=y <a class="indexterm" name="op_lte"></a>equal or less than
|
||
>= x>=y <a class="indexterm" name="op_gte"></a>equal or greater than
|
||
|
||
= x=y <a class="indexterm" name="op_eq"></a>equal
|
||
== x==y <a class="indexterm" name="op_eq2"></a>equal
|
||
!= x!=y <a class="indexterm" name="op_neq"></a>not equal
|
||
|
||
& x&y <a class="indexterm" name="op_bit_and"></a>bitwise and
|
||
and x and y <a class="indexterm" name="op_bit_and2"></a>bitwise and
|
||
|
||
^ x^y <a class="indexterm" name="op_bit_xor"></a>bitwise xor
|
||
xor x xor y <a class="indexterm" name="op_bit_xor2"></a>bitwise xor
|
||
|
||
| x|y <a class="indexterm" name="op_bit_or"></a>bitwise or
|
||
or x or y <a class="indexterm" name="op_bit_or2"></a>bitwise or
|
||
|
||
&& x&&y <a class="indexterm" name="op_logic_and"></a>logical and
|
||
|
||
|| x||y <a class="indexterm" name="op_logic_or"></a>logical or
|
||
|
||
$ $ <a class="indexterm" name="op_dollar"></a>current program counter
|
||
$$ $$ <a class="indexterm" name="op_dollar2"></a>current page at program counter (in virtual device mode)
|
||
$$$ $$$ <a class="indexterm" name="op_dollar3"></a>"physical" program counter (inside DISP block)
|
||
$$$$ $$$$ <a class="indexterm" name="op_dollar4"></a>"physical" memory page (inside DISP block in virtual device mode)
|
||
label label value of label (aka symbol), usually memory address
|
||
$$lab $$lab <a class="indexterm" name="op_label_page"></a>page of "lab" label (in virtual device mode)
|
||
{} {x} <a class="indexterm" name="op_read_word"></a>reads WORD from address x (in virtual device mode, in last pass)
|
||
{b} {b x} <a class="indexterm" name="op_read_byte"></a>reads BYTE from address x (in virtual device mode, in last pass)
|
||
</pre>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_asm_lang"></a>Assembly language</h2></div></div></div>
|
||
|
||
|
||
<p>This version only accepts Z80 mnemonics. There are some additions
|
||
to what I think is standard Z80: </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p>'[' and ']' can be used instead of '(' and ')' for
|
||
indirection. So <code class="code">LD A,[HL]</code> is the same as <code class="code">LD A,(HL)</code> (does not
|
||
apply to IN/OUT ports, those must use '(...)' form)</p>
|
||
</li><li class="listitem">
|
||
<p><code class="code">IN F,(C)</code> and <code class="code">OUT (C),0</code> and <code class="code">SLL/SLI</code> can be used
|
||
(warning: on some CPU versions of Z80 the OUT (C),0 is working as OUT (C),255).</p>
|
||
</li><li class="listitem">
|
||
<p>IXL (or LX, XL), IYL (or LY, YL), IXH (or HX, XH) and IYH
|
||
(or HY, YH) registers are supported.</p>
|
||
</li><li class="listitem">
|
||
<p>Can write code throught colon: ORG 100h:LD A,10:LD B,10:SUB
|
||
B:RET:IFDEF AA:.....</p>
|
||
</li><li class="listitem">
|
||
<p>JP HL, JP IX and JP IY may be used instead of JP (HL),
|
||
etc.</p>
|
||
</li><li class="listitem">
|
||
<p>EX AF,AF or EX AF or EXA may be used instead of EX
|
||
AF,AF'.</p>
|
||
</li><li class="listitem">
|
||
<p>R800's MULUB and MULUW are recognised (but won't work on
|
||
Z80, of course:)</p>
|
||
</li><li class="listitem">
|
||
<p>Z80N, i8080 and LR35902 (SM83) modes use the identical Z80 sjasmplus syntax (!), for the
|
||
correct (and incorrect) syntax examples of extended opcodes, please check the test files:
|
||
Z80N <a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/z80n/op_zx_spectrum_next_2_00_26.asm" target="_top">test 1</a>
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/z80n/op_next_syntax.lst" target="_top">test 2</a>
|
||
and LR35902 (SM83) <a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/lr35902/LR35902_syntax_by_neo.lst" target="_top">test 1</a>
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/tests/lr35902/LR35902_specifics_exercise.lst" target="_top">test 2</a>
|
||
(also for the Z80 syntax examples you can check <a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/tests/z80" target="_top">
|
||
Z80 tests</a>).
|
||
</p>
|
||
</li><li class="listitem">
|
||
<p>RLC, RRC, RL, RR, SLA, SRA, SLL (SLI), RES, SET undocumented
|
||
instructions added.</p>
|
||
</li></ul></div><pre class="programlisting"> SET 4,(IX+4),C ; (aka LD C,SET 4,(IX+4)) is LD C,(IX+4) / SET 4,C / LD (IX+4),C
|
||
RRC (IY),A ; (aka LD A,RRC (IY+0)) is LD A,(IY) / RRC A / LD (IY),A</pre><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p>PUSH and POP can take register lists:</p>
|
||
</li></ul></div><pre class="programlisting"> PUSH AF,BC ; push af / push bc
|
||
POP AF,BC ; pop af / pop bc</pre><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">
|
||
<p>and many other instructions support this "multi-argument" syntax:</p>
|
||
</li></ul></div><pre class="programlisting"> LD A,B,B,D,D,H
|
||
/* this is:
|
||
LD A,B
|
||
LD B,D
|
||
LD D,H
|
||
*/
|
||
;or you can write LD A,B:LD B,D:LD D,H
|
||
|
||
; since v1.13.1 it is possible and *recommended* to change the multi-arg delimiter
|
||
; into ",,", to avoid some ambiguities with certain instructions.
|
||
OPT --syntax=a
|
||
LD A,B,,B,D,,D,H ; same as example above in default syntax
|
||
SUB A,B,,C ; = SUB B, SUB C (the default syntax does for SUB A,B two SUBs!)
|
||
|
||
; since v1.19.0 DEC|INC|POP|PUSH accepts also single-comma in --syntax=a mode
|
||
POP bc,de,hl,,af ; both single/double comma works for these four instructions
|
||
</pre>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_fake_instructions"></a>Fake instructions</h2></div></div></div>
|
||
|
||
|
||
<p>Of course the Z80 is only an 8 bit cpu, but sometimes <code class="code">ld hl,de</code>
|
||
would be nice. SjASMPlus now 'fakes' some instructions like that. This
|
||
improves the readability of the source, but it might not be the fastest
|
||
way to get the result. Also possibly some 'new' load instructions do
|
||
affect the flags in ways you wouldn't expect. You can use option <code class="code">--syntax=f</code>
|
||
to get warnings when fake instruction is used, to avoid using them by accident. Here's the
|
||
list:</p>
|
||
|
||
<pre class="programlisting">
|
||
rl bc ; rl c : rl b
|
||
rl de ; rl e : rl d
|
||
rl hl ; rl l : rl h
|
||
rr bc ; rr b : rr c
|
||
rr de ; rr d : rr e
|
||
rr hl ; rr h : rr l
|
||
sla bc ; sla c : rl b
|
||
sla de ; sla e : rl d
|
||
sla hl ; add hl,hl
|
||
sll bc ; sli c : rl b
|
||
sll de ; sli e : rl d
|
||
sll hl ; sli l : rl h
|
||
sli bc ; sli c : rl b
|
||
sli de ; sli e : rl d
|
||
sli hl ; sli l : rl h
|
||
sra bc ; sra b : rr c
|
||
sra de ; sra d : rr e
|
||
sra hl ; sra h : rr l
|
||
srl bc ; srl b : rr c
|
||
srl de ; srl d : rr e
|
||
srl hl ; srl h : rr l
|
||
|
||
ld bc,bc ; ld b,b : ld c,c
|
||
ld bc,de ; ld b,d : ld c,e
|
||
ld bc,hl ; ld b,h : ld c,l
|
||
ld bc,ix ; ld b,xh : ld c,xl
|
||
ld bc,iy ; ld b,yh : ld c,yl
|
||
ld bc,(hl) ; ld c,(hl) : inc hl : ld b,(hl) : dec hl
|
||
ld bc,(ix+nn) ; ld c,(ix+nn) : ld b,(ix+nn+1)
|
||
ld bc,(iy+nn) ; ld c,(iy+nn) : ld b,(iy+nn+1)
|
||
|
||
ld de,bc ; ld d,b : ld e,c
|
||
ld de,de ; ld d,d : ld e,e
|
||
ld de,hl ; ld d,h : ld e,l
|
||
ld de,ix ; ld d,xh : ld e,xl
|
||
ld de,iy ; ld d,yh : ld e,yl
|
||
ld de,(hl) ; ld e,(hl) : inc hl : ld d,(hl) : dec hl
|
||
ld de,(ix+nn) ; ld e,(ix+nn) : ld d,(ix+nn+1)
|
||
ld de,(iy+nn) ; ld e,(iy+nn) : ld d,(iy+nn+1)
|
||
|
||
ld hl,bc ; ld h,b : ld l,c
|
||
ld hl,de ; ld h,d : ld l,e
|
||
ld hl,hl ; ld h,h : ld l,l
|
||
ld hl,ix ; push ix : pop hl
|
||
ld hl,iy ; push iy : pop hl
|
||
ld hl,(ix+nn) ; ld l,(ix+nn) : ld h,(ix+nn+1)
|
||
ld hl,(iy+nn) ; ld l,(iy+nn) : ld h,(iy+nn+1)
|
||
|
||
ld ix,bc ; ld xh,b : ld xl,c
|
||
ld ix,de ; ld xh,d : ld xl,e
|
||
ld ix,hl ; push hl : pop ix
|
||
ld ix,ix ; ld xh,xh : ld xl,xl
|
||
ld ix,iy ; push iy : pop ix
|
||
|
||
ld iy,bc ; ld yh,b : ld yl,c
|
||
ld iy,de ; ld yh,d : ld yl,e
|
||
ld iy,hl ; push hl : pop iy
|
||
ld iy,ix ; push ix : pop iy
|
||
ld iy,iy ; ld yh,yh : ld yl,yl
|
||
|
||
ld (hl),bc ; ld (hl),c : inc hl : ld (hl),b : dec hl
|
||
ld (hl),de ; ld (hl),e : inc hl : ld (hl),d : dec hl
|
||
|
||
ld (ix+nn),bc ; ld (ix+nn),c : ld (ix+nn+1),b
|
||
ld (ix+nn),de ; ld (ix+nn),e : ld (ix+nn+1),d
|
||
ld (ix+nn),hl ; ld (ix+nn),l : ld (ix+nn+1),h
|
||
|
||
ld (iy+nn),bc ; ld (iy+nn),c : ld (iy+nn+1),b
|
||
ld (iy+nn),de ; ld (iy+nn),e : ld (iy+nn+1),d
|
||
ld (iy+nn),hl ; ld (iy+nn),l : ld (iy+nn+1),h
|
||
|
||
ldi bc,(hl) ; ld c,(hl) : inc hl : ld b,(hl) : inc hl
|
||
ldi bc,(ix+nn) ; ld c,(ix+nn) : inc ix : ld b,(ix+nn) : inc ix
|
||
ldi bc,(iy+nn) ; ld c,(iy+nn) : inc iy : ld b,(iy+nn) : inc iy
|
||
|
||
ldi de,(hl) ; ld e,(hl) : inc hl : ld d,(hl) : inc hl
|
||
ldi de,(ix+nn) ; ld e,(ix+nn) : inc ix : ld d,(ix+nn) : inc ix
|
||
ldi de,(iy+nn) ; ld e,(iy+nn) : inc iy : ld d,(iy+nn) : inc iy
|
||
|
||
ldi hl,(ix+nn) ; ld l,(ix+nn) : inc ix : ld h,(ix+nn) : inc ix
|
||
ldi hl,(iy+nn) ; ld l,(iy+nn) : inc iy : ld h,(iy+nn) : inc iy
|
||
|
||
ldi (hl),bc ; ld (hl),c : inc hl : ld (hl),b : inc hl
|
||
ldi (hl),de ; ld (hl),e : inc hl : ld (hl),d : inc hl
|
||
|
||
ldi (ix+nn),bc ; ld (ix+nn),c : inc ix : ld (ix+nn),b : inc ix
|
||
ldi (ix+nn),de ; ld (ix+nn),e : inc ix : ld (ix+nn),d : inc ix
|
||
ldi (ix+nn),hl ; ld (ix+nn),l : inc ix : ld (ix+nn),h : inc ix
|
||
|
||
ldi (iy+nn),bc ; ld (iy+nn),c : inc iy : ld (iy+nn),b : inc iy
|
||
ldi (iy+nn),de ; ld (iy+nn),e : inc iy : ld (iy+nn),d : inc iy
|
||
ldi (iy+nn),hl ; ld (iy+nn),l : inc iy : ld (iy+nn),h : inc iy
|
||
|
||
ldi a,(bc) ; ld a,(bc) : inc bc
|
||
ldi a,(de) ; ld a,(de) : inc de
|
||
ldi a,(hl) ; ld a,(hl) : inc hl
|
||
ldi b,(hl) ; ld b,(hl) : inc hl
|
||
ldi c,(hl) ; ld c,(hl) : inc hl
|
||
ldi d,(hl) ; ld d,(hl) : inc hl
|
||
ldi e,(hl) ; ld e,(hl) : inc hl
|
||
ldi h,(hl) ; ld h,(hl) : inc hl
|
||
ldi l,(hl) ; ld l,(hl) : inc hl
|
||
ldi a,(ix+nn) ; ld a,(ix+nn) : inc ix
|
||
ldi b,(ix+nn) ; ld b,(ix+nn) : inc ix
|
||
ldi c,(ix+nn) ; ld c,(ix+nn) : inc ix
|
||
ldi d,(ix+nn) ; ld d,(ix+nn) : inc ix
|
||
ldi e,(ix+nn) ; ld e,(ix+nn) : inc ix
|
||
ldi h,(ix+nn) ; ld h,(ix+nn) : inc ix
|
||
ldi l,(ix+nn) ; ld l,(ix+nn) : inc ix
|
||
ldi a,(iy+nn) ; ld a,(iy+nn) : inc iy
|
||
ldi b,(iy+nn) ; ld b,(iy+nn) : inc iy
|
||
ldi c,(iy+nn) ; ld c,(iy+nn) : inc iy
|
||
ldi d,(iy+nn) ; ld d,(iy+nn) : inc iy
|
||
ldi e,(iy+nn) ; ld e,(iy+nn) : inc iy
|
||
ldi h,(iy+nn) ; ld h,(iy+nn) : inc iy
|
||
ldi l,(iy+nn) ; ld l,(iy+nn) : inc iy
|
||
|
||
ldd a,(bc) ; ld a,(bc) : dec bc
|
||
ldd a,(de) ; ld a,(de) : dec de
|
||
ldd a,(hl) ; ld a,(hl) : dec hl
|
||
ldd b,(hl) ; ld b,(hl) : dec hl
|
||
ldd c,(hl) ; ld c,(hl) : dec hl
|
||
ldd d,(hl) ; ld d,(hl) : dec hl
|
||
ldd e,(hl) ; ld e,(hl) : dec hl
|
||
ldd h,(hl) ; ld h,(hl) : dec hl
|
||
ldd l,(hl) ; ld l,(hl) : dec hl
|
||
ldd a,(ix+nn) ; ld a,(ix+nn) : dec ix
|
||
ldd b,(ix+nn) ; ld b,(ix+nn) : dec ix
|
||
ldd c,(ix+nn) ; ld c,(ix+nn) : dec ix
|
||
ldd d,(ix+nn) ; ld d,(ix+nn) : dec ix
|
||
ldd e,(ix+nn) ; ld e,(ix+nn) : dec ix
|
||
ldd h,(ix+nn) ; ld h,(ix+nn) : dec ix
|
||
ldd l,(ix+nn) ; ld l,(ix+nn) : dec ix
|
||
ldd a,(iy+nn) ; ld a,(iy+nn) : dec iy
|
||
ldd b,(iy+nn) ; ld b,(iy+nn) : dec iy
|
||
ldd c,(iy+nn) ; ld c,(iy+nn) : dec iy
|
||
ldd d,(iy+nn) ; ld d,(iy+nn) : dec iy
|
||
ldd e,(iy+nn) ; ld e,(iy+nn) : dec iy
|
||
ldd h,(iy+nn) ; ld h,(iy+nn) : dec iy
|
||
ldd l,(iy+nn) ; ld l,(iy+nn) : dec iy
|
||
|
||
ldi (bc),a ; ld (bc),a : inc bc
|
||
ldi (de),a ; ld (de),a : inc de
|
||
ldi (hl),a ; ld (hl),a : inc hl
|
||
ldi (hl),b ; ld (hl),b : inc hl
|
||
ldi (hl),c ; ld (hl),c : inc hl
|
||
ldi (hl),d ; ld (hl),d : inc hl
|
||
ldi (hl),e ; ld (hl),e : inc hl
|
||
ldi (hl),h ; ld (hl),h : inc hl
|
||
ldi (hl),l ; ld (hl),l : inc hl
|
||
ldi (ix+nn),a ; ld (ix+nn),a : inc ix
|
||
ldi (ix+nn),b ; ld (ix+nn),b : inc ix
|
||
ldi (ix+nn),c ; ld (ix+nn),c : inc ix
|
||
ldi (ix+nn),d ; ld (ix+nn),d : inc ix
|
||
ldi (ix+nn),e ; ld (ix+nn),e : inc ix
|
||
ldi (ix+nn),h ; ld (ix+nn),h : inc ix
|
||
ldi (ix+nn),l ; ld (ix+nn),l : inc ix
|
||
ldi (iy+nn),a ; ld (iy+nn),a : inc iy
|
||
ldi (iy+nn),b ; ld (iy+nn),b : inc iy
|
||
ldi (iy+nn),c ; ld (iy+nn),c : inc iy
|
||
ldi (iy+nn),d ; ld (iy+nn),d : inc iy
|
||
ldi (iy+nn),e ; ld (iy+nn),e : inc iy
|
||
ldi (iy+nn),h ; ld (iy+nn),h : inc iy
|
||
ldi (iy+nn),l ; ld (iy+nn),l : inc iy
|
||
|
||
ldd (bc),a ; ld (bc),a : dec bc
|
||
ldd (de),a ; ld (de),a : dec de
|
||
ldd (hl),a ; ld (hl),a : dec hl
|
||
ldd (hl),b ; ld (hl),b : dec hl
|
||
ldd (hl),c ; ld (hl),c : dec hl
|
||
ldd (hl),d ; ld (hl),d : dec hl
|
||
ldd (hl),e ; ld (hl),e : dec hl
|
||
ldd (hl),h ; ld (hl),h : dec hl
|
||
ldd (hl),l ; ld (hl),l : dec hl
|
||
ldd (ix+nn),a ; ld (ix+nn),a : dec ix
|
||
ldd (ix+nn),b ; ld (ix+nn),b : dec ix
|
||
ldd (ix+nn),c ; ld (ix+nn),c : dec ix
|
||
ldd (ix+nn),d ; ld (ix+nn),d : dec ix
|
||
ldd (ix+nn),e ; ld (ix+nn),e : dec ix
|
||
ldd (ix+nn),h ; ld (ix+nn),h : dec ix
|
||
ldd (ix+nn),l ; ld (ix+nn),l : dec ix
|
||
ldd (iy+nn),a ; ld (iy+nn),a : dec iy
|
||
ldd (iy+nn),b ; ld (iy+nn),b : dec iy
|
||
ldd (iy+nn),c ; ld (iy+nn),c : dec iy
|
||
ldd (iy+nn),d ; ld (iy+nn),d : dec iy
|
||
ldd (iy+nn),e ; ld (iy+nn),e : dec iy
|
||
ldd (iy+nn),h ; ld (iy+nn),h : dec iy
|
||
ldd (iy+nn),l ; ld (iy+nn),l : dec iy
|
||
|
||
ldi (hl),mm ; ld (hl),mm : inc hl
|
||
ldi (ix+nn),mm ; ld (ix+nn),mm : inc ix
|
||
ldi (iy+nn),mm ; ld (iy+nn),mm : inc iy
|
||
|
||
ldd (hl),mm ; ld (hl),mm : dec hl
|
||
ldd (ix+nn),mm ; ld (ix+nn),mm : dec ix
|
||
ldd (iy+nn),mm ; ld (iy+nn),mm : dec iy
|
||
|
||
adc de,bc ; ex de,hl : adc hl,bc : ex de,hl
|
||
adc de,de ; ex de,hl : adc hl,hl : ex de,hl ;; consider alternative: rl e : rl d (-7T)
|
||
adc de,hl ; ex de,hl : adc hl,de : ex de,hl
|
||
adc de,sp ; ex de,hl : adc hl,sp : ex de,hl
|
||
|
||
add de,bc ; ex de,hl : add hl,bc : ex de,hl
|
||
add de,de ; ex de,hl : add hl,hl : ex de,hl ;; consider alternative: srl e : rl d (-3T)
|
||
add de,hl ; ex de,hl : add hl,de : ex de,hl
|
||
add de,sp ; ex de,hl : add hl,sp : ex de,hl
|
||
|
||
sbc de,bc ; ex de,hl : sbc hl,bc : ex de,hl
|
||
sbc de,de ; ex de,hl : sbc hl,hl : ex de,hl
|
||
sbc de,hl ; ex de,hl : sbc hl,de : ex de,hl
|
||
sbc de,sp ; ex de,hl : sbc hl,sp : ex de,hl
|
||
|
||
sub de,bc ; or a : ex de,hl : sbc hl,bc : ex de,hl
|
||
sub de,de ; or a : ex de,hl : sbc hl,hl : ex de,hl ;; consider alternative: ld de,0 (-17T)
|
||
sub de,hl ; or a : ex de,hl : sbc hl,de : ex de,hl
|
||
sub de,sp ; or a : ex de,hl : sbc hl,sp : ex de,hl
|
||
sub hl,bc ; or a : sbc hl,bc
|
||
sub hl,de ; or a : sbc hl,de
|
||
sub hl,hl ; or a : sbc hl,hl ;; consider alternative: ld hl,0 (-9T)
|
||
sub hl,sp ; or a : sbc hl,sp
|
||
|
||
; Z80N only
|
||
mul ; mul de ; to avoid warning specify registers</pre><p>
|
||
<code class="code">LDI</code> increases the data pointer after the data
|
||
access, so <code class="code">LDI A,(HL)</code> is the same as <code class="code">LD A,(HL):INC HL</code>.
|
||
Likewise, <code class="code">LDD A,(DE)</code> is <code class="code">LD A,(DE):DEC DE</code>.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_realdevice"></a>Real device emulation mode</h2></div></div></div>
|
||
|
||
|
||
<p>To enable this mode you must use pseudo-op <a class="link" href="#po_device">DEVICE</a>.</p>
|
||
|
||
<p>In this mode the assembler is assembling program into virtual memory (as
|
||
MSX's WB-ASS2, ZX-Spectrum's GENS, ZEUS, ALASM etc). You can also use pseudo-ops as
|
||
<a class="link" href="#po_mmu">MMU</a>,
|
||
<a class="link" href="#po_slot">SLOT</a>,
|
||
<a class="link" href="#po_page">PAGE</a>,
|
||
<a class="link" href="#po_savebin">SAVEBIN</a>,
|
||
<a class="link" href="#po_savedev">SAVEDEV</a>,
|
||
<a class="link" href="#po_savetap">SAVETAP</a>,
|
||
<a class="link" href="#po_savesna">SAVESNA</a>,
|
||
<a class="link" href="#po_savetrd">SAVETRD</a>,
|
||
<a class="link" href="#po_savenex">SAVENEX</a>,
|
||
<a class="link" href="#po_savecdt">SAVECDT</a>,
|
||
<a class="link" href="#po_savecpcsna">SAVECPCSNA</a>,
|
||
<a class="link" href="#po_saveamsdos">SAVEAMSDOS</a>,
|
||
<a class="link" href="#po_save3dos">SAVE3DOS</a>,
|
||
<a class="link" href="#po_savehob">SAVEHOB</a>,
|
||
<a class="link" href="#po_bplist">BPLIST</a>,
|
||
<a class="link" href="#po_setbp">SETBP</a>,
|
||
<a class="link" href="#po_cspectmap">CSPECTMAP</a>,
|
||
<a class="link" href="#po_labelslist">LABELSLIST</a>,
|
||
use special functions in <a class="link" href="#c_lua_scripting" title="Chapter 7. Lua scripting">Lua scripts</a> and use operators
|
||
<code class="code">{address}, {b address}</code> to read WORD/BYTE from the virtual memory.</p>
|
||
|
||
<p>If only single DEVICE is used in whole source batch, the device
|
||
becomes "global" and will affect also source ahead of the DEVICE line.
|
||
</p><div class="example"><a name="idp546"></a><p class="title"><b>Example 4.2. docs_examples/s_realdevice.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128
|
||
; in this device the default slot is SLOT 3 with PAGE 0 paged in.
|
||
|
||
ORG 32768
|
||
StartProg:
|
||
JP $
|
||
|
||
DEVICE NONE
|
||
;do something, if you don't want to corrupt virtual
|
||
;memory with other code, for example, loader of code.
|
||
;...code...
|
||
|
||
;return to our virtual device:
|
||
DEVICE ZXSPECTRUM128
|
||
|
||
SAVESNA "snapshotname.sna", StartProg</pre>
|
||
</div></div><p><br class="example-break">Predefined devices:</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">NONE<a class="indexterm" name="device_none"></a></span></dt><dd>
|
||
<p>Disable real device emulation mode. By default.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM48<a class="indexterm" name="device_zx48"></a></span></dt><dd>
|
||
<p>Has 4 slots (0-3) with size 4000h, 4 pages (0-3) with size
|
||
4000h. Slot 3 (it from 0C000h) enables to current by
|
||
default.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM128<a class="indexterm" name="device_zx128"></a></span></dt><dd>
|
||
<p>Has 8 RAM pages (0-7) with size 4000h. Default slot is 3.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM256<a class="indexterm" name="device_zx256"></a></span></dt><dd>
|
||
<p>Same as Russian clone Scorption 256. Has 16 RAM pages
|
||
(0-15) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM512<a class="indexterm" name="device_zx512"></a></span></dt><dd>
|
||
<p>Same as Russian clones ATM Turbo 512 and Pentagon 512. Has
|
||
32 RAM pages (0-31) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM1024<a class="indexterm" name="device_zx1024"></a></span></dt><dd>
|
||
<p>Same as Russian clones ATM Turbo 2 and Pentagon 1024 SL.
|
||
Has 64 RAM pages (0-63) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM2048<a class="indexterm" name="device_zx2048"></a></span></dt><dd>
|
||
<p>Similar to other spectrum devices, has 128 RAM pages (0-127) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM4096<a class="indexterm" name="device_zx4096"></a></span></dt><dd>
|
||
<p>Similar to other spectrum devices, has 256 RAM pages (0-255) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUM8192<a class="indexterm" name="device_zx8192"></a></span></dt><dd>
|
||
<p>Similar to other spectrum devices, has 512 RAM pages (0-511) with size 4000h.</p>
|
||
</dd><dt><span class="term">ZXSPECTRUMNEXT<a class="indexterm" name="device_zxn"></a></span></dt><dd>
|
||
<p>ZX Spectrum Next, has 8 slots (0-7) of size 0x2000 and 224
|
||
RAM pages (0-223) totalling at 1.75MiB of memory. The <a class="ulink" href="https://wiki.specnext.dev/Memory_map#Z80_Visible_Memory_map" target="_top">default mapping</a>
|
||
is similar to ZX128, paging in: {14, 15, 10, 11, 4, 5, 0, 1} pages.
|
||
Default slot is 7 (memory range 0xE000..0xFFFF).
|
||
All memory is zeroed during initialization.</p>
|
||
</dd><dt><span class="term">NOSLOT64K<a class="indexterm" name="device_noslot64k"></a></span></dt><dd>
|
||
<p>Has only single slot of size 64kiB (slot 0), covering full Z80 CPU addressing range.
|
||
There are 32 memory pages available, by default page 0 is mapped.
|
||
That makes in total 2MiB of memory available (32 * 64 ki = 2 Mi).</p>
|
||
</dd><dt><span class="term">AMSTRADCPC464<a class="indexterm" name="device_cpc464"></a></span></dt><dd>
|
||
<p>Has 4 slots (0-3) of size 0x4000 and 4 pages (0-3) of 0x4000, totalling 64K. These pages are mapped linearly as
|
||
{ 0, 1, 2, 3 }.</p>
|
||
</dd><dt><span class="term">AMSTRADCPC6128<a class="indexterm" name="device_cpc6128"></a></span></dt><dd>
|
||
<p>Has 4 slots (0-3) of size 0x4000 and 8 RAM pages (0-7) of 0x4000 (128K total). The default page mapping is
|
||
{ 0, 1, 2, 3 }.</p>
|
||
</dd></dl></div>
|
||
|
||
<p>If you want to see other devices you must write to us. See <a class="link" href="#feedback" title="Feedback">Feedback</a> chapter.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_predefined"></a>Predefined defines</h2></div></div></div>
|
||
|
||
|
||
<p>SjASMPlus has predefined <a class="link" href="#po_define">defines</a>.</p><div class="variablelist"><dl class="variablelist"><dt><span class="term">__SJASMPLUS__<a class="indexterm" name="def__sjasmplus__"></a> = <24bit number></span></dt><dd>
|
||
<p>Current version split into three 8bit values, ie. 0x010F02 for "1.15.2".</p>
|
||
</dd><dt><span class="term">__VERSION__<a class="indexterm" name="def__version__"></a> = "version string"</span></dt><dd>
|
||
<p>String value (with quotes around it) of current version like <code class="code">"1.15.2"</code>.</p>
|
||
</dd><dt><span class="term">__ERRORS__<a class="indexterm" name="def__errrors__"></a> = <number></span></dt><dd>
|
||
<p>Number of errors.</p>
|
||
</dd><dt><span class="term">__WARNINGS__<a class="indexterm" name="def__warnings__"></a> = <number></span></dt><dd>
|
||
<p>Number of warnings.</p>
|
||
</dd><dt><span class="term">__DATE__<a class="indexterm" name="def__date__"></a> = "YYYY-MM-DD"</span></dt><dd>
|
||
<p>Date of assembling (timestamp before first pass).</p>
|
||
</dd><dt><span class="term">__TIME__<a class="indexterm" name="def__time__"></a> = "hh:mm:ss"</span></dt><dd>
|
||
<p>Time of assembling (timestamp before first pass, 24h form).</p>
|
||
</dd><dt><span class="term">__PASS__<a class="indexterm" name="def__pass__"></a> = <number></span></dt><dd>
|
||
<p>Current assembling pass (1, 2 or 3).</p>
|
||
</dd><dt><span class="term">__INCLUDE_LEVEL__<a class="indexterm" name="def__include_level__"></a> = <number></span></dt><dd>
|
||
<p>Current include-nesting level.</p>
|
||
</dd><dt><span class="term">__BASE_FILE__<a class="indexterm" name="def__base_file__"></a> = <name of base file></span></dt><dd>
|
||
<p>Name of base file (include-level zero).</p>
|
||
<p>This is raw value without quotes, practically unusable by asm source, but LUA
|
||
provides means to operate with such string value.</p>
|
||
</dd><dt><span class="term">__FILE__<a class="indexterm" name="def__file__"></a> = <name of current file></span></dt><dd>
|
||
<p>Name of current file.</p>
|
||
<p>This is raw value without quotes, practically unusable by asm source, but LUA
|
||
provides means to operate with such string value.</p>
|
||
</dd><dt><span class="term">__LINE__<a class="indexterm" name="def__line__"></a> = <number></span></dt><dd>
|
||
<p>Current line number.</p>
|
||
</dd><dt><span class="term">__COUNTER__<a class="indexterm" name="def__counter__"></a> = <incrementing number></span></dt><dd>
|
||
<p>Does increment upon each usage (starting as value 0). Currently difficult to
|
||
use for labels/symbols, because the starting `_` of the define name prevents
|
||
mid-word substitution, will make more sense with new substitution rules (if ever
|
||
the sjasmplus v2.x happens, would be too big change for v1.x). Right now call
|
||
LUA for the rescue.</p>
|
||
<div class="example"><a name="idp711"></a><p class="title"><b>Example 4.3. __COUNTER__ usage in LUA script</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DB __COUNTER__ ; DB 0
|
||
LUA ALLPASS
|
||
sj.insert_label("label_" .. sj.get_define("__COUNTER__"), sj.current_address)
|
||
-- creates "label_1" at "$" (0x0001)
|
||
sj.insert_label("label_" .. sj.get_define("__COUNTER__"), _c("$+10"))
|
||
-- creates "label_2" at "$+10" (0x000B)
|
||
ENDLUA
|
||
label__COUNTER__: ; does *NOT* substitute in current sjasmplus, sorry
|
||
DB __COUNTER__ ; DB 3
|
||
|
||
; also macro arguments substitution can be used
|
||
MACRO createLabelWithSuffix label?, suffix?
|
||
label?_suffix? ; define global label
|
||
ENDM
|
||
createLabelWithSuffix label, __COUNTER__ ; label_4
|
||
createLabelWithSuffix label, __COUNTER__ ; label_5</pre>
|
||
</div></div><br class="example-break">
|
||
</dd><dt><span class="term">Deprecated predefined values from sjasmplus till version 1.15.1:</span></dt><dd>
|
||
<p>The predefined values were renamed and extended to be more like gcc/clang pre-defines,
|
||
the following ones are deprecated originals.</p>
|
||
</dd><dt><span class="term">_SJASMPLUS = 1</span></dt><dd>
|
||
<p>Deprecated, consider using similar __SJASMPLUS__</p><div class="example"><a name="idp722"></a><p class="title"><b>Example 4.4. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> IFDEF _SJASMPLUS
|
||
;code for sjasmplus
|
||
ELSE
|
||
;code for other compiler
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">_VERSION = "version"</span></dt><dd>
|
||
<p>Deprecated, renamed to __VERSION__</p><div class="example"><a name="idp730"></a><p class="title"><b>Example 4.5. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> IF _VERSION = "1.07"
|
||
;code for 1.07
|
||
ELSE
|
||
;code for other version
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">_RELEASE = releasenumber</span></dt><dd>
|
||
<p>Deprecated, consider using similar __SJASMPLUS__</p><div class="example"><a name="idp738"></a><p class="title"><b>Example 4.6. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> IF _RELEASE = 1 ; 0 - is stable version
|
||
;code for Release Candidate 1
|
||
ELSE
|
||
;code for other version
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">_ERRORS = <number></span></dt><dd>
|
||
<p>Number of errors. Deprecated, renamed to __ERRORS__</p>
|
||
</dd><dt><span class="term">_WARNINGS = <number></span></dt><dd>
|
||
<p>Number of warnings. Deprecated, renamed to __WARNINGS__</p>
|
||
</dd></dl></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_directives"></a>Chapter 5. Pseudo-ops (aka Pseudo-instructions, Directives etc)</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_directive_usage"></a>Simple example of usage</h2></div></div></div>
|
||
|
||
|
||
<pre class="programlisting"> .SOMEPSEUDOOP ;or
|
||
SOMEPSEUDOOP ;or
|
||
somepseudoop</pre>
|
||
|
||
<p>[Almost] complete list of pseudo-ops follows:</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_pseudoops"></a>Pseudo-ops</h2></div></div></div>
|
||
|
||
|
||
<p></p>
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term">.<repeat-count><a class="indexterm" name="po_dot_repeat"></a> <single instruction></span></dt><dd>
|
||
<p>Repeat <single instruction> <repeat-count> many times. Doesn't work
|
||
in the beginning of line. The <repeat-count> must be either simple integer
|
||
number or expression fully enclosed in parentheses.</p><div class="example"><a name="idp767"></a><p class="title"><b>Example 5.1. docs_examples/po_dot_repeat.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> .3 INC A ;will be compiled to INC A:INC A:INC A
|
||
len EQU 10
|
||
.(12-len) BYTE 0 ;will be compiled to BYTE 0,0
|
||
.2 .3 RET ;will be compiled to 6x RET</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">ABYTE<a class="indexterm" name="po_abyte"></a> <offset> <bytes></span></dt><dd>
|
||
<p>Defines a byte or a string of bytes. The offset is added
|
||
to each of the following bytes.</p><div class="example"><a name="idp777"></a><p class="title"><b>Example 5.2. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ABYTE 2 4,9 ; Same as BYTE 6,11
|
||
ABYTE 3 "ABC" ; Same as BYTE "DEF"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">ABYTEC<a class="indexterm" name="po_abytec"></a> <offset> <bytes></span></dt><dd>
|
||
<p>Defines a byte or a string of bytes, where the last byte
|
||
of the string will have bit 7 set. The offset is added to each
|
||
of the following bytes.</p><div class="example"><a name="idp787"></a><p class="title"><b>Example 5.3. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ABYTEC 0 "KIP" ; Same as BYTE "KI",'P'|128
|
||
ABYTEC 1 "ABC",0,"DE" ; Same as BYTE "BC",'D'|128,1,'E','F'|128</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">ABYTEZ<a class="indexterm" name="po_abytez"></a> <offset> <bytes></span></dt><dd>
|
||
<p>Defines a byte or a string of bytes, followed by a zero.
|
||
The offset is added to each of the following bytes.</p><div class="example"><a name="idp797"></a><p class="title"><b>Example 5.4. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ABYTEZ 0 "KIP" ; Same as BYTE "KIP",0</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">ALIGN<a class="indexterm" name="po_align"></a>
|
||
[<expression equal to 1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384 or
|
||
32768>[, <byte>]]</span></dt><dd>
|
||
<p>Align advances to nearest address where <new address> modulo <expression> (default 4)
|
||
equals zero (stays at current address if possible).</p>
|
||
<p>If <byte> is specified, memory advanced over is set to it.
|
||
</p><div class="example"><a name="idp808"></a><p class="title"><b>Example 5.5. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ALIGN ; => ALIGN 4 - simply align by 4
|
||
ALIGN 2 ; by 2 (preserves value of "device" memory)
|
||
ALIGN 2,0 ; + fills memory with zero</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">ASSERT<a class="indexterm" name="po_assert"></a> <expression>[, <anything>]</span></dt><dd>
|
||
<p>An 'assertion failed' error is issued if the expression evaluates to zero.
|
||
The "anything" (optional argument since v1.18.1) is then also visible in the error
|
||
message, so you can add description/notes about expression there.</p><div class="example"><a name="idp818"></a><p class="title"><b>Example 5.6. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">STACKPOINTER=0D500H
|
||
ASSERT END_OF_PROGRAM < STACKPOINTER, Program code leaks into stack area
|
||
END_OF_PROGRAM</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">BINARY<a class="indexterm" name="po_binary"></a> <filename>[,<offset>[,<length>]]</span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_incbin">INCBIN</a>.</p>
|
||
</dd><dt><span class="term">BLOCK<a class="indexterm" name="po_block"></a> <length>[,<fill
|
||
byte>]</span></dt><dd>
|
||
<p>Defines space. Has to be followed by the number of byte to
|
||
reserve, optionally followed by the value to fill these bytes
|
||
with.</p><div class="example"><a name="idp836"></a><p class="title"><b>Example 5.7. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> BLOCK 500 ; define a block of 500 bytes of zero
|
||
BLOCK 500,0 ; define a block of 500 bytes of zero
|
||
BLOCK 400,-1 ; define a block of 400 bytes of 255</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">BPLIST<a class="indexterm" name="po_bplist"></a> <filename> [unreal|zesarux]</span></dt><dd>
|
||
<p>
|
||
<span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span>
|
||
</p>
|
||
<p>Opens file to export breakpoints info directly from ASM source, currently two
|
||
flavours of export are supported: <code class="code">unreal</code> (default) and
|
||
<code class="code">zesarux</code>. For latest Unreal emulators use filename "bpx.ini", you
|
||
can then load the file from the emulator UI. For ZEsarUX the file will contain
|
||
command-line options, which you can add to the command when launching the emulator.
|
||
</p>
|
||
<p>(current version of ZEsarUX will not catch the very first instruction of freshly
|
||
loaded snapshot/NEX/... file, or it will even disable breakpoints when changing
|
||
machine parameters and ignore the <code class="code">--enable-breakpoints</code> option - will
|
||
be hopefully improved in the future)
|
||
</p><div class="example"><a name="idp854"></a><p class="title"><b>Example 5.8. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> BPLIST "bpx.ini" unreal ; open breakpoints list in "Unreal" format
|
||
; or (only one file per assembling-unit can be specified)
|
||
BPLIST "cmd_line_options.txt" zesarux ; open breakpoints list in "ZEsarUX" format</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
</dd><dt><span class="term">BYTE<a class="indexterm" name="po_byte"></a> <bytes></span></dt><dd>
|
||
<p>Defines a byte or a string of bytes. Each value should be
|
||
between -129 and 256.</p><div class="example"><a name="idp863"></a><p class="title"><b>Example 5.9. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> BYTE 0x56
|
||
BYTE 1,-78,'@'
|
||
BYTE "Format C:? ",0h</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">CSPECTMAP<a class="indexterm" name="po_cspectmap"></a> [<filename>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Useful for ZX-Spectrum Emulator
|
||
#CSpect by Mike Dailly.</em></span></p>
|
||
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Saves labels list in format:</p>
|
||
|
||
<pre class="synopsis">HEXA_16BIT_ADDRESS HEXA_LONG_ADDRESS TYPE LABELNAME</pre><p>
|
||
where TYPE is: 00 = regular label, 01 = EQU or struct defined, 02 = DEFL defined,
|
||
03 = ROM page/"none" device, 04 = STRUCT definition.</p>
|
||
|
||
<p>If no filename is provided, default is created by appending ".map" to source name.</p>
|
||
</dd><dt><span class="term">D24<a class="indexterm" name="po_d24"></a></span></dt><dd>
|
||
<p>Defines three bytes by 24b constant. Values should be between
|
||
-16777217 and 16777216.</p><div class="example"><a name="idp887"></a><p class="title"><b>Example 5.10. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> D24 0x123456 ; define three bytes 0x56, 0x34, 0x12</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DB<a class="indexterm" name="po_db"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_byte">BYTE</a>.</p>
|
||
</dd><dt><span class="term">DC<a class="indexterm" name="po_dc"></a></span></dt><dd>
|
||
<p>Same as <a class="link" href="#po_byte">BYTE</a>, but every
|
||
last character of a string will have bit 7 set. Single character in apostrophes is NOT considered as string.
|
||
</p><div class="example"><a name="idp906"></a><p class="title"><b>Example 5.11. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DC "kip" ; same as BYTE "ki",'p'|128
|
||
DC 'A' ; not a string, will produce 0x41 like BYTE 'A'
|
||
DC "A", 'AB', "AB" ; three strings producing: C1 41 C2 41 C2</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DD<a class="indexterm" name="po_dd"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dword">DWORD</a>.</p>
|
||
</dd><dt><span class="term">DEFARRAY<a class="indexterm" name="po_defarray"></a> <id> <replacements></span></dt><dd>
|
||
<p>Array of DEFINEs.</p>
|
||
<p>Use <code class="code">id[#]</code> to retrieve current size of array.
|
||
</p><div class="example"><a name="idp926"></a><p class="title"><b>Example 5.12. docs_examples/po_defarray.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEFARRAY myarray 10*20,"A",20,</D,40>,50,70
|
||
CNT DEFL 0 ;or CNT=0
|
||
DUP myarray[#] ; 6
|
||
DISPLAY myarray[CNT]
|
||
CNT DEFL CNT+1 ;or CNT=CNT+1
|
||
EDUP</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DEFARRAY+<a class="indexterm" name="po_defarray_plus"></a> <id> <additional replacements></span></dt><dd>
|
||
<p>Appending more DEFINEs to already defined array</p><div class="example"><a name="idp935"></a><p class="title"><b>Example 5.13. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEFARRAY myarray 'A', 'B', 'C'
|
||
DEFARRAY+ myarray 'D', 'E' ; now "myarray" has 5 items
|
||
DUP 3 : DEFARRAY+ myarray '!' : EDUP ; "DEFARRAYFILL" adding 3x '!'</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DEFB<a class="indexterm" name="po_defb"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_byte">BYTE</a>.</p>
|
||
</dd><dt><span class="term">DEFD<a class="indexterm" name="po_defd"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dword">DWORD</a>.</p>
|
||
</dd><dt><span class="term">DEFDEVICE<a class="indexterm" name="po_defdevice"></a>
|
||
<deviceid>, <slot_size $100..$10000>, <page_count 1..1024>[, <slot_0_initial_page>[, ...]]</span></dt><dd>
|
||
<p>(since v1.20.1) Add custom device definition. The 64ki Z80 address space is divided evenly by <code class="code">slot_size</code>
|
||
to form N slots and the total device memory is <code class="code">slot_size * page_count</code> bytes.</p>
|
||
|
||
<p>The initial pages are implicitly going from <code class="code">0</code> to <code class="code">page_count-1</code>
|
||
(repeating page <code class="code">page_count-1</code> for remaining slots when there's not enough pages), but you
|
||
can specify initial page layout explicitly.</p>
|
||
|
||
<p>Use <a class="link" href="#po_device">DEVICE</a> to select the newly defined device.</p>
|
||
</dd><dt><span class="term">DEFG<a class="indexterm" name="po_defg"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dg">DG</a>.</p>
|
||
</dd><dt><span class="term">DEFH<a class="indexterm" name="po_defh"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dh">DH</a>.</p>
|
||
</dd><dt><span class="term">DEFINE+<a class="indexterm" name="po_define"></a> <id> <replacement></span></dt><dd></dd><dt><span class="term">DEFINE<a class="indexterm" name="po_define2"></a> <id> <replacement></span></dt><dd>
|
||
<p>The identifier <id> will be replaced with the <replacement>.
|
||
The <code class="code">DEFINE+</code> (since v1.18.0) will also redefine the identifier <id>
|
||
if it already exists. The replacement could be omitted,
|
||
in such case it is still possible to check if the identifier was defined
|
||
with IFDEF or IFNDEF.</p><div class="example"><a name="idp997"></a><p class="title"><b>Example 5.14. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEFINE str_honderd "Honderd"
|
||
BYTE str_honderd,0 ; BYTE "Honderd",0
|
||
DEFINE+ do_stuff set 4,e
|
||
do_stuff ; set 4,e
|
||
DEFINE+ do_stuff set 2,e
|
||
do_stuff ; set 2,e</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term"><label> DEFL<a class="indexterm" name="po_defl"></a> <expression></span></dt><dd>
|
||
<p>Assigns value of <expression> to symbol <label>. New label defined
|
||
by DEFL is marked internally as "modifiable", allowing to re-assign new values to it with
|
||
further DEFL statements (you can use also <code class="code">=</code> instead of <code class="code">DEFL</code>).
|
||
</p><div class="example"><a name="idp1010"></a><p class="title"><b>Example 5.15. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">counter DEFL 0
|
||
DUP 4
|
||
DB 0xAA, counter
|
||
counter = counter + 1
|
||
EDUP
|
||
; machine code produced: AA 00 AA 01 AA 02 AA 03</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DEFM<a class="indexterm" name="po_defm"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_byte">BYTE</a>.</p>
|
||
</dd><dt><span class="term">DEFS<a class="indexterm" name="po_defs"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_block">BLOCK</a>.</p>
|
||
</dd><dt><span class="term">DEFW<a class="indexterm" name="po_defw"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_word">WORD</a>.</p>
|
||
</dd><dt><span class="term">DEPHASE<a class="indexterm" name="po_dephase"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_ent">ENT</a>.</p>
|
||
</dd><dt><span class="term">DEVICE<a class="indexterm" name="po_device"></a> <deviceid>[, <RAMTOP>]</span></dt><dd>
|
||
<p>Enables <a class="link" href="#s_realdevice" title="Real device emulation mode">real device emulation
|
||
mode</a> by it identifier. If there is only single DEVICE directive
|
||
in whole source batch, it becomes "global" and the device affects all
|
||
lines of source, otherwise the DEVICE is applied for lines following it.</p>
|
||
|
||
<p>For ZXSPECTRUM-like devices (except ZX Next) you can provide RAMTOP value,
|
||
which will init the device memory in similar way as "<code class="code">CLEAR <RAMTOP></code>"
|
||
in BASIC would do, putting top of the fake-stack at the RAMTOP address. The
|
||
default RAMTOP is since v1.15.0 0x5D5B (it was 0xFF57 before).</p>
|
||
|
||
<p>Predefined devices' identifiers list:</p>
|
||
|
||
<pre class="synopsis"> NONE ; off real device emulation mode
|
||
ZXSPECTRUM48 ; ZX-Spectrum 48 (4 slots, 4 pages, slot/page size 0x4000, default map: 0, 1, 2, 3)
|
||
ZXSPECTRUM128 ; ZX-Spectrum 128 (like 48 with 8 pages, default map: 7, 5, 2, 0)
|
||
ZXSPECTRUM256 ; e.g. Scorpion 256 (exUSSR clone of ZX-Spectrum 128)
|
||
ZXSPECTRUM512 ; e.g. ATM-Turbo 512 (another clone)
|
||
ZXSPECTRUM1024
|
||
ZXSPECTRUM2048
|
||
ZXSPECTRUM4096
|
||
ZXSPECTRUM8192
|
||
ZXSPECTRUMNEXT ; ZX Spectrum Next (8 slots, 224 pages, slot size 0x2000 = 1.75MiB RAM)
|
||
; (default pages map: 14, 15, 10, 11, 4, 5, 0, 1) (default slot: 7 (0xE000..0xFFFF))
|
||
NOSLOT64K ; Single slot (slot 0) covering full 64kiB address range of Z80, 32 pages
|
||
AMSTRADCPC464 ; Amstrad CPC 464 (4 slots, 4 pages, slot/page size 0x4000, default map: 0, 1, 2, 3)
|
||
AMSTRADCPC6128 ; Amstrad CPC 6128 (like 464 with 8 pages)
|
||
|
||
;disable:
|
||
DEVICE NONE
|
||
;enable:
|
||
DEVICE ZXSPECTRUM128</pre>
|
||
</dd><dt><span class="term">DG<a class="indexterm" name="po_dg"></a> <data encoded in bits></span></dt><dd>
|
||
<p>Data comprises of characters in multiples of eight, each block
|
||
is converted to a byte value.</p>
|
||
|
||
<p>A hyphen '-' (also '.' and '_') represents 0 and any other non-whitespace character
|
||
represents 1. It ignores spaces, use them for formatting if you like. Warning, "DG 10100001" is value 255, because character '0' is not a dash '-'. (since v1.11)</p><div class="example"><a name="idp1069"></a><p class="title"><b>Example 5.16. </b></p><div class="example-contents">
|
||
|
||
<pre class="programlisting"> DG 1-1----1 ; store 161 at the current location
|
||
DG ...# #... .##. .... ; store two bytes: 0x18, 0x60</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DH<a class="indexterm" name="po_dh"></a> "<data>"[,"<data2>"...]</span></dt><dd>
|
||
<p>The data string comprises pairs of hexadecimal digits, each pair is converted to
|
||
a byte value. You can add spaces between pairs as you like. (since v1.11)</p><div class="example"><a name="idp1079"></a><p class="title"><b>Example 5.17. </b></p><div class="example-contents">
|
||
|
||
<pre class="programlisting"> DH "0123456789ABCDEF" ; eight bytes #01 #23 ...
|
||
DH "01 23 45 67" ; four bytes #01 #23 #45 #67</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DISP<a class="indexterm" name="po_disp"></a> <address>[,<page_number>]</span></dt><dd>
|
||
<p>Set the address in which the part of code should work.
|
||
<a class="link" href="#po_phase">PHASE</a> and <a class="link" href="#po_textarea">TEXTAREA</a> are synonyms of DISP.
|
||
<a class="link" href="#po_ent">ENT</a> will restore current address.
|
||
<a class="link" href="#po_unphase">UNPHASE</a>, <a class="link" href="#po_dephase">DEPHASE</a> and <a class="link" href="#po_endt">ENDT</a> are synonyms of <a class="link" href="#po_ent">ENT</a>. DISP blocks can NOT be nested, and to change
|
||
the displacement address within current DISP block use the ordinary ORG.
|
||
When in device mode, you can specify fixed value for "fake" page of emitted
|
||
instructions and regular labels, but to avoid warning, you must also map-in
|
||
the target page into the target memory slot (<a class="link" href="#po_mmu">MMU</a>).
|
||
When no fixed page in DISP is specified, the current mapping of memory pages is used.
|
||
</p><div class="example"><a name="idp1098"></a><p class="title"><b>Example 5.18. docs_examples/po_disp.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM48
|
||
SCREEN EQU $4000
|
||
ORG $8000
|
||
LD HL,BEGIN
|
||
LD DE,SCREEN
|
||
LD BC,ENDOFPROG-BEGIN
|
||
LDIR
|
||
JP SCREEN
|
||
BEGIN DISP SCREEN ;code will compile for address $4000, but to the current ORG
|
||
MARKA DEC A
|
||
HALT
|
||
JP NZ,MARKA
|
||
DI
|
||
HALT
|
||
ENT
|
||
ENDOFPROG
|
||
|
||
ASSERT $800E == BEGIN && $8015 == ENDOFPROG && $4000 == MARKA
|
||
ASSERT $76 == {B $800F} ; HALT instruction lands at $800F (BEGIN+1)</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DISPLAY<a class="indexterm" name="po_display"></a> <bytes></span></dt><dd>
|
||
<p><span class="emphasis"><em>This pseudo-op comes from ZX-Spectrum assembler
|
||
ALASM.</em></span></p>
|
||
|
||
<p>Out to console a string of bytes. Each value should be
|
||
between -129 and 256. Keys /D, /B, /C, /H and /A set format of output of
|
||
numbers:</p><pre class="synopsis">/D - out only in Decimal
|
||
/B - out only in Binary (truncated to 8 bit)
|
||
/C - out as character in apostrophes (truncated to 8 bit)
|
||
/H - out only in Hexadecimal
|
||
/A - out both in Hexadecimal and Decimal</pre><p>
|
||
</p><div class="example"><a name="idp1111"></a><p class="title"><b>Example 5.19. docs_examples/po_display.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ORG 100h
|
||
TESTLABEL:
|
||
;...some code...
|
||
RET
|
||
DISPLAY "--the some program-- by me"
|
||
DISPLAY "TESTLABEL address is:",/A,TESTLABEL
|
||
/*
|
||
will output to the console strings:
|
||
> --the some program-- by me
|
||
> TESTLABEL address is:0x100, 256
|
||
*/</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DM<a class="indexterm" name="po_dm"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_byte">BYTE</a>.</p>
|
||
</dd><dt><span class="term">DS<a class="indexterm" name="po_ds"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_block">BLOCK</a>.</p>
|
||
</dd><dt><span class="term">DUP<a class="indexterm" name="po_dup"></a> <count>[, <index_variable>]</span></dt><dd>
|
||
<p>DUP specifies the number of times to generate the
|
||
following lines until an EDUP pseudo-op is encountered. DUP can be used in macro's.</p>
|
||
<p>Optional second argument (since v1.20.2) is label name to have repetition index
|
||
available inside the block (values 0, 1, 2, 3, ...).
|
||
</p><div class="example"><a name="idp1138"></a><p class="title"><b>Example 5.20. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DUP 3 ; zero count would skip whole block
|
||
NOP
|
||
EDUP
|
||
|
||
/*this will expand to:
|
||
NOP
|
||
NOP
|
||
NOP
|
||
*/</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DW<a class="indexterm" name="po_dw"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_word">WORD</a>.</p>
|
||
</dd><dt><span class="term">DWORD<a class="indexterm" name="po_dword"></a></span></dt><dd>
|
||
<p>Defines a so called doubleword. Values should be between
|
||
-2147483649 and 4294967296.</p><div class="example"><a name="idp1156"></a><p class="title"><b>Example 5.21. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DWORD 4000h,0d000h
|
||
DWORD 4</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">DZ<a class="indexterm" name="po_dz"></a></span></dt><dd>
|
||
<p>Same as <a class="link" href="#po_byte">BYTE</a>, but an extra
|
||
zero will be added at the end.</p><div class="example"><a name="idp1167"></a><p class="title"><b>Example 5.22. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DZ 1 ; same as BYTE 1,0
|
||
DZ "kip" ; same as BYTE "kip",0</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">EMPTYTAP<a class="indexterm" name="po_emptytap"></a> <filenameoftapefile></span></dt><dd>
|
||
<p><span class="emphasis"><em>Useful only for ZX-Spectrum
|
||
users</em></span></p>
|
||
|
||
<p>Create the new or truncate existing standard tape file
|
||
for emulators of ZX-Spectrum. See example of
|
||
<a class="link" href="#po_savetap">SAVETAP</a>.</p>
|
||
</dd><dt><span class="term">EMPTYTRD<a class="indexterm" name="po_emptytrd"></a> <filenameoftrdimage>[,<disclabel>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Useful only for ZX-Spectrum users</em></span></p>
|
||
|
||
<p>Create the empty TRD image for emulators of ZX-Spectrum.
|
||
See example of <a class="link" href="#po_savetrd">SAVETRD</a>.</p>
|
||
</dd><dt><span class="term">ENCODING<a class="indexterm" name="po_encoding"></a> <encoding></span></dt><dd>
|
||
<p><span class="emphasis"><em>Useful only for non English
|
||
users</em></span></p>
|
||
|
||
<p>Set the current encoding, i.e. if you set "DOS", SjASMPlus
|
||
will automatically convert strings from ANSI to DOS-866.
|
||
Encoding may be "DOS"(DOS-866) or "WIN"(ANSI/Win-1251). Default
|
||
is "WIN". </p><div class="example"><a name="idp1197"></a><p class="title"><b>Example 5.23. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ENCODING "WIN"
|
||
DB "тексттекст" ;will be тексттекст
|
||
ENCODING "DOS"
|
||
DB "тексттекст" ;will be ⥪бв⥪бв</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">END<a class="indexterm" name="po_end"></a> [<startaddress>]</span></dt><dd>
|
||
<p>The assembler will stop at this point. The pseudo-op
|
||
END does NOT work in the beginning of line (even with --dirbol).
|
||
The optional argument is used by SAVESNA, SAVECPCSNA, SAVETAP and SAVENEX.</p>
|
||
</dd><dt><span class="term">ENDLUA<a class="indexterm" name="po_endlua"></a></span></dt><dd>
|
||
<p>See <a class="link" href="#po_lua">LUA</a> for more
|
||
information.</p>
|
||
</dd><dt><span class="term">ENDMOD<a class="indexterm" name="po_endmod"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_endmodule">ENDMODULE</a>.</p>
|
||
</dd><dt><span class="term">ENDMODULE<a class="indexterm" name="po_endmodule"></a></span></dt><dd>
|
||
<p>To indicate the end of a module (see <a class="link" href="#po_module">MODULE</a>).</p>
|
||
</dd><dt><span class="term">ENDT<a class="indexterm" name="po_endt"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_ent">ENT</a>.</p>
|
||
</dd><dt><span class="term">ENT<a class="indexterm" name="po_ent"></a></span></dt><dd>
|
||
<p>Restore current address. See <a class="link" href="#po_disp">DISP</a> for more information.</p>
|
||
</dd><dt><span class="term"><label> EQU<a class="indexterm" name="po_equ"></a> <expression>[,<pageNumber>]</span></dt><dd>
|
||
<p>To give the label a value other than the current program
|
||
counter. The label should not already exist (you can assign only one value to it).
|
||
The optional <code class="code">pageNumber</code> can enforce explicit page value for the label
|
||
(for the <code class="code">$$label</code> operator).
|
||
For modifiable labels holding temporary values use <a class="link" href="#po_defl">DEFL</a>.</p><div class="example"><a name="idp1257"></a><p class="title"><b>Example 5.24. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">Label EQU 3
|
||
Kip EQU 0x23*256 + low $</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">EXPORT<a class="indexterm" name="po_export"></a> <label></span></dt><dd>
|
||
<p>The named label will be written to the export-file, in the
|
||
form 'label: EQU value'. This way the export-file can be
|
||
included in other sources. Order of labels in file follows the order of EXPORT statements.
|
||
</p><div class="example"><a name="idp1267"></a><p class="title"><b>Example 5.25. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">DRIE=3
|
||
EXPORT DRIE ; adds into export file line: "DRIE: EQU 0x00000003"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">FPOS<a class="indexterm" name="po_fpos"></a> <position></span></dt><dd>
|
||
<p>The FPOS directive makes it possible to set the file
|
||
position to anywhere in the output file. Position value without sign
|
||
is used as absolute one to be set, position starting with + or - sign will be
|
||
used as relative position.</p>
|
||
|
||
<p>In combination with <a class="link" href="#po_output">OUTPUT</a> <filename>,r it is
|
||
possible to update existing files.</p>
|
||
|
||
<div class="example"><a name="idp1280"></a><p class="title"><b>Example 5.26. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">; This example will result in a file with a length of one byte:
|
||
BYTE 0
|
||
FPOS 0
|
||
BYTE 1
|
||
END</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">HEX<a class="indexterm" name="po_hex"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dh">DH</a>, usually used without quotes around data.</p>
|
||
</dd><dt><span class="term">INCBIN<a class="indexterm" name="po_incbin"></a>
|
||
<filename>[,<offset>[,<length>]]</span></dt><dd>
|
||
<p>To include a binary file into the outputfile. The offset
|
||
and length are optional. Added in v1.12.1: if negative offset or length is provided,
|
||
it counts relatively from the end of the file.</p><div class="example"><a name="idp1298"></a><p class="title"><b>Example 5.27. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> INCBIN "gfx.scc",7 ; include gfx.scc, skip first 7 bytes
|
||
INCBIN "rantab.com",3,256 ; include 256 bytes from offset 3
|
||
INCBIN gfx.scc ,,7 ; 7 bytes from offset 0 (unquoted filename must end with space)
|
||
INCBIN "48.rom",-768,-256 ; include (from 16kiB file) 512 bytes 15616..16127</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">INCHOB<a class="indexterm" name="po_inchob"></a> <filename>[,<offset>[,<length>]]</span></dt><dd>
|
||
<p>To include a data from a hobeta file into the outputfile.
|
||
The offset and length are optional.</p><div class="example"><a name="idp1308"></a><p class="title"><b>Example 5.28. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> INCHOB "gfx.$c",7 ; include gfx.scc, skip first 7 bytes
|
||
INCHOB "sprs.$c",3,256 ; include 256 bytes from offset 3
|
||
INCHOB gfx.$c ,7 ; note the space between the filename and the ',7' here :)</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">INCLUDE<a class="indexterm" name="po_include"></a> <filename></span></dt><dd>
|
||
<p>To include another sourcefile into the current.
|
||
Sourcefiles can be nested 20 levels deep. If the file cannot be
|
||
found in the current directory (the current directory is the
|
||
directory the current asm file comes from!) the file will be searched
|
||
for in the directories specified at the commandline. When angle
|
||
brackets are used, the commandline directories are searched
|
||
before the current directory.</p>
|
||
<p>The directory used to launch the assembling process is automatically added
|
||
to the list (as if "<code class="code">-i.</code>" was added to command line manually)
|
||
(v1.14.0 and v1.14.1 don't add it, reverted back for v1.14.2). If you want to start
|
||
with completely empty include-path list, use "<code class="code">--inc</code>" option
|
||
early (order matters) without the "=" to empty the current list, like:
|
||
<code class="code">sjasmplus --inc --inc=path1 --inc=path2 file.asm</code>
|
||
</p><div class="example"><a name="idp1322"></a><p class="title"><b>Example 5.29. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> INCLUDE <VDP.I> ; search for file "VDP.I" in the include directories, then in current
|
||
INCLUDE MORE.I ; search for "MORE.I" in current directory, then in include directories
|
||
INCLUDE "MORE.I"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">INCLUDELUA<a class="indexterm" name="po_includelua"></a> <filename></span></dt><dd>
|
||
<p>To include another LUA script in first pass(!). If the
|
||
file cannot be found in the current directory (the current
|
||
directory is the directory the current file comes from) the file
|
||
will be searched for in the directories specified at the
|
||
commandline. When angle brackets are used, the commandline
|
||
directories are searched before the current directory.</p><div class="example"><a name="idp1332"></a><p class="title"><b>Example 5.30. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> INCLUDELUA <mylibrary1.lua>
|
||
INCLUDELUA mylibrary2.lua
|
||
INCLUDELUA "library_for_zx.lua"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">INCTRD<a class="indexterm" name="po_inctrd"></a>
|
||
<filenameoftrdimage>,<filenameintrdimage>[,<offset>[,<length>]]</span></dt><dd>
|
||
<p>To include a file from a TRD image into the outputfile.
|
||
The offset and length are optional.</p><div class="example"><a name="idp1342"></a><p class="title"><b>Example 5.31. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> INCTRD "test.trd","mygfx.C" ; include mygfx.C from test.trd
|
||
INCTRD "test.trd","mygfx.C",12 ; include mygfx.C from test.trd, skip first 12 bytes</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">INSERT<a class="indexterm" name="po_insert"></a> <filename>[,<offset>[,<length>]]</span></dt><dd>
|
||
<p>INSERT is a synonym of <a class="link" href="#po_incbin">INCBIN</a>. See above.</p>
|
||
</dd><dt><span class="term">LABELSLIST<a class="indexterm" name="po_labelslist"></a> <filename>[,<virtual labels>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Useful only for ZX-Spectrum Emulator
|
||
UNREALSPECCY.</em></span></p>
|
||
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save labels list in format:</p>
|
||
|
||
<pre class="synopsis">NN:ADDRESS LABELNAME</pre><p>
|
||
where NN is number of RAM page and ADDRESS is truncated to 0000..3FFF range</p>
|
||
|
||
<p>If <code class="code"><virtual labels></code> is non zero, then the page number NN is not
|
||
part of output, and ADDRESS is truncated to 0000..FFFF range.</p>
|
||
|
||
<div class="example"><a name="idp1370"></a><p class="title"><b>Example 5.32. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LABELSLIST "x:/somepath/user.l"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">LUA<a class="indexterm" name="po_lua"></a> [pass]</span></dt><dd>
|
||
<p>Using pseudo-ops LUA and ENDLUA you can insert Lua
|
||
scripts. See more in the chapter "<a class="link" href="#c_lua_scripting" title="Chapter 7. Lua scripting">Lua scripting</a>".</p>
|
||
|
||
<p>Parameter is optional. It may be:</p><pre class="synopsis">PASS1 - interpret Lua script in first pass only.
|
||
PASS2 - interpret Lua script in second pass only.
|
||
PASS3 - interpret Lua script in third pass only. By default.
|
||
ALLPASS - interpret Lua script in all passes. It is needed if you generate some Z80 code.</pre>
|
||
|
||
<div class="example"><a name="idp1384"></a><p class="title"><b>Example 5.33. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA
|
||
-- some comments
|
||
print "Hi, man! This is Lua!"
|
||
ENDLUA
|
||
; some code now:
|
||
LUA ALLPASS
|
||
_pl("LABEL LD A,10")
|
||
_pc("RET")
|
||
ENDLUA</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">MEMORYMAP</span></dt><dd>
|
||
<p>Not available yet.</p>
|
||
</dd><dt><span class="term">MMU<a class="indexterm" name="po_mmu"></a> <first slot number or address> [<last slot number or address>|<single slot option>], <page number>[,<address>]</span></dt><dd>
|
||
<p>Maps memory page(s) to slot(s), similar to SLOT + PAGE combination, but allows
|
||
to set up whole range of consecutive slots (with consecutive memory pages). Or when
|
||
only single slot is specified, extra option can be used to extend particular slot
|
||
functionality. The slot behaviour will stay set in the current DEVICE until reset
|
||
by another MMU specifying same slot (even as part of range, that will clear the option
|
||
to "default").</p>
|
||
|
||
<p>The optional third argument is address for <a class="link" href="#po_org">ORG</a>
|
||
functionality.</p>
|
||
|
||
<p>(since v1.18.1) You can also use starting address of particular slot instead
|
||
of its number, ie. for ZX128: <code class="code">MMU $8000,3</code> is alias of <code class="code">MMU 2,3</code></p>
|
||
|
||
<p>Single slot option (default state is: no error/warning and no wrap = nothing special):
|
||
</p><pre class="synopsis">e = error on writing beyond last byte of slot
|
||
w = warning on writing beyond last byte of slot
|
||
n = wrap address back to start of slot, map next page</pre><p>
|
||
</p><div class="example"><a name="idp1408"></a><p class="title"><b>Example 5.34. docs_examples/po_mmu.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128 : LABELSLIST "po_mmu.lbl" ; to check label pages
|
||
MMU 1 3, 5 ; maps slots 1, 2, 3 with pages 5, 6, 7
|
||
ORG 0xBFFF
|
||
label1_p6: scf ; last byte of page 6 (in slot 2)
|
||
label2_p7: scf ; first byte of page 7 (in slot 3)
|
||
|
||
MMU 3 e, 0 ; page 0 into slot 3, write beyond slot will cause error
|
||
ORG 0xFFFF
|
||
ld a,1 ; error: Write outside of memory slot: 65536 (65536 = address outside)
|
||
|
||
MMU 3 n, 1 ; page 1 into slot 3, make it wrap + map next page automatically
|
||
ORG 0xFFFF ; ! also the $ address was truncated by MMU from $10001 to $0001 !
|
||
label3_p1: scf ; last byte of page 1, then wrapping back to 0xC000 with page 2
|
||
label4_p2: scf ; first byte of page 2 at 0xC000</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">MODULE<a class="indexterm" name="po_module"></a> <name></span></dt><dd>
|
||
<p>
|
||
Labels has to be unique only whithin the current module (module is added as prefix to them).
|
||
Also note the use of '@' operator to suppress all this label-processing. Modules can
|
||
be nested, and module has to be ended by <a class="link" href="#po_endmodule">ENDMODULE</a>.
|
||
</p><div class="example"><a name="idp1419"></a><p class="title"><b>Example 5.35. docs_examples/po_module.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MODULE xxx
|
||
Kip: ; label xxx.Kip
|
||
ld hl,@Kip ; global Kip
|
||
ld hl,@Kop ; global Kop
|
||
ld hl,Kop ; xxx.Kop
|
||
Kop: ; label xxx.Kop
|
||
ld hl,Kip ; xxx.Kip
|
||
ld hl,yyy.Kip ; yyy.Kip
|
||
ld hl,nested.Kip ; xxx.nested.Kip
|
||
MODULE nested
|
||
Kip: ret ; label xxx.nested.Kip
|
||
ENDMODULE
|
||
ENDMODULE
|
||
|
||
MODULE yyy
|
||
Kip: ret ; label yyy.Kip
|
||
@Kop: ret ; label Kop (global one, no module prefix)
|
||
@xxx.Kop: nop ; ERROR: duplicate: label xxx.Kop
|
||
ENDMODULE
|
||
|
||
Kip ret ; global label Kip</pre>
|
||
</div></div><p><br class="example-break">
|
||
Since v1.14.0 the module <code class="code"><name></code> can NOT contain dot character. You can
|
||
use nested modules to get identical identifier as in older versions, or please rename with
|
||
underscores/etc:
|
||
</p><pre class="programlisting"> ; invalid since v1.14.0
|
||
MODULE older.version
|
||
fn1: ret ; final label: @older.version.fn1
|
||
ENDMODULE
|
||
; can be replaced in v1.14.0 with
|
||
MODULE new
|
||
MODULE version
|
||
fn1: ret ; final label: @new.version.fn1
|
||
ENDMODULE
|
||
ENDMODULE</pre><p>
|
||
Since v1.14.0 the <code class="code">MODULE</code> and <code class="code">ENDMODULE</code> also resets the current "non-local"
|
||
label prefix back to "_":
|
||
</p><pre class="programlisting">Kep: ; "Kep" label (global one), and also works as "non-local" prefix for local labels
|
||
MODULE zzz
|
||
.local: ; in v1.14.0 this will be "zzz._.local" label, previously it was "zzz.Kep.local"
|
||
Kup: ; this is "zzz.Kup", but also defines "non-local" prefix as "Kup"
|
||
.local ; this is "zzz.Kup.local"
|
||
ENDMODULE
|
||
.local: ; in v1.14.0 this will be "_.local" label, previously it was "Kup.local"</pre><p>
|
||
</p>
|
||
</dd><dt><span class="term"><p>OPT<a class="indexterm" name="po_opt"></a> [push] [reset] [listoff] [liston] [listall] [listact] [listmc] [<command line options>]</p>
|
||
<p>OPT pop</p></span></dt><dd>
|
||
<p>Allows to reset and modify <a class="link" href="#s_cli" title="Command line">options</a> affecting syntax and
|
||
parsing (for lines of source following the OPT). The options allowed for OPT
|
||
are: <code class="code">-W[no-]<warning_id></code>, <code class="code">--syntax</code>, <code class="code">--zxnext</code>,
|
||
<code class="code">--reversepop</code> and <code class="code">--dirbol</code>.
|
||
</p>
|
||
<p>
|
||
Ahead of options you can use OPT commands: push, pop, reset, listoff, liston, listall, listact, listmc.
|
||
The "push" command will make OPT to preserve current state of options. The "reset"
|
||
command will reset OPT-related options to default state. The "listoff" command will
|
||
suspend the listing for following lines until "liston" command is used (listing
|
||
availability is part of the push/pop state, so to "nest" listing-off you can use
|
||
"OPT push listoff : ... code ... : OPT pop" code sequence). The "listall", "listact"
|
||
and "listmc" commands will select the filter for listing. The "listmc" lists only
|
||
lines containing machine code bytes, "listact" will remove the "skipped" blocks
|
||
(like false-blocks of IF/ELSE conditional assembling, or inner definitions of macros
|
||
and structures), "listall" will switch back to default listing without filtering.
|
||
</p>
|
||
<p>Then the provided options are applied. The default values are: fake instructions
|
||
enabled (no warning), multi-argument delimiter is ",", both () and [] brackets
|
||
can be used to access memory, labels can have any name, ZX Next instructions are OFF,
|
||
POP with multiple arguments doesn't reverse them and pseudo-ops at beginning of
|
||
line are OFF (to just reset to these defaults you can use <code class="code">OPT reset</code>).
|
||
</p>
|
||
<p>The "pop" command: the previously preserved state of options is restored (states
|
||
are preserved in "stack" way, so further OPT with "pop" will restore older states).
|
||
</p>
|
||
<p>The <a class="link" href="#s_id_warnings" title="Warnings with id">id-warning system</a> state is NOT saved/restored
|
||
by OPT push/pop/reset and can be modified only by <code class="code">-W</code> option.
|
||
</p>
|
||
<div class="example"><a name="idp1448"></a><p class="title"><b>Example 5.36. docs_examples/po_opt.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> POP bc, hl ; pops BC first
|
||
OPT push reset --reversepop --syntax=af
|
||
POP bc,,hl ; pops HL first
|
||
LD bc,hl ; warning about Fake instruction
|
||
LD bc,hl ; warning supressed by lowercase "fake" in this comment
|
||
OPT reset --syntax=a
|
||
POP bc,,hl ; pop BC first (--reversepop was reset)
|
||
OPT pop ; restoring syntax to original state</pre>
|
||
</div></div><br class="example-break">
|
||
</dd><dt><span class="term">ORG<a class="indexterm" name="po_org"></a> <address>[,<page_number>]</span></dt><dd>
|
||
<p>Set the program counter to a specific address. If the second argument is
|
||
provided, it will change memory page in the current slot, see
|
||
<a class="link" href="#po_page">PAGE</a> and <a class="link" href="#po_slot">SLOT</a> (it will
|
||
warn you when <address> is outside of it).</p>
|
||
<p>When used inside <a class="link" href="#po_disp">DISP</a> block, only the virtual
|
||
"displaced" program counter is affected, but the machine code will be still
|
||
sequentially emitted in the original physical location and warning is emitted.
|
||
</p><div class="example"><a name="idp1462"></a><p class="title"><b>Example 5.37. docs_examples/po_org.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> ORG 100h ; or 0x100, or $100, or #100
|
||
|
||
; useful macro that padding code
|
||
MACRO PADORG addr
|
||
; add padding
|
||
IF $ < addr
|
||
BLOCK addr-$
|
||
ENDIF
|
||
ORG addr
|
||
ENDM
|
||
|
||
MACRO PADORG2 addr ; z80asm "FORG" replacement
|
||
; add padding + display warning
|
||
IF $ > addr
|
||
; no padding
|
||
DISPLAY /L, "Warning! PADORG failed! ", $, " is more than ", addr
|
||
ELSE
|
||
; add padding
|
||
BLOCK addr-$
|
||
ENDIF
|
||
ORG addr
|
||
ENDM</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">OUTEND<a class="indexterm" name="po_outend"></a></span></dt><dd>
|
||
<p>Ends generating compiler output to file specified in OUTPUT and resets
|
||
<a class="link" href="#po_size">SIZE</a> value to default "none".</p>
|
||
</dd><dt><span class="term">OUTPUT<a class="indexterm" name="po_output"></a>
|
||
[<filename>[,<mode>]]</span></dt><dd>
|
||
<p>With OUTPUT it is possible to create multiple files from
|
||
one source. All following instructions will be assembled to this
|
||
file. It will also <a class="link" href="#po_outend">close (OUTEND)</a>
|
||
and finalize any previously opened output.</p>
|
||
|
||
<p>There are three possible output modes: truncate (overwrite
|
||
existing files, this is the default), rewind (open and execute
|
||
FPOS 0) and append (open and leave the file pointer at the end
|
||
of the file).</p><pre class="synopsis">OUTPUT <filename>,t ; truncate (default)
|
||
OUTPUT <filename>,r ; rewind
|
||
OUTPUT <filename>,a ; append</pre><p>
|
||
</p><div class="example"><a name="idp1485"></a><p class="title"><b>Example 5.38. bigfile.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> OUTPUT loader.com
|
||
ORG 100H
|
||
INCLUDE loader.asm
|
||
INCLUDE bios.asm
|
||
|
||
OUTPUT bigfile.dat
|
||
ORG 4000H
|
||
INCLUDE main.asm
|
||
ORG 8000H
|
||
INCLUDE data.asm
|
||
OUTEND
|
||
INCLUDE next.asm</pre>
|
||
</div></div><p><br class="example-break">This will create two files: loader.com and
|
||
bigfile.dat.</p>
|
||
|
||
</dd><dt><span class="term">PAGE<a class="indexterm" name="po_page"></a> <number></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Set the current memory page to current slot.</p>
|
||
|
||
<div class="example"><a name="idp1502"></a><p class="title"><b>Example 5.39. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> PAGE 7 ;set 7 page
|
||
SAVEBIN "ram7.bin",$C000,$4000 ;- save $4000 begin from $C000 of RAM to file</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">PHASE<a class="indexterm" name="po_phase"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_disp">DISP</a>.</p>
|
||
</dd><dt><span class="term">RELOCATE_END<a class="indexterm" name="po_relocate_end"></a></span></dt><dd>
|
||
<p>Ends the block of code for which relocation data are produced (started by
|
||
<a class="link" href="#po_relocate_start">RELOCATE_START</a>). To get the relocation
|
||
data themselves, use <a class="link" href="#po_relocate_table">RELOCATE_TABLE</a> and
|
||
related symbols.</p>
|
||
<p>For more details/examples check the <a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/examples/relocation" target="_top">examples/relocation</a>,
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/examples/SymbOS_nslookup" target="_top">examples/SymbOS_nslookup</a> and the
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/tree/master/tests/relocate" target="_top">relocation tests</a>.</p>
|
||
</dd><dt><span class="term">RELOCATE_START<a class="indexterm" name="po_relocate_start"></a> [HIGH]</span></dt><dd>
|
||
<p>Marks start of block for which relocation data are produced. Any *regular* label
|
||
(not EQU/DEFL symbols) defined inside the RELOCATE_START .. RELOCATE_END block will
|
||
be treated as "relocatable" label. Any instruction/directive within the block which
|
||
needs resulting opcode adjusted when relocated to different address will produce
|
||
relocation-data for the <a class="link" href="#po_relocate_table">RELOCATE_TABLE</a>.
|
||
</p>
|
||
<p>The <code class="code">RELOCATE_START HIGH</code> variant checks only high-byte relocation.
|
||
The produced table points to high byte (MSB) of the machine code. This mode is
|
||
for OS/loaders which relocate only to 256-byte aligned boundaries (keeping LSB intact).</p>
|
||
<p>The relocation feature of regular label is transitive and EQU value based on already
|
||
relocatable label will be tagged as relocatable too. Also structures instantiated in
|
||
relocatable block have their labels tagged as relocatable and their initial values may
|
||
become part of relocation data if the initial value is based on relocatable value.</p>
|
||
<p>You can prepend operator <code class="code">norel</code> to label to strip it of its relocatable
|
||
property for particular expression.</p>
|
||
<p>The internal heuristic is not bullet-proof, some complex expression may fail
|
||
to be recognised as fixed/relocatable value and instead warn about unstable result.
|
||
It is recommended to assemble relocatable blocks in lower regions of address space
|
||
(like <code class="code">ORG 0</code> or <code class="code">ORG $1000</code>) and to keep expressions simple enough.</p>
|
||
</dd><dt><span class="term">RELOCATE_TABLE<a class="indexterm" name="po_relocate_table"></a> [<subtract_offset>]</span></dt><dd>
|
||
<p>Emits relocation data gathered across all relocation blocks. There are also
|
||
two built-in symbols <code class="code">relocate_count</code> and <code class="code">relocate_size</code>
|
||
containing the size of the table (only word-type tables are supported in sjasmplus,
|
||
so size is always doubled count).</p>
|
||
<p>The table is raw array of WORD (16 bit) values with memory offsets of machine
|
||
code which should be adjusted (when the code is relocated to different than original
|
||
base address). To get offsets from particular base address, use <a class="link" href="#po_org">ORG</a>
|
||
ahead of relocation block to land instructions and labels from there.</p>
|
||
<p>The <subtract_offset> is subtracted from every offset recorded in the relocation table
|
||
(same what WinAPE does with its optional argument "base_address" for RELOCATE_TABLE).</p>
|
||
</dd><dt><span class="term">REPT<a class="indexterm" name="po_rept"></a> <count>[, <index_variable>]</span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_dup">DUP</a>. There is also synonym ENDR to end REPT block (EDUP works too).</p>
|
||
</dd><dt><span class="term">SAVE3DOS<a class="indexterm" name="po_save3dos"></a>
|
||
<filename>,<address>,<size>[,<type>[,<w2_line>[,<w3>]]]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in virtual device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Like <a class="link" href="#po_savebin">SAVEBIN</a>, saves the block of device RAM
|
||
from "address", but with +3DOS 128 byte header prepended.</p><div class="example"><a name="idp1570"></a><p class="title"><b>Example 5.40. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM48
|
||
...
|
||
|
||
; +3 BASIC header (8 bytes starting from offset 15 in +3DOS header):
|
||
; type is first byte (0 = basic, 1, 2 = arrays, 3 = code/screen$)
|
||
; size is "first word" (bytes 1 and 2)
|
||
; w2_line argument is "second word" (bytes 3 and 4)
|
||
; w3 argument is "third word" (bytes 5 and 6) (default value = size)
|
||
|
||
; by default the type=3 (CODE/SCREEN$) is saved
|
||
SAVE3DOS "screen.bin", $4000, $1b00
|
||
; type 3: w2 argument $C000 is target load-address
|
||
SAVE3DOS "code.bin", $8000, $1234, 3, $C000
|
||
; type 0: BASIC, default w2 = $8000 (no auto-run)
|
||
SAVE3DOS "prg1.bas", $5c00, 1234, 0
|
||
; type 0: w2_line is LINE auto-run (30 in example)
|
||
SAVE3DOS "prg2.bas", $5c00, 1234, 0, 30
|
||
; type 1: Numeric array (refer to +3 manual for these)
|
||
SAVE3DOS "b.dat", $8000, 30, 1
|
||
; type 2: Character array (or maybe just ignore these)
|
||
SAVE3DOS "c.dat", $8000, 30, 2</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVEAMSDOS<a class="indexterm" name="po_saveamsdos"></a>
|
||
<filename>,<address>,<size>[,<start = 0>[,<type = 2>]]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in virtual device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Like <a class="link" href="#po_savebin">SAVEBIN</a>, saves the block of device RAM
|
||
from "address", but with AMSDOS 128 byte header prepended.</p><div class="example"><a name="idp1584"></a><p class="title"><b>Example 5.41. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE AMSTRADCPC464
|
||
... some code ...
|
||
|
||
; by default the type=2 (BINARY) is saved
|
||
; "start" (entry) value is by default 0, overriden here to $1234
|
||
SAVEAMSDOS "code.bin", $1000, $1b00, $1234</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVEBIN<a class="indexterm" name="po_savebin"></a>
|
||
<filename>,<startadress>,<lengthofcode></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the block of RAM.</p>
|
||
|
||
<div class="example"><a name="idp1598"></a><p class="title"><b>Example 5.42. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> PAGE 7 ;set 7 page to current slot
|
||
SAVEBIN "ram7.bin",$C000,$4000 ;- save 4000h begin from C000h of RAM to file
|
||
SAVEBIN "ram2.bin",$8000,$3000 ;- save 3000h begin from 8000h of RAM to file</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term"><p>SAVECDT<a class="indexterm" name="po_savecdt"></a>
|
||
FULL <cdtname>[,<startaddr>[,<screenmode>[,<border>[,<ink0>...<ink15>]]]]</p>
|
||
<p>SAVECDT EMPTY <cdtname></p>
|
||
<p>SAVECDT BASIC <cdtname>,<name>,<start>,<length></p>
|
||
<p>SAVECDT CODE <cdtname>,<name>,<start>,<length>[,<customstartaddress>]</p>
|
||
<p>SAVECDT HEADLESS <cdtname>,<start>,<length>[,<sync>[,<format>]]</p></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in Amstrad device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Manipulate CDT file (tape/TZX file format used by Amstrad CPC emulators).</p><div class="example"><a name="idp1616"></a><p class="title"><b>Example 5.43. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE AMSTRADCPC6128
|
||
...
|
||
; create empty CDT file (truncates already existing file to make it empty)
|
||
SAVECDT EMPTY "output.cdt"
|
||
|
||
; snapshot-like dump with default loader, including loading screen, all banks, ...
|
||
SAVECDT FULL "output.cdt" ; defaults: END start addres, screenmode=1, border=1
|
||
; ink# = 1, 24, 20, 6, 26, 0, 2, 8, 10, 12, 14, 16, 18, 22, 24, 16
|
||
|
||
; BASIC program prepared at address "label"
|
||
SAVECDT BASIC "output.cdt","A",label,length
|
||
|
||
; block of binary data at address "label" (default "entry" = "label")
|
||
SAVECDT CODE "output.cdt","C",label,length,entry
|
||
|
||
; headless block with custom sync and format at address "label", formats: 0 = AMSTRAD, 1 = ZX
|
||
SAVECDT HEADLESS "output.cdt",label,length,sync,format ; default sync = 0x16, format = 0</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVECPCSNA<a class="indexterm" name="po_savecpcsna"></a> <filename>[,<startadressofprogram>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in AMSTRADCPC464 / AMSTRADCPC6128 real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the snapshot for emulators of Amstrad CPC machines. (If start address is omitted,
|
||
the one provided by <a class="link" href="#po_end">END</a> is used)</p>
|
||
|
||
<p>The snapshot header content is hard-wired in the sjasmplus binary, with the CRTC, Palette and Gate Array registers
|
||
set to those of a CPC after a boot into the main ROM. Similarly to the ZX-Spectrum SAVESNA directive, interrupts are disabled and must
|
||
be re-enabled by your program. A full list of the settings can be found in the
|
||
<a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/sjasm/io_cpc.cpp#L66" target="_top">source</a>.
|
||
If you absolutely need different defaults and can't afford init-code modifying the state, you can post-patch the resulting SNA
|
||
file directly from source, see <a class="ulink" href="https://github.com/z00m128/sjasmplus/issues/139" target="_top">Issue #139</a> for example.
|
||
</p><div class="example"><a name="idp1633"></a><p class="title"><b>Example 5.44. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE AMSTRADCPC464
|
||
ORG $1200
|
||
START .... ;some code
|
||
RET
|
||
SAVECPCSNA "game.sna",START ;save snapshot to file game.sna. Start address is START ($1200)</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVEDEV<a class="indexterm" name="po_savedev"></a>
|
||
<filename>,<startPage>,<startOffset>,<length></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Like <a class="link" href="#po_savebin">SAVEBIN</a>, saves the block of device RAM.</p>
|
||
|
||
<p>But it allows lengths over 64ki, and the offset value goes directly into device
|
||
virtual memory (where pages are allocated consecutively), ignoring current slot
|
||
"mapping". I.e. page=2,offset=0 will start saving data from page 2 at its beginning,
|
||
going through pages 3, 4, 5, ... until the requested length of data is saved.</p>
|
||
|
||
<p>The offset is not limited to page size, i.e. arguments page=1,offset=0x500 are equal
|
||
to arguments page=0,offset=0x4500 for ZXSPECTRUM128 device (has page size 0x4000).</p>
|
||
|
||
<div class="example"><a name="idp1649"></a><p class="title"><b>Example 5.45. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128 : SAVEDEV "fullram.bin",0,0,0x20000 ; save full 128kiB</pre>
|
||
</div></div><br class="example-break">
|
||
</dd><dt><span class="term">SAVEHOB<a class="indexterm" name="po_savehob"></a>
|
||
<filename>,<filename_in_trdos>,<startadress>,<lengthofcode></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the block of RAM in Hobeta format.</p>
|
||
|
||
<div class="example"><a name="idp1662"></a><p class="title"><b>Example 5.46. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> PAGE 7 ;set 7 page to current slot
|
||
SAVEHOB "ram7.$c","myfile1.C",$C000,$4000 ;- save 4000h begin from C000h of RAM to file
|
||
SAVEHOB "ram2.$c","myfile2.C",$8000,$3000 ;- save 3000h begin from 8000h of RAM to file</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVENEX<a class="indexterm" name="po_savenex"></a> <command> <command arguments></span></dt><dd>
|
||
<p>Commands to build NEX file, for details check <a class="link" href="#c_savenex" title="Chapter 8. SAVENEX guide">SAVENEX
|
||
</a> chapter.</p>
|
||
|
||
<p><span class="emphasis"><em>Works only in ZXSPECTRUMNEXT device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
</dd><dt><span class="term">SAVESNA<a class="indexterm" name="po_savesna"></a> <filename>[,<startadressofprogram>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the snapshot for emulators of ZX-Spectrum. (If start address is omitted,
|
||
the one provided by <a class="link" href="#po_end">END</a> is used)</p>
|
||
|
||
<p>The snapshot header content is hard-wired in sjasmplus binary (disabled interrupts may surprise some users, you can check
|
||
the <a class="ulink" href="https://github.com/z00m128/sjasmplus/blob/master/sjasm/io_snapshots.cpp#L55" target="_top">source</a> to see all the values).
|
||
If you absolutely need different defaults and can't afford init-code modifying the state, you can post-patch the resulting SNA
|
||
file directly from source, see <a class="ulink" href="https://github.com/z00m128/sjasmplus/issues/139" target="_top">Issue #139</a> for example.
|
||
</p><div class="example"><a name="idp1689"></a><p class="title"><b>Example 5.47. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128
|
||
ORG $8000
|
||
START .... ;something code
|
||
RET
|
||
SAVESNA "game.sna",START ;save snapshot to file game.sna. Start address is START ($8000)</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term"><p>SAVETAP<a class="indexterm" name="po_savetap"></a> <filename>,BASIC,<fileintapeheader>,<start>,<length>[,<autorunline>[,<lengthwithoutvars>]]</p>
|
||
<p>SAVETAP <filename>,CODE,<fileintapeheader>,<start>,<length>[,<customstartaddress>[,<optional3rdparam>]]</p>
|
||
<p>SAVETAP <filename>,NUMBERS,<fileintapeheader>,<start>,<length>[,<variableletter(A..Z)>]</p>
|
||
<p>SAVETAP <filename>,CHARS,<fileintapeheader>,<start>,<length>[,<variableletter(A..Z)>]</p>
|
||
<p>SAVETAP <filename>,HEADLESS,<start>,<length>[,<customblockflag(0..255)>]</p></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Append the tape header or block of data to the end of the
|
||
standard tape file for emulators of ZX-Spectrum.</p><div class="example"><a name="idp1707"></a><p class="title"><b>Example 5.48. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM48
|
||
...
|
||
EMPTYTAP "output.tap"
|
||
|
||
SAVETAP "output.tap",BASIC,"noAutorun",label,100
|
||
SAVETAP "output.tap",BASIC,"w/Autorun",label,100,9999
|
||
SAVETAP "output.tap",BASIC,"withVars",label,123,9999,100
|
||
SAVETAP "output.tap",CODE,"bank17",screen,6912
|
||
SAVETAP "output.tap",CODE,"screen",demo,length,org
|
||
SAVETAP "output.tap",NUMBERS,"dimArray",label,100 ; a()
|
||
SAVETAP "output.tap",NUMBERS,"othernum",label,200,'b' ; b()
|
||
SAVETAP "output.tap",CHARS,"charArray",label,300 ; a$()
|
||
SAVETAP "output.tap",CHARS,"nextone",label,400,'m' ; m$()
|
||
SAVETAP "output.tap",HEADLESS,start,length</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVETAP <filename>[,<startadressofprogram>]</span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the tape file for emulators of ZX-Spectrum as a
|
||
"snapshot" of almost-whole memory. Generated tape file supports the
|
||
ZX-Spectrum clones with extended RAM such as ATM Turbo 512, etc.
|
||
(If start address is omitted, the one provided by <a class="link" href="#po_end">END</a> is used)</p>
|
||
|
||
<p>The stored memory starts at $5E00 (with screen data at $4000 auto-detected
|
||
and optionally stored into the TAP file). The stored memory is automatically
|
||
trimmed of zero values at start and end of the region (put non-zero byte markers
|
||
around region you want to store, if you have zero-ed bytes at beginning or end
|
||
of your code).
|
||
|
||
</p><div class="example"><a name="idp1720"></a><p class="title"><b>Example 5.49. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM48
|
||
ORG $7FFF
|
||
DB $01 ; non-zero marker to store the following zero-ed data
|
||
DAT DS 1024, 0 ; zero-ed data at $8000 (1024 bytes)
|
||
START .... ; some code
|
||
RET
|
||
SAVETAP "game.tap", START ; save tape-snapshot to file game.tap. Start address is $8400</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SAVETRD<a class="indexterm" name="po_savetrd"></a> <filename_of_trd_image>,<filename_in_trdos>,<address>,<length>[,<autostart_BASIC_line>[,<length_minus_variables>]]</span></dt><dd></dd><dt><span class="term">SAVETRD <filename_of_trd_image>,|<filename_in_trdos>,<address>,<length>[,<autostart_BASIC_line>]</span></dt><dd></dd><dt><span class="term">SAVETRD <filename_of_trd_image>,&<filename_in_trdos>,<address>,<length></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Save the device memory into TRD disk image. Saving two files with same filename will
|
||
emit warning, but two files (with same name) will be created in the disk directory.</p>
|
||
|
||
<p>Adding pipe character "|" ahead of file
|
||
name will make sjasmplus to delete old file(s) with the same name before writing
|
||
the new one => replace-like functionality. If the deleted file did occupy all
|
||
sectors till the free space position in disc info, sjasmplus will salvage those sectors
|
||
back and save new file over them (but it will not do full reshuffle/defrag in more
|
||
complex cases, sjasmplus is just assembler, not full featured TRD images manipulation tool).</p>
|
||
|
||
<p>Adding ampersand character "&" ahead of file name will make sjasmplus to look
|
||
for existing file with the requested name (last of them, any earlier duplicates are deleted).
|
||
The new content is appended to the file (sector aligned append) and the catalog entry gets
|
||
only number of sectors patched, up to 255 sectors at most. This is special mode for
|
||
single-file big-loaders.</p>
|
||
|
||
<p>The unofficial three-letter extensions are also supported (official extensions
|
||
are only: B, C, D and #).
|
||
|
||
</p><div class="example"><a name="idp1739"></a><p class="title"><b>Example 5.50. </b></p><div class="example-contents">
|
||
<pre class="programlisting"> EMPTYTRD "test.trd" ;create empty TRD image
|
||
PAGE 7 ;set 7 page to current slot
|
||
SAVETRD "test.trd","myfile1.C",$C000,$4000 ;- save 4000h begin from C000h of RAM to file to TRD image
|
||
SAVETRD "test.trd","myfile2.C",$8000,$3000 ;- save 3000h begin from 8000h of RAM to file to TRD image
|
||
SAVETRD "test.trd",|"myfile1.C",$B000,$400 ;- replace "myfile1.C" with new file
|
||
SAVETRD "test.trd",&"myfile1.C",$9000,$734 ;- sector-append new data to "myfile1.C"</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
</dd><dt><span class="term">SETBP<a class="indexterm" name="po_setbp"></a> [<expression>]</span></dt><dd></dd><dt><span class="term">SETBREAKPOINT<a class="indexterm" name="po_setbreakpoint"></a> [<expression>]</span></dt><dd>
|
||
<p>
|
||
<span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span>
|
||
</p>
|
||
<p>Will add execution-type breakpoint at address <expression> to the
|
||
<a class="link" href="#po_bplist">BPLIST</a> export file. If no expression is specified,
|
||
the current program counter will be used.
|
||
</p><div class="example"><a name="idp1759"></a><p class="title"><b>Example 5.51. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> BPLIST "cmd_line.options.txt" zesarux ; open breakpoints list in "ZEsarUX" format
|
||
start:
|
||
nop ; ZEsarUX will not catch very first instruction of snapshot file loaded
|
||
SETBP ; so breakpoint ahead of the second instruction (after first "nop")
|
||
xor a
|
||
SETBP some_routine_label ; set also some breakpoint to other code by its label
|
||
SETBREAKPOINT $0D6B ; alias of SETBP, works identically
|
||
; ... your code of app
|
||
</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
</dd><dt><span class="term">SHELLEXEC<a class="indexterm" name="po_shellexec"></a> <filename>[,<parameters>]</span></dt><dd>
|
||
<p>Execute external program <filename> using optional
|
||
command line <parameters>.</p><div class="example"><a name="idp1768"></a><p class="title"><b>Example 5.52. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> OUTPUT "mybin.bin"
|
||
;some code
|
||
IF ((_ERRORS = 0) && (_WARNINGS = 0))
|
||
SHELLEXEC "x:/somepath/bin2tap.exe mybin.bin mytap.tap"
|
||
; or SHELLEXEC "x:/somepath/bin2tap.exe","mybin.bin mytap.tap"
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SIZE<a class="indexterm" name="po_size"></a> <filesize in bytes></span></dt><dd>
|
||
<p>If the resulting file is less than the given length, as
|
||
many zero bytes are added as necessary. See <a class="link" href="#po_output">OUTPUT</a> for more.</p><div class="example"><a name="idp1780"></a><p class="title"><b>Example 5.53. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> SIZE 32768 ; make sure file will be 32K</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SLDOPT<a class="indexterm" name="po_sldopt"></a> <type> <arguments></span></dt><dd>
|
||
<p>Type `<code class="code">COMMENT</code>` - add comma delimited list of case sensitive keywords
|
||
to be detected in end-of-line comments and exported to
|
||
<a class="link" href="#c_sld_data" title="Chapter 9. Source Level Debugging (SLD) data">Source Level Debugging (SLD) data</a>.
|
||
The particular keywords depend on the debugger you are using to process SLD data.</p>
|
||
|
||
<div class="example"><a name="idp1793"></a><p class="title"><b>Example 5.54. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128
|
||
SLDOPT COMMENT WPMEM, Log
|
||
ORG $8000
|
||
call init ; Log("calling init") - gets exported to SLD
|
||
ret ; no keyword here - not exported to SLD
|
||
var1 DB 1 ; WPMEM - exported
|
||
var2 DB 2 ; WpMem - not exported, case sensitive!</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">SLOT<a class="indexterm" name="po_slot"></a> <number_or_address></span></dt><dd>
|
||
<p><span class="emphasis"><em>Works only in real device emulation mode. See
|
||
<a class="link" href="#po_device">DEVICE</a>.</em></span></p>
|
||
|
||
<p>Set current slot. Slots are defined by DEVICE pseudo-op.
|
||
Use pseudo-op <a class="link" href="#po_page">PAGE</a> to change page
|
||
in the current slot.</p>
|
||
|
||
<p>(since v1.18.1) You can also use starting address of particular slot instead
|
||
of its number, ie. for ZX128: <code class="code">SLOT $8000</code> is alias of <code class="code">SLOT 2</code></p>
|
||
|
||
<div class="example"><a name="idp1814"></a><p class="title"><b>Example 5.55. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUM128
|
||
SLOT 3 ;from 0C000h to 0FFFFh
|
||
PAGE 1 ;set page 1 to slot 3
|
||
ORG 0C000h
|
||
;your program here
|
||
PAGE 2
|
||
INCBIN "somegfx.bin"
|
||
;....</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">TAPEND<a class="indexterm" name="po_tapend"></a></span></dt><dd>
|
||
<p>Ends generating compiler output to tape file block specified in TAPOUT.</p>
|
||
</dd><dt><span class="term">TAPOUT<a class="indexterm" name="po_tapout"></a> <filename>[,<flagbyte>]</span></dt><dd>
|
||
<p>Appends one tape block at the end of specified file.
|
||
All following code will be assembled to this tape file block.</p>
|
||
|
||
<p>Default value of flagbyte is 255.</p><div class="example"><a name="idp1832"></a><p class="title"><b>Example 5.56. bigfile.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> EMPTYTAP screen.tap
|
||
|
||
TAPOUT screen.tap,0
|
||
DB 3
|
||
DB 'ScreenName'
|
||
DW 6912
|
||
DW 16384
|
||
DW 32768
|
||
TAPEND
|
||
|
||
TAPOUT screen.tap
|
||
INCBIN screen.bin
|
||
TAPEND</pre>
|
||
</div></div><p><br class="example-break">This will create tap file with the screen.</p>
|
||
</dd><dt><span class="term">TEXTAREA<a class="indexterm" name="po_textarea"></a> <address></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_disp">DISP</a>.</p>
|
||
</dd><dt><span class="term">UNDEFINE<a class="indexterm" name="po_undefine"></a> <id></span></dt><dd>
|
||
<p>Removes the identifier defined by <a class="link" href="#po_define">DEFINE</a></p>
|
||
|
||
<div class="example"><a name="idp1853"></a><p class="title"><b>Example 5.57. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> DEFINE Release 1
|
||
|
||
IFDEF Release
|
||
DISPLAY "Building release version"
|
||
ENDIF
|
||
|
||
UNDEFINE Release
|
||
|
||
IFNDEF Release
|
||
DISPLAY "It's works!"
|
||
ENDIF
|
||
|
||
IFDEF _SJASMPLUS
|
||
DISPLAY "Yes, it's the sjasmplus!"
|
||
ENDIF
|
||
|
||
UNDEFINE * ; undefine all identifiers
|
||
|
||
IFNDEF _SJASMPLUS
|
||
DISPLAY "It's not the sjasmplus??"
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">UNPHASE<a class="indexterm" name="po_unphase"></a></span></dt><dd>
|
||
<p>Synonym of <a class="link" href="#po_ent">ENT</a>.</p>
|
||
</dd><dt><span class="term">WHILE<a class="indexterm" name="po_while"></a> <expression>[, <guardian-counter>]</span></dt><dd>
|
||
<p>While expression evaluates to non-zero value, generates following lines until
|
||
an ENDW (EDUP/ENDR alias) pseudo-op is encountered.</p>
|
||
<p>The optional guardian-counter value will abort the WHILE if there are
|
||
more iterations, default guardian-counter is set to 100k.
|
||
</p><div class="example"><a name="idp1872"></a><p class="title"><b>Example 5.58. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">ptr = $4000
|
||
WHILE ptr < $4020, 500 ; max 500 loops before error
|
||
DB low ptr
|
||
ptr = ptr + 1
|
||
ENDW ; EDUP or ENDR works too, but ENDW is advised for WHILE
|
||
|
||
/* will emit bytes $00, $01, ..., $1F */</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
</dd><dt><span class="term">WORD<a class="indexterm" name="po_word"></a> <words></span></dt><dd>
|
||
<p>Defines a word. Values should be between -32787 and
|
||
65536.</p><div class="example"><a name="idp1881"></a><p class="title"><b>Example 5.59. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> WORD 4000h,0d000h
|
||
WORD 4,"HA"</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd></dl></div>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_conditional_assembly"></a>Conditional assembly</h2></div></div></div><a class="indexterm" name="s_conditional_assembly2"></a>
|
||
|
||
|
||
<p>It may be useful to assemble a part (or not) based on a certain
|
||
condition.</p>
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term">IF<a class="indexterm" name="ca_if"></a> <expression></span></dt><dd>
|
||
<p>If <expression> is non-zero the following lines are
|
||
assembled until an ELSE, ELSEIF or ENDIF.</p>
|
||
|
||
<p>Forward reference of label will cause warning - as any machine code emitted inside
|
||
the IF/IFN block with such expression can lead to unstable results. If you are sure
|
||
the late definition of label will not affect resulting machine code (the IF block
|
||
does not emit any machine code and does not define any label), you can suppress the
|
||
warning.</p>
|
||
|
||
<div class="example"><a name="idp1898"></a><p class="title"><b>Example 5.60. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> IF (aaa == 0) || (2 = aaa && ((bbb % 13) & 0x01))
|
||
; some code to assemble only if the symbol `aaa` is zero
|
||
; or (logical OR) when symbol `aaa` is two
|
||
; and (logical AND) modulo 13 of `bbb` is odd number
|
||
ENDIF</pre><p>
|
||
</p>
|
||
</div></div><br class="example-break">
|
||
</dd><dt><span class="term">IFN<a class="indexterm" name="ca_ifn"></a> <expression></span></dt><dd>
|
||
<p>If <expression> is zero the following lines are
|
||
assembled until an ELSE, ELSEIF or ENDIF.</p>
|
||
</dd><dt><span class="term">IFDEF<a class="indexterm" name="ca_ifdef"></a> <id></span></dt><dd>
|
||
<p>The condition is true if there is an id defined. These are
|
||
NOT labels.</p>
|
||
|
||
<div class="example"><a name="idp1915"></a><p class="title"><b>Example 5.61. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> IFDEF MSX_LEAN_AND_MEAN
|
||
CALL InitOwnMM
|
||
ELSE
|
||
CALL InitDos2MemMan
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">IFNDEF<a class="indexterm" name="ca_ifndef"></a> <id></span></dt><dd>
|
||
<p>The condition is true if there isn't an id defined. These
|
||
are NOT labels.</p>
|
||
|
||
<div class="example"><a name="idp1926"></a><p class="title"><b>Example 5.62. </b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">1 IN A,(0C4H)
|
||
AND 2
|
||
IFNDEF DEBUG
|
||
JR NC,1B
|
||
ENDIF</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</dd><dt><span class="term">IFUSED<a class="indexterm" name="ca_ifused"></a> <label></span></dt><dd>
|
||
<p>The condition is true if there is an label used somewhere
|
||
in the code. You can create libraries of useful functions using
|
||
IFUSED pseudo-op</p>
|
||
|
||
<div class="example"><a name="idp1937"></a><p class="title"><b>Example 5.63. (similar to tests/misc/ifused_test.asm)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> OUTPUT "TEST.OUT"
|
||
|
||
CALL LABEL3 ; LABEL3 - yes
|
||
LD A,(LABEL1) ; LABEL1 - yes
|
||
|
||
IFUSED LABEL1
|
||
LABEL1:
|
||
DB 1
|
||
ENDIF
|
||
|
||
IFUSED LABEL2
|
||
LABEL2:
|
||
DB 2
|
||
ENDIF
|
||
|
||
IFUSED LABEL3
|
||
LABEL3:
|
||
DB 3
|
||
ENDIF
|
||
|
||
IFUSED LABEL4
|
||
LABEL4:
|
||
DB 4
|
||
ENDIF
|
||
|
||
LD A,LABEL2 ; LABEL2 - yes
|
||
|
||
RET
|
||
|
||
; Output will contain bytes from LABEL1 to LABEL3 (1, 2, 3), but not contain from LABEL4, because this label is not used.
|
||
|
||
; Alternative syntax:
|
||
LABEL5:
|
||
IFUSED ; sjasmplus will use name of previous label, i.e. LABEL5
|
||
|
||
ENDIF
|
||
</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
<p>Known bug: when code is using label inside module "moduleX",
|
||
like <code class="code">call labelY</code>, only usage of <code class="code">moduleX.labelY</code> label is noted.
|
||
Then if you define "labelY" outside of module and hide it inside <code class="code">IFUSED labelY</code>
|
||
block, the call from module will be unable to find the routine.
|
||
</p>
|
||
<p>
|
||
Workaround: you can use the global-label operator @: "<code class="code">call @labelY</code>" to
|
||
trigger usage of the global "labelY", or you can use the alternative IFUSED syntax
|
||
"<code class="code">labelY: IFUSED</code>" which does not only check condition, but also does define the label.
|
||
Once the label is defined, the "call labelY" line inside module will find the global
|
||
variant and mark it as "used" correctly.
|
||
</p>
|
||
<p>
|
||
Local labels inside the IFUSED block are not visible until the main label is used, if you want to call only
|
||
local label, you can force the visibility of the routine by "<code class="code">ASSERT main_label</code>" - this will
|
||
trigger usage of the global "main_label", and then the IFUSED block will be assembled, and local labels
|
||
will become visible too.
|
||
</p>
|
||
</dd><dt><span class="term">IFNUSED<a class="indexterm" name="ca_ifnused"></a> <label></span></dt><dd>
|
||
<p>The condition is true if there is an label
|
||
<span class="emphasis"><em>not</em></span> used somewhere in the code.</p>
|
||
</dd><dt><span class="term">ELSE<a class="indexterm" name="ca_else"></a></span></dt><dd>
|
||
<p>See <a class="link" href="#ca_if">IF</a>. If the IF condition is
|
||
false (in all previous IF/ELSEIF blocks), the else-part is assembled.</p>
|
||
</dd><dt><span class="term">ELSEIF<a class="indexterm" name="ca_elseif"></a> <expression></span></dt><dd>
|
||
<p>If the previous IF-block had false condition, the ELSEIF expression is evaluated
|
||
and the ELSEIF acts as new <a class="link" href="#ca_if">IF</a>.</p>
|
||
</dd><dt><span class="term">ENDIF<a class="indexterm" name="ca_endif"></a></span></dt><dd>
|
||
<p>Every <a class="link" href="#ca_if">IF</a> should be followed
|
||
by an ENDIF.</p>
|
||
</dd></dl></div>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_macros"></a>Macros</h2></div></div></div>
|
||
|
||
|
||
<p>The MACRO pseudo-op defines a macro. It should be followed by the
|
||
name of the macro, optionally followed by the parameters. The following
|
||
lines will be stored as the macro-body until an ENDM pseudo-op is
|
||
encountered. Macro's have to be defined before their use. Macro's name
|
||
must be unique (even if two macros differ by required arguments).
|
||
</p><div class="example"><a name="idp1983"></a><p class="title"><b>Example 5.64. Macro without parameters (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MACRO ADD_HL_A
|
||
ADD A,L
|
||
JR NC,.hup
|
||
INC H
|
||
.hup
|
||
LD L,A
|
||
ENDM</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
|
||
<p>Labels in a macro starting with a dot are local to each macro
|
||
expansion.</p><div class="example"><a name="idp1987"></a><p class="title"><b>Example 5.65. A macro with parameters (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MACRO WAVEOUT reg, data
|
||
LD A,reg
|
||
OUT (7EH),A
|
||
LD A,data
|
||
OUT (7FH),A
|
||
ENDM
|
||
; this macro will make
|
||
WAVEOUT 2,17
|
||
; expand to:
|
||
LD A,2
|
||
OUT (7EH),A
|
||
LD A,17
|
||
OUT (7FH),A</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p><div class="example"><a name="idp1990"></a><p class="title"><b>Example 5.66. Another example (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MACRO LOOP
|
||
IF $-.lus<127
|
||
DJNZ .lus
|
||
ELSE
|
||
DEC B
|
||
JP NZ,.lus
|
||
ENDIF
|
||
ENDM
|
||
|
||
Main
|
||
.lus
|
||
CALL DoALot
|
||
LOOP
|
||
; This will expand to:
|
||
Main
|
||
.lus ; Main.lus
|
||
CALL DoALot
|
||
DJNZ .lus ; Main.lus</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
|
||
<p>Angle brackets can be used when the arguments contain commas.
|
||
</p><div class="example"><a name="idp1994"></a><p class="title"><b>Example 5.67. Argument in angle brackets (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> MACRO UseLess data
|
||
DB data
|
||
ENDM
|
||
|
||
UseLess <10,12,13,0>
|
||
; expands to:
|
||
DB 10,12,13,0
|
||
|
||
; use '!' to include '!' and '>' in those strings.
|
||
|
||
UseLess <5, 6 !> 3>
|
||
; expands to:
|
||
DB 5, 6 > 3
|
||
|
||
UseLess <"Kip!!",3>
|
||
; expands to:
|
||
DB "Kip!",3</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
|
||
<p>As compatibility convenience to make porting from different assemblers somewhat
|
||
easier, there is alternative syntax, where the macro name is written at beginning
|
||
of line (as if label, but MODULE part is NOT applied to macro name).
|
||
</p><div class="example"><a name="idp1998"></a><p class="title"><b>Example 5.68. Macro name at beginning of line (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
<pre class="programlisting">LabelAsMacroName MACRO arg1?, arg2?
|
||
ld a,arg1?
|
||
ld hl,arg2?
|
||
ENDM
|
||
|
||
LabelAsMacroName 1,$1234
|
||
; expands to:
|
||
ld a,1 : ld hl,$1234</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
|
||
<p>
|
||
If some macro over-shadows regular instruction or directive name, the <code class="code">@</code>
|
||
character in front of instruction/directive name can be used to inhibit macro expansion.
|
||
</p><div class="example"><a name="idp2003"></a><p class="title"><b>Example 5.69. Inhibit macro expansion operator (docs_examples/s_macros.asm)</b></p><div class="example-contents">
|
||
<pre class="programlisting">djnz MACRO arg1?
|
||
dec c
|
||
jr nz,arg1?
|
||
@djnz arg1? ; avoid self-reference and use real instruction
|
||
ENDM
|
||
|
||
1: djnz 1B ; macro replacement will be used here
|
||
1: @djnz 1B ; original djnz instruction here</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_structures"></a>Chapter 6. Structures</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_structures_about"></a>What is it?</h2></div></div></div>
|
||
|
||
|
||
<p>Structures can be used to define data structures in memory more
|
||
easily. The name of the structure is set to the total size of the
|
||
structure.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_define_structure"></a>Defining structure</h2></div></div></div>
|
||
|
||
|
||
<p>A structure definition starts with: <code class="code">STRUCT
|
||
<name>[,<initial offset>]</code> and ends with
|
||
<code class="code">ENDS</code>. Structure definitions are local to the current
|
||
module, but, as with labels, '@' can be used to override this.</p>
|
||
|
||
<p>Lines between STRUCT and ENDS should have the following
|
||
format:</p>
|
||
|
||
<p><code class="code">membername pseudo-operation operands</code></p>
|
||
|
||
<p>All fields are optional. Lines without label should start with
|
||
whitespace.</p>
|
||
|
||
<p>When non zero <code class="code">offset</code> is used, it acts as if
|
||
<a class="link" href="#st_block">BLOCK</a> with <code class="code">length</code> equal to
|
||
<code class="code">offset</code> was defined as first member of structure.</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_structure_instructions"></a>STRUCT instructions</h2></div></div></div>
|
||
|
||
|
||
<p>Between the STRUCT and ENDS pseudo-instructions the following
|
||
instructions can be used:</p>
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term">BYTE<a class="indexterm" name="st_byte"></a> [<defaultvalue>]</span></dt><dd>
|
||
<p>To define a one byte member. The defaultvalue is used when
|
||
no initialisation value is given when the structure is declared.
|
||
(DB and DEFB may be used instead of BYTE).</p>
|
||
</dd><dt><span class="term">WORD<a class="indexterm" name="st_word"></a> [<defaultvalue>]</span></dt><dd>
|
||
<p>To define a two byte member. The defaultvalue is used when
|
||
no initialisation value is given when the structure is declared.
|
||
(DW and DEFW may be used instead of WORD).</p>
|
||
</dd><dt><span class="term">D24<a class="indexterm" name="st_d24"></a> [<defaultvalue>]</span></dt><dd>
|
||
<p>To define a three byte member. The defaultvalue is used
|
||
when no initialisation value is given when the structure is
|
||
declared.</p>
|
||
</dd><dt><span class="term">DWORD<a class="indexterm" name="st_dword"></a> [<defaultvalue>]</span></dt><dd>
|
||
<p>To define a four byte member. The defaultvalue is used
|
||
when no initialisation value is given when the structure is
|
||
declared. (DD and DEFD may be used instead of DWORD).</p>
|
||
</dd><dt><span class="term">TEXT<a class="indexterm" name="st_text"></a> <length>[,{<DB-like operand(s)>}]</span></dt><dd>
|
||
<p>(since v1.17) To define a member of the specified <code class="code">length</code> of bytes.
|
||
The operands are <a class="link" href="#po_byte">DB-like</a> formatted, and the last
|
||
byte explicitly defined will fill the remaining bytes reserved upon definition
|
||
(zeroed when no value is specified at all).</p>
|
||
<p>The default value can be modified with init values when structure is used, but
|
||
then only the given bytes overwrite default content, NOT filling remainder of it.</p>
|
||
<p>While the operands are DB-like formatted, they must be enclosed in curly braces.
|
||
Also make sure the braces are not mistaken with the optional braces on the sub-structure
|
||
boundaries, when using TEXT member in sub-structure, you may need to use curly braces
|
||
for the sub-structure itself around of curly braces used for TEXT values (making the
|
||
sub-structure braces mandatory in such case). The length can be from 1 to 8192 bytes
|
||
(if you need even longer "text", use two members and split your arguments).</p>
|
||
</dd><dt><span class="term">BLOCK<a class="indexterm" name="st_block"></a> <length>[,<fillbyte>]</span></dt><dd>
|
||
<p>To define a member of the specified number of bytes. Arguments are set
|
||
when defining the current structure, and are not part of init values when
|
||
the structure is later used.
|
||
('#', DS and DEFS may be used instead of BLOCK).</p>
|
||
|
||
<p>(since v1.11) If <code class="code">fillbyte</code> is omitted, the device memory
|
||
content in the block area is preserved (not zeroed).</p>
|
||
</dd><dt><span class="term">ALIGN<a class="indexterm" name="st_align"></a> [<expression>[, <byte>]]</span></dt><dd>
|
||
<p>To <a class="link" href="#po_align">align</a> the offset. If the expression
|
||
is omitted, 4 is assumed. ('##' May be used instead of ALIGN).</p>
|
||
|
||
<p>(since v1.11) If the byte is omitted, device memory content is preserved (not zeroed).</p>
|
||
</dd><dt><span class="term"><structure name> [<init values>]</span></dt><dd>
|
||
<p>It is possible to nest structures, and give new defaults
|
||
for the BYTE and WORD members.</p>
|
||
</dd></dl></div>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="st_usage"></a>Usage of defined structure</h2></div></div></div>
|
||
|
||
|
||
<p><code class="code">[<label>] <struct_name> [<initial values>]</code> will emit full
|
||
structure into machine code, either using default values from structure definition,
|
||
or overriding them with explicit value from the <initial values> list. In initial
|
||
values you can use curly brackets {} to group particular initial values for particular
|
||
sub-structure, any missing values in particular sub-structure init-list are set up by
|
||
default values of particular field. See "SDOT" example below or tests/struct asm files
|
||
for more examples.</p>
|
||
|
||
<p><code class="code"><label> <struct_name> = <expression></code> will only set up
|
||
<label>.<struct_field> labels starting from designed address provided by
|
||
expression, but there will be no machine code emitted (and current address "$" will not
|
||
advance).</p>
|
||
|
||
<p>(since v1.17) The initial values inside curly braces block can now span over multiple
|
||
lines with new line ending current value expression (the comma after expression is optional
|
||
in such case). Please bear in mind this is pushing original sjasmplus architecture beyond
|
||
its original design (multi-line definitions) and may fail in complex scenarios (for
|
||
example the "dot-repeater" macro mechanics will repeat only the remainder of current
|
||
line, ignoring the curly-braces block spanning across following lines). If you have
|
||
example of code which fails but you believe it's reasonable use case, please open the
|
||
issue on github with such example, so it is possible to improve the feature in future
|
||
(the dot-repeater is "won't fix" case, but otherwise the feature should work reliably).
|
||
</p>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_structure_examples"></a>Examples</h2></div></div></div>
|
||
|
||
|
||
<div class="example"><a name="idp2092"></a><p class="title"><b>Example 6.1. docs_examples/c_structures.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> STRUCT SCOLOR
|
||
RED BYTE 4
|
||
GREEN BYTE 5
|
||
BLUE BYTE 6
|
||
ENDS</pre>
|
||
|
||
<p>This is identical to:</p>
|
||
|
||
<pre class="synopsis">SCOLOR EQU 3 ; length
|
||
SCOLOR.RED EQU 0 ; offset
|
||
SCOLOR.GREEN EQU 1 ; offset
|
||
SCOLOR.BLUE EQU 2 ; offset</pre>
|
||
</div></div><br class="example-break">
|
||
<div class="example"><a name="idp2098"></a><p class="title"><b>Example 6.2. docs_examples/c_structures.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> STRUCT SDOT
|
||
X BYTE
|
||
Y BYTE
|
||
C SCOLOR 0,0,0 ; use new default values
|
||
ENDS
|
||
</pre>
|
||
|
||
<p>This is identical to:</p>
|
||
|
||
<pre class="synopsis">SDOT EQU 5 ; length
|
||
SDOT.X EQU 0 ; offset
|
||
SDOT.Y EQU 1 ; offset
|
||
SDOT.C EQU 2 ; offset
|
||
SDOT.C.RED EQU 2 ; offset
|
||
SDOT.C.GREEN EQU 3 ; offset
|
||
SDOT.C.BLUE EQU 4 ; offset
|
||
</pre>
|
||
</div></div><br class="example-break">
|
||
<div class="example"><a name="idp2104"></a><p class="title"><b>Example 6.3. docs_examples/c_structures.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> STRUCT SPOS,4
|
||
X WORD
|
||
Y BYTE
|
||
ALIGN 2
|
||
AD WORD
|
||
ENDS</pre>
|
||
|
||
<p>This is identical to:</p>
|
||
|
||
<pre class="synopsis">SPOS EQU 10 ; length
|
||
SPOS.X EQU 4 ; offset
|
||
SPOS.Y EQU 6 ; offset
|
||
SPOS.AD EQU 8 ; offset</pre>
|
||
</div></div><br class="example-break">
|
||
<div class="example"><a name="idp2110"></a><p class="title"><b>Example 6.4. docs_examples/c_structures.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<p>When a structure is defined it is possible to declare labels
|
||
with it</p><pre class="programlisting">COLOR SCOLOR</pre><p>This is
|
||
identical to:</p><pre class="synopsis">COLOR
|
||
COLOR.RED BYTE 4
|
||
COLOR.GREEN BYTE 5
|
||
COLOR.BLUE BYTE 6
|
||
</pre><p>Note the default values.</p>
|
||
|
||
<p>Or without label:</p><pre class="programlisting">COLORTABLE
|
||
SCOLOR 0,0,0
|
||
SCOLOR 1,2,3
|
||
SCOLOR ,2
|
||
; etc.</pre><p>This is identical to:</p><pre class="synopsis">COLORTABLE
|
||
BYTE 0,0,0
|
||
BYTE 1,2,3
|
||
BYTE 4,2,6
|
||
; etc.</pre><p>
|
||
|
||
</p><pre class="programlisting">DOT1 SDOT 0,0, 0,0,0 ; or 0,0,0,0,0 or {0,0,{0,0,0}}</pre><p>Only
|
||
BYTE and WORD members can be initialised.</p>
|
||
|
||
<p>The resulting labels can be used as any other
|
||
label:</p><pre class="programlisting"> ld b,(ix+SCOLOR.RED)
|
||
ld a,(COLOR.GREEN)
|
||
ld de,COLOR
|
||
; etc.</pre>
|
||
|
||
</div></div><br class="example-break">
|
||
<div class="example"><a name="idp2121"></a><p class="title"><b>Example 6.5. docs_examples/st_usage_example.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> STRUCT BIN_FILE_MAP, 256
|
||
value1 BYTE
|
||
value2 WORD
|
||
ENDS
|
||
|
||
ORG 0x8000
|
||
binData BIN_FILE_MAP = $ ; set up label values only (no bytes)
|
||
INCBIN "some_data.bin" ; load the bytes from file instead
|
||
|
||
; using the data through struct definition
|
||
ld a,(binData.value1)
|
||
ld hl,(binData.value2)</pre>
|
||
|
||
<p>This is identical to:</p>
|
||
|
||
<pre class="synopsis">BIN_FILE_MAP EQU 259 ; length
|
||
BIN_FILE_MAP.value1 EQU 256 ; offset
|
||
BIN_FILE_MAP.value2 EQU 257 ; offset
|
||
; labels to access binary data loaded by INCBIN
|
||
binData EQU 0x8000 ; address
|
||
binData.value1 EQU 0x8100 ; address
|
||
binData.value2 EQU 0x8101 ; address</pre>
|
||
</div></div><br class="example-break">
|
||
|
||
<div class="example"><a name="idp2127"></a><p class="title"><b>Example 6.6. docs_examples/st_text.asm</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> STRUCT BLOCK_HEADER
|
||
length WORD BLOCK_HEADER
|
||
type BYTE $AB
|
||
name TEXT 10, { "none", 32, '!' } ; will produce "none !!!!!" default data
|
||
; because this is definition of the field, here last byte is "filler"
|
||
datastart WORD
|
||
datalen WORD
|
||
checksum BYTE $CC
|
||
ENDS
|
||
|
||
ORG 0x8000
|
||
head1 BLOCK_HEADER { ; Multi-line initialization requires curly braces.
|
||
, , ; Keeping default length and type by specifying empty values.
|
||
{ 'New', ; The final `name` data will be "New Name!!"
|
||
32, ; overwriting only 8 bytes of default data.
|
||
"Name" }, ; The last "e" is NOT "filler" in the non-default value.
|
||
$8000, $1234 ; Explicit datastart and datalen values.
|
||
} ; End of initial data block ("checksum" keeps default value).
|
||
|
||
; machine code (struct data):
|
||
; 12 00 AB 4E 65 77 20 4E 61 6D 65 21 21 00 80 34 12 CC
|
||
; = { $0012, $AB, "New Name!!", $8000, $1234, $CC }</pre>
|
||
</div></div><br class="example-break">
|
||
|
||
<div class="warning" style="margin-left: 0.5in; margin-right: 0.5in;"><h3 class="title">Warning</h3>
|
||
<p>Do not use the offset labels in indirections
|
||
like:</p><pre class="programlisting">LD A,(SDOT.X)</pre><p>This will
|
||
conflict with futher 'improvements' ;-)</p>
|
||
|
||
<p>If this is absolutely necessary (why?) use something like
|
||
this:</p><pre class="programlisting">LD A,(+SDOT.X)</pre>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_lua_scripting"></a>Chapter 7. Lua scripting</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_lua_oh_why"></a>Why?</h2></div></div></div>
|
||
|
||
|
||
<div align="top"><img src="lua.gif" align="top"></div><p>Why is scripting engine
|
||
as <a class="ulink" href="https://www.lua.org/" target="_top">Lua</a> embedded to the assembler? Answer is simple: it can be used to add extra
|
||
features by users. And Lua is small enough, fast and powerful scripting engine.</p>
|
||
|
||
<p>Sjasmplus currently includes Lua 5.4.6 (since v1.20.3). The upgrade from Lua 5.1 in v1.20.0
|
||
was done along replacing tolua++ with LuaBridge2.6 and while there was lot of effort
|
||
to maintain original Lua bindings to sjasmplus, there were few changes to the API.</p>
|
||
|
||
<p>If your old source does not work any more after upgrade, please carefully check
|
||
against the <a class="link" href="#s_lua_sjasmplus_bindings" title="SjASMPlus functions bindings to Lua">bindings documentation</a> below.</p>
|
||
|
||
<p>Check if your code does use only official API, and if you were using secret extra
|
||
arguments, check the test files and examples how those lua scripts were adjusted to
|
||
build with v1.20.0. The bindings API documentation has been cleaned up, some API
|
||
extended and has better test-coverage to make it less likely to change in the future.</p>
|
||
|
||
<p>Also please mind the breaking changes of the Lua itself, and adjust your scripts
|
||
to Lua 5.4 syntax and library functions, there is example below with common issues
|
||
already encountered (open github issues with others so we can add them to docs).</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_lua_how_to"></a>How to use?</h2></div></div></div>
|
||
|
||
|
||
<p>You must use <a class="link" href="#po_lua">LUA</a> and <a class="link" href="#po_endlua">ENDLUA</a> pseudo-ops.</p><div class="example"><a name="idp2153"></a><p class="title"><b>Example 7.1. Hello World!</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA
|
||
print ("Hello World!")
|
||
ENDLUA</pre>
|
||
</div></div><p><br class="example-break"></p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_lua_sjasmplus_bindings"></a>SjASMPlus functions bindings to Lua</h2></div></div></div>
|
||
|
||
|
||
<p>From Lua you can control some variables and use functions of the
|
||
compiler. Complete list:</p>
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term">[integer] _c("expression")<a class="indexterm" name="lua__c"></a></span></dt><dd>
|
||
<p>Calculate expression using calculator of the compiler (32-bit only).
|
||
Example: <code class="code">val = _c("SOMELABEL+12")</code></p>
|
||
</dd><dt><span class="term">[void] _pc("code")<a class="indexterm" name="lua__pc"></a></span></dt><dd>
|
||
<p>Parse string of Z80 assembly. Example: <code class="code">_pc("ADD A,B")</code></p>
|
||
</dd><dt><span class="term">[void] _pl("label code")<a class="indexterm" name="lua__pl"></a></span></dt><dd>
|
||
<p>Parse line of Z80 assembly. Example: <code class="code">_pl("SOMELABEL ADD A,B")</code></p>
|
||
|
||
<p>This binding makes almost all pseudo-instructions (directives) available from Lua script
|
||
with all options and features. In the future the bindings API will be mostly frozen, extended
|
||
only in case where using <code class="code">_pl(...)</code> is too cumbersome.</p>
|
||
</dd><dt><span class="term">[integer] sj.calc("expression")<a class="indexterm" name="lua_sj_calc"></a></span></dt><dd>
|
||
<p>See <a class="link" href="#lua__c">_c</a></p>
|
||
</dd><dt><span class="term">[void] sj.parse_code("code")<a class="indexterm" name="lua_sj_parse_code"></a></span></dt><dd>
|
||
<p>See <a class="link" href="#lua__pc">_pc</a></p>
|
||
</dd><dt><span class="term">[void] sj.parse_line("label code")<a class="indexterm" name="lua_sj_parse_line"></a></span></dt><dd>
|
||
<p>See <a class="link" href="#lua__pl">_pl</a></p>
|
||
</dd><dt><span class="term">[void] sj.error("message","bad_value" = nil)<a class="indexterm" name="lua_sj_error"></a></span></dt><dd>
|
||
<p>Print error message.</p>
|
||
</dd><dt><span class="term">[void] sj.warning("message","bad_value" = nil)<a class="indexterm" name="lua_sj_warning"></a></span></dt><dd>
|
||
<p>Print warning message.</p>
|
||
</dd><dt><span class="term">[boolean] sj.file_exists("filename")<a class="indexterm" name="lua_sj_file_exists"></a></span></dt><dd>
|
||
<p>Check for file exists.</p>
|
||
</dd><dt><span class="term">[string] sj.get_define("name", "include_macro_args" = false)<a class="indexterm" name="lua_sj_get_define"></a></span></dt><dd>
|
||
<p>Get define value, returns nil if define is not found. Can optionally search also macro arguments (with higher priority).</p>
|
||
</dd><dt><span class="term">[boolean] sj.insert_define("id", "value" = "")<a class="indexterm" name="lua_sj_insert_define"></a></span></dt><dd>
|
||
<p>Add new define. Returns true if the define is new, false when define already existed and value was replaced or when id is invalid.</p>
|
||
</dd><dt><span class="term">[integer] sj.get_label("name")<a class="indexterm" name="lua_sj_get_label"></a></span></dt><dd>
|
||
<p>Get label address. Returns -1 if name is invalid, 0 when not found or has still undefined value (you can use also <code class="code">_c("name")</code> to get symbol value and do some calculations with it).</p>
|
||
</dd><dt><span class="term">[boolean] sj.insert_label("name", address)<a class="indexterm" name="lua_sj_insert_label"></a></span></dt><dd>
|
||
<p>Add new label. Returns true when label was successfully inserted (or value modified first time in next assembling pass), false when name is invalid or label was already defined.</p>
|
||
</dd><dt><span class="term">[integer] sj.current_address<a class="indexterm" name="lua_sj_current_address"></a></span></dt><dd>
|
||
<p>Read-only variable. Current address.</p>
|
||
</dd><dt><span class="term">[integer] sj.error_count<a class="indexterm" name="lua_sj_error_count"></a></span></dt><dd>
|
||
<p>Read-only variable. Count of Errors.</p>
|
||
</dd><dt><span class="term">[integer] sj.warning_count<a class="indexterm" name="lua_sj_warning_count"></a></span></dt><dd>
|
||
<p>Read-only variable. Count of Warnings.</p>
|
||
</dd><dt><span class="term">[void] sj.exit(errorcode = 1)<a class="indexterm" name="lua_sj_exit"></a></span></dt><dd>
|
||
<p>Shutdown the compiler.</p>
|
||
</dd><dt><span class="term">[void] sj.add_byte(byte)<a class="indexterm" name="lua_sj_add_byte"></a></span></dt><dd>
|
||
<p>Add byte to output (or to memory) and increase <a class="link" href="#lua_sj_current_address">sj.current_address</a></p>
|
||
</dd><dt><span class="term">[void] sj.add_word(word)<a class="indexterm" name="lua_sj_add_word"></a></span></dt><dd>
|
||
<p>Add word to output (or to memory) and twice increase <a class="link" href="#lua_sj_current_address">sj.current_address</a></p>
|
||
</dd><dt><span class="term">[integer] sj.get_byte(address)<a class="indexterm" name="lua_sj_get_byte"></a></span></dt><dd>
|
||
<p>Get byte from memory. <span class="emphasis"><em>Works only in real device
|
||
emulation mode and only in last assembling pass.</em></span></p>
|
||
</dd><dt><span class="term">[integer] sj.get_word(address)<a class="indexterm" name="lua_sj_get_word"></a></span></dt><dd>
|
||
<p>Get word from memory. <span class="emphasis"><em>Works only in real device
|
||
emulation mode and only in last assembling pass.</em></span></p>
|
||
</dd><dt><span class="term">[string] sj.get_device()<a class="indexterm" name="lua_sj_get_device"></a></span></dt><dd>
|
||
<p>Return current emulating device's identifier. Returns
|
||
"NONE" if no emulation mode.</p>
|
||
</dd><dt><span class="term">[boolean] sj.set_device("id" = "NONE", ramtop = 0)<a class="indexterm" name="lua_sj_set_device"></a></span></dt><dd>
|
||
<p>Set current emulating device's identifier. Returns false
|
||
if requested device id is not found and current device set is lost ("NONE" is set).</p>
|
||
</dd><dt><span class="term">[boolean] sj.set_page(number)<a class="indexterm" name="lua_sj_set_page"></a></span></dt><dd>
|
||
<p>Set page "number" to the current slot. Works as pseudo-op <a class="link" href="#po_page">PAGE</a>.</p>
|
||
</dd><dt><span class="term">[boolean] sj.set_slot(number_or_address)<a class="indexterm" name="lua_sj_set_slot"></a></span></dt><dd>
|
||
<p>Set current slot to "number". Works as pseudo-op <a class="link" href="#po_slot">SLOT</a>.</p>
|
||
<p>(since v1.20.0) You can also use starting address of slot instead, ie. for ZX128
|
||
<code class="code">sj.set_slot(0x8000)</code> is alias of <code class="code">sj.set_slot(2)</code>.</p>
|
||
</dd><dt><span class="term">[void] sj.shellexec("programname")<a class="indexterm" name="lua_sj_shellexec"></a></span></dt><dd>
|
||
<p>See pseudo-op SHELLEXEC.</p>
|
||
</dd><dt><span class="term">[boolean] zx.trdimage_create("trd_name", "label" = "")<a class="indexterm" name="lua_zx_trdimage_create"></a></span></dt><dd>
|
||
<p>Creates empty TRD image file.</p>
|
||
</dd><dt><span class="term">[boolean] zx.trdimage_add_file<a class="indexterm" name="lua_zx_trdimage_add_file"></a>("trd_name", "somenameC",
|
||
startaddress, length, autostart = -1, replace = false)</span></dt><dd>
|
||
<p>Save block of memory to TRD image file. <span class="emphasis"><em>Work
|
||
only in real device emulation mode.</em></span></p>
|
||
</dd><dt><span class="term">[boolean] zx.save_snapshot_sna<a class="indexterm" name="lua_zx_save_snapshot_sna"></a>("filename.sna",
|
||
startaddressofprogram)</span></dt><dd>
|
||
<p>Save snapshot of memory in SNA format. <span class="emphasis"><em>Works only
|
||
in real device emulation mode and only for ZXSPECTRUM48 and
|
||
ZXSPECTRUM128..</em></span></p>
|
||
</dd></dl></div>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_lua_third_party_libs"></a>Third-party embedded library(ies)</h2></div></div></div>
|
||
|
||
|
||
<p><span class="emphasis"><em>None at this moment.</em></span></p>
|
||
|
||
<p>Since v1.20.0 the sjasmplus integrates Lua 5.4.4 (now 5.4.6).</p>
|
||
|
||
<p>The libraries included in older versions of sjasmplus: lpack.c, bit (bitwise operators)
|
||
and hex (convert to/from hexa numbers) are now all part of the standard Lua 5.4.</p>
|
||
|
||
<p>Refer to <a class="ulink" href="https://www.lua.org/manual/5.4/manual.html#6" target="_top">Lua documentation</a>
|
||
for full list of functions and detailed help.</p>
|
||
|
||
<p>For small example check the test <code class="code">tests/lua_examples/trivial/lua_standard_libs.asm</code></p>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_lua_examples"></a>Example</h2></div></div></div>
|
||
|
||
|
||
<p></p>
|
||
|
||
<div class="example"><a name="idp2372"></a><p class="title"><b>Example 7.2. Variables doesn't clear in new passes of the compiler</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA PASS1
|
||
v = 1
|
||
ENDLUA
|
||
|
||
LUA PASS2
|
||
print (v)
|
||
-- out to console: 1
|
||
v = v + 1
|
||
ENDLUA
|
||
|
||
LUA PASS3
|
||
print (v)
|
||
-- out to console: 2
|
||
ENDLUA</pre>
|
||
</div></div><p><br class="example-break"></p><div class="example"><a name="idp2376"></a><p class="title"><b>Example 7.3. To generate some code you need to generate it in all
|
||
passes</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA ALLPASS
|
||
_pl("ClearScreen LD (.savesp+1),SP")
|
||
_pc("LD SP,16384+6144")
|
||
_pc("LD HL,0")
|
||
for i = 32768, 38912, 2 do
|
||
_pc("PUSH HL")
|
||
end
|
||
_pl(".savesp: LD SP,0")
|
||
_pc("RET")
|
||
ENDLUA
|
||
|
||
LUA PASS2 ; if you fully understand what you are doing
|
||
sj.add_byte(123) -- and you need emit bytes in other mode
|
||
ENDLUA ; luamc-ok ; you can suppress warning here or at start of block</pre>
|
||
</div></div><p><br class="example-break"></p><div class="example"><a name="idp2380"></a><p class="title"><b>Example 7.4. Declare function and use it</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA
|
||
function savetape_mytype(filename, startaddress)
|
||
local fp
|
||
fp = assert(io.open(filename, "wb"))
|
||
for i = 16384, 32767, 4 do
|
||
assert(fp:write( string.pack("bbbb",
|
||
sj.get_byte(i),
|
||
sj.get_byte(i+1),
|
||
sj.get_byte(i+2),
|
||
sj.get_byte(i+3)) ))
|
||
end
|
||
assert(fp:flush())
|
||
assert(fp:close())
|
||
end
|
||
ENDLUA
|
||
|
||
;somewhere in your program
|
||
LUA
|
||
savetape_mytype("tapefiles/myprogram.tape", _c("StartGameLabel"))
|
||
ENDLUA</pre>
|
||
</div></div><p><br class="example-break"></p><div class="example"><a name="idp2384"></a><p class="title"><b>Example 7.5. Simple sample :)</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA
|
||
-- Function reads number from file <fname>, increases it, creates define "BUILD" with the number and saves the number to <fname>.
|
||
-- With this function you can control count of compilations.
|
||
function increase_build(fname)
|
||
local fp
|
||
local build
|
||
fp = assert(io.open(fname, "rb"))
|
||
build = tonumber(fp:read("*all"))
|
||
assert(fp:close())
|
||
if type(build) == "nil" then
|
||
build = 0
|
||
end
|
||
build = build + 1;
|
||
sj.insert_define("BUILD", build)
|
||
fp = assert(io.open(fname, "wb"))
|
||
assert(fp:write( build ))
|
||
assert(fp:flush())
|
||
assert(fp:close())
|
||
end
|
||
|
||
-- Before using you must create empty file "build.txt"!
|
||
increase_build("build.txt")
|
||
|
||
-- Creates define "TIME" with current time
|
||
sj.insert_define("TIME", '"' .. os.date("%Y-%m-%d %H:%M:%S") .. '"')
|
||
ENDLUA
|
||
|
||
; print to console our time and build number
|
||
DISPLAY "Build time: ", TIME
|
||
DISPLAY "Build number: ", /D, BUILD</pre>
|
||
</div></div><p><br class="example-break">
|
||
|
||
</p><div class="example"><a name="idp2388"></a><p class="title"><b>Example 7.6. Common issues with upgrade to Lua 5.4</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting"> LUA ALLPASS
|
||
x = 2.3 ^ 4.5 -- old syntax: math.exp(2.3, 4.5)
|
||
_pc("db " .. math.floor(x))
|
||
_pc("db " .. 35//7) -- old syntax: 35/7
|
||
-- floating point values are now formatted rigorously with ".0" from the Lua
|
||
-- which leads to error in sjasmplus parser: Unexpected: .0
|
||
-- and requires to enforce integer type already at lua side
|
||
-- you can use either `math.floor()` function, or integer
|
||
-- operators like integer divide `//` or left shift `1<<7`
|
||
|
||
-- the floating point values (like "12.0") are silently truncated since v1.20.1 (to "12"),
|
||
-- but v1.20.0 errors out on these, unless you patch the lua script to produce integers
|
||
ENDLUA
|
||
</pre>
|
||
</div></div><p><br class="example-break">
|
||
</p>
|
||
|
||
<p></p>
|
||
|
||
<p></p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_savenex"></a>Chapter 8. SAVENEX guide</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_savenex_file_format"></a>NEX File Format</h2></div></div></div>
|
||
|
||
|
||
<p>NEX is binary format for ZX Spectrum Next, aiming to provide simple delivery of software
|
||
for the platform. For file format details check <a class="ulink" href="https://specnext.dev/wiki/NEX_file_format" target="_top">
|
||
https://specnext.dev/wiki/NEX_file_format</a>. In short it is header + loading screen +
|
||
like-snapshot binary and remaining resources appended after.</p>
|
||
|
||
<p>Sjasmplus currently supports V1.2 and V1.3 of NEX file format (see wiki for details).</p>
|
||
|
||
<p>As such, the SAVENEX commands are available only in ZXSPECTRUMNEXT device emulation mode,
|
||
see <a class="link" href="#po_device">DEVICE</a>.</p>
|
||
|
||
<p>As the file is designed for self-contained distribution of whole applications/games,
|
||
its configuration and assembling is a bit too complex for single directive, and the
|
||
configuration is instead divided into multiple commands, and the assembling goes
|
||
through multiple stages, so some commands must be used in correct sequence.</p>
|
||
|
||
<p>While the format technically allows to include multiple screen types data, they are all
|
||
loaded at the beginning over each other, so it makes sense to provide only single loading
|
||
screen (sjasmplus enforces that).</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_savenex_commands"></a>Detailed description of each SAVENEX command</h2></div></div></div>
|
||
|
||
<div class="variablelist"><dl class="variablelist"><dt><span class="term"><a name="nex_open"></a>
|
||
SAVENEX OPEN <filename>[,<startAddress>[,<stackAddress>[,<entryBank16k 0..111>[,<fileVersion 2..3>]]]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Opens a NEX file, defines start address, stack address and 16k bank to be mapped
|
||
at 0xC000 before code is executed (if values are omitted, start address is zero
|
||
= no start, stack address is 0xFFFE, entryBank is zero, fileVersion is 2).
|
||
</p>
|
||
<p>
|
||
Only single NEX file can be open at the same time, and to finalize the header
|
||
content the command CLOSE has to be used (does auto-close if source ends).
|
||
</p>
|
||
<p>
|
||
Entry bank is number of 16k bank (0..111), not native 8k page, default is zero,
|
||
i.e. the default memory map is identical to ZX 128 (ROM, RAM banks 5, 2 and 0).
|
||
</p>
|
||
<p>
|
||
Make sure your new stack has at least tens of bytes available as those will be
|
||
used already by the NEX loader before executing your entry point (although
|
||
released back).
|
||
</p>
|
||
<p>
|
||
The fileVersion can be 2 (NEX V1.2) or 3 (NEX V1.3), which will enforce the
|
||
specified version of file. Otherwise the file is V1.2 by default and will
|
||
auto-switch to V1.3 when some V1.3 feature is configured/used. When version 2
|
||
is enforced, any usage of V1.3 feature will emit error.
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_core"></a>
|
||
SAVENEX CORE <major 0..15>,<minor 0..15>,<subminor 0..255>
|
||
</span></dt><dd>
|
||
<p>
|
||
Set minimum required Next core version, can be set any time before <a class="link" href="#nex_close">CLOSE</a>.
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_cfg"></a>
|
||
SAVENEX CFG <border 0..7>[,<fileHandle 0/1/$4000+>[,<PreserveNextRegs 0/1>[,<2MbRamReq 0/1>]]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Set border colour (during loading), whether the machine should be set to default
|
||
state (PreserveNextRegs = 0 = default), if the app requires extended RAM
|
||
(224 8k pages) and how the file handle of the NEX file should be treated:
|
||
0 = default = close, 1 = keep open and pass in BC, $4000..$FFFE = keep open,
|
||
and write into memory at provided address (after entry bank is paged in). This
|
||
can be set any time before <a class="link" href="#nex_close">CLOSE</a>.
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_cfg3"></a>
|
||
SAVENEX CFG3 <DoCRC 0/1>[,<PreserveExpansionBus 0/1>[,<CLIbufferAdr>,<CLIbufferSize>]]
|
||
</span></dt><dd>
|
||
<p>
|
||
All of these are NEX format V1.3 features and using "CFG3" command will change
|
||
the version to V1.3 automatically (if not specified by <a class="link" href="#nex_open">OPEN</a>).
|
||
</p>
|
||
<p>
|
||
DoCRC: default = 1, sjasmplus will checksum the file (if you know you will be
|
||
further patching file afterwards, switch it off, otherwise keep 1).
|
||
</p>
|
||
<p>
|
||
PreserveExpansionBus: default = 0, 0 = the NEX loader will disable expansion
|
||
bus through NextReg $80 / 1 = the NEX loader will not do anything.
|
||
</p>
|
||
<p>
|
||
CLIbufferAdr, CLIbufferSize: default = [0, 0], address and size of buffer for
|
||
NEX loader to copy the arguments line into. The buffer is copied after the
|
||
"entryBank" is mapped, so you can allocate buffer in your entryBank. The
|
||
loader/format has hard limit 2048 bytes, the argument line will be truncated
|
||
if longer. If your reserved buffer is shorter than 2048 bytes, the copy will
|
||
be also truncated to your buffer size only. If not truncated, the argument line
|
||
can end with any of these: Enter (13), colon or zero byte (truncated has no
|
||
terminator character, just fills the full buffer).
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_bar"></a>
|
||
SAVENEX BAR <loadBar 0/1>,<barColour 0..255>[,<startDelay 0..255>[,<bankDelay 0..255>[,<posY 0..255>]]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Loading-bar related setup ("colour" usage depends on screen mode), can be set
|
||
any time before <a class="link" href="#nex_close">CLOSE</a>.
|
||
</p>
|
||
<p>
|
||
The posY argument will apply only to V1.3 Layer2 screens in 320x256 and
|
||
640x256 resolution (then defaults to 254 = bottom of screen, 2px tall bar).
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_palette"></a>
|
||
<p>SAVENEX PALETTE NONE</p>
|
||
<p>SAVENEX PALETTE DEFAULT</p>
|
||
<p>SAVENEX PALETTE MEM <palPage8kNum 0..223>,<palOffset></p>
|
||
<p>SAVENEX PALETTE BMP <filename></p>
|
||
</span></dt><dd>
|
||
<p>
|
||
This is optional command to set palette in alternative way ahead of SCREEN
|
||
command, with higher priority (if the PALETTE command is used, following
|
||
SCREEN commands will ignore the palette arguments and keep the palette defined
|
||
by this command). You can be use it between <a class="link" href="#nex_open">OPEN</a>
|
||
and <a class="link" href="#nex_auto">SCREEN</a> command. But appropriate SCREEN
|
||
type supporting palette must be defined by SCREEN command too.
|
||
</p>
|
||
<p>
|
||
Palette consists of 512 bytes (256 palette items from index 0), in 9b colour
|
||
format: first byte is %RRRGGGBB, second byte is %P000000B (P is priority flag
|
||
for Layer 2 colours).
|
||
</p>
|
||
<p>
|
||
The DEFAULT palette will generate colour values from the colour index, the same
|
||
way how default Layer 2 palette is initialized on the ZX Spectrum Next.
|
||
</p>
|
||
<p>
|
||
The NONE palette will force the "no palette" flag even if SCREEN command later
|
||
does specify some palette (it will be still ignored).
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_screen"></a>
|
||
SAVENEX SCREEN L2 [<Page8kNum 0..223>,<offset>[,<palPage8kNum 0..223>,<palOffset>]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Layer 2 loading screen, can be used between <a class="link" href="#nex_open">OPEN</a>
|
||
and first <a class="link" href="#nex_auto">AUTO</a>/<a class="link" href="#nex_bank">BANK</a> command.
|
||
</p>
|
||
<p>
|
||
Palette consists of 512 bytes (256 palette items from index 0), in 9b colour
|
||
format: first byte is %RRRGGGBB, second byte is %P000000B (P is priority flag
|
||
for Layer 2 colours).
|
||
</p>
|
||
<p>
|
||
Image data are 48kiB block of memory, the loader will use always banks 9..11 to display
|
||
it (8k pages 18..23), but if you will prepare the data there, it will be also re-saved
|
||
by <a class="link" href="#nex_auto">AUTO</a> command, so either use other banks, and overwrite
|
||
them with valid data/code after using the SCREEN command, or reset pages 18..23 to zero
|
||
after SCREEN.
|
||
</p>
|
||
<p>
|
||
If no memory address is specified, the pages 18..23 are stored in file, and if
|
||
no palette address is specified, no-palette flag is set in NEX file.
|
||
</p>
|
||
</dd><dt><span class="term">
|
||
<p>SAVENEX SCREEN L2_320 [<Page8kNum 0..223>,<offset>[,<palPage8kNum 0..223>,<palOffset>]]</p>
|
||
<p>SAVENEX SCREEN L2_640 [<Page8kNum 0..223>,<offset>[,<palPage8kNum 0..223>,<palOffset>]]</p>
|
||
</span></dt><dd>
|
||
<p>
|
||
Works same way as "L2" variant, but will set up screen for new resolutions 320x256x8
|
||
and 640x256x4. The difference is that the required image data are 80kiB (five 16kiB
|
||
banks; equals ten 8kiB pages), the banks used to show the screen in loader are
|
||
9..13 (8k pages 18..27 - that's also the default address of data if not specified)
|
||
- avoid these in regular banks stored in the file.
|
||
</p>
|
||
<p>
|
||
These are NEX format V1.3 features and using them will change the version to V1.3
|
||
automatically (if not specified by <a class="link" href="#nex_open">OPEN</a>). This
|
||
command doesn't allow to set specific palette offset value (too lazy to add it,
|
||
use BMP variant if you really need it).
|
||
</p>
|
||
<p>
|
||
The data has to be already in correct format and organized as if displayed (the
|
||
"transposed" bitmap where +1 address goes to pixel below, and +256 goes to pixel
|
||
on the right (or pair of pixels in case of 640x256x4bpp mode), this command will
|
||
just dump them into file "as is".
|
||
</p>
|
||
<p>
|
||
The loading bar colour byte will be also used "as is", which in 4bpp mode means
|
||
the byte does define pair of 4 bit pixels, i.e. if you want solid-colour "3"
|
||
loading bar in 4bpp mode, define it as value $33. Keep also in mind the default
|
||
loading bar position is Y=254, which on most of the TV/LCD displays is outside
|
||
of visible range, the reasonably "safe" (visible on almost all of the screens)
|
||
resolution is about 288x224 (+16px around PAPER area, +24px is visible on many
|
||
displays too), you may want to organize your screen in a way to show all important
|
||
information within this area, and make the rest "unimportant" so it can hide
|
||
beyond the edge of screen.
|
||
</p>
|
||
</dd><dt><span class="term">
|
||
SAVENEX SCREEN LR [<Page8kNum 0..223>,<offset>[,<palPage8kNum 0..223>,<palOffset>]]
|
||
</span></dt><dd>
|
||
<p>
|
||
LoRes (128x96) loading screen, can be used between <a class="link" href="#nex_open">OPEN</a>
|
||
and first <a class="link" href="#nex_auto">AUTO</a>/<a class="link" href="#nex_bank">BANK</a> command.
|
||
</p>
|
||
<p>
|
||
Palette is similar to Layer 2 mode, just LoRes mode doesn't have priority bit.
|
||
</p>
|
||
<p>
|
||
Image data are 12288 bytes memory block - either consecutive block if specific
|
||
address is provided, or without address the actual bank 5 memory is stored
|
||
(taking 6144 bytes from address 0x4000 and 6144 bytes from address 0x6000).
|
||
</p>
|
||
</dd><dt><span class="term">
|
||
SAVENEX SCREEN BMP <filename>[,<savePalette 0/1>[,<paletteOffset 0..15>]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Only small subset of BMP files can be used: 256x192 (Layer 2) or 128x96 (LoRes),
|
||
indexed (8bit image data with palette) and palette data will be truncated
|
||
to 3:3:3 color space directly (no smart colour quantization or dithering is applied).
|
||
And the file must be uncompressed.
|
||
</p>
|
||
<p>
|
||
For V1.3 NEX files you can include also 320x256 and 640x256 files (Layer 2), the
|
||
640x256 should be also 8bit indexed, but only 4 bits of pixel data will be used
|
||
(256 colour palette is legitimate and will be stored "as is" in NEX file).
|
||
These two new modes can also include paletteOffset argument 0..15 (does not apply
|
||
to V1.2 BMP files above), the offset is added to top four bits of pixel value.
|
||
</p>
|
||
<p>
|
||
The BMP will be included as loading screen, can be used between <a class="link" href="#nex_open">OPEN</a>
|
||
and first <a class="link" href="#nex_auto">AUTO</a>/<a class="link" href="#nex_bank">BANK</a> command.
|
||
</p>
|
||
<p>
|
||
By default the palette from BMP file is used, but you can override that by savePalette = 0.
|
||
</p>
|
||
</dd><dt><span class="term">
|
||
SAVENEX SCREEN (SCR|SHC|SHR) [<hiResColour 0..7>]
|
||
</span></dt><dd>
|
||
<p>
|
||
ULA/Timex modes loading screen, can be used between <a class="link" href="#nex_open">OPEN</a>
|
||
and first <a class="link" href="#nex_auto">AUTO</a>/<a class="link" href="#nex_bank">BANK</a> command.
|
||
</p>
|
||
<p>
|
||
The actual bank 5 memory (pages 10..11) is stored as if the image is displayed,
|
||
in these modes the palette can't be specified.
|
||
</p>
|
||
<p>
|
||
SCR is classic ZX 6912 bytes long screen from address 0x4000 (page 10 is used,
|
||
even if the slot 1 is modified to other page, so you must prepare the image "in place").
|
||
</p>
|
||
<p>
|
||
SHC and SHR are Timex HiColor (8x1 attribute) and HiRes (512x192 bitmap) modes,
|
||
prepare data "in place", i.e. 6144 bytes into page 10 and 6144 bytes into page
|
||
11 (0x4000 and 0x6000 addresses in default memory setup). For HiRes mode you
|
||
should specify ink colour (the paper is complement of ink).
|
||
</p>
|
||
</dd><dt><span class="term">
|
||
SAVENEX SCREEN TILE <NextReg $6B>,<NextReg $6C>,<NextReg $6E>,<NextReg $6F>[,<AlsoStoreBank5 0/1 = 1>]
|
||
</span></dt><dd>
|
||
<p>
|
||
NEX V1.3 tilemap loading screen, can be used between <a class="link" href="#nex_open">OPEN</a>
|
||
and first <a class="link" href="#nex_auto">AUTO</a>/<a class="link" href="#nex_bank">BANK</a> command.
|
||
</p>
|
||
<p>
|
||
To define palette use the <a class="link" href="#nex_palette">PALETTE</a> command.
|
||
</p>
|
||
<p>
|
||
The image data are stored as regular Bank 5 of the NEX file (which is the first bank
|
||
to be loaded by loader), depending on AlsoStoreBank5 value (default 1), this SCREEN
|
||
command will also execute <a class="link" href="#nex_bank">BANK 5</a> command to store
|
||
the image data.
|
||
</p>
|
||
<p>
|
||
The NextRegisters $6B, $6C, $6E and $6F should be enough to specify any variant
|
||
of tilemap mode, so the precise sub-type and image data layout is under control
|
||
of user, the sjasmplus doesn't enforce any particular configuration.
|
||
</p>
|
||
<p>
|
||
If you want to use also <a class="link" href="#nex_copper">COPPER</a> command, use it
|
||
either ahead of the SCREEN TILE command, or use "AlsoStoreBank5 = 0" to delay the
|
||
storage of Bank 5 data. In such case you must then later explicitly store
|
||
the Bank 5 as regular bank, either with BANK or AUTO command.
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_copper"></a>
|
||
SAVENEX COPPER <Page8kNum 0..223>,<offset>
|
||
</span></dt><dd>
|
||
<p>
|
||
Can be used after <a class="link" href="#nex_open">OPEN</a> and before first <a class="link" href="#nex_auto">AUTO</a> or <a class="link" href="#nex_bank">BANK</a>
|
||
command (the copper data are stored between screen and bank data).
|
||
</p>
|
||
<p>
|
||
Exactly 2048 bytes are stored (full Copper memory), and the loader will start
|
||
the copper code in mode %01 (reset CPC to 0, then starts the copper), so the
|
||
copper code will wrap around infinitely after the 1024th instruction executed.
|
||
The copper is started after the screen block is loaded and displayed.
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_bank"></a>
|
||
SAVENEX BANK <bank16k 0..111>[,...]
|
||
</span></dt><dd>
|
||
<p>
|
||
Can be used after <a class="link" href="#nex_open">OPEN</a> or <a class="link" href="#nex_screen">
|
||
SCREEN</a> and before <a class="link" href="#nex_close">CLOSE</a>, but the 16ki
|
||
banks must be saved in correct order: 5, 2, 0, 1, 3, 4, 6, 7, 8, 9, 10, ..., 111
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_auto"></a>
|
||
SAVENEX AUTO [<fromBank16k 0..111>[,<toBank16k 0..111>]]
|
||
</span></dt><dd>
|
||
<p>
|
||
Can be used after <a class="link" href="#nex_open">OPEN</a> or <a class="link" href="#nex_screen">
|
||
SCREEN</a> and before <a class="link" href="#nex_close">CLOSE</a>. The sjasmplus
|
||
will save every 16k bank containing at least one non-zero byte; detected in the correct order (automatically
|
||
will save every non-zero 16k bank detected in the correct order (automatically
|
||
starting from first possible bank after previous BANK/AUTO commands, or from
|
||
provided "fromBank").
|
||
</p>
|
||
<p>
|
||
For "fromBank" value use the specified order above in <a class="link" href="#nex_bank">BANK
|
||
</a> command, i.e. 5, 2, 0, ...
|
||
</p>
|
||
</dd><dt><span class="term"><a name="nex_close"></a>
|
||
SAVENEX CLOSE [<fileToAppend>]
|
||
</span></dt><dd>
|
||
<p>
|
||
Can be used after <a class="link" href="#nex_open">OPEN</a>. The currently open NEX
|
||
file will be finalized (header adjusted), and optional extra file just appended
|
||
to the end of NEX file.
|
||
</p>
|
||
</dd></dl></div>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_savenex_examples"></a>Examples</h2></div></div></div>
|
||
|
||
|
||
<div class="example"><a name="idp2548"></a><p class="title"><b>Example 8.1. docs_examples/s_savenex_examples.asm</b></p><div class="example-contents">
|
||
|
||
<p>
|
||
Creating NEX file which will have Layer2 loading screen (stripes), progress bar, and will
|
||
enter infinite loop with calling stack (used by IM 1 interrupt handler) visible on the
|
||
Layer 2 screen.
|
||
</p>
|
||
<pre class="programlisting"> DEVICE ZXSPECTRUMNEXT
|
||
ORG $7E00
|
||
start: ei : jr $ ; app code entry point, BC = NEX file handle
|
||
; Layer2 screen (top 1/3 defined, bottom of it will be used also as "visible" stack)
|
||
ORG $C000 : DUP 64*32 : DB $90,$91,$92,$93,$94,$95,$96,$97 : EDUP
|
||
|
||
; write everything into NEX file
|
||
SAVENEX OPEN "example.nex", start, $FFFE, 9 ; stack will go into Layer2
|
||
SAVENEX CORE 2, 0, 0 ; Next core 2.0.0 required as minimum
|
||
SAVENEX CFG 4, 1, 0, 1 ; green border, file handle in BC, reset NextRegs, 2MB required
|
||
SAVENEX BAR 1, $E0, 50, 25 ; do load bar, red colour, start/load delays 50/25 frames
|
||
SAVENEX SCREEN L2 0, 0 ; store the data from C000 (page 0, offset 0), no palette
|
||
SAVENEX BANK 5, 100, 101 ; store the 16ki banks 5 (contains the code at 0x7E00), 100, 101
|
||
SAVENEX CLOSE ; (banks 100 and 101 are added just as example)
|
||
</pre>
|
||
</div></div><br class="example-break">
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="chapter"><div class="titlepage"><div><div><h1 class="title"><a name="c_sld_data"></a>Chapter 9. Source Level Debugging (SLD) data</h1></div></div></div>
|
||
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_sld_intro"></a>What is it?</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
SLD data are extra "tracing" data produced during assembling for debuggers and IDEs,
|
||
similar to "map" files already supported by sjasmplus (<a class="link" href="#po_labelslist">
|
||
LABELSLIST</a> and <a class="link" href="#po_cspectmap">CSPECTMAP</a>).
|
||
</p>
|
||
|
||
<p>
|
||
The debugger can read these data, and with non-tricky source producing machine code
|
||
with correct device memory mapping, the debugger can trace the origins of every
|
||
instruction back to the original source code line, and display the source instead/along
|
||
the disassembly view (the "map" files mentioned above provide only list of labels
|
||
which is usually already super helpful, but can't track the source origins of each
|
||
instruction).
|
||
</p>
|
||
|
||
<p>
|
||
The original impulse and working patch for this feature came from Chris Kirby, adding the
|
||
single-instruction-step feature to his development tools: <a class="ulink" href="https://github.com/Ckirby101/NDS-NextDevSystem" target="_top">
|
||
Next Development System</a> (currently in 2019 under heavy development).
|
||
</p>
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_sld_cli"></a>Usage</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
On the sjasmplus side all you need is to add another command line option when starting
|
||
the assembler.
|
||
</p><pre class="synopsis">prompt$ sjasmplus --sld=project.sld.txt file1.asm file2.asm</pre><p>
|
||
This will produce along regular files also file `project.sld.txt` containing the
|
||
tracing data. The file format is text-like, so the content can be viewed
|
||
in any text editor, but it's supposed to be processed by the debugger.
|
||
</p>
|
||
|
||
<p>
|
||
The SLD data are being exported <span class="strong"><strong>only</strong></span> for machine code produced
|
||
within one of the virtual devices (see <a class="link" href="#s_realdevice" title="Real device emulation mode">DEVICE</a>).
|
||
And the accuracy of the data directly depends on the state of the virtual device at
|
||
the moment when the particular instruction is assembled, see next section for further
|
||
advice how to get best tracing data.
|
||
</p>
|
||
|
||
<p>
|
||
If the option `--sld` without explicit filename is used, the first input source filename
|
||
will be copied and its extension changed to `.sld.txt`, which should work well for
|
||
single-main file type of projects.
|
||
</p>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_sld_source_advice"></a>How to write "non tricky" source</h2></div></div></div>
|
||
|
||
|
||
<p>
|
||
For best results (tracing data covering all your instructions and making source-level
|
||
debugging available all the time):
|
||
</p>
|
||
|
||
<p>
|
||
Generate machine code only with instructions, i.e. while `db 0` in source will produce
|
||
`nop` instruction, the tracing data for such `nop` will be missing. Only source line
|
||
containing the "nop" will emit both the zero byte into machine code and tracing data.
|
||
</p>
|
||
|
||
<p>
|
||
Keep the memory map of the virtual device as it will be set at run-time when writing
|
||
particular code. While using only regular <a class="link" href="#po_org">ORG</a> to place
|
||
the code in desired memory area, keeping only the modified area with memory pages
|
||
mapped-in is enough to get correct SLD data - but when using <a class="link" href="#po_disp">DISP</a>
|
||
directive to generate code in displaced way, you need to map-in correct pages in both
|
||
memory areas (where the code is currently assembled, and where it is supposed to be
|
||
operational at run-time - currently impossible if the two areas share the same SLOT area).
|
||
</p>
|
||
|
||
<p>
|
||
To map-in correct pages you can use directives:
|
||
<a class="link" href="#po_slot">SLOT</a>, <a class="link" href="#po_page">PAGE</a>,
|
||
<a class="link" href="#po_mmu">MMU</a> and <a class="link" href="#po_org">ORG</a>
|
||
</p>
|
||
|
||
<p>
|
||
Only labels defined in regular way get also the memory-page data in SLD file, EQU
|
||
values are exported without the page information, even if they represent memory
|
||
address:
|
||
</p><pre class="programlisting">
|
||
regularLabel: nop ; current page exported to SLD data
|
||
equLabel EQU $8000 ; only value without page is exported
|
||
varSymbol = 14 ; =/DEFL labels are omitted completely</pre><p>
|
||
</p>
|
||
|
||
<p>
|
||
Re-using the same memory area (page + address) for two different pieces of code (for
|
||
example by having multiple routines targeting the same address with DISP, and run-time
|
||
code uploading the correct variant dynamically at the destination) will highly likely
|
||
confuse the debugger, producing two source-origins data for the identical address.
|
||
You may want to avoid this, especially with early version of tools not being able to
|
||
resolve such ambiguity in reasonable way (the sjasmplus will generate tracing data ok
|
||
even in this case, but they are tricky to interpret).
|
||
</p>
|
||
|
||
<p>
|
||
If you are using the colons to put multiple instructions on single line, verify the
|
||
debugger can cope with the tracing data containing full line + column begin/end
|
||
information, the simple/early tools will likely highlight only whole line of source.
|
||
For a start keeping single instruction per line may keep things simple.
|
||
</p>
|
||
|
||
<p>
|
||
The various code generators written in macros or Lua scripts will produce accurate
|
||
tracing data in case of macros, and condensed (pointing at "ENDLUA" line) data for
|
||
Lua generators, but it still depends on the debugger if it can display both top
|
||
level source code triggering the generator and source lines containing definitions
|
||
of particular instructions.
|
||
</p>
|
||
|
||
</div>
|
||
|
||
<div class="section"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="s_sld_file_format"></a>SLD File Format definition (version "1")</h2></div></div></div>
|
||
|
||
|
||
<p><span class="emphasis"><em>The file format is still under development. If you are working on support in debugger, stay
|
||
in touch with us, so we can discuss any modifications to current format with you.</em></span>
|
||
</p>
|
||
|
||
<p>The SLD data is text-file (sjasmplus is using UNIX-like newlines 0x0A, but parsers
|
||
should rather cope with any of common EOL scheme). The general format is CSV-like
|
||
using pipe character as delimiter between fields.
|
||
</p>
|
||
|
||
<p>
|
||
If the first field is empty, the line is one of the special control lines - the second
|
||
field selects type of control line. If also the second field is empty, the remaining
|
||
part of line should be ignored (comment line).
|
||
Currently only one type of "control line" exists, the "SLD.data.version" (third
|
||
field is integer number):
|
||
</p><pre class="programlisting">|SLD.data.version|1
|
||
||anything ... comment-like line</pre><p>
|
||
The file format version line should be always first line of the SLD data file.
|
||
</p>
|
||
|
||
<p>
|
||
The regular tracing data lines have fixed amount of fields: eight. The seventh field
|
||
contains single uppercase letter defining type of the line, which affects sub-variants
|
||
of format for eighth field, but first six fields share the same formatting and meaning
|
||
across all types of regular lines:
|
||
</p><pre class="programlisting">
|
||
<source file>|<src line>|<definition file>|<def line>|<page>|<value>|<type>|<data>
|
||
</pre><p>
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><source file></code> - file name of top-level source emitting the
|
||
instruction/label/device.
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><src line></code> - line and characters in top-level source file, the precise
|
||
format is "<code class="code"><line>[:<column begin>[:<column end>]]</code>" where
|
||
first number is line number (starting at 1). The two following numbers delimited by colon
|
||
are optional, representing the column where the segment starts/ends at the line. The
|
||
column values are starting from 1 too, the "end" column is pointing beyond the current
|
||
segment. The columns are in "bytes", i.e. tabulator does increase the column value by +1
|
||
only, and the "end" may actually point well beyond "strlen(line)".
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><definition file></code> - file name of the source defining the particular
|
||
instruction (for example where the instruction inside MACRO was originally defined).
|
||
If empty, the definition-file name is identical to <code class="code"><source file></code>
|
||
(common case for single-source projects).
|
||
</p>
|
||
|
||
|
||
<p>
|
||
<code class="code"><def line></code> - zero when there is no extra "definition" of instruction
|
||
involved. When non-zero, the format is identical to <code class="code"><src line></code>, but
|
||
with regard to the file specified in <code class="code"><definition file></code> field.
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><page></code> - number of memory page where the <code class="code"><value></code>
|
||
address points to, or -1 when value is not memory address.
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><value></code> - any 32 bit integer value (EQU), but when representing memory
|
||
address, it is full 16 bit value from Z80 address space (the top bits beyond the memory
|
||
page size contains the number of "slot" where the instruction/label resides).
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><type></code> - single uppercase letter representing type of line, current
|
||
types: T (instruction Trace), L (Label), F [deprecated, parse L], D [deprecated, parse L], Z (device memory model),
|
||
K (keyword comment, see <a class="link" href="#po_sldopt">`SLDOPT COMMENT`</a>).
|
||
</p>
|
||
|
||
<p>
|
||
<code class="code"><data></code> - extra data specific for particular line type. Empty for
|
||
"T" lines. For "L" a list of items separated by comma, where first three items
|
||
represent sub-parts of symbol name: module name, main label, local label (sub-part
|
||
may be empty), optional remaining items are usage-traits giving away various internal info about
|
||
usage of symbol (currently exported traits: +equ, +macro, +reloc, +reloc_high, +used, +module, +endmod,
|
||
+struct_def, +struct_data).
|
||
For type "K" the comment containing one of they defined keywords is present.
|
||
</p>
|
||
|
||
<p>
|
||
For type "Z" the data field contains string describing the device memory model which
|
||
is being selected in source and should be applied for following SLD data lines. The
|
||
memory model string format is:
|
||
</p><pre class="programlisting">
|
||
pages.size:<page size>,pages.count:<page count>,slots.count:<slots count>[,slots.adr:<slot0 adr>,...,<slotLast adr>]
|
||
// unsigned <page size> is also any-slot size in current version.
|
||
// unsigned <page count> and <slots count> define how many pages/slots there are
|
||
// uint16_t <slotX adr> is starting address of slot memory region in Z80 16b addressing
|
||
</pre><p>
|
||
</p>
|
||
|
||
<div class="example"><a name="idp2620"></a><p class="title"><b>Example 9.1. Example of SLD file</b></p><div class="example-contents">
|
||
|
||
|
||
<pre class="programlisting">
|
||
|SLD.data.version|1
|
||
|| ZX Spectrum Next device description:
|
||
toplevel.asm|59||0|-1|-1|Z|pages.size:8192,pages.count:224,slots.count:8,slots.adr:0,8192,16384,24576,32768,40960,49152,57344
|
||
|| label "main" points to 32768, with page 14 mapped-in (defined in toplevel.asm:62)
|
||
|| the label "main" is used by other code (IFUSED-like), and has relocation data
|
||
toplevel.asm|62||0|14|32768|L|,main,,+reloc,+used
|
||
|| instruction opcode at 32768 (page 14) was created by toplevel.asm:64
|
||
toplevel.asm|64||0|14|32768|T|
|
||
|| instruction opcode at 32769 (p 14) was created by toplevel.asm:67
|
||
|| (but it is a line using macro, the instruction was defined by toplevel.asm:52)
|
||
toplevel.asm|67||52|14|32769|T|
|
||
|| instruction opcode at 32770 (p 18) was created by toplevel.asm:68:12-24
|
||
toplevel.asm|68:12:24||0|18|32770|T|
|
||
|| instruction opcode at 32771 (p 18) was created by toplevel.asm:68:24 (till EOL)
|
||
toplevel.asm|68:24||0|18|32771|T|
|
||
|| "PORT_NUMBER EQU 254" defined at toplevel.asm:69
|
||
toplevel.asm|69||0|-1|254|L|,PORT_NUMBER,,+equ
|
||
|| label+instruction emitted from toplevel.asm:70, but defined in include.asm:3
|
||
|| with macro label "0>macro_defined_in_include_asm" (source ".macro_defined_in_include_asm:")
|
||
toplevel.asm|70|include.asm|3|37|40976|L|,0,macro_defined_in_include_asm,+macro,+used
|
||
toplevel.asm|70|include.asm|3|37|40976|T|
|
||
</pre>
|
||
|
||
</div></div><br class="example-break">
|
||
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="index"><div class="titlepage"><div><div><h1 class="title"><a name="index"></a>Index</h1></div></div></div><div xmlns:xlink="http://www.w3.org/1999/xlink" class="index"><div class="indexdiv"><h3>Symbols</h3><dl><dt id="ientry-idp386">!, <a class="indexterm" href="#op_log_not">Expressions</a></dt><dt id="ientry-idp436">!=, <a class="indexterm" href="#op_neq">Expressions</a></dt><dt id="ientry-idp454">$, <a class="indexterm" href="#op_dollar">Expressions</a></dt><dt id="ientry-idp456">$$, <a class="indexterm" href="#op_dollar2">Expressions</a></dt><dt id="ientry-idp458">$$$, <a class="indexterm" href="#op_dollar3">Expressions</a></dt><dt id="ientry-idp460">$$$$, <a class="indexterm" href="#op_dollar4">Expressions</a></dt><dt id="ientry-idp462">$$label, <a class="indexterm" href="#op_label_page">Expressions</a></dt><dt id="ientry-idp402">%, <a class="indexterm" href="#op_mod">Expressions</a></dt><dt id="ientry-idp438">&, <a class="indexterm" href="#op_bit_and">Expressions</a></dt><dt id="ientry-idp450">&&, <a class="indexterm" href="#op_logic_and">Expressions</a></dt><dt id="ientry-idp398">*, <a class="indexterm" href="#op_mul">Expressions</a></dt><dt id="ientry-idp406">+, <a class="indexterm" href="#op_add">Expressions</a></dt><dt id="ientry-idp408">-, <a class="indexterm" href="#op_sub">Expressions</a></dt><dt id="ientry-idp763">.<repeat-count>, <a class="indexterm" href="#po_dot_repeat">Pseudo-ops</a></dt><dt id="ientry-idp400">/, <a class="indexterm" href="#op_div">Expressions</a></dt><dt id="ientry-idp424"><, <a class="indexterm" href="#op_lt">Expressions</a></dt><dt id="ientry-idp410"><<, <a class="indexterm" href="#op_sla">Expressions</a></dt><dt id="ientry-idp428"><=, <a class="indexterm" href="#op_lte">Expressions</a></dt><dt id="ientry-idp420"><?, <a class="indexterm" href="#op_min">Expressions</a></dt><dt id="ientry-idp432">=, <a class="indexterm" href="#op_eq">Expressions</a></dt><dt id="ientry-idp434">==, <a class="indexterm" href="#op_eq2">Expressions</a></dt><dt id="ientry-idp426">>, <a class="indexterm" href="#op_gt">Expressions</a></dt><dt id="ientry-idp430">>=, <a class="indexterm" href="#op_gte">Expressions</a></dt><dt id="ientry-idp412">>>, <a class="indexterm" href="#op_sra">Expressions</a></dt><dt id="ientry-idp414">>>>, <a class="indexterm" href="#op_srl">Expressions</a></dt><dt id="ientry-idp422">>?, <a class="indexterm" href="#op_max">Expressions</a></dt><dt id="ientry-idp442">^, <a class="indexterm" href="#op_bit_xor">Expressions</a></dt><dt id="ientry-idp2163">_c(..), <a class="indexterm" href="#lua__c">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2170">_pc(..), <a class="indexterm" href="#lua__pc">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2177">_pl(..), <a class="indexterm" href="#lua__pl">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp687">__BASE_FILE__, <a class="indexterm" href="#def__base_file__">Predefined defines</a></dt><dt id="ientry-idp707">__COUNTER__, <a class="indexterm" href="#def__counter__">Predefined defines</a></dt><dt id="ientry-idp663">__DATE__, <a class="indexterm" href="#def__date__">Predefined defines</a></dt><dt id="ientry-idp651">__ERRORS__, <a class="indexterm" href="#def__errrors__">Predefined defines</a></dt><dt id="ientry-idp694">__FILE__, <a class="indexterm" href="#def__file__">Predefined defines</a></dt><dt id="ientry-idp681">__INCLUDE_LEVEL__, <a class="indexterm" href="#def__include_level__">Predefined defines</a></dt><dt id="ientry-idp701">__LINE__, <a class="indexterm" href="#def__line__">Predefined defines</a></dt><dt id="ientry-idp675">__PASS__, <a class="indexterm" href="#def__pass__">Predefined defines</a></dt><dt id="ientry-idp638">__SJASMPLUS__, <a class="indexterm" href="#def__sjasmplus__">Predefined defines</a></dt><dt id="ientry-idp669">__TIME__, <a class="indexterm" href="#def__time__">Predefined defines</a></dt><dt id="ientry-idp644">__VERSION__, <a class="indexterm" href="#def__version__">Predefined defines</a></dt><dt id="ientry-idp657">__WARNINGS__, <a class="indexterm" href="#def__warnings__">Predefined defines</a></dt><dt id="ientry-idp464">{..}, <a class="indexterm" href="#op_read_word">Expressions</a></dt><dt id="ientry-idp466">{b ..}, <a class="indexterm" href="#op_read_byte">Expressions</a></dt><dt id="ientry-idp446">|, <a class="indexterm" href="#op_bit_or">Expressions</a></dt><dt id="ientry-idp452">||, <a class="indexterm" href="#op_logic_or">Expressions</a></dt><dt id="ientry-idp388">~, <a class="indexterm" href="#op_cpl">Expressions</a></dt></dl></div><div class="indexdiv"><h3>A</h3><dl><dt id="ientry-idp396">abs, <a class="indexterm" href="#op_abs">Expressions</a></dt><dt id="ientry-idp773">ABYTE, <a class="indexterm" href="#po_abyte">Pseudo-ops</a></dt><dt id="ientry-idp783">ABYTEC, <a class="indexterm" href="#po_abytec">Pseudo-ops</a></dt><dt id="ientry-idp793">ABYTEZ, <a class="indexterm" href="#po_abytez">Pseudo-ops</a></dt><dt id="ientry-idp803">ALIGN, <a class="indexterm" href="#po_align">Pseudo-ops</a>, <a class="indexterm" href="#st_align">STRUCT instructions</a></dt><dt id="ientry-idp620">AMSTRADCPC464, <a class="indexterm" href="#device_cpc464">Real device emulation mode</a></dt><dt id="ientry-idp626">AMSTRADCPC6128, <a class="indexterm" href="#device_cpc6128">Real device emulation mode</a></dt><dt id="ientry-idp440">and, <a class="indexterm" href="#op_bit_and2">Expressions</a></dt><dt id="ientry-idp814">ASSERT, <a class="indexterm" href="#po_assert">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>B</h3><dl><dt id="ientry-idp824">BINARY (see <a href="#ientry-idp1294">INCBIN</a>)</dt><dt id="ientry-idp832">BLOCK, <a class="indexterm" href="#po_block">Pseudo-ops</a>, <a class="indexterm" href="#st_block">STRUCT instructions</a></dt><dt id="ientry-idp842">BPLIST, <a class="indexterm" href="#po_bplist">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1745">SETBP</a>)</dt></dl></dd><dt id="ientry-idp859">BYTE, <a class="indexterm" href="#po_byte">Pseudo-ops</a>, <a class="indexterm" href="#st_byte">STRUCT instructions</a></dt></dl></div><div class="indexdiv"><h3>C</h3><dl><dt id="ientry-idp1885">Conditional assembly, <a class="indexterm" href="#s_conditional_assembly2">Conditional assembly</a></dt><dt id="ientry-idp869">CSPECTMAP, <a class="indexterm" href="#po_cspectmap">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>D</h3><dl><dt id="ientry-idp883">D24, <a class="indexterm" href="#po_d24">Pseudo-ops</a>, <a class="indexterm" href="#st_d24">STRUCT instructions</a></dt><dt id="ientry-idp893">DB (see <a href="#ientry-idp859">BYTE</a>)</dt><dt id="ientry-idp901">DC, <a class="indexterm" href="#po_dc">Pseudo-ops</a></dt><dt id="ientry-idp912">DD (see <a href="#ientry-idp1152">DWORD</a>)</dt><dt id="ientry-idp920">DEFARRAY, <a class="indexterm" href="#po_defarray">Pseudo-ops</a></dt><dt id="ientry-idp931">DEFARRAY+, <a class="indexterm" href="#po_defarray_plus">Pseudo-ops</a></dt><dt id="ientry-idp941">DEFB (see <a href="#ientry-idp859">BYTE</a>)</dt><dt id="ientry-idp949">DEFD (see <a href="#ientry-idp1152">DWORD</a>)</dt><dt id="ientry-idp957">DEFDEVICE, <a class="indexterm" href="#po_defdevice">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1049">DEVICE</a>)</dt></dl></dd><dt id="ientry-idp972">DEFG (see <a href="#ientry-idp1064">DG</a>)</dt><dt id="ientry-idp980">DEFH (see <a href="#ientry-idp1075">DH</a>)</dt><dt id="ientry-idp992">DEFINE, <a class="indexterm" href="#po_define2">Pseudo-ops</a></dt><dt id="ientry-idp988">DEFINE+, <a class="indexterm" href="#po_define">Pseudo-ops</a></dt><dt id="ientry-idp1003">DEFL, <a class="indexterm" href="#po_defl">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1249">EQU</a>)</dt></dl></dd><dt id="ientry-idp1016">DEFM (see <a href="#ientry-idp859">BYTE</a>)</dt><dt id="ientry-idp1024">DEFS (see <a href="#ientry-idp832">BLOCK</a>)</dt><dt id="ientry-idp1032">DEFW (see <a href="#ientry-idp1877">WORD</a>)</dt><dt id="ientry-idp1040">DEPHASE (see <a href="#ientry-idp1241">ENT</a>)</dt><dd><dl><dt>(see also <a href="#ientry-idp1085">DISP</a>)</dt></dl></dd><dt id="ientry-idp1049">DEVICE, <a class="indexterm" href="#po_device">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp957">DEFDEVICE</a>)</dt><dt>(see also <a href="#ientry-idp1394">MMU</a>)</dt><dt>(see also <a href="#ientry-idp565">ZXSPECTRUM128</a>)</dt><dt>(see also <a href="#ientry-idp607">ZXSPECTRUMNEXT</a>)</dt></dl></dd><dt id="ientry-idp1064">DG, <a class="indexterm" href="#po_dg">Pseudo-ops</a></dt><dt id="ientry-idp1075">DH, <a class="indexterm" href="#po_dh">Pseudo-ops</a></dt><dt id="ientry-idp1085">DISP, <a class="indexterm" href="#po_disp">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1241">ENT</a>)</dt></dl></dd><dt id="ientry-idp1104">DISPLAY, <a class="indexterm" href="#po_display">Pseudo-ops</a></dt><dt id="ientry-idp1117">DM (see <a href="#ientry-idp859">BYTE</a>)</dt><dt id="ientry-idp1125">DS (see <a href="#ientry-idp832">BLOCK</a>)</dt><dt id="ientry-idp1133">DUP, <a class="indexterm" href="#po_dup">Pseudo-ops</a></dt><dt id="ientry-idp1144">DW (see <a href="#ientry-idp1877">WORD</a>)</dt><dt id="ientry-idp1152">DWORD, <a class="indexterm" href="#po_dword">Pseudo-ops</a>, <a class="indexterm" href="#st_dword">STRUCT instructions</a></dt><dt id="ientry-idp1162">DZ, <a class="indexterm" href="#po_dz">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>E</h3><dl><dt id="ientry-idp1959">ELSE, <a class="indexterm" href="#ca_else">Conditional assembly</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1893">IF</a>)</dt></dl></dd><dt id="ientry-idp1967">ELSEIF, <a class="indexterm" href="#ca_elseif">Conditional assembly</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1893">IF</a>)</dt></dl></dd><dt id="ientry-idp1173">EMPTYTAP, <a class="indexterm" href="#po_emptytap">Pseudo-ops</a></dt><dt id="ientry-idp1182">EMPTYTRD, <a class="indexterm" href="#po_emptytrd">Pseudo-ops</a></dt><dt id="ientry-idp1191">ENCODING, <a class="indexterm" href="#po_encoding">Pseudo-ops</a></dt><dt id="ientry-idp1203">END, <a class="indexterm" href="#po_end">Pseudo-ops</a></dt><dt id="ientry-idp1975">ENDIF, <a class="indexterm" href="#ca_endif">Conditional assembly</a></dt><dt id="ientry-idp1209">ENDLUA, <a class="indexterm" href="#po_endlua">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1376">LUA</a>)</dt></dl></dd><dt id="ientry-idp1217">ENDMOD (see <a href="#ientry-idp1225">ENDMODULE</a>)</dt><dt id="ientry-idp1225">ENDMODULE, <a class="indexterm" href="#po_endmodule">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1414">MODULE</a>)</dt></dl></dd><dt id="ientry-idp1233">ENDT (see <a href="#ientry-idp1241">ENT</a>)</dt><dt id="ientry-idp1241">ENT, <a class="indexterm" href="#po_ent">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1085">DISP</a>)</dt></dl></dd><dt id="ientry-idp1249">EQU, <a class="indexterm" href="#po_equ">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1003">DEFL</a>)</dt></dl></dd><dt id="ientry-idp384">exist, <a class="indexterm" href="#op_exist">Expressions</a></dt><dt id="ientry-idp1263">EXPORT, <a class="indexterm" href="#po_export">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>F</h3><dl><dt id="ientry-idp1273">FPOS, <a class="indexterm" href="#po_fpos">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>H</h3><dl><dt id="ientry-idp1286">HEX, <a class="indexterm" href="#po_hex">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1075">DH</a>)</dt></dl></dd><dt id="ientry-idp392">high, <a class="indexterm" href="#op_high">Expressions</a></dt></dl></div><div class="indexdiv"><h3>I</h3><dl><dt id="ientry-idp1893">IF, <a class="indexterm" href="#ca_if">Conditional assembly</a></dt><dt id="ientry-idp1910">IFDEF, <a class="indexterm" href="#ca_ifdef">Conditional assembly</a></dt><dt id="ientry-idp1904">IFN, <a class="indexterm" href="#ca_ifn">Conditional assembly</a></dt><dt id="ientry-idp1921">IFNDEF, <a class="indexterm" href="#ca_ifndef">Conditional assembly</a></dt><dt id="ientry-idp1952">IFNUSED, <a class="indexterm" href="#ca_ifnused">Conditional assembly</a></dt><dt id="ientry-idp1932">IFUSED, <a class="indexterm" href="#ca_ifused">Conditional assembly</a></dt><dt id="ientry-idp1294">INCBIN, <a class="indexterm" href="#po_incbin">Pseudo-ops</a></dt><dt id="ientry-idp1304">INCHOB, <a class="indexterm" href="#po_inchob">Pseudo-ops</a></dt><dt id="ientry-idp1314">INCLUDE, <a class="indexterm" href="#po_include">Pseudo-ops</a></dt><dt id="ientry-idp1328">INCLUDELUA, <a class="indexterm" href="#po_includelua">Pseudo-ops</a></dt><dt id="ientry-idp1338">INCTRD, <a class="indexterm" href="#po_inctrd">Pseudo-ops</a></dt><dt id="ientry-idp1348">INSERT (see <a href="#ientry-idp1294">INCBIN</a>)</dt></dl></div><div class="indexdiv"><h3>L</h3><dl><dt id="ientry-idp1356">LABELSLIST, <a class="indexterm" href="#po_labelslist">Pseudo-ops</a></dt><dt id="ientry-idp390">low, <a class="indexterm" href="#op_low">Expressions</a></dt><dt id="ientry-idp1376">LUA, <a class="indexterm" href="#po_lua">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>M</h3><dl><dt id="ientry-idp1394">MMU, <a class="indexterm" href="#po_mmu">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1049">DEVICE</a>)</dt><dt>(see also <a href="#ientry-idp1491">PAGE</a>)</dt><dt>(see also <a href="#ientry-idp1799">SLOT</a>)</dt></dl></dd><dt id="ientry-idp404">mod, <a class="indexterm" href="#op_mod2">Expressions</a></dt><dt id="ientry-idp1414">MODULE, <a class="indexterm" href="#po_module">Pseudo-ops</a></dt></dl></div><div class="indexdiv"><h3>N</h3><dl><dt id="ientry-idp553">NONE, <a class="indexterm" href="#device_none">Real device emulation mode</a></dt><dt id="ientry-idp382">norel, <a class="indexterm" href="#op_norel">Expressions</a></dt><dt id="ientry-idp614">NOSLOT64K, <a class="indexterm" href="#device_noslot64k">Real device emulation mode</a></dt><dt id="ientry-idp394">not, <a class="indexterm" href="#op_log_not2">Expressions</a></dt></dl></div><div class="indexdiv"><h3>O</h3><dl><dt id="ientry-idp1430">OPT, <a class="indexterm" href="#po_opt">Pseudo-ops</a></dt><dt id="ientry-idp448">or, <a class="indexterm" href="#op_bit_or2">Expressions</a></dt><dt id="ientry-idp1453">ORG, <a class="indexterm" href="#po_org">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1049">DEVICE</a>)</dt></dl></dd><dt id="ientry-idp1468">OUTEND, <a class="indexterm" href="#po_outend">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1477">OUTPUT</a>)</dt><dt>(see also <a href="#ientry-idp1774">SIZE</a>)</dt></dl></dd><dt id="ientry-idp1477">OUTPUT, <a class="indexterm" href="#po_output">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1774">SIZE</a>)</dt></dl></dd></dl></div><div class="indexdiv"><h3>P</h3><dl><dt id="ientry-idp1491">PAGE, <a class="indexterm" href="#po_page">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1049">DEVICE</a>)</dt><dt>(see also <a href="#ientry-idp1394">MMU</a>)</dt><dt>(see also <a href="#ientry-idp1799">SLOT</a>)</dt></dl></dd><dt id="ientry-idp1508">PHASE (see <a href="#ientry-idp1085">DISP</a>)</dt></dl></div><div class="indexdiv"><h3>R</h3><dl><dt id="ientry-idp1516">RELOCATE_END, <a class="indexterm" href="#po_relocate_end">Pseudo-ops</a></dt><dt id="ientry-idp1528">RELOCATE_START, <a class="indexterm" href="#po_relocate_start">Pseudo-ops</a></dt><dt id="ientry-idp1543">RELOCATE_TABLE, <a class="indexterm" href="#po_relocate_table">Pseudo-ops</a></dt><dt id="ientry-idp1554">REPT (see <a href="#ientry-idp1133">DUP</a>)</dt></dl></div><div class="indexdiv"><h3>S</h3><dl><dt id="ientry-idp1562">SAVE3DOS, <a class="indexterm" href="#po_save3dos">Pseudo-ops</a></dt><dt id="ientry-idp1576">SAVEAMSDOS, <a class="indexterm" href="#po_saveamsdos">Pseudo-ops</a></dt><dt id="ientry-idp1590">SAVEBIN, <a class="indexterm" href="#po_savebin">Pseudo-ops</a></dt><dt id="ientry-idp1605">SAVECDT, <a class="indexterm" href="#po_savecdt">Pseudo-ops</a></dt><dt id="ientry-idp1622">SAVECPCSNA, <a class="indexterm" href="#po_savecpcsna">Pseudo-ops</a></dt><dt id="ientry-idp1639">SAVEDEV, <a class="indexterm" href="#po_savedev">Pseudo-ops</a></dt><dt id="ientry-idp1654">SAVEHOB, <a class="indexterm" href="#po_savehob">Pseudo-ops</a></dt><dt id="ientry-idp1668">SAVENEX, <a class="indexterm" href="#po_savenex">Pseudo-ops</a></dt><dt id="ientry-idp1678">SAVESNA, <a class="indexterm" href="#po_savesna">Pseudo-ops</a></dt><dt id="ientry-idp1696">SAVETAP, <a class="indexterm" href="#po_savetap">Pseudo-ops</a></dt><dt id="ientry-idp1725">SAVETRD, <a class="indexterm" href="#po_savetrd">Pseudo-ops</a></dt><dt id="ientry-idp1745">SETBP, <a class="indexterm" href="#po_setbp">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp842">BPLIST</a>)</dt></dl></dd><dt id="ientry-idp1750">SETBREAKPOINT (see <a href="#ientry-idp1745">SETBP</a>)</dt><dt id="ientry-idp1764">SHELLEXEC, <a class="indexterm" href="#po_shellexec">Pseudo-ops</a></dt><dt id="ientry-idp416">shl, <a class="indexterm" href="#op_shl">Expressions</a></dt><dt id="ientry-idp418">shr, <a class="indexterm" href="#op_shr">Expressions</a></dt><dt id="ientry-idp1774">SIZE, <a class="indexterm" href="#po_size">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1477">OUTPUT</a>)</dt></dl></dd><dt id="ientry-idp2277">sj.add_byte(..), <a class="indexterm" href="#lua_sj_add_byte">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2284">sj.add_word(..), <a class="indexterm" href="#lua_sj_add_word">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2186">sj.calc(..) (see <a href="#ientry-idp2163">_c(..)</a>)</dt><dt id="ientry-idp2253">sj.current_address, <a class="indexterm" href="#lua_sj_current_address">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2210">sj.error(..), <a class="indexterm" href="#lua_sj_error">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2259">sj.error_count, <a class="indexterm" href="#lua_sj_error_count">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2271">sj.exit(..), <a class="indexterm" href="#lua_sj_exit">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2222">sj.file_exists(..), <a class="indexterm" href="#lua_sj_file_exists">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2291">sj.get_byte(..), <a class="indexterm" href="#lua_sj_get_byte">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2228">sj.get_define(..), <a class="indexterm" href="#lua_sj_get_define">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2305">sj.get_device(), <a class="indexterm" href="#lua_sj_get_device">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2240">sj.get_label(..), <a class="indexterm" href="#lua_sj_get_label">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2298">sj.get_word(..), <a class="indexterm" href="#lua_sj_get_word">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2234">sj.insert_define(..), <a class="indexterm" href="#lua_sj_insert_define">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2247">sj.insert_label(..), <a class="indexterm" href="#lua_sj_insert_label">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2194">sj.parse_code(..) (see <a href="#ientry-idp2170">_pc(..)</a>)</dt><dt id="ientry-idp2202">sj.parse_line(..) (see <a href="#ientry-idp2177">_pl(..)</a>)</dt><dt id="ientry-idp2311">sj.set_device(..), <a class="indexterm" href="#lua_sj_set_device">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2317">sj.set_page(..), <a class="indexterm" href="#lua_sj_set_page">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2324">sj.set_slot(..), <a class="indexterm" href="#lua_sj_set_slot">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2334">sj.shellexec(..), <a class="indexterm" href="#lua_sj_shellexec">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2216">sj.warning(..), <a class="indexterm" href="#lua_sj_warning">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2265">sj.warning_count, <a class="indexterm" href="#lua_sj_warning_count">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp1786">SLDOPT, <a class="indexterm" href="#po_sldopt">Pseudo-ops</a></dt><dt id="ientry-idp1799">SLOT, <a class="indexterm" href="#po_slot">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1049">DEVICE</a>)</dt><dt>(see also <a href="#ientry-idp1394">MMU</a>)</dt><dt>(see also <a href="#ientry-idp1491">PAGE</a>)</dt></dl></dd></dl></div><div class="indexdiv"><h3>T</h3><dl><dt id="ientry-idp1820">TAPEND, <a class="indexterm" href="#po_tapend">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp1827">TAPOUT</a>)</dt></dl></dd><dt id="ientry-idp1827">TAPOUT, <a class="indexterm" href="#po_tapout">Pseudo-ops</a></dt><dt id="ientry-idp2055">TEXT, <a class="indexterm" href="#st_text">STRUCT instructions</a></dt><dt id="ientry-idp1838">TEXTAREA (see <a href="#ientry-idp1085">DISP</a>)</dt></dl></div><div class="indexdiv"><h3>U</h3><dl><dt id="ientry-idp1846">UNDEFINE, <a class="indexterm" href="#po_undefine">Pseudo-ops</a></dt><dd><dl><dt>(see also <a href="#ientry-idp992">DEFINE</a>)</dt></dl></dd><dt id="ientry-idp1859">UNPHASE (see <a href="#ientry-idp1241">ENT</a>)</dt></dl></div><div class="indexdiv"><h3>W</h3><dl><dt id="ientry-idp1867">WHILE, <a class="indexterm" href="#po_while">Pseudo-ops</a></dt><dt id="ientry-idp1877">WORD, <a class="indexterm" href="#po_word">Pseudo-ops</a>, <a class="indexterm" href="#st_word">STRUCT instructions</a></dt></dl></div><div class="indexdiv"><h3>X</h3><dl><dt id="ientry-idp444">xor, <a class="indexterm" href="#op_bit_xor2">Expressions</a></dt></dl></div><div class="indexdiv"><h3>Z</h3><dl><dt id="ientry-idp2353">zx.save_snapshot_sna(..), <a class="indexterm" href="#lua_zx_save_snapshot_sna">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2346">zx.trdimage_add_file(..), <a class="indexterm" href="#lua_zx_trdimage_add_file">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp2340">zx.trdimage_create(..), <a class="indexterm" href="#lua_zx_trdimage_create">SjASMPlus functions bindings to Lua</a></dt><dt id="ientry-idp583">ZXSPECTRUM1024, <a class="indexterm" href="#device_zx1024">Real device emulation mode</a></dt><dt id="ientry-idp565">ZXSPECTRUM128, <a class="indexterm" href="#device_zx128">Real device emulation mode</a></dt><dt id="ientry-idp589">ZXSPECTRUM2048, <a class="indexterm" href="#device_zx2048">Real device emulation mode</a></dt><dt id="ientry-idp571">ZXSPECTRUM256, <a class="indexterm" href="#device_zx256">Real device emulation mode</a></dt><dt id="ientry-idp595">ZXSPECTRUM4096, <a class="indexterm" href="#device_zx4096">Real device emulation mode</a></dt><dt id="ientry-idp559">ZXSPECTRUM48, <a class="indexterm" href="#device_zx48">Real device emulation mode</a></dt><dt id="ientry-idp577">ZXSPECTRUM512, <a class="indexterm" href="#device_zx512">Real device emulation mode</a></dt><dt id="ientry-idp601">ZXSPECTRUM8192, <a class="indexterm" href="#device_zx8192">Real device emulation mode</a></dt><dt id="ientry-idp607">ZXSPECTRUMNEXT, <a class="indexterm" href="#device_zxn">Real device emulation mode</a></dt></dl></div></div></div>
|
||
|
||
</div></body></html>
|