-
Notifications
You must be signed in to change notification settings - Fork 9
/
README.html
6480 lines (5321 loc) · 293 KB
/
README.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE HTML>
<html lang="en">
<!-- $Id: README.html 3137 2024-06-08 16:10:55Z soci $ -->
<head>
<title>64tass v1.59 r3120 reference manual</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Description" content="64tass, an advanced multi pass macro assembler for the 65xx family of microprocessors">
<meta name="Keywords" content="6502 assembler, 65816, 6510, 65C02, dtv, c64 cross assembler">
<meta name="Author" content="Kajtar Zsolt">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
dt {margin-top:0.5em}
dt + dt {margin-top:0em}
body {font-family:serif;}
p, dd, h1, h2, h3, h4, li, caption {hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;-ms-hyphens:auto;}
code {hyphens:manual;-moz-hyphens:manual;-webkit-hyphens:manual;-ms-hyphens:manual;}
h1, h2, h3, h4 {text-align:left;font-family:sans-serif}
hr {display:none}
pre {border:1px dotted #eee;background-color:#ffe;padding:2px; border-radius: 4px;}
pre.make b {color:inherit;}
pre.make span {color:navy;}
pre.make span.cmd {color:green;}
pre.diag span.error {color:red;}
pre.diag span.note {color:darkcyan;}
pre.diag span.caret {color:green;}
pre b, code b {color:navy;}
pre b.d, code b.d {color:#e60;}
pre b.k, pre span.k, code b.k, code span.k {color:#00d;}
pre span, code span {color:#d00;}
pre span.s, code span.s {color:#e60;}
pre i {color:brown;}
pre u, code u {text-decoration:none;color:green;}
p, dd {text-align:justify;}
p + p {text-indent:3ex;margin-top:-0.5em}
table {border-bottom:2px solid black;border-top:2px solid black;border-collapse:collapse;width:100%;margin-top:0.5em;margin-bottom:0.5em; border-spacing: 0px;}
td, th {padding: 0px 1ex 0px 1ex;border-left:1px solid silver;border-top:1px solid silver}
tr:nth-child(odd) {background: #fafaff;}
td:first-child, th:first-child {border-left: 0px;}
caption {caption-side:bottom;}
table.opcodes th, table.opcodes td {text-align:left;table-layout:fixed;}
table.trans td:nth-child(1), table.trans td:nth-child(4) {text-align:center;}
dl.errorlist > dt, dl.dir > dt, table.trans td, table.esc td, table.opcodes th, table.opcodes td, code, pre, table.trans2 td {font-family:monospace,monospace;}
dl.errorlist > dt {font-weight:bold;}
thead th {background-color:#eee;border-bottom:1px solid black;}
a[href], a:visited { text-decoration: none; color: blue; }
a[href]:hover { text-decoration: underline; }
@media screen {
html {background-color: gray;}
body > div {max-width:50em;margin-left:auto; margin-right:auto; overflow: hidden;}
body {font-size:12pt;max-width:60em; background-color:white; margin-left:auto; margin-right:auto; border:1px solid black; box-shadow: black 2px 2px; padding: 5em 0.5em;}
pre, div {overflow:auto;}
}
.links {line-height: 2em; word-spacing: 1ex; text-align: justify;}
@media print {
h1, h2, h3, h4 {page-break-after:avoid;}
a[href], a:visited {text-decoration:none;color:inherit;}
body {font-size:10pt;}
pre {overflow:hidden;}
}
#toc li { list-style: none; }
#toc ul { counter-reset: section; }
#toc li > a:before { content: counters(section, ".") " "; counter-increment: section; color:black; }
#toc ul { margin: 0px; font-weight: normal;}
#toc > ul > li { margin-top: 0.5em; font-weight: bold; }
body { counter-reset: countcaption;}
h1 { counter-reset: counth2; font-size: 2em; margin: 0 0 0.67em 0; }
h2:before { content: counter(counth2) " "; counter-increment: counth2; min-width: 45pt;display:inline-block;}
h2 { counter-reset: counth3; }
h3:before { content: counter(counth2) "." counter(counth3) " "; counter-increment: counth3; min-width: 45pt;display:inline-block;}
h3 { counter-reset: counth4; }
h4:before { content: counter(counth2) "." counter(counth3) "." counter(counth4) " "; counter-increment: counth4; min-width: 45pt;display:inline-block;}
caption:before { content: "Table " counter(countcaption) ": "; counter-increment: countcaption; font-weight:bold;}
h2 a:after, h3 a:after, h4 a:after, dt a[name][href]:after {content: "¶"}
h2 a, h3 a, h4 a, dt a[name][href] {color:blue;visibility:hidden;text-decoration:none;}
h2:hover a, h3:hover a, h4:hover a, dt:hover a[name][href] {visibility:visible;}
q { quotes: "\201C" "\201D" "\2018" "\2019"; }
</style>
</head>
<body>
<div>
<h1>64tass v1.59 r3120 reference manual</h1>
<p>This is the manual for 64tass, the multi pass optimizing macro assembler for
the 65xx series of processors. Key features:
<ul>
<li>Open source portable C with minimal dependencies</li>
<li>Familiar syntax to Omicron TASS and TASM</li>
<li>Supports 6502, 65C02, R65C02, W65C02, 65CE02, 65816, DTV, 65EL02, 4510</li>
<li>Arbitrary-precision integers and bit strings, double precision floating point numbers</li>
<li>Character and byte strings, array arithmetic</li>
<li>Handles UTF-8, UTF-16 and 8 bit RAW encoded source files, Unicode character strings</li>
<li>Supports Unicode identifiers with compatibility normalization and optional case insensitivity</li>
<li>Built-in <q>linker</q> with section support</li>
<li>Various memory models, binary targets and text output formats (also Hex/S-record)</li>
<li>Assembly and label listings available for debugging or exporting</li>
<li>Conditional compilation, macros, structures, unions, scopes</li>
</ul>
<p>Contrary how the length of this document suggests 64tass can be used with
just basic 6502 assembly knowledge in simple ways like any other assembler. If
some advanced functionality is needed then this document can serve as a
reference.
<p><b>This is a development version. Features or syntax may change as a result
of corrections in non-backwards compatible ways in some rare cases. It's
difficult to get everything <q>right</q> first time.</b>
<p>Project page: <a href="https://sourceforge.net/projects/tass64/">https://sourceforge.net/projects/tass64/</a>
<p>The page hosts the latest and older versions with sources and a bug and a feature request tracker.</p>
<hr>
<nav id="toc">
<h2>Table of Contents<a name="contents" href="#contents"></a></h2>
<ul>
<li><a href="#contents">Table of Contents</a></li>
<li><a href="#usage-tips">Usage tips</a></li>
<li><a href="#expressions-datatypes">Expressions and data types</a>
<ul>
<li><a href="#integers">Integer constants</a></li>
<li><a href="#bit-string">Bit string constants</a></li>
<li><a href="#floating-point">Floating point constants</a></li>
<li><a href="#character-string">Character string constants</a></li>
<li><a href="#byte-string">Byte string constants</a></li>
<li><a href="#list-tuples">Lists and tuples</a></li>
<li><a href="#dictionaries">Dictionaries</a></li>
<li><a href="#code">Code</a></li>
<li><a href="#addressing">Addressing modes</a></li>
<li><a href="#uninitialized">Uninitialized memory</a></li>
<li><a href="#booleans">Booleans</a></li>
<li><a href="#type">Types</a></li>
<li><a href="#symbols">Symbols</a>
<ul>
<li><a href="#symbols-regular">Regular symbols</a></li>
<li><a href="#symbols-local">Local symbols</a></li>
<li><a href="#symbols-anonymous">Anonymous symbols</a></li>
<li><a href="#symbols-constant">Constant and re-definable symbols</a></li>
<li><a href="#star">The star label</a></li>
</ul></li>
<li><a href="#builtin-functions">Built-in functions</a>
<ul>
<li><a href="#math-functions">Mathematical functions</a></li>
<li><a href="#byte-functions">Byte string functions</a></li>
<li><a href="#other-functions">Other functions</a></li>
</ul></li>
<li><a href="#expressions">Expressions</a>
<ul>
<li><a href="#operators">Operators</a></li>
<li><a href="#comparison">Comparison operators</a></li>
<li><a href="#bitstringextractor">Bit string extraction operators</a></li>
<li><a href="#conditionals">Conditional operators</a></li>
<li><a href="#addresslength">Address length forcing</a></li>
<li><a href="#compound">Compound assignment</a></li>
<li><a href="#slicing_indexing">Slicing and indexing</a></li>
</ul></li>
</ul></li>
<li><a href="#compiler-directives">Compiler directives</a>
<ul>
<li><a href="#program-counter">Controlling the compile offset and program counter</a></li>
<li><a href="#alignment">Aligning data or code</a></li>
<li><a href="#data-dumping">Dumping data</a>
<ul>
<li><a href="#data-numeric">Storing numeric values</a></li>
<li><a href="#data-text">Storing string values</a></li>
</ul></li>
<li><a href="#text-encoding">Text encoding</a></li>
<li><a href="#structures">Structured data</a>
<ul>
<li><a href="#structure">Structure</a></li>
<li><a href="#union">Union</a></li>
<li><a href="#struct-and-union">Combined use of structures and unions</a></li>
</ul></li>
<li><a href="#macros">Macros</a>
<ul>
<li><a href="#macro-parameters">Parameter references</a></li>
<li><a href="#macro-textreference">Text references</a></li>
</ul></li>
<li><a href="#user-functions">Custom functions</a></li>
<li><a href="#conditional-assembly">Conditional assembly</a>
<ul>
<li><a href="#conditional-if">If, else if, else</a></li>
<li><a href="#conditional-switch">Switch, case, default</a></li>
<li><a href="#conditional-comment">Comment</a></li>
</ul></li>
<li><a href="#repetitions">Repetitions</a></li>
<li><a href="#including">Including files</a></li>
<li><a href="#scopes">Scopes</a></li>
<li><a href="#sections">Sections</a></li>
<li><a href="#w65816">65816 related</a></li>
<li><a href="#compiletime-checks">Controlling errors</a></li>
<li><a href="#target-cpu">Target</a></li>
<li><a href="#misc">Misc</a></li>
<li><a href="#listing-control">Printer control</a></li>
</ul></li>
<li><a href="#pseudo-instructions">Pseudo instructions</a>
<ul>
<li><a href="#aliases">Aliases</a></li>
<li><a href="#branch-always">Always taken branches</a></li>
<li><a href="#branch-long">Long branches</a></li>
</ul></li>
<li><a href="#tasm-compatibility">Original turbo assembler compatibility</a>
<ul>
<li><a href="#tasm-convert">How to convert source code for use with 64tass</a></li>
<li><a href="#tasm-diff">Differences to the original turbo ass macro on the C64</a></li>
<li><a href="#tasm-labels">Labels</a></li>
<li><a href="#tasm-expression">Expression evaluation</a></li>
<li><a href="#tasm-macros">Macros</a></li>
<li><a href="#tasm-bugs">Bugs</a></li>
</ul></li>
<li><a href="#commandline-options">Command line options</a>
<ul>
<li><a href="#commandline-output">Output options</a></li>
<li><a href="#commandline-operation">Operation options</a></li>
<li><a href="#commandline-diagnostic">Diagnostic options</a></li>
<li><a href="#commandline-target">Target selection on command line</a></li>
<li><a href="#commandline-symbol">Symbol listing</a></li>
<li><a href="#commandline-assembly">Assembly listing</a></li>
<li><a href="#commandline-other">Other options</a></li>
<li><a href="#commandline-file">Command line from file</a></li>
</ul></li>
<li><a href="#messages">Messages</a>
<ul>
<li><a href="#messages-warnings">Warnings</a></li>
<li><a href="#messages-errors">Errors</a></li>
<li><a href="#messages-fatal">Fatal errors</a></li>
</ul></li>
<li><a href="#credits">Credits</a></li>
<li><a href="#builtin-translations-escapes">Default translation and escape sequences</a>
<ul>
<li><a href="#translate-raw8">Raw 8-bit source</a>
<ul>
<li><a href="#translate-raw8-none">The none encoding for raw 8-bit</a></li>
<li><a href="#translate-raw8-screen">The screen encoding for raw 8-bit</a></li>
</ul></li>
<li><a href="#translate-unicode">Unicode and ASCII source</a>
<ul>
<li><a href="#translate-unicode-none">The none encoding for Unicode</a></li>
<li><a href="#translate-unicode-screen">The screen encoding for Unicode</a></li>
</ul></li>
</ul></li>
<li><a href="#opcodes">Opcodes</a>
<ul>
<li><a href="#opcodes-6502">Standard 6502 opcodes</a></li>
<li><a href="#opcodes-6502i">6502 illegal opcodes</a></li>
<li><a href="#opcodes-65dtv02">65DTV02 opcodes</a></li>
<li><a href="#opcodes-65c02">Standard 65C02 opcodes</a></li>
<li><a href="#opcodes-r65c02">R65C02 opcodes</a></li>
<li><a href="#opcodes-w65c02">W65C02 opcodes</a></li>
<li><a href="#opcodes-w65816">W65816 opcodes</a></li>
<li><a href="#opcodes-65el02">65EL02 opcodes</a></li>
<li><a href="#opcodes-65ce02">65CE02 opcodes</a></li>
<li><a href="#opcodes-4510">CSG 4510 opcodes</a></li>
</ul></li>
<li><a href="#appendix">Appendix</a>
<ul>
<li><a href="#directives">Assembler directives</a></li>
<li><a href="#functions">Built-in functions</a></li>
<li><a href="#types">Built-in types</a></li>
</ul></li>
</ul>
</nav>
<hr>
<h2>Usage tips<a name="usage-tips" href="#usage-tips"></a></h2>
<p>64tass is a command line assembler, the source can be written in any text
editor. As a minimum the source filename must be given on the command line. The
<q><a href="#o_ascii"><code>-a</code></a></q> command line option is highly recommended if the source is Unicode or
ASCII.
<pre>
64tass -a src.asm
</pre>
<p>There are also some useful parameters which are described later.
<p>For comfortable compiling I use such <q>Makefile</q>s (for <a href="https://en.wikipedia.org/wiki/Make_%28software%29">make</a>):
<pre class="make">
<span>demo.prg:</span> source.asm macros.asm pic.drp music.bin
<span class="cmd">64tass -C -a -B -i source.asm -o demo.tmp</span>
<span class="cmd">pucrunch -ffast -x 2048 demo.tmp >demo.prg</span>
</pre>
<p>This way <q>demo.prg</q> is recreated by compiling <q>source.asm</q>
whenever <q>source.asm</q>, <q>macros.asm</q>, <q>pic.drp</q> or <q>music.bin</q> had changed.
<p>Of course it's not much harder to create something similar for win32 (make.bat),
however this will always compile and compress:
<pre>
64tass.exe -C -a -B -i source.asm -o demo.tmp
pucrunch.exe -ffast -x 2048 demo.tmp >demo.prg
</pre>
<p>Here's a slightly more advanced Makefile example with default action as
testing in VICE, clean target for removal of temporary files and compressing
using an intermediate temporary file:
<pre class="make">
<span>all:</span> demo.prg
<span class="cmd">x64 -autostartprgmode 1 -autostart-warp +truedrive +cart</span> $<
<span>demo.prg:</span> demo.tmp
<span class="cmd">pucrunch -ffast -x 2048</span> $< >$@
<span>demo.tmp:</span> source.asm macros.asm pic.drp music.bin
<span class="cmd">64tass -C -a -B -i</span> $< <span class="cmd">-o</span> $@
<b>.INTERMEDIATE:</b> demo.tmp
<b>.PHONY:</b> all clean
<span>clean:</span>
$(RM) <span class="cmd">demo.prg demo.tmp</span>
</pre>
<p>It's useful to add a basic header to your source files like the one below,
so that the resulting file is directly runnable without additional
compression:
<pre>
* <b>=</b> <span>$0801</span>
<b class="d">.word</b> (<u>+</u>), <span>2005</span> <i>;pointer, line number</i>
<b class="d">.null</b> <span>$9e</span>, <span class="k">format</span>(<span class="s">"%4d"</span>, <u>start</u>)<i>;will be sys 4096</i>
+ <b class="d">.word</b> <span>0</span> <i>;basic line end</i>
* <b>=</b> <span>$1000</span>
start <b>rts</b>
</pre>
<p>A frequently coming up question is, how to automatically allocate
memory, without hacks like <code>*=*+1</code>? Sure
there's <a href="#d_byte"><code>.byte</code></a> and friends for variables with initial values
but what about zero page, or RAM outside of program area? The solution
is to not use an initial value by using <q><a href="#uninitialized"><code>?</code></a></q> or not
giving a fill byte value to <a href="#d_fill"><code>.fill</code></a>.
<pre>
* <b>=</b> <span>$02</span>
p1 <b class="d">.addr</b> <span>?</span> <i>;a zero page pointer</i>
temp <b class="d">.fill</b> <span>10</span> <i>;a 10 byte temporary area</i>
</pre>
<p>Space allocated this way
is not saved in the output as there's no data to save at those
addresses.
<p>What about some code running on zero page for speed? It needs to be
relocated, and the length must be known to copy it there. Here's
an example:
<pre>
<b>ldx</b> #<span class="k">size</span>(<u>zpcode</u>)-<span>1</span><i>;calculate length</i>
- <b>lda</b> <u>zpcode</u>,x
<b>sta</b> <u>wrbyte</u>,x
<b>dex</b> <i>;install to zero page</i>
<b>bpl</b> <u>-</u>
<b>jsr</b> <u>wrbyte</u>
<b>rts</b>
<i>;code continues here but is compiled to run from $02</i>
zpcode <b class="k">.logical</b> <span>$02</span>
wrbyte <b>sta</b> <span>$ffff</span> <i>;quick byte writer at $02</i>
<b>inc</b> <u>wrbyte</u>+<span>1</span>
<b>bne</b> <u>+</u>
<b>inc</b> <u>wrbyte</u>+<span>2</span>
+ <b>rts</b>
<b class="k">.endlogical</b>
</pre>
<p>The assembler supports lists and tuples, which does not seems interesting at
first as it sound like something which is only useful when heavy scripting is
involved. But as normal arithmetic operations also apply on all their elements at
once, this could spare quite some typing and repetition.
<p>Let's take a simple example of a low/high byte jump table of return
addresses, this usually involves some unnecessary copy/pasting to create a pair
of tables with constructs like <code>>(label-1)</code>.
<pre>
jumpcmd <b>lda</b> <u>hibytes</u>,x <i>; selected routine in X register</i>
<b>pha</b>
<b>lda</b> <u>lobytes</u>,x <i>; push address to stack</i>
<b>pha</b>
<b>rts</b> <i>; jump, rts will increase pc by one!</i>
<i>; Build a list of jump addresses minus 1</i>
_ <b>:=</b> (<u>cmd_p</u>, <u>cmd_c</u>, <u>cmd_m</u>, <u>cmd_s</u>, <u>cmd_r</u>, <u>cmd_l</u>, <u>cmd_e</u>)-<span>1</span>
lobytes <b class="d">.byte</b> <<u>_</u> <i>; low bytes of jump addresses</i>
hibytes <b class="d">.byte</b> ><u>_</u> <i>; high bytes</i>
</pre>
<p>There are some other tips below in the descriptions.</p>
<hr>
<h2>Expressions and data types<a name="expressions-datatypes" href="#expressions-datatypes"></a></h2>
<h3>Integer constants<a name="integers" href="#integers"></a></h3>
<p>Integer constants can be entered as decimal digits of arbitrary
length. An underscore can be used between digits as a separator for
better readability of long numbers. The following operations are
accepted:
<div><table border="0">
<caption>Integer operators and functions</caption>
<tr><td width="60"><code><u>x</u> + <u>y</u></code><td>add <code><u>x</u></code> to <code><u>y</u></code><td><code><span>2</span> + <span>2</span></code> is <code><span>4</span></code>
<tr><td><code><u>x</u> - <u>y</u></code><td>subtract <code><u>y</u></code> from <code><u>x</u></code><td><code><span>4</span> - <span>1</span></code> is <code><span>3</span></code>
<tr><td><code><u>x</u> * <u>y</u></code><td>multiply <code><u>x</u></code> with <code><u>y</u></code><td><code><span>2</span> * <span>3</span></code> is <code><span>6</span></code>
<tr><td><code><u>x</u> / <u>y</u></code><td>integer divide <code><u>x</u></code> by <code><u>y</u></code><td><code><span>7</span> / <span>2</span></code> is <code><span>3</span></code>
<tr><td><code><u>x</u> % <u>y</u></code><td>integer modulo of <code><u>x</u></code> divided by <code><u>y</u></code><td><code><span>5</span> % <span>2</span></code> is <code><span>1</span></code>
<tr><td><code><u>x</u> ** <u>y</u></code><td><code><u>x</u></code> raised to power of <code><u>y</u></code><td><code><span>2</span> ** <span>4</span></code> is <code><span>16</span></code>
<tr><td><code>-<u>x</u></code><td>negated value<td><code>-<span>2</span></code> is <code><span>-2</span></code>
<tr><td><code>+<u>x</u></code><td>unchanged<td><code>+<span>2</span></code> is <code><span>2</span></code>
<tr><td><code>~<u>x</u></code><td><code>-<u>x</u> - <span>1</span></code><td><code>~<span>3</span></code> is <code><span>-4</span></code>
<tr><td><code><u>x</u> | <u>y</u></code><td>bitwise or<td><code><span>2</span> | <span>6</span></code> is <code><span>6</span></code>
<tr><td><code><u>x</u> ^ <u>y</u></code><td>bitwise xor<td><code><span>2</span> ^ <span>6</span></code> is <code><span>4</span></code>
<tr><td><code><u>x</u> & <u>y</u></code><td>bitwise and<td><code><span>2</span> & <span>6</span></code> is <code><span>2</span></code>
<tr><td><code><u>x</u> << <u>y</u></code><td>logical shift left<td><code><span>1</span> << <span>3</span></code> is <code><span>8</span></code>
<tr><td><code><u>x</u> >> <u>y</u></code><td>arithmetic shift right<td><code><span>-8</span> >> <span>3</span></code> is <code><span>-1</span></code>
</table></div>
<p>Integers are automatically promoted to floats as necessary in expressions.
Other types can be converted to integer using the integer type
<code>int</code>.
<p>Integer division is a floor division (rounding down) so <code>7 / 4</code>
is <code>1</code> and not <code>1.75</code>. If ceiling division is required (rounding up) that
can be done by negating both the divident and the result. Typically it's done like <code>0 - -5 / 4</code> which results in <code>2</code>.
<pre>
<b class="d">.byte</b> <span>23</span> <i>; as unsigned</i>
<b class="d">.char</b> <span>-23</span> <i>; as signed</i>
<i>; using negative integers as immediate values</i>
<b>ldx</b> #-<span>3</span> <i>; works as '#-' is signed immediate</i>
num <b>=</b> <span>-3</span>
<b>ldx</b> #+<u>num</u> <i>; needs explicit '#+' for signed 8 bits</i>
<b>lda</b> #((<u>bitmap</u> >> <span>10</span>) & <span>$0f</span>) | ((<u>screen</u> >> <span>6</span>) & <span>$f0</span>)
<b>sta</b> <span>$d018</span>
</pre>
<h3>Bit string constants<a name="bit-string" href="#bit-string"></a></h3>
<p>Bit string constants can be entered in hexadecimal form with a leading
dollar sign or in binary with a leading percent sign. An underscore can
be used between digits as a separator for better readability of long
numbers. The following operations are accepted:
<div><table border="0">
<caption>Bit string operators and functions</caption>
<tr><td><code>~<u>x</u></code><td>invert bits<td><code>~<span>%101</span></code> is <code><span>~%101</span></code>
<tr><td><code><u>y</u> .. <u>x</u></code><td>concatenate bits<td><code><span>$a</span> .. <span>$b</span></code> is <code><span>$ab</span></code>
<tr><td><code><u>y</u> <span class="k">x</span> <u>n</u></code><td>repeat<td><code><span>%101</span> <span class="k">x</span> <span>3</span></code> is <code><span>%101101101</span></code>
<tr><td><code><u>x</u>[<u>n</u>]</code><td>extract bit(s)<td><code><span>$a</span>[<span>1</span>]</code> is <code><span>%1</span></code>
<tr><td><code><u>x</u>[<u>s</u>]</code><td>slice bits<td><code><span>$1234</span>[<span>4</span>:<span>8</span>]</code> is <code><span>$3</span></code>
<tr><td><code><u>x</u> | <u>y</u></code><td>bitwise or<td><code><span>~$2</span> | <span>$6</span></code> is <code><span>~$0</span></code>
<tr><td><code><u>x</u> ^ <u>y</u></code><td>bitwise xor<td><code><span>~$2</span> ^ <span>$6</span></code> is <code><span>~$4</span></code>
<tr><td><code><u>x</u> & <u>y</u></code><td>bitwise and<td><code><span>~$2</span> & <span>$6</span></code> is <code><span>$4</span></code>
<tr><td><code><u>x</u> << <u>y</u></code><td>bitwise shift left<td><code><span>$0f</span> << <span>4</span></code> is <code><span>$0f0</span></code>
<tr><td><code><u>x</u> >> <u>y</u></code><td>bitwise shift right<td><code><span>~$f4</span> >> <span>4</span></code> is <code><span>~$f</span></code>
</table></div>
<p>Length of bit string constants are defined in bits and is calculated from
the number of bit digits used including leading zeros.
<p>Bit strings are automatically promoted to integer or floating point as necessary in
expressions. The higher bits are extended with zeros or ones as needed.
<p>Bit strings support indexing and slicing. This is explained in detail
in section <q><a href="#slicing_indexing">Slicing and indexing</a></q>.
<p>Other types can be converted to bit string using the bit string type <code>bits</code>.
<pre>
<b class="d">.byte</b> <span>$33</span> <i>; 8 bits in hexadecimal</i>
<b class="d">.byte</b> <span>%00011111</span> <i>; 8 bits in binary</i>
<b class="d">.text</b> <span>$1234</span> <i>; $34, $12 (little endian)</i>
<b>lda</b> <span>$01</span>
<b>and</b> #~<span>$07</span> <i>; 8 bits even after inversion</i>
<b>ora</b> #<span>$05</span>
<b>sta</b> <span>$01</span>
<b>lda</b> <span>$d015</span>
<b>and</b> #~<span>%00100000</span> <i>;clear a bit</i>
<b>sta</b> <span>$d015</span>
</pre>
<h3>Floating point constants<a name="floating-point" href="#floating-point"></a></h3>
<p>Floating point constants have a radix point in them and optionally an
exponent. A decimal exponent is <q><code>e</code></q> while a binary one is <q><code>p</code></q>.
An underscore can be used between digits as a separator for better
readability. The following operations can be used:
<div><table border="0">
<caption>Floating point operators and functions</caption>
<tr><td width="80"><code><u>x</u> + <u>y</u></code><td>add <code><u>x</u></code> to <code><u>y</u></code><td><code><span>2.2</span> + <span>2.2</span></code> is <code><span>4.4</span></code>
<tr><td><code><u>x</u> - <u>y</u></code><td>subtract <code><u>y</u></code> from <code><u>x</u></code><td><code><span>4.1</span> - <span>1.1</span></code> is <code><span>3.0</span></code>
<tr><td><code><u>x</u> * <u>y</u></code><td>multiply <code><u>x</u></code> with <code><u>y</u></code><td><code><span>1.5</span> * <span>3</span></code> is <code><span>4.5</span></code>
<tr><td><code><u>x</u> / <u>y</u></code><td>integer divide <code><u>x</u></code> by <code><u>y</u></code><td><code><span>7.0</span> / <span>2.0</span></code> is <code><span>3.5</span></code>
<tr><td><code><u>x</u> % <u>y</u></code><td>integer modulo of <code><u>x</u></code> divided by <code><u>y</u></code><td><code><span>5.0</span> % <span>2.0</span></code> is <code><span>1.0</span></code>
<tr><td><code><u>x</u> ** <u>y</u></code><td><code><u>x</u></code> raised to power of <code><u>y</u></code><td><code><span>2.0</span> ** <span>-1</span></code> is <code><span>0.5</span></code>
<tr><td><code>-<u>x</u></code><td>negated value<td><code>-<span>2.0</span></code> is <code><span>-2.0</span></code>
<tr><td><code>+<u>x</u></code><td>unchanged<td><code>+<span>2.0</span></code> is <code><span>2.0</span></code>
<tr><td><code>~<u>x</u></code><td>almost <code>-<u>x</u></code><td><code>~<span>2.1</span></code> is almost <code><span>-2.1</span></code>
<tr><td><code><u>x</u> | <u>y</u></code><td>bitwise or<td><code><span>2.5</span> | <span>6.5</span></code> is <code><span>6.5</span></code>
<tr><td><code><u>x</u> ^ <u>y</u></code><td>bitwise xor<td><code><span>2.5</span> ^ <span>6.5</span></code> is <code><span>4.0</span></code>
<tr><td><code><u>x</u> & <u>y</u></code><td>bitwise and<td><code><span>2.5</span> & <span>6.5</span></code> is <code><span>2.5</span></code>
<tr><td><code><u>x</u> << <u>y</u></code><td>logical shift left<td><code><span>1.0</span> << <span>3.0</span></code> is <code><span>8.0</span></code>
<tr><td><code><u>x</u> >> <u>y</u></code><td>arithmetic shift right<td><code><span>-8.0</span> >> <span>4</span></code> is <code><span>-0.5</span></code>
</table></div>
<p>As usual comparing floating point numbers for (non) equality is a bad idea due to rounding errors.
<p>The only predefined constant is <code>pi</code>.
<p>Floating point numbers are automatically truncated to integer as necessary.
Other types can be converted to floating point by using the type <code>float</code>.
<p>Fixed point conversion can be done by using the shift operators. For example
an 8.16 fixed point number can be calculated as <code>(3.14 << 16) & $ffffff</code>.
The binary operators operate like if the floating point number would be a fixed
point one. This is the reason for the strange definition of inversion.
<pre>
<b class="d">.byte</b> <span>3.66e1</span> <i>; 36.6, truncated to 36</i>
<b class="d">.byte</b> <span>$1.8p4</span> <i>; 4:4 fixed point number (1.5)</i>
<b class="d">.sint</b> <span>12.2p8</span> <i>; 8:8 fixed point number (12.2)</i>
</pre>
<h3>Character string constants<a name="character-string" href="#character-string"></a></h3>
<p>Character strings are enclosed in single or double quotes and can hold any Unicode
character.
<p>Operations like indexing or slicing are always done on the original
representation. The current encoding is only applied when it's used in
expressions as numeric constants or in context of text data directives.
<p>Doubling the quotes inside string literals escapes them and results in a single quote.
<div><table border="0">
<caption>Character string operators and functions</caption>
<tr><td><code><u>y</u> .. <u>x</u></code><td>concatenate strings<td><code><span class="s">"a"</span> .. <span class="s">"b"</span></code> is <code><span class="s">"ab"</span></code>
<tr><td><code><u>y</u> <span class="k">in</span> <u>x</u></code><td>is substring of<td><code><span class="s">"b"</span> <span class="k">in</span> <span class="s">"abc"</span></code> is <code><span>true</span></code>
<tr><td><code><u>a</u> <span class="k">x</span> <u>n</u></code><td>repeat<td><code><span class="s">"ab"</span> <span class="k">x</span> <span>3</span></code> is <code><span class="s">"ababab"</span></code>
<tr><td><code><u>a</u>[<u>i</u>]</code><td>character from start<td><code><span class="s">"abc"</span>[<span>1</span>]</code> is <code><span class="s">"b"</span></code>
<tr><td><code><u>a</u>[-<u>i</u>]</code><td>character from end<td><code><span class="s">"abc"</span>[<span>-1</span>]</code> is <code><span class="s">"c"</span></code>
<tr><td><code><u>a</u>[:]</code><td>no change<td><code><span class="s">"abc"</span>[:]</code> is <code><span class="s">"abc"</span></code>
<tr><td><code><u>a</u>[<u>s</u>:]</code><td>cut off start<td><code><span class="s">"abc"</span>[<span>1</span>:]</code> is <code><span class="s">"bc"</span></code>
<tr><td><code><u>a</u>[:-<u>s</u>]</code><td>cut off end<td><code><span class="s">"abc"</span>[:<span>-1</span>]</code> is <code><span class="s">"ab"</span></code>
<tr><td><code><u>a</u>[<u>s</u>]</code><td>reverse<td><code><span class="s">"abc"</span>[::<span>-1</span>]</code> is <code><span class="s">"cba"</span></code>
</table></div>
<p>Character strings are converted to integers, byte and bit strings as necessary using the current
encoding and escape rules. For example when using a sane encoding <code>"z"-"a"</code> is
<code>25</code>.
<p>Other types can be converted to character strings by using the type
<code>str</code> or by using the <code>repr</code> and <code>format</code>
functions.
<p>Character strings support indexing and slicing. This is explained in detail
in section <q><a href="#slicing_indexing">Slicing and indexing</a></q>.
<pre>
mystr <b>=</b> <span class="s">"oeU"</span> <i>; character string constant</i>
<b class="d">.text</b> <span class="s">'it''s'</span> <i>; it's</i>
<b class="d">.word</b> <span class="s">"ab"</span>+<span>1</span> <i>; conversion result is "bb" usually</i>
<b class="d">.text</b> <span class="s">"text"</span>[:<span>2</span>] <i>; "te"</i>
<b class="d">.text</b> <span class="s">"text"</span>[<span>2</span>:] <i>; "xt"</i>
<b class="d">.text</b> <span class="s">"text"</span>[:<span>-1</span>] <i>; "tex"</i>
<b class="d">.text</b> <span class="s">"reverse"</span>[::<span>-1</span>]<i>; "esrever"</i>
</pre>
<h3>Byte string constants<a name="byte-string" href="#byte-string"></a></h3>
<p>Byte strings are like character strings, but hold bytes instead of characters.
<p>Quoted character strings prefixing by <q><code>b</code></q>, <q><code>l</code></q>, <q><code>n</code></q>, <q><code>p</code></q>, <q><code>s</code></q>, <q><code>x</code></q>
or <q>z</q> characters can be used to create byte strings. The resulting byte
string contains what <a href="#d_text"><code>.text</code></a>, <a href="#d_shiftl"><code>.shiftl</code></a>,
<a href="#d_null"><code>.null</code></a>, <a href="#d_ptext"><code>.ptext</code></a> and <a href="#d_shift"><code>.shift</code></a> would
create. Direct hexadecimal entry can be done using the <q><code>x</code></q> prefix and
<q><code>z</code></q> denotes a z85 encoded byte string. Spaces can be used between pairs of
hexadecimal digits as a separator for better readability.
<div><table border="0">
<caption>Byte string operators and functions</caption>
<tr><td><code><u>y</u> .. <u>x</u></code><td>concatenate strings<td><code><span class="s">x"12"</span> .. <span class="s">x"34"</span></code> is <code><span class="s">x"1234"</span></code>
<tr><td><code><u>y</u> <span class="k">in</span> <u>x</u></code><td>is substring of<td><code><span class="s">x"34"</span> <span class="k">in</span> <span class="s">x"1234"</span></code> is <code><span>true</span></code>
<tr><td><code><u>a</u> <span class="k">x</span> <u>n</u></code><td>repeat<td><code><span class="s">x"ab"</span> <span class="k">x</span> <span>3</span></code> is <code><span class="s">x"ababab"</span></code>
<tr><td><code><u>a</u>[<u>i</u>]</code><td>byte from start<td><code><span class="s">x"abcd12"</span>[<span>1</span>]</code> is <code><span class="s">x"cd"</span></code>
<tr><td><code><u>a</u>[-<u>i</u>]</code><td>byte from end<td><code><span class="s">x"abcd"</span>[<span>-1</span>]</code> is <code><span class="s">x"cd"</span></code>
<tr><td><code><u>a</u>[:]</code><td>no change<td><code><span class="s">x"abcd"</span>[:]</code> is <code><span class="s">x"abcd"</span></code>
<tr><td><code><u>a</u>[<u>s</u>:]</code><td>cut off start<td><code><span class="s">x"abcdef"</span>[<span>1</span>:]</code> is <code><span class="s">x"cdef"</span></code>
<tr><td><code><u>a</u>[:-<u>s</u>]</code><td>cut off end<td><code><span class="s">x"abcdef"</span>[:<span>-1</span>]</code> is <code><span class="s">x"abcd"</span></code>
<tr><td><code><u>a</u>[<u>s</u>]</code><td>reverse<td><code><span class="s">x"abcdef"</span>[::<span>-1</span>]</code> is <code><span class="s">x"efcdab"</span></code>
</table></div>
<p>Byte strings support indexing and slicing. This is explained in detail
in section <q><a href="#slicing_indexing">Slicing and indexing</a></q>.
<p>Other types can be converted to byte strings by using the type <code>bytes</code>.
<pre>
<b class="k">.enc</b> <span class="s">"screen"</span> <i>;use screen encoding</i>
mystr <b>=</b> <span class="s">b"oeU"</span> <i>;convert text to bytes, like <a href="#d_text">.text</a></i>
<b class="k">.enc</b> <span class="s">"none"</span> <i>;normal encoding</i>
<b class="d">.text</b> <u>mystr</u> <i>;text as originally encoded</i>
<b class="d">.text</b> <span class="s">s"p1"</span> <i>;convert to bytes like <a href="#d_shift">.shift</a></i>
<b class="d">.text</b> <span class="s">l"p2"</span> <i>;convert to bytes like <a href="#d_shiftl">.shiftl</a></i>
<b class="d">.text</b> <span class="s">n"p3"</span> <i>;convert to bytes like <a href="#d_null">.null</a></i>
<b class="d">.text</b> <span class="s">p"p4"</span> <i>;convert to bytes like <a href="#d_ptext">.ptext</a></i>
</pre>
<p>Binary data may be embedded in source code by using hexadecimal byte
strings. This is more compact than using <code>.byte</code> followed by a lot
of numbers. As expected 1 byte becomes 2 characters.
<pre>
<b class="d">.text</b> <span class="s">x"fce2"</span> <i>;2 bytes: $fc and $e2 (big endian)</i>
</pre>
<p>If readability is not a concern then the more compact z85 encoding may be used
which encodes 4 bytes into 5 characters. Data lengths not a multiple of 4 are
handled by omitting leading zeros in the last group.
<pre>
<b class="d">.text</b> <span class="s">z"FiUj*2M$hf"</span><i>;8 bytes: 80 40 20 10 08 04 02 01</i>
</pre>
<p>For data lengths of multiple of 4 bytes any z85 encoder will do. Otherwise the
simplest way to encode a binary file into a z85 string is to create a source file
which reads it using the line <q><code>label = binary('filename')</code></q>. Now if the labels
are listed to a file then there will be a z85 encoded definition for this
label.
<h3>Lists and tuples<a name="list-tuples" href="#list-tuples"></a></h3>
<p>Lists and tuples can hold a collection of values. Lists are defined from
values separated by comma between square brackets <code>[1, 2, 3]</code>, an
empty list is <code>[]</code>. Tuples are similar but are enclosed in
parentheses instead. An empty tuple is <code>()</code>, a single element tuple
is <code>(4,)</code> to differentiate from normal numeric expression
parentheses. When nested they function similar to an array. Both
types are immutable.
<div><table border="0">
<caption>List and tuple operators and functions</caption>
<tr><td><code><u>y</u> .. <u>x</u></code><td>concatenate lists<td><code>[<span>1</span>] .. [<span>2</span>]</code> is <code>[<span>1</span>, <span>2</span>]</code>
<tr><td><code><u>y</u> <span class="k">in</span> <u>x</u></code><td>is member of list<td><code><span>2</span> <span class="k">in</span> [<span>1</span>, <span>2</span>, <span>3</span>]</code> is <code><span>true</span></code>
<tr><td><code><u>a</u> <span class="k">x</span> <u>n</u></code><td>repeat<td><code>[<span>1</span>, <span>2</span>] <span class="k">x</span> <span>2</span></code> is <code>[<span>1</span>, <span>2</span>, <span>1</span>, <span>2</span>]</code>
<tr><td><code><u>a</u>[<u>i</u>]</code><td>element from start<td><code>(<span class="s">"1"</span>, <span>2</span>)[<span>1</span>]</code> is <code><span>2</span></code>
<tr><td><code><u>a</u>[-<u>i</u>]</code><td>element from end<td><code>(<span class="s">"1"</span>, <span>2</span>, <span>3</span>)[<span>-1</span>]</code> is <code><span>3</span></code>
<tr><td><code><u>a</u>[:]</code><td>no change<td><code>(<span>1</span>, <span>2</span>, <span>3</span>)[:]</code> is <code>(<span>1</span>, <span>2</span>, <span>3</span>)</code>
<tr><td><code><u>a</u>[<u>s</u>:]</code><td>cut off start<td><code>(<span>1</span>, <span>2</span>, <span>3</span>)[<span>1</span>:]</code> is <code>(<span>2</span>, <span>3</span>)</code>
<tr><td><code><u>a</u>[:-<u>s</u>]</code><td>cut off end<td><code>(<span>1</span>, <span>2.0</span>, <span>3</span>)[:<span>-1</span>]</code> is <code>(<span>1</span>, <span>2.0</span>)</code>
<tr><td><code><u>a</u>[<u>s</u>]</code><td>reverse<td><code>(<span>1</span>, <span>2</span>, <span>3</span>)[::<span>-1</span>]</code> is <code>(<span>3</span>, <span>2</span>, <span>1</span>)</code>
<tr><td><code>*<u>a</u></code><td>convert to arguments<td><code><span class="k">format</span>(<span class="s">"%d: %s"</span>, *<u>mylist</u>)</code>
<tr><td><code>... op <u>a</u></code><td>left fold<td><code>... + (<span>1</span>, <span>2</span>, <span>3</span>)</code> is <code>((<span>1</span>+<span>2</span>)+<span>3</span>)</code>
<tr><td><code><u>a</u> op ...</code><td>right fold<td><code>(<span>1</span>, <span>2</span>, <span>3</span>) - ...</code> is <code>(<span>1</span>-(<span>2</span>-<span>3</span>))</code>
</table></div>
<p>Arithmetic operations are applied on the all elements recursively,
therefore <code>[1, 2] + 1</code> is <code>[2, 3]</code>, and <code>abs([1,
-1])</code> is <code>[1, 1]</code>.
<p>Arithmetic operations between lists are applied one by one on their
elements, so <code>[1, 2] + [3, 4]</code> is <code>[4, 6]</code>.
<p>When lists form an array and columns/rows are missing the smaller array is
stretched to fill in the gaps if possible, so <code>[[1], [2]] * [3, 4]</code>
is <code>[[3, 4], [6, 8]]</code>.
<p>Lists and tuples support indexing and slicing. This is explained in detail
in section <q><a href="#slicing_indexing">Slicing and indexing</a></q>.
<pre>
mylist <b>=</b> [<span>1</span>, <span>2</span>, <span class="s">"whatever"</span>]
mytuple <b>=</b> (<u>cmd_e</u>, <u>cmd_g</u>)
mylist <b>=</b> (<span class="s">"e"</span>, <u>cmd_e</u>, <span class="s">"g"</span>, <u>cmd_g</u>, <span class="s">"i"</span>, <u>cmd_i</u>)
keys <b class="d">.text</b> <u>mylist</u>[::<span>2</span>] <i>; keys ("e", "g", "i")</i>
call_l <b class="d">.byte</b> <<u>mylist</u>[<span>1</span>::<span>2</span>]-<span>1</span><i>; routines (<cmd_e-1, <cmd_g-1, <cmd_i-1)</i>
call_h <b class="d">.byte</b> ><u>mylist</u>[<span>1</span>::<span>2</span>]-<span>1</span><i>; routines (>cmd_e-1, >cmd_g-1, >cmd_i-1)</i>
</pre>
<p>Although lists elements of variables can't be changed using indexing (at the
moment) the same effect can be achieved by combining slicing and
concatenation:
<pre>
lst := <u>lst</u>[:<span>2</span>] .. [<span>4</span>] .. <u>lst</u>[<span>3</span>:]<i>; same as lst[2] := 4 would be</i>
</pre>
<p>Folding is done on pair of elements either forward (left) or reverse
(right). The list must contain at least one element. Here are some folding examples:
<pre>
minimum <b>=</b> size([<u>part1</u>, <u>part2</u>, <u>part3</u>]) <? ...
maximum <b>=</b> size([<u>part1</u>, <u>part2</u>, <u>part3</u>]) >? ...
sum <b>=</b> size([<u>part1</u>, <u>part2</u>, <u>part3</u>]) + ...
xorall <b>=</b> <u>list_of_numbers</u> ^ ...
join <b>=</b> <u>list_of_strings</u> .. ...
allbits <b>=</b> <u>sprites</u>.(<u>left</u>, <u>middle</u>, <u>right</u>).<u>bits</u> | ...
all <b>=</b> [<span>true</span>, <span>true</span>, <span>true</span>, <span>true</span>] && ...
any <b>=</b> [<span>false</span>, <span>false</span>, <span>false</span>, <span>true</span>] || ...
</pre>
<p>The <code>range(start, end, step)</code> built-in function can be used to
create lists of integers in a range with a given step value. At least the end
must be given, the start defaults to 0 and the step to 1. Sounds not very
useful, so here are a few examples:
<pre>
<i>;Bitmask table, 8 bits from left to right</i>
<b class="d">.byte</b> <span>%10000000</span> >> <span class="k">range</span>(<span>8</span>)
<i>;Classic 256 byte single period sinus table with values of 0–255.</i>
<b class="d">.byte</b> <span>128</span> + <span>127.5</span> * <span class="k">sin</span>(<span class="k">range</span>(<span>256</span>) * <u>pi</u> / <span>128</span>)
<i>;Screen row address tables</i>
_ <b>:=</b> <span>$400</span> + <span class="k">range</span>(<span>0</span>, <span>1000</span>, <span>40</span>)
scrlo <b class="d">.byte</b> <<u>_</u>
scrhi <b class="d">.byte</b> ><u>_</u>
</pre>
<h3>Dictionaries<a name="dictionaries" href="#dictionaries"></a></h3>
<p>Dictionaries hold key and value pairs. Definition is done by collecting
key:value pairs separated by comma between braces <code>{"key":"value",
:"default value"}</code>.
<p>Looking up a non-existing key is normally an error
unless a default value is given. An empty dictionary is <code>{}</code>.
This type is immutable. There are limitations what may be used as a
key but the value can be anything.
<div><table border="0">
<caption>Dictionary operators and functions</caption>
<tr><td><code><u>y</u> .. <u>x</u></code><td>combine dictionaries<td><code>{<span>1</span>:<span>2</span>, <span>3</span>:<span>4</span>} .. {<span>2</span>:<span>3</span>, <span>3</span>:<span>1</span>}</code> is <code>{<span>1</span>:<span>2</span>, <span>2</span>:<span>3</span>, <span>3</span>:<span>1</span>}</code>
<tr><td><code><u>x</u>[<u>i</u>]</code><td>value lookup<td><code>{<span class="s">"1"</span>:<span>2</span>}[<span class="s">"1"</span>]</code> is <code><span>2</span></code>
<tr><td><code><u>x</u>.<u>i</u></code><td>symbol lookup<td><code>{.<u>ONE</u>:<span>1</span>, .<u>TWO</u>:<span>2</span>}.<u>ONE</u></code> is <code><span>1</span></code>
<tr><td><code><u>y</u> <span class="k">in</span> <u>x</u></code><td>is a key<td><code><span>1</span> <span class="k">in</span> {<span>1</span>:<span>2</span>}</code> is <code><span>true</span></code>
</table></div>
<pre>
<i>; Simple lookup</i>
<b class="d">.text</b> {<span>1</span>:<span class="s">"one"</span>, <span>2</span>:<span class="s">"two"</span>}[<span>2</span>]<i>; "two"</i>
<i>; 16 element "fader" table 1->15->12->11->0</i>
<b class="d">.byte</b> {<span>1</span>:<span>15</span>, <span>15</span>:<span>12</span>, <span>12</span>:<span>11</span>, :<span>0</span>}[<span class="k">range</span>(<span>16</span>)]
<i>; Symbol accessible values. May be useful as a function return value too.</i>
coords <b>=</b> {.<u>x</u>: <span>24</span>, .<u>y</u>: <span>50</span>}
<b>ldx</b> #<u>coords</u>.<u>x</u>
<b>ldy</b> #<u>coords</u>.<u>y</u>
</pre>
<h3>Code<a name="code" href="#code"></a></h3>
<p>Code holds the result of compilation in binary and other enclosed objects.
In an arithmetic operation it's used as the numeric address of the memory where
it starts. The compiled content remains static even if later parts of the
source overwrite the same memory area.
<p><b>Indexing and slicing of code to access the compiled content might be
implemented differently in future releases. Use this feature at your own
risk for now, you might need to update your code later.</b>
<div><table border="0">
<caption>Label operators and functions</caption>
<tr><td><code><u>a</u>.<u>b</u></code><td>b member of a<td><code><u>label</u>.<u>locallabel</u></code>
<tr><td><code>.<u>b</u> <span class="k">in</span> <u>a</u></code><td>if a has symbol b<td><code>.<u>locallabel</u> <span class="k">in</span> <u>label</u></code>
<tr><td><code><u>a</u>[<u>i</u>]</code><td>element from start<td><code><u>label</u>[<span>1</span>]</code>
<tr><td><code><u>a</u>[-<u>i</u>]</code><td>element from end<td><code><u>label</u>[<span>-1</span>]</code>
<tr><td><code><u>a</u>[<u>:</u>]</code><td>copy as tuple<td><code><u>label</u>[:]</code>
<tr><td><code><u>a</u>[<u>s</u>:]</code><td>cut off start, as tuple<td><code><u>label</u>[<span>1</span>:]</code>
<tr><td><code><u>a</u>[:-<u>s</u>]</code><td>cut off end, as tuple<td><code><u>label</u>[:<span>-1</span>]</code>
<tr><td><code><u>a</u>[<u>s</u>]</code><td>reverse, as tuple<td><code><u>label</u>[::<span>-1</span>]</code>
</table></div>
<pre>
mydata <b class="d">.word</b> <span>1</span>, <span>4</span>, <span>3</span>
mycode <b class="k">.block</b>
local <b>lda</b> #<span>0</span>
<b class="k">.endblock</b>
<b>ldx</b> #<span class="k">size</span>(<u>mydata</u>) <i>;6 bytes (3*2)</i>
<b>ldx</b> #<span class="k">len</span>(<u>mydata</u>) <i>;3 elements</i>
<b>ldx</b> #<u>mycode</u>[<span>0</span>] <i>;lda instruction, $a9</i>
<b>ldx</b> #<u>mydata</u>[<span>1</span>] <i>;2nd element, 4</i>
<b>jmp</b> <u>mycode</u>.<u>local</u> <i>;address of local label</i>
</pre>
<h3>Addressing modes<a name="addressing" href="#addressing"></a></h3>
<p>Addressing modes are used for determining addressing modes of
instructions.
<p>For indexing there must be no white space between the comma and the register letter,
otherwise the indexing operator is not recognized. On the other hand put a space between
the comma and a single letter symbol in a list to avoid it being recognized
as an operator.
<div><table border="0">
<caption>Addressing mode operators</caption>
<tr><td><code>#</code><td>immediate
<tr><td><code>#+</code><td>signed immediate
<tr><td><code>#-</code><td>signed immediate
<tr><td><code>( )</code><td>indirect
<tr><td><code>[ ]</code><td>long indirect
<tr><td><code>,b</code><td>data bank indexed
<tr><td><code>,d</code><td>direct page indexed
<tr><td><code>,k</code><td>program bank indexed
<tr><td><code>,r</code><td>data stack pointer indexed
<tr><td><code>,s</code><td>stack pointer indexed
<tr><td><code>,x</code><td>x register indexed
<tr><td><code>,y</code><td>y register indexed
<tr><td><code>,z</code><td>z register indexed
</table></div>
<p>Parentheses are used for indirection and square brackets for long
indirection. These operations are only available after instructions and
functions to not interfere with their normal use in expressions.
<p>Several addressing mode operators can be combined together. <b>Currently the
complexity is limited to 4 operators. This is enough to describe all addressing
modes of the supported CPUs.</b>
<div><table border="0">
<caption>Valid addressing mode operator combinations</caption>
<tr><td><code>#</code><td>immediate<td><code><b>lda</b> #<span>$12</span></code>
<tr><td><code>#+</code><td>signed immediate<td><code><b>lda</b> #<span>+127</span></code>
<tr><td><code>#-</code><td>signed immediate<td><code><b>lda</b> #<span>-128</span></code>
<tr><td><code>#<u>addr</u>,#<u>addr</u></code><td>move<td><code><b>mvp</b> #<span>5</span>,#<span>6</span></code>
<tr><td><code><u>addr</u></code><td>direct or relative<td><code><b>lda</b> <span>$12</span> <b>lda</b> <span>$1234</span> <b>bne</b> <span>$1234</span></code>
<tr><td><code><u>bit</u>,<u>addr</u></code><td>direct page bit<td><code><b>rmb</b> <span>5</span>,<span>$12</span></code>
<tr><td><code><u>bit</u>,<u>addr</u>,<u>addr</u></code><td>direct page bit relative jump<td><code><b>bbs</b> <span>5</span>,<span>$12</span>,<span>$1234</span></code>
<tr><td><code>(<u>addr</u>)</code><td>indirect<td><code><b>lda</b> (<span>$12</span>) <b>jmp</b> (<span>$1234</span></code>)
<tr><td><code>(<u>addr</u>),y</code><td>indirect y indexed<td><code><b>lda</b> (<span>$12</span>),y</code>
<tr><td><code>(<u>addr</u>),z</code><td>indirect z indexed<td><code><b>lda</b> (<span>$12</span>),z</code>
<tr><td><code>(<u>addr</u>,x)</code><td>x indexed indirect<td><code><b>lda</b> (<span>$12</span>,x) <b>jmp</b> (<span>$1234</span>,x)</code>
<tr><td><code>[<u>addr</u>]</code><td>long indirect<td><code><b>lda</b> [<span>$12</span>] <b>jmp</b> [<span>$1234</span>]</code>
<tr><td><code>[<u>addr</u>],y</code><td>long indirect y indexed<td><code><b>lda</b> [<span>$12</span>],y</code>
<tr><td><code>#<u>addr</u>,b</code><td>data bank indexed<td><code><b>lda</b> #<span>0</span>,b</code>
<tr><td><code>#<u>addr</u>,b,x</code><td>data bank x indexed<td><code><b>lda</b> #<span>0</span>,b,x</code>
<tr><td><code>#<u>addr</u>,b,y</code><td>data bank y indexed<td><code><b>lda</b> #<span>0</span>,b,y</code>
<tr><td><code>#<u>addr</u>,d</code><td>direct page indexed<td><code><b>lda</b> #<span>0</span>,d</code>
<tr><td><code>#<u>addr</u>,d,x</code><td>direct page x indexed<td><code><b>lda</b> #<span>0</span>,d,x</code>
<tr><td><code>#<u>addr</u>,d,y</code><td>direct page y indexed<td><code><b>ldx</b> #<span>0</span>,d,y</code>
<tr><td><code>(#<u>addr</u>,d)</code><td>direct page indirect<td><code><b>lda</b> (#<span>$12</span>,d)</code>
<tr><td><code>(#<u>addr</u>,d,x)</code><td>direct page x indexed indirect<td><code><b>lda</b> (#<span>$12</span>,d,x)</code>
<tr><td><code>(#<u>addr</u>,d),y</code><td>direct page indirect y indexed<td><code><b>lda</b> (#<span>$12</span>,d),y</code>
<tr><td><code>(#<u>addr</u>,d),z</code><td>direct page indirect z indexed<td><code><b>lda</b> (#<span>$12</span>,d),z</code>
<tr><td><code>[#<u>addr</u>,d]</code><td>direct page long indirect<td><code><b>lda</b> [#<span>$12</span>,d]</code>
<tr><td><code>[#<u>addr</u>,d],y</code><td>direct page long indirect y indexed<td><code><b>lda</b> [#<span>$12</span>,d],y</code>
<tr><td><code>#<u>addr</u>,k</code><td>program bank indexed<td><code><b>jsr</b> #<span>0</span>,k</code>
<tr><td><code>(#<u>addr</u>,k,x)</code><td>program bank x indexed indirect<td><code><b>jmp</b> (#<span>$1234</span>,k,x)</code>
<tr><td><code>#<u>addr</u>,r</code><td>data stack indexed<td><code><b>lda</b> #<span>1</span>,r</code>
<tr><td><code>(#<u>addr</u>,r),y</code><td>data stack indexed indirect y indexed<td><code><b>lda</b> (#<span>$12</span>,r),y</code>
<tr><td><code>#<u>addr</u>,s</code><td>stack indexed<td><code><b>lda</b> #<span>1</span>,s</code>
<tr><td><code>(#<u>addr</u>,s),y</code><td>stack indexed indirect y indexed<td><code><b>lda</b> (#<span>$12</span>,s),y</code>
<tr><td><code><u>addr</u>,x</code><td>x indexed<td><code><b>lda</b> <span>$12</span>,x</code>
<tr><td><code><u>addr</u>,y</code><td>y indexed<td><code><b>lda</b> <span>$12</span>,y</code>
</table></div>
<p>Direct page, data bank, program bank indexed and long addressing modes
of instructions are intelligently chosen based on the instruction type,
the address ranges set up by <a href="#d_dpage"><code>.dpage</code></a>, <a href="#d_databank"><code>.databank</code></a>
and the current program counter address. Therefore the <q><code>,d</code></q>,
<q><code>,b</code></q> and <q><code>,k</code></q> indexing is only used in very special cases.
<p>The immediate direct page indexed <q><code>#0,d</code></q> addressing
mode is usable for direct page access. The 8 bit constant is a
direct offset from the start of actual direct page. Alternatively it may
be written as <q><code>0,d</code></q>.
<p>The immediate data bank indexed <q><code>#0,b</code></q> addressing
mode is usable for data bank access. The 16 bit constant is a direct
offset from the start of actual data bank. Alternatively it may be
written as <q><code>0,b</code></q>.
<p>The immediate program bank indexed <q><code>#0,k</code></q> addressing mode
is usable for program bank jumps, branches and calls. The 16 bit constant
is a direct offset from the start of actual program bank. Alternatively it may
be written as <q><code>0,k</code></q>.
<p>The immediate stack indexed <q><code>#0,s</code></q> and data stack indexed
<q><code>#0,r</code></q> accept 8 bit constants as an offset from the
start of (data) stack. These are sometimes written without the immediate
notation, but this makes it more clear what's going on. For the same reason the
move instructions are written with an immediate addressing mode <q><code>#0,#0</code></q> as well.
<p>The immediate (<code>#</code>) addressing mode expects unsigned values of byte or
word size. Therefore it only accepts constants of 1 byte or in range 0–255
or 2 bytes or in range 0–65535.
<p>The signed immediate (<code>#+</code> and <code>#-</code>) addressing
mode is to allow signed numbers to be used as immediate constants. It accepts
a single byte or an integer in range −128–127, or two bytes or an integer of
−32768–32767.
<p>The use of signed immediate (like <code>#-3</code>) is seamless, but
it needs to be explicitly written out for variables or expressions
(<code>#+variable</code>). In case the unsigned variant is needed but the
expression starts with a negation then it needs to be put into parentheses
(<code>#(-variable)</code>) or else it'll change the address mode to
signed.
<p>Normally addressing mode operators are used in expressions right after
instructions. They can also be used for defining stack variable symbols when
using a 65816, or to force a specific addressing mode.
<pre>
param <b>=</b> #<span>1</span>,s <i>;define a stack variable</i>
const <b>=</b> #<span>1</span> <i>;immediate constant</i>
<b>lda</b> #<span>0</span>,b <i>;always "absolute" lda $0000</i>
<b>lda</b> <u>param</u> <i>;results in lda #$01,s</i>
<b>lda</b> <u>param</u>+<span>1</span> <i>;results in lda #$02,s</i>
<b>lda</b> (<u>param</u>),y <i>;results in lda (#$01,s),y</i>
<b>ldx</b> <u>const</u> <i>;results in ldx #$01</i>
<b>lda</b> #<span>-2</span> <i>;negative constant, $fe</i>
</pre>
<h3>Uninitialized memory<a name="uninitialized" href="#uninitialized"></a></h3>
<p>There's a special value for uninitialized memory, it's represented by a
question mark. Whenever it's used to generate data it creates a <q>hole</q>
where the previous content of memory is visible.
<p>Uninitialized memory holes without previous content are not saved unless
it's really necessary for the output format, in that case it's replaced with
zeros.
<p>It's not just data generation statements (e.g. <a href="#d_byte"><code>.byte</code></a>) that can
create uninitialized memory, but <a href="#d_fill"><code>.fill</code></a>, <a href="#d_align"><code>.align</code></a> or address manipulation as
well.
<pre>
* <b>=</b> <span>$200</span> <i>;bytes as necessary</i>
<b class="d">.word</b> <span>?</span> <i>;2 bytes</i>
<b class="d">.fill</b> <span>10</span> <i>;10 bytes</i>
<b class="k">.align</b> <span>64</span> <i>;bytes as necessary</i>
</pre>
<h3>Booleans<a name="booleans" href="#booleans"></a></h3>
<p>There are two predefined boolean constant variables, <code>true</code> and <code>false</code>.
<p>Booleans are created by comparison operators (<code><</code>,
<code><=</code>, <code>!=</code>, <code>==</code>, <code>>=</code>, <code>></code>),
logical operators (<code>&&</code>, <code>||</code>, <code>^^</code>,
<code>!</code>), the membership operator (<code>in</code>) and the
<code>all</code> and <code>any</code> functions.
<p>Normally in numeric expressions <code>true</code> is <code>1</code> and
<code>false</code> is <code>0</code>, unless the <q><a href="#o_Wstrict-bool"><code>-Wstrict-bool</code></a></q> command line option was
used.
<p>Other types can be converted to boolean by using the type <code>bool</code>.
<div><table border="0">
<caption>Boolean values of various types</caption>
<tr><td><code><u>bits</u></code><td>At least one non-zero bit
<tr><td><code><u>bool</u></code><td>When true
<tr><td><code><u>bytes</u></code><td>At least one non-zero byte
<tr><td><code><u>code</u></code><td>Address is non-zero
<tr><td><code><u>float</u></code><td>Not <code><span>0.0</span></code>
<tr><td><code><u>int</u></code><td>Not zero
<tr><td><code><u>str</u></code><td>At least one non-zero byte after translation
</table></div>
<h3>Types<a name="type" href="#type"></a></h3>
<p>The various types mentioned earlier have predefined names. These can
used for conversions or type checks.
<div><table border="0">
<caption>Built-in type names</caption>
<tr><td><code><a name="t_address"><u>address</u></a></code><td>Address type
<tr><td><code><a name="t_bits"><u>bits</u></a></code><td>Bit string type
<tr><td><code><a name="t_bool"><u>bool</u></a></code><td>Boolean type
<tr><td><code><a name="t_bytes"><u>bytes</u></a></code><td>Byte string type
<tr><td><code><a name="t_code"><u>code</u></a></code><td>Code type
<tr><td><code><a name="t_dict"><u>dict</u></a></code><td>Dictionary type
<tr><td><code><a name="t_float"><u>float</u></a></code><td>Floating point type
<tr><td><code><a name="t_gap"><u>gap</u></a></code><td>Uninitialized memory type
<tr><td><code><a name="t_int"><u>int</u></a></code><td>Integer type
<tr><td><code><a name="t_list"><u>list</u></a></code><td>List type
<tr><td><code><a name="t_str"><u>str</u></a></code><td>Character string type
<tr><td><code><a name="t_symbol"><u>symbol</u></a></code><td>Symbol type
<tr><td><code><a name="t_tuple"><u>tuple</u></a></code><td>Tuple type