-
Notifications
You must be signed in to change notification settings - Fork 11
/
README.txt
1225 lines (984 loc) · 33 KB
/
README.txt
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
OOO O O OOO O O
O O O O O O OO OO
O OO O O O O O O
OOO O O O OOO O O O
O O OOOOO O O O
O O O O O O O O O
OOO O O O O OOO O O
OO
Sjasm Z80 Assembler v0.39h
Copyright 2006 Sjoerd Mastijn - www.xl2s.tk - [email protected]
Copyright 2015 Konamiman - www.konamiman.com
Introduction
============
Sjasm version 0.3 is just yet another Z80 cross assembler.
Thanks to Eli-Jean Leyssens there is also a Linux version of Sjasm.
From Konamiman:
I decided to continue the development of Sjasm mainly for two reasons: I thought that it was a pity that such a great project was not in a proper source code repository, and I actually needed it to assemble Compass sources for one of my projects. I went for the 0.39 version instead of 0.42 because it works well enough and has the multiple PUSH and POP statements implemented already.
A big thank you to Sjoerd Mastijn for his awesome work. Enjoy!
DISCLAIMER
----------
If Sjasm breaks anything - I didn't do it.
From Konamiman: Me neither! (For more details, please read the license file)
Changes from 0.2
----------------
- Sjasm v0.3x assumes Z80-mode as there are no other cpus supported.
- All calculations are 32 bits.
Changes from 0.30
-----------------
- '#' Can be used now to indicate a hexadecimal value.
- Local 'number' labels should really work now.
- Multiple error messages per source line possible.
- Things like ld a,(4)+1 work again (=> ld a,5). Somehow I broke this in v0.3.
- Filenames don't need surrounding quotes anymore.
- Macro's can be nested once again.
- Better define-handling.
- 'Textarea' detects forward references.
- Include within include searches relative to that include.
- 'Unlocked' some directives (assert, output).
- '#' Can be used in labels.
- No space needed between label and '=' in statements like 'label=value'.
- The 'export' directive now exports 'label: EQU value' instead of 'label = value'.
- Labelnames starting with a register name (like HL_kip) shouldn't confuse Sjasm anymore.
- RLC, RRC, RL, RR, SLA, SRA, SLL (SLI), RES and SET undocumented instructions added.
- "ex af,af" and "ex af" are possible now.
- Added defb, defw and defs.
- Locallabels now also work correctly when used in macros.
- Added // and limited /* */ comments.
- Sjasm now checks the label values between passes.
- '>>>' Operator added.
- Sources included.
- '>>>' And '>>' operators now work the way they should (I think).
- Removed the 'data/text/pool'-bug. (Together with the data/text/pool directives. ~8)
- Added endmodule and endmod to end a module.
- STRUCT directive.
- REPT, DWORD, DD, DEFD directives.
- More freedom with character constants; in some cases it's possible to use double quotes...
- It's now possible to specify include paths at the command line.
- Angle brackets are used now to include commas in macroarguments. So check your macro's.
- Fixed a structure initialization bug.
- It's not possible to use CALLs or jumps without arguments anymore.
- DZ and ABYTEZ directives to define null terminated strings.
- Sjasm now checks for lines that are too long.
- Added '16 bit' LD, LDI and LDD 'instructions'. (See end of this text:)
- PUSH and POP accept a list of registers.
- Added '16 bit SUB' instruction.
- Unreferenced labels are indicated with an 'X' in the label listing.
- Unknown escapecodes in strings result in just one error (instead of more).
- Labelnameparts now have a maximum of 70 characters.
- Improved IX and IY offset checking.
- Maximum, minimum, and, or, mod, xor, not, shl, shr, low and high operators added.
- Logical operations result in -1 or 0 instead of 1 or 0. Of course, -1 for true and 0 for false ;)
- Fixed the 'ifdef <illegal identifier>' bug. (:
New in 0.39g:
--------------
- ENDMAP directive.
- DEFM and DM synonyms for BYTE.
- Some bug fixes:
- file size is reset when a new output file is opened.
- 'bytes lost' warning fixed.
And thanks to Konamiman:
- PHASE and DEPHASE directives as synonyms of TEXTAREA and ENDT.
- FPOS directive.
- Expanded OUTPUT directive.
- The possibility to generate a symbol file.
New in 0.39g1:
- Sjasm now allows spaces in filenames.
New in 0.39g6:
- : Operator.
- MULUB and MULUW work.
- Labels starting with an underscore are listed.
- Can't remember the other changes.
New in 0.39h (by Konamiman):
----------------------------
- Added the -e command line switch to send error messages to the standard error pipe.
- Added the -v command line switch to generate error messages in Visual Studio format.
- Added the Compass compatibility mode (-c command line switch). See "Compass compatibility mode".
- Added different exit codes for different error conditions. See "Exit codes".
- &H and &B can be used as prefixes for hexadecimal and binary constants respectively.
New in 0.39i (by Konamiman):
----------------------------
- Fix: program crashes without any error message when declaring a Compass-style macro
in which the macro name doesn't end with ":".
- The backslash character, "\", is no longer interpreted as an escape character when running in Compass
compatibility mode. So things like 'ld a,"\"' or 'db "\"' work as expected.
- The TSRHOOKS, .LABEL, .UPPER, and BREAKP directives are now just ignored (instead of throwing errors)
when running in Compass compatibility mode.
Known bugs:
-----------
- The listfile doesn't always look that good.
- Commas in strings in macroarguments are not ignored.
- Sourcelines are not further processed after an ELSE, ENDwhatever and the like.
- Using INCLUDE instead of INCBIN isn't detected, and will crash Sjasm quite nicely.
- The combination of comments, strings and the af' register can be very confusing for Sjasm :)
Files
-----
The Sjasm package consists of the following files:
sjasm.exe - the Win32 executable.
sjasm.txt - this file.
license.txt - the license file.
Sorry, no Linux executable for v0.39h (but you can generate one from the sources, the original Makefile is included)
RUN!
====
To use Sjasm:
sjasm [options] inputfile [outputfile [listfile [exportfile]]]
Options:
-L output a list of all defined labels in the listing.
-Q do not list the source and resulting objectcode in listfile.
-I specify a directory to search for includefiles.
-S output a .SYM symbolfile which contains all labels.
-E send error messages to the standard error pipe, instead of the standard output pipe.
-V produce error messages in Visual Studio format.
-C enable compatibility with Compass.
Options may be grouped, and it's permitted to place them anywhere. Examples:
sjasm -l prog.asm
assemble prog.asm to prog.out with prog.lst as listfile, include labels and code in listfile
sjasm -ql prog.asm
assemble prog.asm to prog.out with prog.lst as listfile, include only the label listing in listfile
sjasm prog.asm -i/devel/inc
assemble prog.asm to prog.out with prog.lst as listfile, include only code in listfile and search in /devel/inc for includefiles if not found in the current directory
sjasm -lidevel -izooi prog.asm prog.com
assemble prog.asm to prog.com with prog.lst as listfile, include code and label listing in listfile and search in zooi and devel for includefiles if not found in the current directory
When the output-, list- or exportfile are omitted the following filenames are constructed:
Outputfile: inputfile-without-extension.out
Listfile: inputfile-without-extension.lst
Exportfile: inputfile-without-extension.exp
The symbols file name will always constructed as follows: exportfile-without-extension.sym
Exit codes
----------
Sjasm will terminate with one of the following exit codes:
0: Success
1: Error(s) found in source code
2: Can't open or read file
3: Fatal error (internal error or can't write file)
4: No input file specified
5: Invalid command line argument(s)
Source file format
==================
Lines in the source file should have the following form:
Label Operator Operand Comment
All fields are optional. Lines without label should start with whitespace. Comments should start with ';' or '//'. Comment blocks start with '/*' and end with '*/'.
; comment
// comment
ld /* comment */ a,80
/*
comment
*/
ld /*
but this won't be ld a,3!
*/ a,3
Labels
======
Labels are case-sensitive and may be of any reasonable length, that is: up to about 70 characters. Label definitions should 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:
Kip
KIP
Kip@@
MAIN.loop?
It is possible to use mnemonics, pseudo-ops and register names as labels but it is not advised to do so. Also note that the identifiers defined with the DEFINE pseudo-op use another name space.
Local labels
------------
When there is a module definition (see module pseudo-op) 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.
module main
Main: ; main.Main
CALL SetScreen ; SetScreen
CALL vdp.Cls ; vdp.Cls
.loop: ; main.Main.loop
LD A,(.event) ; main.Main.event
CALL ProcesEvent ; label not found: main.ProcesEvent
DJNZ .loop ; main.Main.loop
module vdp
@SetScreen: ; SetScreen
.loop ; vdp.SetScreen.loop
RET
Cls: ; vdp.Cls
.loop ; vdp.Cls.loop
DJNZ .loop ; vdp.Cls.loop
RET
endmodule
Main.event ; main.Main.event
byte 0
@ Labels
--------
Labels starting with a '@' are not touched by the label processing and used 'as-is'. See 'SetScreen' in the previous example code.
Another example:
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
Temporary labels
----------------
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 not be used within macro's.
Example:
ADD A,E
JR NC,1F
INC D
1 LD E,A
2 LD B,4
LD A,(DE)
OUT (152),A
DJNZ 2B
Constants
=========
Numeric constants
-----------------
Numeric constants should always start with a digit or $, #, & or %. The following formats are supported:
12 decimal
12d decimal
0ch hexadecimal
0xc hexadecimal
$c hexadecimal
#c hexadecimal
&hc hexadecimal
1100b binary
%1100 binary
&b1100 binary
14q octal
14o octal
Character and string constants
------------------------------
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. The following escape sequences are recognized:
\\ 92
\? 63
\' 39
\" 34
\A 7
\B 8
\D 127
\E 27
\F 12
\N 10
\R 13
\T 9
\V 11
Examples:
BYTE "stringconstant" ; single quote string constants can't be used with BYTE
LD HL,'hl'
LD HL,"hl" ; :(
LD A,"7" ; :(
LD A,'8' ; :)
LD A,'\E'
LD A,'"'
LD A,"'"
When running in Compass compatibility mode:
- The special constants "" and '' are recognized as being equal to zero.
- There are no escape sequences, thus the backslash character, "\", is treated as any other character
(so e.g. the following works: ld a,"\").
Expressions
===========
Expressions are evaluated in 32 bits in this version of Sjasm. '$' Represents the current program counter. It is possible to use parenthesis '(' and ')' to override the precedence of the operators. The following operators may be used in expressions:
! !x logical not
~ ~x complement
+ +x does absolutely nothing :)
- -x minus
low low x low 8 bits of 16 bit value
high high x high 8 bits of 16 bit value
not not x logical not
: x:y x multiplied by 256, added to y
* x*y multiplication
/ x/y division
% x%y modulo
mod x mod y modulo
+ x+y addition
- x-y subtraction
<< x<<y shift left
>> x>>y shift right signed
>>> x>>>y shift right unsigned
shl x shl y shift left
shr x shr y shift right signed
<? x<?y minimum
>? x>?y maximum
< x<y less than
> x>y greater than
<= x<=y equal or less than
>= x>=y equal or greater than
= x=y equal
== x==y equal
!= x!=y not equal
& x&y bitwise and
and x and y bitwise and
^ x^y bitwise xor
xor x xor y bitwise xor
| x|y bitwise or
or x or y bitwise or
&& x&&y logical and
|| x||y logical or
Assembly language
=================
This version only accepts Z80 mnemonics. There are some additions to what I think is standard Z80:
- '[' and ']' can be used in stead of '(' and ')' for indirections. So LD A,[HL] is the same as LD A,(HL).
- IN F,(C) and OUT (C),0 and SLL/SLI can be used.
- IXL, IYL, IXH and IYH registers are supported.
- JP HL, JP IX and JP IY may be used instead of JP (HL), etc.
- EX AF,AF or EX AF may be used instead of EX AF,AF'.
- MULUB and MULUW are recognised (but won't work on Z80, of course:)
- RLC, RRC, RL, RR, SLA, SRA, SLL (SLI), RES, SET undocumented instructions added.
examples:
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
- PUSH and POP can take register lists:
PUSH AF,BC ; push af / push bc
POP AF,BC ; pop bc / pop af <- reversed order
Pseudo-ops
==========
Pseudo-ops don't have to start with a '.' anymore. However, it is still permitted.
ABYTE <offset> <bytes>
-----
Defines a byte or a string of bytes. The offset is added to each of the following bytes.
ABYTE 2 4,9 ; Same as BYTE 6,11
ABYTE 3 "ABC" ; Same as BYTE "DEF"
ABYTEC <offset> <bytes>
------
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.
ABYTEC 0 "KIP" ; Same as BYTE "KI",'P'|128
ABYTEC 1 "ABC",0,"DE" ; Same as BYTE "BC",'D'|128,1,'E','F'|128
ABYTEZ <offset> <bytes>
------
Defines a byte or a string of bytes, followed by a zero. The offset is added to each of the following bytes.
ABYTEZ 0 "KIP" ; Same as BYTE "KIP",0
ALIGN <2,4,8,16,32,64,128 or 256>
-----
Align fills zero or more byte with zeros until the new address modulo <expression> equals zero.
ALIGN ; => ALIGN 4
ALIGN 2 ;
ASSERT <expression>
------
An 'assertion failed' error is issued if the expression evaluates to zero.
STACKPOINTER=0D500H
ASSERT END_OF_PROGRAM < STACKPOINTER
END_OF_PROGRAM
END
BLOCK <length>[,<fill byte>]
-----
Defines space. Has to be followed by the number of byte to reserve, optionally followed by the value to fill these bytes with.
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
BYTE <bytes>
----
Defines a byte or a string of bytes. Each value should be between -129 and 256.
BYTE 0x56
BYTE 1,-78,'@'
BYTE "Format C:? ",0h
DB
--
See BYTE.
DC
--
Same as BYTE, but every last character of a string will have bit 7 set.
DC "kip" ; same as BYTE "ki",'p'|128
DD
--
See DWORD.
DEFB
----
See BYTE.
DEFD
----
See DWORD.
DEFINE <id> <replacement>
------
The identifier <id> will be replaced with the <replacement>. The replacement could be omitted, in such case it is still possible to check if the identifier was defined with IFDEF or IFNDEF.
DEFINE str_honderd "Honderd"
BYTE str_honderd,0 ; BYTE "Honderd",0
DEFS
----
See BLOCK.
DEFW
----
See WORD.
DEPHASE
-------
See ENDT.
DS
--
See BLOCK.
DW
--
See WORD.
DWORD
-----
Defines a so called doubleword. Values should be between -2147483649 and 4294967296.
DWORD 4000h,0d000h
DWORD 4
DZ
--
Same as BYTE, but an extra zero will be added at the end.
DZ 1 ; same as BYTE 1,0
DZ "kip" ; same as BYTE "kip",0
END
---
The assembler will stop at this point.
ENDMAP
------
Restores the mapcounter with the value it had before the last MAP directive.
MAP 100
MAP 200
kop # 2 ; kop=200
ENDMAP
kip # 2 ; kip=100
kip2 # 2 ; kip2=102
ENDMOD
------
See ENDMODULE.
ENDMODULE
---------
To indicate the end of a module (see MODULE), and use the previous modulename.
MODULE M1
A ; M1.A
MODULE M2
A ; M2.A
ENDMODULE
B ; M1.B
EQU
---
To give a label a value other than the current program counter. '=' can be used instead of 'EQU'. The label should not already exist.
Label EQU 3
Kip=3
EXPORT label
------
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.
DRIE=3
EXPORT DRIE
FIELD
-----
To give a label the value of the current map counter. Afterwards the map counter is increment by the given amount. '#' May be used instead of 'FIELD'. With map and field it is possible to create structure-like data structures. With '##' it is possible to align the map counter.
MAP 8
Label # 2 ; Label=8
Kip # 3 ; Kip=10
Kop # ; Kop=13
Kop2 # 1 ; Kop2=13
## ; align map address (align 4 is default)
Kop3 # 6 ; Kop3=16
FPOS <position>
----
The FPOS directive makes it possible to set the file position to anywhere in the output file.
This example will result in a file with a length of one byte:
BYTE 0
FPOS 0
BYTE 1
END
In combination with OUTPUT "<filename>",r it is possible to update existing files.
INCBIN <filename>[,offset[,length]]
------
To include a binary file into the outputfile. The offset and length are optional.
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 ; note the space between the filename and the ',7' here :)
INCLUDE <filename>
-------
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 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.
INCLUDE <VDP.I>
INCLUDE MORE.I
INCLUDE "MORE.I"
MAP <address>
---
Set the map counter to the specified value. See 'FIELD' for an example.
MAP 5
MODULE <name>
------
Labels are to be unique only in the current module. Also note the use of '@' to suppress all this label-processing. (The '@' is NOT part of the label name though!)
MODULE xxx
Kip ; label xxx.Kip
CALL Kip ; call xxx.Kip
CALL yyy.Kip ; call yyy.Kip
CALL Kop ; call xxx.Kop
CALL @Kop ; call Kop
Call @Kip ; call Kip
MODULE yyy
Kip ; label yyy.Kip
@Kop ; label Kop
@xxx.Kop ; label xxx.Kop
MODULE ; no modulename
Kip ; label Kip
ORG <address>
---
Set the program counter to a specific address.
ORG 100h
OUTPUT "<filename>",mode
------
With OUTPUT it is possible to create multiple files from one source. All following instructions will be assembled to this file.
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).
OUTPUT "<filename>",t ; truncate (default)
OUTPUT "<filename>",r ; rewind
OUTPUT "<filename>",a ; append
Example:
OUTPUT loader.com
ORG 100H
INCLUDE loader.asm
INCLUDE bios.asm
OUTPUT bigfile.dat
ORG 4000H
INCLUDE main.asm
ORG 8000H
INCLUDE data.asm
END
This will create two files: loader.com and bigfile.dat.
When Sjasm is invoked without specifying an output file, there is still one created even when no bytes are output to it. So when the above file is called bigfile.asm, and assembled with the following line:
sjasm bigfile.asm
The following files are created:
Bigfile.out ; file length is zero
Loader.com
Bigfile.dat
PHASE
-----
See TEXTAREA.
REPT <count>
----
REPT specifies the number of times to generate the statements inside the macro. REPT cannot be used in macro's.
REPT 3
NOP
ENDM
this will expand to:
NOP
NOP
NOP
SIZE <filesize in bytes>
----
If the resulting file is less than the given length, as many bytes are added as necessary.
SIZE 32768 ; make sure file will be 32K
TEXTAREA <address>
--------
The program counter is set to the specified address, and restored with an 'ENDT' directive.
MODULE Main
LD HL,start
LD DE,8000h
LD BC,len
LDIR
CALL DoThings
RET
start
MODULE DoUsefulThings
TEXTAREA 8000h
@DoThings
CALL DoALot
CALL DoEvenMore
RET
ENDT
MODULE Main
Len:=$-start
WORD <words>
----
Defines a word. Values should be between -32787 and 65536.
WORD 4000h,0d000h
WORD 4,"HA"
Conditional assembly
====================
It may be useful to assemble a part or not based on a certain condition.
COND <expression>
----
Same as IF, but only works with Compass compatibility enabled.
IF <expression>
--
If <expression> is non-zero the following lines are assembled until an ELSE or ENDIF.
IFDEF <id>
-----
The condition is true if there is an id defined. These are NOT labels.
IFDEF MSX_LEAN_AND_MEAN
CALL InitOwnMM
ELSE
CALL InitDos2MemMan
ENDIF
IFNDEF <id>
------
The condition is true if there isn't an id defined. These are NOT labels.
1 IN A,(0C4H)
AND 2
IFNDEF DEBUG
JR NC,1B
ENDIF
ELSE
----
See IF. If the condition is not true, the else-part is assembled.
ENDC
----
Same as ENDIF, but only works with Compass compatibility enabled.
ENDIF
-----
Every IF should be followed by an ENDIF.
Macros
======
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.
See also "Compass compatibility mode" to see the Compass format for macros.
Macro without parameters:
MACRO ADD_HL_A
ADD A,L
JR NC,.hup
INC H
.hup
LD L,A
ENDM
Labels in a macro starting with a dot are local to each macro expansion.
A macro with parameters:
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
Another example:
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
Angle brackets can be used when the arguments contain commas:
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
Structures
==========
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.
A structure definition starts with: 'STRUCT <name>,[<initial offset>]' and ends with 'ENDS'. Structure definitions are local to the current module, but, as with labels, '@' can be used to override this.
Lines between STRUCT and ENDS should have the following format:
membername pseudo-operation operands
All fields are optional. Lines without label should start with whitespace.
Between the STRUCT and ENDS pseudo-instructions the following instructions can be used:
BYTE [<defaultvalue>]
----
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).
WORD [<defaultvalue>]
----
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).
D24 [<defaultvalue>]
---
To define a three byte member. The defaultvalue is used when no initialisation value is given when the structure is declared.
DWORD [<defaultvalue>]
----
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 WORD).
BLOCK <length>[,<fillbyte>]]
-----
To define an member of the specified number of bytes. ('#', DS and DEFS may be used instead of WORD).
ALIGN [<expression>]
-----
To align the offset. If the expression is omitted, 4 is assumed. ('##' May be used instead of ALIGN).
<structure name> [<init values>]
----------------
It is possible to nest structures, and give new defaults for the BYTE and WORD members.
Examples
--------
STRUCT SCOLOR
RED BYTE 4
GREEN BYTE 5
BLUE BYTE 6
ENDS
This is identical to:
SCOLOR EQU 3 ; lenght
SCOLOR.RED EQU 0 ; offset
SCOLOR.GREEN EQU 1 ; offset
SCOLOR.BLUE EQU 2 ; offset
STRUCT SDOT
X BYTE
Y BYTE
C SCOLOR 0,0,0 ; use new default values
ENDS
This is identical to:
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
STRUCT SPOS,4
X WORD
Y BYTE
ALIGN 2
AD WORD
ENDS
This is identical to:
SPOS EQU 10 ; length
SPOS.X EQU 4 ; offset
SPOS.Y EQU 6 ; offset
SPOS.AD EQU 8 ; offset
When a structure is defined it is possible to declare labels with it:
COLOR SCOLOR
This is identical to:
COLOR
COLOR.RED BYTE 4
COLOR.GREEN BYTE 5
COLOR.BLUE BYTE 6
Note the default values.
Or without label:
COLORTABLE
SCOLOR 0,0,0
SCOLOR 1,2,3
SCOLOR ,2
; etc.
This is identical to:
COLORTABLE
BYTE 0,0,0
BYTE 1,2,3
BYTE 4,2,6
; etc.
DOT1 SDOT 0,0, 0,0,0 ; or 0,0,0,0,0 or {0,0,{0,0,0}}
Only BYTE and WORD members can be initialised.
The resulting labels can be used as any other label:
ld b,(ix+SCOLOR.RED)
ld a,(COLOR.GREEN)
ld de,COLOR
; etc.
BUT!
Do not use the offset labels in indirections like:
LD A,(SDOT.X)
This will conflict with futher 'improvements' ;-)
If this is absolutely necessary (why?) use something like this:
LD A,(+SDOT.X)
"Extended instructions"
=======================
Of course the Z80 is only an 8 bit cpu, but sometimes ld hl,de would be nice. Sjasm 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.
Anyway, here's the list:
rl bc
rl de
rl hl
rr bc
rr de
rr hl
sla bc
sla de
sla hl
sll bc
sll de
sll hl
sli bc
sli de
sli hl
sra bc
sra de
sra hl
srl bc
srl de
srl hl
ld bc,bc
ld bc,de
ld bc,hl
ld bc,ix
ld bc,iy
ld bc,(hl)
ld bc,(ix+nn)
ld bc,(iy+nn)
ld de,bc
ld de,de