1 |
178 |
jshamlet |
----------------------------------------------
|
2 |
|
|
Open8_assembler Documentation - Index
|
3 |
|
|
----------------------------------------------
|
4 |
|
|
|
5 |
|
|
1..... Introduction
|
6 |
|
|
2..... Assembler Directives
|
7 |
|
|
3..... Assembler Syntax
|
8 |
|
|
3.1.. Case Sensitivity
|
9 |
|
|
3.2.. Comments
|
10 |
|
|
3.3.. Labels
|
11 |
|
|
3.4.. Number Types
|
12 |
|
|
3.5.. Strings
|
13 |
|
|
3.6.. Mnemonics
|
14 |
|
|
4..... Error Messages
|
15 |
|
|
5..... Bugs
|
16 |
|
|
6..... Temporary Files
|
17 |
|
|
7..... Compiling
|
18 |
|
|
7.1.. Compiling Object Files
|
19 |
|
|
7.2.. Compiling Library Files
|
20 |
|
|
8..... Linking
|
21 |
|
|
9..... Arithmetics
|
22 |
|
|
10.... Open8_as Flags
|
23 |
|
|
11.... Good things to know about Open8_as
|
24 |
|
|
12.... Legal Note
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
----------------------------------------------
|
28 |
|
|
1.... Introduction
|
29 |
|
|
----------------------------------------------
|
30 |
|
|
|
31 |
|
|
This assembler was originally based on the WLA Assembler. The original
|
32 |
|
|
WLA assembler can be found at
|
33 |
|
|
|
34 |
|
|
http://www.iki.fi/~vhelin/wla.html
|
35 |
|
|
|
36 |
|
|
Please don't bother Ville Helin if Open8_as does something wrong. No doubt I've
|
37 |
|
|
introduced a bug or two when I modified it for Open8 uRISC code.
|
38 |
|
|
|
39 |
|
|
Note that the original assembler was targetted for other architectures, and
|
40 |
|
|
intended for use by game designers, so some of the samples aren't proper
|
41 |
|
|
Open8 uRISC code.
|
42 |
|
|
|
43 |
|
|
----------------------------------------------
|
44 |
|
|
2.... Assembler Directives
|
45 |
|
|
----------------------------------------------
|
46 |
|
|
|
47 |
|
|
Here are the supported directives (with examples) in Open8_as:
|
48 |
|
|
|
49 |
|
|
.ASC "HELLO WORLD!"
|
50 |
|
|
.ASCTABLE
|
51 |
|
|
.ASCIITABLE
|
52 |
|
|
.ASM
|
53 |
|
|
.BR
|
54 |
|
|
.BREAKPOINT
|
55 |
|
|
.BYT 100, $30, %1000, "HELLO WORLD!"
|
56 |
|
|
.DB 100, $30, %1000, "HELLO WORLD!"
|
57 |
|
|
.DBCOS 0.2, 10, 3.2, 120, 1.3
|
58 |
|
|
.DBRND 20, 0, 10
|
59 |
|
|
.DBSIN 0.2, 10, 3.2, 120, 1.3
|
60 |
|
|
.DEFINE IF $FF0F
|
61 |
|
|
.DEF IF $FF0F
|
62 |
|
|
.DS 256, $10
|
63 |
|
|
.DSB 256, $10
|
64 |
|
|
.DSTRUCT waterdrop INSTANCEOF water DATA "tingle", 40, 120
|
65 |
|
|
.DSW 128, 20
|
66 |
|
|
.DW 16000, 10, 255
|
67 |
|
|
.DWCOS 0.2, 10, 3.2, 1024, 1.3
|
68 |
|
|
.DWRND 20, 0, 10
|
69 |
|
|
.DWSIN 0.2, 10, 3.2, 1024, 1.3
|
70 |
|
|
.ELSE
|
71 |
|
|
.EMPTYFILL $C9
|
72 |
|
|
.ENDASM
|
73 |
|
|
.ENDB
|
74 |
|
|
.ENDE
|
75 |
|
|
.ENDIF
|
76 |
|
|
.ENDM
|
77 |
|
|
.ENDME
|
78 |
|
|
.ENDR
|
79 |
|
|
.ENDRO
|
80 |
|
|
.ENDS
|
81 |
|
|
.ENDST
|
82 |
|
|
.ENUM $C000
|
83 |
|
|
.EQU IF $FF0F
|
84 |
|
|
.FAIL
|
85 |
|
|
.FCLOSE FP_DATABIN
|
86 |
|
|
.FOPEN "data.bin" FP_DATABIN
|
87 |
|
|
.FREAD FP_DATABIN DATA
|
88 |
|
|
.FSIZE FP_DATABIN SIZE
|
89 |
|
|
.IF DEBUG == 2
|
90 |
|
|
.IFDEF IF
|
91 |
|
|
.IFDEFM \2
|
92 |
|
|
.IFEQ DEBUG 2
|
93 |
|
|
.IFEXISTS "main.s"
|
94 |
|
|
.IFGR DEBUG 2
|
95 |
|
|
.IFGREQ DEBUG 1
|
96 |
|
|
.IFLE DEBUG 2
|
97 |
|
|
.IFLEEQ DEBUG 1
|
98 |
|
|
.IFNDEF IF
|
99 |
|
|
.IFNDEFM \2
|
100 |
|
|
.IFNEQ DEBUG 2
|
101 |
|
|
.INCBIN "sorority.bin"
|
102 |
|
|
.INCDIR "/usr/programming/gb/include/"
|
103 |
|
|
.INCLUDE "cgb_hardware.i"
|
104 |
|
|
.INPUT NAME
|
105 |
|
|
.MACRO TEST
|
106 |
|
|
.ORG $150
|
107 |
|
|
.OUTNAME "other.o"
|
108 |
|
|
.PRINTT "Here we are...\n"
|
109 |
|
|
.PRINTV DEC DEBUG+1
|
110 |
|
|
.REDEFINE IF $F
|
111 |
|
|
.REDEF IF $F
|
112 |
|
|
.REPEAT 6
|
113 |
|
|
.REPT 6
|
114 |
|
|
.SEED 123
|
115 |
|
|
.SECTION "Init" FORCE
|
116 |
|
|
.SHIFT
|
117 |
|
|
.STRUCT enemy_object
|
118 |
|
|
.SYM SAUSAGE
|
119 |
|
|
.SYMBOL SAUSAGE
|
120 |
|
|
.UNDEFINE DEBUG
|
121 |
|
|
.UNDEF DEBUG
|
122 |
|
|
.WORD 16000, 10, 255
|
123 |
|
|
|
124 |
|
|
|
125 |
|
|
Descriptions:
|
126 |
|
|
|
127 |
|
|
----
|
128 |
|
|
.ASM
|
129 |
|
|
----
|
130 |
|
|
|
131 |
|
|
Tells Open8_as to start assembling. Use .ASM to continue the work which has been
|
132 |
|
|
disabled with .ENDASM. .ASM and .ENDASM can be used to mask away big blocks
|
133 |
|
|
of code. This is analogous to the ANSI C -comments (/*...*/), but .ASM and
|
134 |
|
|
.ENDASM can be nested, unlike the ANSI C -counterpart.
|
135 |
|
|
|
136 |
|
|
This is not a compulsory directive.
|
137 |
|
|
|
138 |
|
|
-------
|
139 |
|
|
.ENDASM
|
140 |
|
|
-------
|
141 |
|
|
|
142 |
|
|
Tells Open8_as to stop assembling. Use .ASM to continue the work.
|
143 |
|
|
|
144 |
|
|
This is not a compulsory directive.
|
145 |
|
|
|
146 |
|
|
----------------
|
147 |
|
|
.DBRND 20, 0, 10
|
148 |
|
|
----------------
|
149 |
|
|
|
150 |
|
|
Defines bytes, just like .DSB does, only this time they are filled with
|
151 |
|
|
(pseudo) random numbers. We use stdlib's rand() to generate the random
|
152 |
|
|
numbers. If you want to seed the random number generator, use .SEED.
|
153 |
|
|
|
154 |
|
|
The first parameter (20 in the example) defines the amount of numbers
|
155 |
|
|
we want to generate. The next two tell the range of the random numbers,
|
156 |
|
|
i.e. min and max.
|
157 |
|
|
|
158 |
|
|
Here's how it works:
|
159 |
|
|
|
160 |
|
|
.DBRND A, B, C
|
161 |
|
|
|
162 |
|
|
for (i = 0; i < A; i++)
|
163 |
|
|
output_data((rand() % (C-B+1)) + B);
|
164 |
|
|
|
165 |
|
|
This is not a compulsory directive.
|
166 |
|
|
|
167 |
|
|
----------------
|
168 |
|
|
.DWRND 20, 0, 10
|
169 |
|
|
----------------
|
170 |
|
|
|
171 |
|
|
Analogous to .DBRND (but defines words).
|
172 |
|
|
|
173 |
|
|
This is not a compulsory directive.
|
174 |
|
|
|
175 |
|
|
-----------------------------
|
176 |
|
|
.DBCOS 0.2, 10, 3.2, 120, 1.3
|
177 |
|
|
-----------------------------
|
178 |
|
|
|
179 |
|
|
Defines bytes just like .DSB does, only this time they are filled with
|
180 |
|
|
cosine data. .DBCOS takes five arguments.
|
181 |
|
|
|
182 |
|
|
The first argument is the starting angle. Angle value ranges from 0 to
|
183 |
|
|
359.999..., but you can supply Open8_as with values that are out of the range -
|
184 |
|
|
Open8_as fixes them ok. The value can be integer or float.
|
185 |
|
|
|
186 |
|
|
The second one descibes the amount of additional angles. The example
|
187 |
|
|
will define 11 angles.
|
188 |
|
|
|
189 |
|
|
The third one is the adder value which is added to the angle value when
|
190 |
|
|
next angle is calculated. The value can be integer or float.
|
191 |
|
|
|
192 |
|
|
The fourth and fifth ones can be seen from the pseudo code below, which
|
193 |
|
|
also describes how .DBCOS works. The values can be integer or float.
|
194 |
|
|
|
195 |
|
|
Remember that cos (and sin) here returns values ranging from -1 to 1.
|
196 |
|
|
|
197 |
|
|
.DBCOS A, B, C, D, E
|
198 |
|
|
|
199 |
|
|
for (B++; B > 0; B--) {
|
200 |
|
|
output_data((D * cos(A)) + E)
|
201 |
|
|
A = keep_in_range(A + C)
|
202 |
|
|
}
|
203 |
|
|
|
204 |
|
|
This is not a compulsory directive.
|
205 |
|
|
|
206 |
|
|
-----------------------------
|
207 |
|
|
.DBSIN 0.2, 10, 3.2, 120, 1.3
|
208 |
|
|
-----------------------------
|
209 |
|
|
|
210 |
|
|
Analogous to .DBCOS, but does sin() instead of cos().
|
211 |
|
|
|
212 |
|
|
This is not a compulsory directive.
|
213 |
|
|
|
214 |
|
|
------------------------------
|
215 |
|
|
.DWCOS 0.2, 10, 3.2, 1024, 1.3
|
216 |
|
|
------------------------------
|
217 |
|
|
|
218 |
|
|
Analogous to .DBCOS (but defines words).
|
219 |
|
|
|
220 |
|
|
This is not a compulsory directive.
|
221 |
|
|
|
222 |
|
|
------------------------------
|
223 |
|
|
.DWSIN 0.2, 10, 3.2, 1024, 1.3
|
224 |
|
|
------------------------------
|
225 |
|
|
|
226 |
|
|
Analogous to .DBCOS (but defines words and does sin() instead of cos()).
|
227 |
|
|
|
228 |
|
|
This is not a compulsory directive.
|
229 |
|
|
|
230 |
|
|
--------------
|
231 |
|
|
.EMPTYFILL $C9
|
232 |
|
|
--------------
|
233 |
|
|
|
234 |
|
|
This byte is used in filling the unused areas of memory. EMPTYFILL
|
235 |
|
|
defaults to $00.
|
236 |
|
|
|
237 |
|
|
This is not a compulsory directive.
|
238 |
|
|
|
239 |
|
|
--------------------------------------
|
240 |
|
|
.INCDIR "/usr/programming/Open8/include/"
|
241 |
|
|
--------------------------------------
|
242 |
|
|
|
243 |
|
|
Changes the current include root directory. Use this to specify main
|
244 |
|
|
directory for the following .INCLUDE and .INCBIN directives.
|
245 |
|
|
If you want to change to the current working directory (Open8_as also defaults
|
246 |
|
|
to this), use
|
247 |
|
|
|
248 |
|
|
.INCDIR ""
|
249 |
|
|
|
250 |
|
|
This is not a compulsory directive.
|
251 |
|
|
|
252 |
|
|
-------------------------
|
253 |
|
|
.INCLUDE "cgb_hardware.i"
|
254 |
|
|
-------------------------
|
255 |
|
|
|
256 |
|
|
Includes the specified file to the source file. If the file's not found
|
257 |
|
|
in the .INCDIR directory, Open8_as tries to find it in the current working
|
258 |
|
|
directory.
|
259 |
|
|
|
260 |
|
|
This is not a compulsory directive.
|
261 |
|
|
|
262 |
|
|
----------------------
|
263 |
|
|
.INCBIN "sorority.bin"
|
264 |
|
|
----------------------
|
265 |
|
|
|
266 |
|
|
Includes the specified data file into the source file. .INCBIN caches
|
267 |
|
|
all files into memory, so you can .INCBIN any data file millions of
|
268 |
|
|
times, but it is loaded from hard drive only once.
|
269 |
|
|
|
270 |
|
|
You can optionally use SWAP after the file name, e.g.,
|
271 |
|
|
|
272 |
|
|
.INCBIN "kitten.bin" SWAP
|
273 |
|
|
|
274 |
|
|
.INCBIN data is divided into blocks of two bytes, and inside every block
|
275 |
|
|
the bytes are exchanged (like "SWAP r" does to nibbles). This requires that
|
276 |
|
|
the size of the file is even.
|
277 |
|
|
|
278 |
|
|
You can also force Open8_as to skip n bytes from the beginning of the file
|
279 |
|
|
by writing for example:
|
280 |
|
|
|
281 |
|
|
.INCBIN "kitten.bin" SKIP 4
|
282 |
|
|
|
283 |
|
|
Four bytes are skipped from the beginning of kitten.bin and the rest
|
284 |
|
|
is incbinned.
|
285 |
|
|
|
286 |
|
|
It is also possible to incbin only n bytes from a file:
|
287 |
|
|
|
288 |
|
|
.INCBIN "kitten.bin" READ 10
|
289 |
|
|
|
290 |
|
|
Will read ten bytes from the beginning of kitten.bin.
|
291 |
|
|
|
292 |
|
|
You can also force Open8_as to create a definition holding the size
|
293 |
|
|
of the file:
|
294 |
|
|
|
295 |
|
|
.INCBIN "kitten.bin" FSIZE size_of_kitten
|
296 |
|
|
|
297 |
|
|
And you can combine all these four commands:
|
298 |
|
|
|
299 |
|
|
.INCBIN "kitten.bin" SKIP 10 READ 8 SWAP FSIZE size_of_kitten
|
300 |
|
|
|
301 |
|
|
This example shows how to incbin eight bytes (swapped) after skipping
|
302 |
|
|
10 bytes from the beginning of file "kitten.bin", and how to get the
|
303 |
|
|
size of the file into a definition label "size_of_kitten". Note that the
|
304 |
|
|
order of the extra commands is important.
|
305 |
|
|
|
306 |
|
|
If the file's not found in the .INCDIR directory, Open8_as tries to find it
|
307 |
|
|
in the current working directory.
|
308 |
|
|
|
309 |
|
|
This is not a compulsory directive.
|
310 |
|
|
|
311 |
|
|
-----------
|
312 |
|
|
.INPUT NAME
|
313 |
|
|
-----------
|
314 |
|
|
|
315 |
|
|
.INPUT is much like any Basic-language input: .INPUT asks the user
|
316 |
|
|
for a value or string. After .INPUT is the variable name used to store
|
317 |
|
|
the data.
|
318 |
|
|
|
319 |
|
|
.INPUT works like .REDEFINE, but the user gets to type in the data.
|
320 |
|
|
|
321 |
|
|
Here are few examples how to use input:
|
322 |
|
|
|
323 |
|
|
.PRINTT "The name of the TFT pic? "
|
324 |
|
|
.INPUT NAME
|
325 |
|
|
.NAME NAME
|
326 |
|
|
|
327 |
|
|
...
|
328 |
|
|
|
329 |
|
|
.PRINTT "Give the .DB amount.\n"
|
330 |
|
|
.INPUT S
|
331 |
|
|
.PRINTT "Give .DB data one at a time.\n"
|
332 |
|
|
.REPEAT S
|
333 |
|
|
.INPUT B
|
334 |
|
|
.DB B
|
335 |
|
|
.ENDR
|
336 |
|
|
|
337 |
|
|
...
|
338 |
|
|
|
339 |
|
|
This is not a compulsory directive.
|
340 |
|
|
|
341 |
|
|
-----
|
342 |
|
|
.FAIL
|
343 |
|
|
-----
|
344 |
|
|
|
345 |
|
|
Terminates the compiling process.
|
346 |
|
|
|
347 |
|
|
This is not a compulsory directive.
|
348 |
|
|
|
349 |
|
|
------------------
|
350 |
|
|
.FCLOSE FP_DATABIN
|
351 |
|
|
------------------
|
352 |
|
|
|
353 |
|
|
Closes the filehandle FP_DATABIN.
|
354 |
|
|
|
355 |
|
|
This is not a compulsory directive.
|
356 |
|
|
|
357 |
|
|
----------------------------
|
358 |
|
|
.FOPEN "data.bin" FP_DATABIN
|
359 |
|
|
----------------------------
|
360 |
|
|
|
361 |
|
|
Opens the file "data.bin" for reading and associates the filehandle with
|
362 |
|
|
name "FP_DATABIN".
|
363 |
|
|
|
364 |
|
|
This is not a compulsory directive.
|
365 |
|
|
|
366 |
|
|
----------------------
|
367 |
|
|
.FREAD FP_DATABIN DATA
|
368 |
|
|
----------------------
|
369 |
|
|
|
370 |
|
|
Reads one byte from "FP_DATABIN" and creates a definition called "DATA"
|
371 |
|
|
to hold it. "DATA" is an ordinary definition label, so you can .UNDEFINE it.
|
372 |
|
|
|
373 |
|
|
Here's an example on how to use .FREAD:
|
374 |
|
|
|
375 |
|
|
.fopen "data.bin" fp
|
376 |
|
|
.fsize fp t
|
377 |
|
|
.repeat t
|
378 |
|
|
.fread fp d
|
379 |
|
|
.db d+26
|
380 |
|
|
.endr
|
381 |
|
|
.undefine t, d
|
382 |
|
|
|
383 |
|
|
This is not a compulsory directive.
|
384 |
|
|
|
385 |
|
|
----------------------
|
386 |
|
|
.FSIZE FP_DATABIN SIZE
|
387 |
|
|
----------------------
|
388 |
|
|
|
389 |
|
|
Creates a definition called "SIZE", which holds the size of the file
|
390 |
|
|
associated with the filehandle "FP_DATABIN". "SIZE" is an ordinary
|
391 |
|
|
definition label, so you can .UNDEFINE it.
|
392 |
|
|
|
393 |
|
|
This is not a compulsory directive.
|
394 |
|
|
|
395 |
|
|
-----------
|
396 |
|
|
.MACRO TEST
|
397 |
|
|
-----------
|
398 |
|
|
|
399 |
|
|
Begins a macro called 'TEST'.
|
400 |
|
|
|
401 |
|
|
You can use '\@' inside a macro to e.g., separate a label from the other
|
402 |
|
|
macro 'TEST' occurrences. '\@' is replaced with an integer number
|
403 |
|
|
indicating the amount of times the macro has been called previously so
|
404 |
|
|
it is unique to every macro call. '\@' can also be used inside strings
|
405 |
|
|
inside a macro or just as a plain value. Look at the following examples
|
406 |
|
|
for more information.
|
407 |
|
|
|
408 |
|
|
Also, if you want to use macro arguments in e.g., calculation, you can
|
409 |
|
|
type '\X' where X is the number of the argument. Another way to refer
|
410 |
|
|
to the arguments is to use their names given in the definition of the
|
411 |
|
|
macro (see the examples for this).
|
412 |
|
|
|
413 |
|
|
Remember to use .ENDM to finish the macro definition. Note that you
|
414 |
|
|
cannot use .INCLUDE inside a macro. Note that Open8_as' macros are in fact
|
415 |
|
|
more like procedures than real macros, because Open8_as doesn't substitute
|
416 |
|
|
macro calls with macro data. Instead Open8_as jumps to the macro when it
|
417 |
|
|
encounters a macro call at compile time.
|
418 |
|
|
|
419 |
|
|
You can call macros from inside a macro. Note that the preprocessor
|
420 |
|
|
does not expand the macros. Open8_as traverses through the code according to
|
421 |
|
|
the macro calls, so macros really define a very simple programming
|
422 |
|
|
language.
|
423 |
|
|
|
424 |
|
|
Here are some examples:
|
425 |
|
|
|
426 |
|
|
.MACRO NOPMONSTER
|
427 |
|
|
.REPT 32 ; it's just an example...
|
428 |
|
|
NOP
|
429 |
|
|
.ENDR
|
430 |
|
|
.ENDM
|
431 |
|
|
|
432 |
|
|
.MACRO LOAD_ABCD
|
433 |
|
|
LD A, \1
|
434 |
|
|
LD B, \2
|
435 |
|
|
LD C, \3
|
436 |
|
|
LD D, \4
|
437 |
|
|
NOPMONSTER
|
438 |
|
|
LD HL, 1<<\1
|
439 |
|
|
.INCBIN \5
|
440 |
|
|
.ENDM
|
441 |
|
|
|
442 |
|
|
.MACRO QUEEN
|
443 |
|
|
|
444 |
|
|
QUEEN\@:
|
445 |
|
|
LD A, \1
|
446 |
|
|
LD B, \1
|
447 |
|
|
CALL QUEEN\@
|
448 |
|
|
|
449 |
|
|
.DB "\@", 0 ; will translate into a zero terminated string
|
450 |
|
|
; holding the amount of macro QUEEN calls.
|
451 |
|
|
.DB "\\@", 0 ; will translate into a string containing
|
452 |
|
|
; \@.
|
453 |
|
|
.DB \@ ; will translate into a number indicating
|
454 |
|
|
; the amount of macro QUEEN calls.
|
455 |
|
|
|
456 |
|
|
.ENDM
|
457 |
|
|
|
458 |
|
|
.MACRO LOAD_ABCD_2 ARGS ONE, TWO, THREE, FOUR, FIVE
|
459 |
|
|
LD A, ONE
|
460 |
|
|
LD B, TWO
|
461 |
|
|
LD C, THREE
|
462 |
|
|
LD D, FOUR
|
463 |
|
|
NOPMONSTER
|
464 |
|
|
LD HL, 1< \2, etc.).
|
465 |
|
|
.SHIFT can thus only be used inside a .MACRO.
|
466 |
|
|
|
467 |
|
|
This is not a compulsory directive.
|
468 |
|
|
|
469 |
|
|
---------
|
470 |
|
|
.ORG $150
|
471 |
|
|
---------
|
472 |
|
|
|
473 |
|
|
Defines the starting address. The default starting address is $0
|
474 |
|
|
|
475 |
|
|
This is not a compulsory directive.
|
476 |
|
|
|
477 |
|
|
------------
|
478 |
|
|
.DS 256, $10
|
479 |
|
|
------------
|
480 |
|
|
|
481 |
|
|
.DS is an alias for .DSB.
|
482 |
|
|
|
483 |
|
|
This is not a compulsory directive.
|
484 |
|
|
|
485 |
|
|
-------------
|
486 |
|
|
.DSB 256, $10
|
487 |
|
|
-------------
|
488 |
|
|
|
489 |
|
|
Defines 256 bytes of $10.
|
490 |
|
|
|
491 |
|
|
This is not a compulsory directive.
|
492 |
|
|
|
493 |
|
|
----------------------------------------------------------
|
494 |
|
|
.DSTRUCT waterdrop INSTANCEOF water DATA "tingle", 40, 120
|
495 |
|
|
----------------------------------------------------------
|
496 |
|
|
|
497 |
|
|
Defines an instance of struct water, called waterdrop, and fills
|
498 |
|
|
it with the given data. Before calling .DSTRUCT we must have defined
|
499 |
|
|
the structure, and in this example it could be like:
|
500 |
|
|
|
501 |
|
|
.STRUCT water
|
502 |
|
|
name ds 8
|
503 |
|
|
age db
|
504 |
|
|
weight dw
|
505 |
|
|
.ENDST
|
506 |
|
|
|
507 |
|
|
Note that the keywords INSTANCEOF and DATA are optional, so
|
508 |
|
|
|
509 |
|
|
.DSTRUCT waterdrop, water, "tingle", 40, 120
|
510 |
|
|
|
511 |
|
|
also works. Also note that Open8_as fills the missing bytes with the data
|
512 |
|
|
defined with .EMPTYFILL, or $00 if no .EMPTYFILL has been issued.
|
513 |
|
|
|
514 |
|
|
In this example you would also get the following labels:
|
515 |
|
|
|
516 |
|
|
waterdrop
|
517 |
|
|
waterdrop.name
|
518 |
|
|
waterdrop.age
|
519 |
|
|
waterdrop.weight
|
520 |
|
|
|
521 |
|
|
This is not a compulsory directive.
|
522 |
|
|
|
523 |
|
|
------------
|
524 |
|
|
.DSW 128, 20
|
525 |
|
|
------------
|
526 |
|
|
|
527 |
|
|
Defines 128 words (two bytes) of 20.
|
528 |
|
|
|
529 |
|
|
This is not a compulsory directive.
|
530 |
|
|
|
531 |
|
|
-----------------------------------
|
532 |
|
|
.DB 100, $30, %1000, "HELLO WORLD!"
|
533 |
|
|
-----------------------------------
|
534 |
|
|
|
535 |
|
|
Defines bytes.
|
536 |
|
|
|
537 |
|
|
This is not a compulsory directive.
|
538 |
|
|
|
539 |
|
|
------------------------------------
|
540 |
|
|
.BYT 100, $30, %1000, "HELLO WORLD!"
|
541 |
|
|
------------------------------------
|
542 |
|
|
|
543 |
|
|
.BYT is an alias for .DB.
|
544 |
|
|
|
545 |
|
|
This is not a compulsory directive.
|
546 |
|
|
|
547 |
|
|
------------
|
548 |
|
|
.SYM SAUSAGE
|
549 |
|
|
------------
|
550 |
|
|
|
551 |
|
|
Open8_as treats symbols ("SAUSAGE" in this example) like labels, but they
|
552 |
|
|
only appear in the symbol files Open8_link outputs. Useful for finding out
|
553 |
|
|
the location where Open8_link puts data.
|
554 |
|
|
|
555 |
|
|
This is not a compulsory directive.
|
556 |
|
|
|
557 |
|
|
---------------
|
558 |
|
|
.SYMBOL SAUSAGE
|
559 |
|
|
---------------
|
560 |
|
|
|
561 |
|
|
.SYMBOL is an alias for .SYM.
|
562 |
|
|
|
563 |
|
|
This is not a compulsory directive.
|
564 |
|
|
|
565 |
|
|
---
|
566 |
|
|
.BR
|
567 |
|
|
---
|
568 |
|
|
|
569 |
|
|
Inserts a breakpoint that behaves like a .SYM without a name. Breakpoints
|
570 |
|
|
can only be seen in Open8_link's symbol file.
|
571 |
|
|
|
572 |
|
|
This is not a compulsory directive.
|
573 |
|
|
|
574 |
|
|
-----------
|
575 |
|
|
.BREAKPOINT
|
576 |
|
|
-----------
|
577 |
|
|
|
578 |
|
|
.BREAKPOINT is an alias for .BR.
|
579 |
|
|
|
580 |
|
|
This is not a compulsory directive.
|
581 |
|
|
|
582 |
|
|
-----------
|
583 |
|
|
.ASCIITABLE
|
584 |
|
|
-----------
|
585 |
|
|
|
586 |
|
|
.ASCIITABLE's only purpose is to provide character mapping for .ASC.
|
587 |
|
|
Take a look at the example:
|
588 |
|
|
|
589 |
|
|
.ASCIITABLE
|
590 |
|
|
MAP "A" TO "Z" = 0
|
591 |
|
|
MAP "!" = 90
|
592 |
|
|
.ENDA
|
593 |
|
|
|
594 |
|
|
Here we set such a mapping that character 'A' is equal to 0, 'B'
|
595 |
|
|
is equal to 1, 'C' is equal to 2, and so on, and '!' is equal to 90.
|
596 |
|
|
|
597 |
|
|
After you've given the .ASCIITABLE, use .ASC to define bytes using
|
598 |
|
|
this mapping (.ASC is an alias for .DB, but with .ASCIITABLE mapping).
|
599 |
|
|
For example, .ASC "AB!" would define bytes 0, 1 and 90.
|
600 |
|
|
|
601 |
|
|
Note that the following works as well:
|
602 |
|
|
|
603 |
|
|
.ASCIITABLE
|
604 |
|
|
MAP 'A' TO 'Z' = 0
|
605 |
|
|
MAP 65 = 90
|
606 |
|
|
.ENDA
|
607 |
|
|
|
608 |
|
|
Also note that the characters that are not given any mapping in
|
609 |
|
|
.ASCIITABLE map to themselves (i.e., 'A' maps to 'A', etc.).
|
610 |
|
|
|
611 |
|
|
This is not a compulsory directive.
|
612 |
|
|
|
613 |
|
|
---------
|
614 |
|
|
.ASCTABLE
|
615 |
|
|
---------
|
616 |
|
|
|
617 |
|
|
.ASCTABLE is an alias for .ASCIITABLE.
|
618 |
|
|
|
619 |
|
|
This is not a compulsory directive.
|
620 |
|
|
|
621 |
|
|
-------------------
|
622 |
|
|
.ASC "HELLO WORLD!"
|
623 |
|
|
-------------------
|
624 |
|
|
|
625 |
|
|
.ASC is an alias for .DB, but if you use .ASC it will remap
|
626 |
|
|
the characters using the mapping given via .ASCIITABLE.
|
627 |
|
|
|
628 |
|
|
This is not a compulsory directive.
|
629 |
|
|
|
630 |
|
|
------------------
|
631 |
|
|
.DW 16000, 10, 255
|
632 |
|
|
------------------
|
633 |
|
|
|
634 |
|
|
Defines words (two bytes each). .DW takes only numbers and
|
635 |
|
|
characters as input, not strings.
|
636 |
|
|
|
637 |
|
|
This is not a compulsory directive.
|
638 |
|
|
|
639 |
|
|
--------------------
|
640 |
|
|
.WORD 16000, 10, 255
|
641 |
|
|
--------------------
|
642 |
|
|
|
643 |
|
|
.WORD is an alias for .DW.
|
644 |
|
|
|
645 |
|
|
This is not a compulsory directive.
|
646 |
|
|
|
647 |
|
|
----------------
|
648 |
|
|
.DEFINE IF $FF0F
|
649 |
|
|
----------------
|
650 |
|
|
|
651 |
|
|
Assigns a number or a string to a definition label.
|
652 |
|
|
|
653 |
|
|
By default all defines are local to the file where they are
|
654 |
|
|
presented. If you want to make the definition visible to all the
|
655 |
|
|
files in the project, use .EXPORT.
|
656 |
|
|
|
657 |
|
|
Here are some examples:
|
658 |
|
|
|
659 |
|
|
.DEFINE X 1000
|
660 |
|
|
.DEFINE FILE "PD-03.TFT"
|
661 |
|
|
.DEFINE TXT1 "hello and welcome", 1, "to the Open8", 0
|
662 |
|
|
.DEFINE BYTES 1, 2, 3, 4, 5
|
663 |
|
|
.DEFINE COMPUTATION X+1
|
664 |
|
|
.DEFINE DEFAULTV
|
665 |
|
|
|
666 |
|
|
All definitions with multiple values are marked as data strings,
|
667 |
|
|
and .DB is about the only place where you can later on use them.
|
668 |
|
|
|
669 |
|
|
.DEFINE BYTES 1, 2, 3, 4, 5
|
670 |
|
|
.DB 0, BYTES, 6
|
671 |
|
|
|
672 |
|
|
is the same as
|
673 |
|
|
|
674 |
|
|
.DB 0, 1, 2, 3, 4, 5, 6
|
675 |
|
|
|
676 |
|
|
If you omit the definition value (in our example "DEFAULTV"), Open8_as
|
677 |
|
|
will default to 0.
|
678 |
|
|
|
679 |
|
|
Note that you must do your definition before you use it, otherwise
|
680 |
|
|
Open8_as will use the final value of the definition. Here's an example
|
681 |
|
|
of this:
|
682 |
|
|
|
683 |
|
|
.DEFINE AAA 10
|
684 |
|
|
.DB AAA ; will be 10.
|
685 |
|
|
.REDEFINE AAA 11
|
686 |
|
|
|
687 |
|
|
but
|
688 |
|
|
|
689 |
|
|
.DB AAA ; will be 11.
|
690 |
|
|
.DEFINE AAA 10
|
691 |
|
|
.REDEFINE AAA 11
|
692 |
|
|
|
693 |
|
|
You can also create definitions on the command line. Here's an
|
694 |
|
|
example of this:
|
695 |
|
|
|
696 |
|
|
Open8_as AS -vl -DMOON -DNAME=john -DPRICE=100 -DADDRESS=$100 math.s
|
697 |
|
|
|
698 |
|
|
MOON's value will be 0, NAME is a string definition with value "john",
|
699 |
|
|
PRICE's value will be 100, and ADDRESS's value will be $100.
|
700 |
|
|
|
701 |
|
|
Note that
|
702 |
|
|
|
703 |
|
|
.DEFINE AAA = 10 ; the same as ".DEFINE AAA 10".
|
704 |
|
|
|
705 |
|
|
works as well.
|
706 |
|
|
|
707 |
|
|
This is not a compulsory directive.
|
708 |
|
|
|
709 |
|
|
-------------
|
710 |
|
|
.DEF IF $FF0F
|
711 |
|
|
-------------
|
712 |
|
|
|
713 |
|
|
.DEF is an alias for .DEFINE.
|
714 |
|
|
|
715 |
|
|
This is not a compulsory directive.
|
716 |
|
|
|
717 |
|
|
-------------
|
718 |
|
|
.EQU IF $FF0F
|
719 |
|
|
-------------
|
720 |
|
|
|
721 |
|
|
.EQU is an alias for .DEFINE.
|
722 |
|
|
|
723 |
|
|
This is not a compulsory directive.
|
724 |
|
|
|
725 |
|
|
----------------
|
726 |
|
|
.REDEFINE IF $0F
|
727 |
|
|
----------------
|
728 |
|
|
|
729 |
|
|
Assigns a new value or a string to an old definition. If the
|
730 |
|
|
definition doesn't exist, .REDEFINE performs .DEFINE's work.
|
731 |
|
|
|
732 |
|
|
When used with .REPT REDEFINE helps creating tables:
|
733 |
|
|
|
734 |
|
|
.DEFINE CNT 0
|
735 |
|
|
|
736 |
|
|
.REPT 256
|
737 |
|
|
.DB CNT
|
738 |
|
|
.REDEFINE CNT CNT+1
|
739 |
|
|
.ENDR
|
740 |
|
|
|
741 |
|
|
This is not a compulsory directive.
|
742 |
|
|
|
743 |
|
|
-------------
|
744 |
|
|
.REDEF IF $0F
|
745 |
|
|
-------------
|
746 |
|
|
|
747 |
|
|
.REDEF is an alias for .REDEFINE.
|
748 |
|
|
|
749 |
|
|
This is not a compulsory directive.
|
750 |
|
|
|
751 |
|
|
--------------
|
752 |
|
|
.IF DEBUG == 2
|
753 |
|
|
--------------
|
754 |
|
|
|
755 |
|
|
If the condition is fulfilled the following piece of code is
|
756 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise
|
757 |
|
|
it is skipped. Operands must be immediate values or strings.
|
758 |
|
|
|
759 |
|
|
The following operators are supported:
|
760 |
|
|
< - less than
|
761 |
|
|
<= - less or equal to
|
762 |
|
|
> - greater than
|
763 |
|
|
>= - greater or equal to
|
764 |
|
|
== - equals to
|
765 |
|
|
!= - doesn't equal to
|
766 |
|
|
|
767 |
|
|
All IF (yes, including .IFDEF, .IFNDEF, etc) directives can be
|
768 |
|
|
nested.
|
769 |
|
|
|
770 |
|
|
This is not a compulsory directive.
|
771 |
|
|
|
772 |
|
|
---------
|
773 |
|
|
.IFDEF IF
|
774 |
|
|
---------
|
775 |
|
|
|
776 |
|
|
If "IF" is defined, then the following piece of code is acknowledged
|
777 |
|
|
until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
778 |
|
|
|
779 |
|
|
This is not a compulsory directive.
|
780 |
|
|
|
781 |
|
|
------------------
|
782 |
|
|
.IFEXISTS "main.s"
|
783 |
|
|
------------------
|
784 |
|
|
|
785 |
|
|
If "main.s" file can be found, then the following piece of code is
|
786 |
|
|
acknowledged until .ENDIF/.LESE occurs in the text, otherwise it is
|
787 |
|
|
skipped.
|
788 |
|
|
|
789 |
|
|
By writing the following few lines you can include a file if it exists
|
790 |
|
|
without breaking the compiling loop if it doesn't exist.
|
791 |
|
|
|
792 |
|
|
.IFEXISTS FILE
|
793 |
|
|
.INCLUDE FILE
|
794 |
|
|
.ENDIF
|
795 |
|
|
|
796 |
|
|
This is not a compulsory directive.
|
797 |
|
|
|
798 |
|
|
---------------
|
799 |
|
|
.UNDEFINE DEBUG
|
800 |
|
|
---------------
|
801 |
|
|
|
802 |
|
|
Removes the supplied definition label from system. If there is no
|
803 |
|
|
such label as given no error is displayed as the result would be the
|
804 |
|
|
same.
|
805 |
|
|
|
806 |
|
|
You can undefine as many definitions as you wish with one .UNDEFINE:
|
807 |
|
|
|
808 |
|
|
.UNDEFINE NUMBER, NAME, ADDRESS, COUNTRY
|
809 |
|
|
.UNDEFINE NAME, AGE
|
810 |
|
|
|
811 |
|
|
This is not a compulsory directive.
|
812 |
|
|
|
813 |
|
|
------------
|
814 |
|
|
.UNDEF DEBUG
|
815 |
|
|
------------
|
816 |
|
|
|
817 |
|
|
.UNDEF is an alias for .UNDEFINE.
|
818 |
|
|
|
819 |
|
|
This is not a compulsory directive.
|
820 |
|
|
|
821 |
|
|
----------
|
822 |
|
|
.IFNDEF IF
|
823 |
|
|
----------
|
824 |
|
|
|
825 |
|
|
If "IF" is not defined, then the following piece of code is acknowledged
|
826 |
|
|
until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
827 |
|
|
|
828 |
|
|
This is not a compulsory directive.
|
829 |
|
|
|
830 |
|
|
----------
|
831 |
|
|
.IFDEFM \2
|
832 |
|
|
----------
|
833 |
|
|
|
834 |
|
|
If the specified argument is defined (argument number two, in the example),
|
835 |
|
|
then the following piece of code is acknowledged until .ENDIF/.ELSE occurs
|
836 |
|
|
in the macro, otherwise it is skipped.
|
837 |
|
|
|
838 |
|
|
This is not a compulsory directive. .IFDEFM works only inside a macro.
|
839 |
|
|
|
840 |
|
|
-----------
|
841 |
|
|
.IFNDEFM \2
|
842 |
|
|
-----------
|
843 |
|
|
|
844 |
|
|
If the specified argument is not defined, then the following piece of
|
845 |
|
|
code is acknowledged until .ENDIF/.ELSE occurs in the macro, otherwise
|
846 |
|
|
it is skipped.
|
847 |
|
|
|
848 |
|
|
This is not a compulsory directive. .IFNDEFM works only inside a macro.
|
849 |
|
|
|
850 |
|
|
-------------
|
851 |
|
|
.IFEQ DEBUG 2
|
852 |
|
|
-------------
|
853 |
|
|
|
854 |
|
|
If the value of DEBUG equals to 2, then the following piece of code is
|
855 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
856 |
|
|
Both arguments can be computations, defines or immediate values.
|
857 |
|
|
|
858 |
|
|
This is not a compulsory directive.
|
859 |
|
|
|
860 |
|
|
--------------
|
861 |
|
|
.IFNEQ DEBUG 2
|
862 |
|
|
--------------
|
863 |
|
|
|
864 |
|
|
If the value of DEBUG doesn't equal to 2, then the following piece of
|
865 |
|
|
code is acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is
|
866 |
|
|
skipped. Both arguments can be computations, defines or immediate
|
867 |
|
|
values.
|
868 |
|
|
|
869 |
|
|
This is not a compulsory directive.
|
870 |
|
|
|
871 |
|
|
-------------
|
872 |
|
|
.IFLE DEBUG 2
|
873 |
|
|
-------------
|
874 |
|
|
|
875 |
|
|
If the value of DEBUG is less than 2, then the following piece of code is
|
876 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
877 |
|
|
Both arguments can be computations, defines or immediate values.
|
878 |
|
|
|
879 |
|
|
This is not a compulsory directive.
|
880 |
|
|
|
881 |
|
|
---------------
|
882 |
|
|
.IFLEEQ DEBUG 2
|
883 |
|
|
---------------
|
884 |
|
|
|
885 |
|
|
If the value of DEBUG is less or equal to 2, then the following piece of code is
|
886 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
887 |
|
|
Both arguments can be computations, defines or immediate values.
|
888 |
|
|
|
889 |
|
|
This is not a compulsory directive.
|
890 |
|
|
|
891 |
|
|
-------------
|
892 |
|
|
.IFGR DEBUG 2
|
893 |
|
|
-------------
|
894 |
|
|
|
895 |
|
|
If the value of DEBUG is greater than 2, then the following piece of code is
|
896 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
897 |
|
|
Both arguments can be computations, defines or immediate values.
|
898 |
|
|
|
899 |
|
|
This is not a compulsory directive.
|
900 |
|
|
|
901 |
|
|
---------------
|
902 |
|
|
.IFGREQ DEBUG 2
|
903 |
|
|
---------------
|
904 |
|
|
|
905 |
|
|
If the value of DEBUG is greater or equal to 2, then the following piece of code is
|
906 |
|
|
acknowledged until .ENDIF/.ELSE occurs in the text, otherwise it is skipped.
|
907 |
|
|
Both arguments can be computations, defines or immediate values.
|
908 |
|
|
|
909 |
|
|
This is not a compulsory directive.
|
910 |
|
|
|
911 |
|
|
-----
|
912 |
|
|
.ELSE
|
913 |
|
|
-----
|
914 |
|
|
|
915 |
|
|
If the previous .IFxxx failed then the following text until
|
916 |
|
|
.ENDIF is acknowledged.
|
917 |
|
|
|
918 |
|
|
This is not a compulsory directive.
|
919 |
|
|
|
920 |
|
|
------
|
921 |
|
|
.ENDIF
|
922 |
|
|
------
|
923 |
|
|
|
924 |
|
|
This terminates any .IFxxx directive.
|
925 |
|
|
|
926 |
|
|
This is not a compulsory directive, but if you use any .IFxxx then
|
927 |
|
|
you need also to apply this.
|
928 |
|
|
|
929 |
|
|
---------
|
930 |
|
|
.REPEAT 6
|
931 |
|
|
---------
|
932 |
|
|
|
933 |
|
|
Repeats the text enclosed between ".REPEAT x" and ".ENDR" x times (6 in
|
934 |
|
|
this example). You can use .REPEATs inside .REPEATs. 'x' must be >= 0.
|
935 |
|
|
|
936 |
|
|
This is not a compulsory directive.
|
937 |
|
|
|
938 |
|
|
-------
|
939 |
|
|
.REPT 6
|
940 |
|
|
-------
|
941 |
|
|
|
942 |
|
|
.REPT is an alias for .REPEAT.
|
943 |
|
|
|
944 |
|
|
This is not a compulsory directive.
|
945 |
|
|
|
946 |
|
|
-----
|
947 |
|
|
.ENDR
|
948 |
|
|
-----
|
949 |
|
|
|
950 |
|
|
Ends the repetition.
|
951 |
|
|
|
952 |
|
|
This is not a compulsory directive, but when .REPEAT is used this one is
|
953 |
|
|
required to terminate it.
|
954 |
|
|
|
955 |
|
|
-----------
|
956 |
|
|
.ENUM $C000
|
957 |
|
|
-----------
|
958 |
|
|
|
959 |
|
|
Starts enumeration from $C000. Very useful for defining variables.
|
960 |
|
|
|
961 |
|
|
To start a descending enumeration, put "DESC" after the starting
|
962 |
|
|
address. Open8_as defaults to "ASC" (ascending enumeration).
|
963 |
|
|
|
964 |
|
|
You can also add "EXPORT" after these if you want to export all
|
965 |
|
|
the generated definitions automatically.
|
966 |
|
|
|
967 |
|
|
Here's an example of .ENUM:
|
968 |
|
|
|
969 |
|
|
...
|
970 |
|
|
.STRUCT mon ; check out the documentation on
|
971 |
|
|
name ds 2 ; .STRUCT
|
972 |
|
|
age db
|
973 |
|
|
.ENDST
|
974 |
|
|
|
975 |
|
|
.ENUM $A000
|
976 |
|
|
_scroll_x DB ; db - define byte (byt and byte work also)
|
977 |
|
|
_scroll_y DB
|
978 |
|
|
player_x: DW ; dw - define word (word works also)
|
979 |
|
|
player_y: DW
|
980 |
|
|
map_01: DS 16 ; ds - define size (bytes)
|
981 |
|
|
map_02 DSB 16 ; dsb - define size (bytes)
|
982 |
|
|
map_03 DSW 8 ; dsw - define size (words)
|
983 |
|
|
monster INSTANCEOF mon 3 ; three instances of structure mon
|
984 |
|
|
dragon INSTANCEOF mon ; one mon
|
985 |
|
|
.ENDE
|
986 |
|
|
...
|
987 |
|
|
|
988 |
|
|
Previous example transforms into following definitions:
|
989 |
|
|
|
990 |
|
|
.DEFINE _scroll_x $A000
|
991 |
|
|
.DEFINE _scroll_y $A001
|
992 |
|
|
.DEFINE player_x $A002
|
993 |
|
|
.DEFINE player_y $A004
|
994 |
|
|
.DEFINE map_01 $A006
|
995 |
|
|
.DEFINE map_02 $A016
|
996 |
|
|
.DEFINE map_03 $A026
|
997 |
|
|
.DEFINE monster $A036
|
998 |
|
|
.DEFINE monster.name $A036
|
999 |
|
|
.DEFINE monster.age $A038
|
1000 |
|
|
.DEFINE monster.1 $A036
|
1001 |
|
|
.DEFINE monster.1.name $A036
|
1002 |
|
|
.DEFINE monster.1.age $A038
|
1003 |
|
|
.DEFINE monster.2 $A039
|
1004 |
|
|
.DEFINE monster.2.name $A039
|
1005 |
|
|
.DEFINE monster.2.age $A03B
|
1006 |
|
|
.DEFINE monster.3 $A03C
|
1007 |
|
|
.DEFINE monster.3.name $A03C
|
1008 |
|
|
.DEFINE monster.3.age $A03E
|
1009 |
|
|
.DEFINE dragon $A03F
|
1010 |
|
|
.DEFINE dragon.name $A03F
|
1011 |
|
|
.DEFINE dragon.age $A041
|
1012 |
|
|
|
1013 |
|
|
DB, DW, DS, DSB, DSW and INSTANCEOF can also be in lowercase. You
|
1014 |
|
|
can also use a dotted version of the symbols, but it doesn't advance
|
1015 |
|
|
the memory address. Here's an exmple:
|
1016 |
|
|
|
1017 |
|
|
.ENUM $C000 DESC EXPORT
|
1018 |
|
|
bigapple_h db
|
1019 |
|
|
bigapple_l db
|
1020 |
|
|
bigapple: .dw
|
1021 |
|
|
.ENDE
|
1022 |
|
|
|
1023 |
|
|
And this is what is generated:
|
1024 |
|
|
|
1025 |
|
|
.DEFINE bigapple_h $BFFF
|
1026 |
|
|
.DEFINE bigapple_l $BFFE
|
1027 |
|
|
.DEFINE bigapple $BFFE
|
1028 |
|
|
.EXPORT bigapple, bigapple_l, bigapple_h
|
1029 |
|
|
|
1030 |
|
|
This way you can generate a 16bit variable address along with pointers
|
1031 |
|
|
to its parts.
|
1032 |
|
|
|
1033 |
|
|
If you want more flexible variable positioning, take a look at
|
1034 |
|
|
.RAMSECTIONs.
|
1035 |
|
|
|
1036 |
|
|
This is not a compulsory directive.
|
1037 |
|
|
|
1038 |
|
|
-----
|
1039 |
|
|
.ENDE
|
1040 |
|
|
-----
|
1041 |
|
|
|
1042 |
|
|
Ends the enumeration.
|
1043 |
|
|
|
1044 |
|
|
This is not a compulsory directive, but when .ENUM is used this one is
|
1045 |
|
|
required to terminate it.
|
1046 |
|
|
|
1047 |
|
|
--------------------
|
1048 |
|
|
.STRUCT enemy_object
|
1049 |
|
|
--------------------
|
1050 |
|
|
|
1051 |
|
|
Begins the definition of a structure. These structures can be placed
|
1052 |
|
|
inside RAMSECTIONs and ENUMs. Here's an example:
|
1053 |
|
|
|
1054 |
|
|
.STRUCT enemy_object
|
1055 |
|
|
id dw ; the insides of a .STRUCT are 1:1 like in .ENUM
|
1056 |
|
|
x db ; except that no structs inside structs are
|
1057 |
|
|
y db ; allowed.
|
1058 |
|
|
data ds 10
|
1059 |
|
|
info dsb 16
|
1060 |
|
|
stats dsw 4
|
1061 |
|
|
.ENDST
|
1062 |
|
|
|
1063 |
|
|
This also creates a definition "_sizeof_[struct name]", in our example
|
1064 |
|
|
this would be "_sizeof_enemy_object", and the value of this definition
|
1065 |
|
|
is the size of the object, in bytes (2+1+1+10+16+4*2 = 38 in the example).
|
1066 |
|
|
|
1067 |
|
|
You'll get the following definitions as well:
|
1068 |
|
|
|
1069 |
|
|
enemy_object.id (== 0)
|
1070 |
|
|
enemy_object.x (== 2)
|
1071 |
|
|
enemy_object.y (== 3)
|
1072 |
|
|
enemy_object.data (== 4)
|
1073 |
|
|
enemy_object.info (== 14)
|
1074 |
|
|
enemy_object.stats (== 30)
|
1075 |
|
|
|
1076 |
|
|
After defining a .STRUCT you can create an instance of it in a .RAMSECTION /
|
1077 |
|
|
.ENUM by typing
|
1078 |
|
|
|
1079 |
|
|
INSTANCEOF [optional, the number of structures]
|
1080 |
|
|
|
1081 |
|
|
Here's an example:
|
1082 |
|
|
|
1083 |
|
|
.RAMSECTION "enemies" BANK 4 SLOT 4
|
1084 |
|
|
enemies INSTANCEOF enemy_object 4
|
1085 |
|
|
enemyman INSTANCEOF enemy_object
|
1086 |
|
|
enemyboss INSTANCEOF enemy_object
|
1087 |
|
|
.ENDS
|
1088 |
|
|
|
1089 |
|
|
This will create labels like "enemies", "enemies.id", "enemies.x", "enemies.y"
|
1090 |
|
|
and so on. Label "enemies" is followed by four "enemy_object" structures,
|
1091 |
|
|
and only the first one is labeled. After there four come "enemyman" and
|
1092 |
|
|
"enemyboss" instances.
|
1093 |
|
|
|
1094 |
|
|
Take a look at the documentation on .RAMSECTION & .ENUM, they have more
|
1095 |
|
|
examples of how you can use .STRUCTs.
|
1096 |
|
|
|
1097 |
|
|
A WORD OF WARNING: Don't use labels b, B, w and W inside a struct as e.g.,
|
1098 |
|
|
Open8_as sees enemy.b as a byte sized reference to enemy. All other labels should
|
1099 |
|
|
be safe.
|
1100 |
|
|
|
1101 |
|
|
lda enemy1.b ; load a byte from zeropage address enemy1 or from the address
|
1102 |
|
|
; of enemy1.b??? i can't tell you, and Open8_as can't tell you...
|
1103 |
|
|
|
1104 |
|
|
This is not a compulsory directive.
|
1105 |
|
|
|
1106 |
|
|
------
|
1107 |
|
|
.ENDST
|
1108 |
|
|
------
|
1109 |
|
|
|
1110 |
|
|
Ends the structure definition.
|
1111 |
|
|
|
1112 |
|
|
This is not a compulsory directive, but when .STRUCT is used this one is
|
1113 |
|
|
required to terminate it.
|
1114 |
|
|
|
1115 |
|
|
---------
|
1116 |
|
|
.SEED 123
|
1117 |
|
|
---------
|
1118 |
|
|
|
1119 |
|
|
Seeds the random number generator.
|
1120 |
|
|
|
1121 |
|
|
This is not a compulsory directive. The random number generator is
|
1122 |
|
|
initially seeded with the output of time(), which is, according to
|
1123 |
|
|
the manual, "the time since the Epoch (00:00:00 UTC, January 1, 1970),
|
1124 |
|
|
measured in seconds". So if you don't .SEED the random number generator
|
1125 |
|
|
yourself with a constant value, .DBRND and .DWRND give you different
|
1126 |
|
|
values every time you run Open8_as.
|
1127 |
|
|
|
1128 |
|
|
---------------------
|
1129 |
|
|
.SECTION "Init" FORCE
|
1130 |
|
|
---------------------
|
1131 |
|
|
|
1132 |
|
|
Section is a continuous area of data which is placed into the output
|
1133 |
|
|
file according to the section type and .ORG directive
|
1134 |
|
|
values.
|
1135 |
|
|
|
1136 |
|
|
The example begins a section called "Init". Before a section can be
|
1137 |
|
|
declared, .ORG must be used unless Open8_as is in library file
|
1138 |
|
|
output mode. Library file's sections must all be FREE ones. .BANK tells
|
1139 |
|
|
the bank number where this section will be later relocated into. .ORG
|
1140 |
|
|
tells the offset for the relocation from the beginning of .BANK.
|
1141 |
|
|
|
1142 |
|
|
You can supply the preferred section size (bytes) inside the section
|
1143 |
|
|
name string. Here's an example:
|
1144 |
|
|
|
1145 |
|
|
.SECTION "Init_100" FREE
|
1146 |
|
|
|
1147 |
|
|
will create a section ("Init") with size of 100 bytes, unless the actual
|
1148 |
|
|
data overflows from the section, in which case the section size is
|
1149 |
|
|
enlarged to contain all the data. Note that the syntax for explicit
|
1150 |
|
|
section size defining is: "NAME_X", where "NAME" is the name of the
|
1151 |
|
|
section and "X" is the size (decimal or hexadecimal value).
|
1152 |
|
|
|
1153 |
|
|
You can also give the size of the section the following way:
|
1154 |
|
|
|
1155 |
|
|
.SECTION "Init" SIZE 100 FREE
|
1156 |
|
|
|
1157 |
|
|
It's possible to force Open8_link to align the FREE, SEMIFREE and SUPERFREE
|
1158 |
|
|
sections by giving the alignment as follows:
|
1159 |
|
|
|
1160 |
|
|
.SECTION "Init" SIZE 100 ALIGN 4 FREE
|
1161 |
|
|
|
1162 |
|
|
And if you want that Open8_as returns the ORG to what it was before issuing
|
1163 |
|
|
the section, put RETURNORG at the end of the parameter list:
|
1164 |
|
|
|
1165 |
|
|
.SECTION "Init" SIZE 100 ALIGN 4 FREE RETURNORG
|
1166 |
|
|
|
1167 |
|
|
By default Open8_as advances the ORG, so, for example, if your ORG was $0 before
|
1168 |
|
|
a section of 16 bytes, then the ORG will be 16 after the section.
|
1169 |
|
|
|
1170 |
|
|
Note also that if your section name begins with double underlines (e.g.,
|
1171 |
|
|
"__UNIQUE_SECTION!!!") the section will be unique in the sense that
|
1172 |
|
|
when Open8_link recieves files containing sections which share the same
|
1173 |
|
|
name, Open8_link will save only the first of them for further processing,
|
1174 |
|
|
all others are deleted from memory with corresponding labels, references
|
1175 |
|
|
and calculations.
|
1176 |
|
|
|
1177 |
|
|
If a section name begins with an exclamation mark ('!') it tells
|
1178 |
|
|
Open8_link to not to drop it, even if you use Open8_link's ability to discard
|
1179 |
|
|
all unreferenced sections and there are no references to the section.
|
1180 |
|
|
|
1181 |
|
|
FORCE after the name of the section tells Open8_as that the section _must_ be
|
1182 |
|
|
inserted so it starts at .ORG. FORCE can be replaced with FREE which
|
1183 |
|
|
means that the section can be inserted somewhere in the defined bank,
|
1184 |
|
|
where there is room. You can also use OVERWRITE to insert the section
|
1185 |
|
|
into the memory regardless of data collisions. Using OVERWRITE you can
|
1186 |
|
|
easily patch an existing ROM image just by .BACKGROUND'ing the ROM image and
|
1187 |
|
|
inserting OVERWRITE sections into it. SEMIFREE sections are also
|
1188 |
|
|
possible and they behave much like FREE sections. The only difference
|
1189 |
|
|
is that they are positioned somewhere in the bank starting from .ORG.
|
1190 |
|
|
SUPERFREE sections are also available, and they will be positioned into
|
1191 |
|
|
the first suitable place inside the first suitable bank (candidates
|
1192 |
|
|
for these suitable banks have the same size with the slot of the section,
|
1193 |
|
|
no other banks are considered). You can also leave away the type
|
1194 |
|
|
specifier as the default type for the section is FREE.
|
1195 |
|
|
|
1196 |
|
|
You can name the sections as you wish, but there is one special name.
|
1197 |
|
|
A section called "BANKHEADER" is placed in the front of the bank
|
1198 |
|
|
where it is defined. These sections contain data that is not in the
|
1199 |
|
|
memory map of the machine, so you can't refer to the data of a
|
1200 |
|
|
BANKHEADER section, but you can write references to outside. So no
|
1201 |
|
|
labels inside BANKHEADER sections. These special sections are useful
|
1202 |
|
|
when writing e.g., MSX programs. Note that library files don't take
|
1203 |
|
|
BANKHEADER sections.
|
1204 |
|
|
|
1205 |
|
|
Here's an example of a "BANKHEADER" section:
|
1206 |
|
|
|
1207 |
|
|
.BANK 0
|
1208 |
|
|
.ORG 0
|
1209 |
|
|
.SECTION "BANKHEADER"
|
1210 |
|
|
.DW MAIN
|
1211 |
|
|
.DW VBI
|
1212 |
|
|
.ENDS
|
1213 |
|
|
|
1214 |
|
|
.SECTION "Program"
|
1215 |
|
|
MAIN: CALL MONTY_ON_THE_RUN
|
1216 |
|
|
VBI: PUSH HL
|
1217 |
|
|
...
|
1218 |
|
|
POP HL
|
1219 |
|
|
RETI
|
1220 |
|
|
.ENDS
|
1221 |
|
|
|
1222 |
|
|
Here's an example of an ordinary section:
|
1223 |
|
|
|
1224 |
|
|
.BANK 0
|
1225 |
|
|
.ORG $150
|
1226 |
|
|
.SECTION "Init" FREE
|
1227 |
|
|
DI
|
1228 |
|
|
LD SP, $FFFE
|
1229 |
|
|
SUB A
|
1230 |
|
|
LD ($FF00+R_IE), A
|
1231 |
|
|
.ENDS
|
1232 |
|
|
|
1233 |
|
|
This tells Open8_as that a FREE section called "Init" must be located somewhere
|
1234 |
|
|
in bank 0. If you replace FREE with SEMIFREE the section will be inserted
|
1235 |
|
|
somewhere in the bank 0, but not in the $0-$14F area. If you replace FREE
|
1236 |
|
|
with SUPERFREE the section will be inserted somewhere in the
|
1237 |
|
|
|
1238 |
|
|
Here's the order in which Open8_as writes the sections:
|
1239 |
|
|
1. FORCE
|
1240 |
|
|
2. SEMIFREE & FREE
|
1241 |
|
|
3. SUPERFREE
|
1242 |
|
|
4. OVERWRITE
|
1243 |
|
|
|
1244 |
|
|
Before the sections are inserted into the output file, they are sorted by
|
1245 |
|
|
size, so that the biggest section gets processed first and the smallest
|
1246 |
|
|
last.
|
1247 |
|
|
|
1248 |
|
|
You can also create a RAM section. For more information about them, please
|
1249 |
|
|
read the .RAMSECTION directive explanation.
|
1250 |
|
|
|
1251 |
|
|
This is not a compulsory directive.
|
1252 |
|
|
|
1253 |
|
|
--------------
|
1254 |
|
|
.EXPORT work_x
|
1255 |
|
|
--------------
|
1256 |
|
|
|
1257 |
|
|
Exports the definition "work_x" to outside world. Exported definitions are
|
1258 |
|
|
visible to all object files and libraries in the linking procedure. Note
|
1259 |
|
|
that you can only export value definitions, not string definitions.
|
1260 |
|
|
|
1261 |
|
|
You can export as many definitions as you wish with one .EXPORT:
|
1262 |
|
|
|
1263 |
|
|
.EXPORT NUMBER, NAME, ADDRESS, COUNTRY
|
1264 |
|
|
.EXPORT NAME, AGE
|
1265 |
|
|
|
1266 |
|
|
This is not a compulsory directive.
|
1267 |
|
|
|
1268 |
|
|
--------------------------
|
1269 |
|
|
.PRINTT "Here we are...\n"
|
1270 |
|
|
--------------------------
|
1271 |
|
|
|
1272 |
|
|
Prints the given text into stdout. Good for debugging stuff. PRINTT takes
|
1273 |
|
|
only a string as argument, and the only supported formatting symbol is '\n'
|
1274 |
|
|
(line feed).
|
1275 |
|
|
|
1276 |
|
|
This is not a compulsory directive.
|
1277 |
|
|
|
1278 |
|
|
-------------------
|
1279 |
|
|
.PRINTV DEC DEBUG+1
|
1280 |
|
|
-------------------
|
1281 |
|
|
|
1282 |
|
|
Prints the value of the supplied definition or computation into stdout.
|
1283 |
|
|
Computation must be solvable at the time of printing (just like definitions
|
1284 |
|
|
values). PRINTV takes two parameters. The first describes the type of the
|
1285 |
|
|
print output. "DEC" means decimal, "HEX" means hexadecimal.
|
1286 |
|
|
|
1287 |
|
|
Use PRINTV with PRINTT as PRINTV doesn't print linefeeds, only the result.
|
1288 |
|
|
Here's an example:
|
1289 |
|
|
|
1290 |
|
|
.PRINTT "Value of \"DEBUG\" = $"
|
1291 |
|
|
.PRINTV HEX DEBUG
|
1292 |
|
|
.PRINTT "\n"
|
1293 |
|
|
|
1294 |
|
|
This is not a compulsory directive.
|
1295 |
|
|
|
1296 |
|
|
------------------
|
1297 |
|
|
.OUTNAME "other.o"
|
1298 |
|
|
------------------
|
1299 |
|
|
|
1300 |
|
|
Changes the name of the output file. Here's and example:
|
1301 |
|
|
|
1302 |
|
|
Open8_as -o test.s
|
1303 |
|
|
|
1304 |
|
|
would normally output "test.o", but if you had written
|
1305 |
|
|
|
1306 |
|
|
.OUTNAME "new.o"
|
1307 |
|
|
|
1308 |
|
|
somewhere in the code Open8_as would write the output to new.o instead.
|
1309 |
|
|
|
1310 |
|
|
This is not a compulsory directive.
|
1311 |
|
|
|
1312 |
|
|
|
1313 |
|
|
----------------------------------------------
|
1314 |
|
|
3.... Assembler Syntax
|
1315 |
|
|
----------------------------------------------
|
1316 |
|
|
|
1317 |
|
|
|
1318 |
|
|
3.1. Case Sensitivity
|
1319 |
|
|
|
1320 |
|
|
Open8_as is case sensitive, so be careful.
|
1321 |
|
|
|
1322 |
|
|
|
1323 |
|
|
3.2. Comments
|
1324 |
|
|
|
1325 |
|
|
Comments begin with ';' or '*' and end along with the line. ';' can be
|
1326 |
|
|
used anywhere, but '*' can be placed only at the beginning of a new line.
|
1327 |
|
|
|
1328 |
|
|
Open8_as also has ANSI-C -like commenting. This means you can start a
|
1329 |
|
|
multiline comment with "/*" and end it with "*/". Additionally, it has
|
1330 |
|
|
.ASM and .ENDASM directives. These function much like ANSI-C comments, but
|
1331 |
|
|
unlike the ANSI-C comments these can be nested.
|
1332 |
|
|
|
1333 |
|
|
|
1334 |
|
|
3.3. Labels
|
1335 |
|
|
|
1336 |
|
|
Labels are ordinary strings (which can also end to a ':'). Labels starting
|
1337 |
|
|
with "_" are considered to be local labels and do not show outside sections
|
1338 |
|
|
where they were defined, or outside object files, if they were not defined
|
1339 |
|
|
inside a section.
|
1340 |
|
|
|
1341 |
|
|
Here are few examples of different labels:
|
1342 |
|
|
|
1343 |
|
|
VBI_IRQ:
|
1344 |
|
|
VBI_IRQ2
|
1345 |
|
|
_VBI_LOOP:
|
1346 |
|
|
main:
|
1347 |
|
|
|
1348 |
|
|
3.4. Number Types
|
1349 |
|
|
|
1350 |
|
|
1000 - decimal
|
1351 |
|
|
$100 - hexadecimal
|
1352 |
|
|
100h - hexadecimal
|
1353 |
|
|
%100 - binary
|
1354 |
|
|
'x' - character
|
1355 |
|
|
|
1356 |
|
|
Remember that if you use the suffix 'h' to give a hexadecimal value,
|
1357 |
|
|
and the value begins with an alphabet, you must place a zero in front of it
|
1358 |
|
|
so Open8_as knows it's not a label (e.g., "0ah" instead of "ah").
|
1359 |
|
|
|
1360 |
|
|
|
1361 |
|
|
3.5. Strings
|
1362 |
|
|
|
1363 |
|
|
Strings begin with and end to '"'. Note that no 0 is inserted to indicate
|
1364 |
|
|
the termination of the string like in e.g., ANSI C. You'll have to do it
|
1365 |
|
|
yourself. You can place quotation marks inside strings the way C
|
1366 |
|
|
preprocessors accept them.
|
1367 |
|
|
|
1368 |
|
|
Here are some examples of strings:
|
1369 |
|
|
|
1370 |
|
|
"Hello world!"
|
1371 |
|
|
"He said: \"Please, kiss me honey.\""
|
1372 |
|
|
|
1373 |
|
|
|
1374 |
|
|
----------------------------------------------
|
1375 |
|
|
4.... Error Messages
|
1376 |
|
|
----------------------------------------------
|
1377 |
|
|
|
1378 |
|
|
|
1379 |
|
|
There are quite a few of them in Open8_as, but most of them are not very
|
1380 |
|
|
informative. Coder beware.
|
1381 |
|
|
|
1382 |
|
|
|
1383 |
|
|
----------------------------------------------
|
1384 |
|
|
5.... Bugs
|
1385 |
|
|
----------------------------------------------
|
1386 |
|
|
|
1387 |
|
|
|
1388 |
|
|
Report bugs to billwiley777@gmail.com
|
1389 |
|
|
|
1390 |
|
|
|
1391 |
|
|
----------------------------------------------
|
1392 |
|
|
6.... Temporary Files
|
1393 |
|
|
----------------------------------------------
|
1394 |
|
|
|
1395 |
|
|
|
1396 |
|
|
Note that Open8 will generate two temporary files while it works. Both files
|
1397 |
|
|
are placed into the current working directory.
|
1398 |
|
|
|
1399 |
|
|
The filenames are ".wla%PID%a" and ".wla%PID%b" (%PID% is the process id).
|
1400 |
|
|
|
1401 |
|
|
When Open8 finishes its work these two files are deleted as they serve
|
1402 |
|
|
of no further use.
|
1403 |
|
|
|
1404 |
|
|
|
1405 |
|
|
----------------------------------------------
|
1406 |
|
|
7.... Compiling
|
1407 |
|
|
----------------------------------------------
|
1408 |
|
|
|
1409 |
|
|
|
1410 |
|
|
7.1. Compiling Object Files
|
1411 |
|
|
|
1412 |
|
|
To compile an object file use:
|
1413 |
|
|
|
1414 |
|
|
"Open8_as -[itvx]o [DEFINITIONS] [OUTPUT FILE]"
|
1415 |
|
|
|
1416 |
|
|
These object files can be linked together (or with library files) later
|
1417 |
|
|
with "Open8_link".
|
1418 |
|
|
|
1419 |
|
|
Name object files so that they can be recognized as object files. Normal
|
1420 |
|
|
suffix is ".o" (Open8 default). This can also be changed with .OUTNAME.
|
1421 |
|
|
|
1422 |
|
|
With object files you can reduce the amount of compiling when editing
|
1423 |
|
|
small parts of the program. Note also the possibility of using local
|
1424 |
|
|
labels (starting with "_").
|
1425 |
|
|
|
1426 |
|
|
Note! When you compile objects, group 1 directives are saved for linking
|
1427 |
|
|
time, when they are all compared and if they differ, an error message is
|
1428 |
|
|
shown. It is advisable to use something like an include file to hold all
|
1429 |
|
|
the group 1 directives for that particular project and include it to every
|
1430 |
|
|
object file.
|
1431 |
|
|
|
1432 |
|
|
Here are some examples of definitions:
|
1433 |
|
|
|
1434 |
|
|
-DIEXIST
|
1435 |
|
|
-DDAY=10
|
1436 |
|
|
-DBASE=$10
|
1437 |
|
|
-DNAME=elvis
|
1438 |
|
|
|
1439 |
|
|
And here's an Open8 example creating definitions on the command line:
|
1440 |
|
|
|
1441 |
|
|
Open8_as -o -DDEBUG -DVERBOSE=5 -DNAME="math v1.0" math.s
|
1442 |
|
|
|
1443 |
|
|
DEBUG's value will be 0, VERBOSE's 5 and NAME is a string definition
|
1444 |
|
|
with value "math v1.0".
|
1445 |
|
|
|
1446 |
|
|
|
1447 |
|
|
7.2. Compiling Library Files
|
1448 |
|
|
|
1449 |
|
|
To compile a library file use:
|
1450 |
|
|
|
1451 |
|
|
"Open8_as -[itvx]l [DEFINITIONS] [OUTPUT FILE]"
|
1452 |
|
|
|
1453 |
|
|
Name object files so that they can be recognized as library files. Normal
|
1454 |
|
|
suffix is ".lib" (Open8 default).
|
1455 |
|
|
|
1456 |
|
|
With library files you can reduce the amount of compiling. Library files
|
1457 |
|
|
are meant to hold general functions that can be used in different projects.
|
1458 |
|
|
Note also the possibility of using local labels (starting with "_").
|
1459 |
|
|
Library files consist only of FREE sections.
|
1460 |
|
|
|
1461 |
|
|
|
1462 |
|
|
----------------------------------------------
|
1463 |
|
|
8... Linking
|
1464 |
|
|
----------------------------------------------
|
1465 |
|
|
|
1466 |
|
|
|
1467 |
|
|
After you have produced one or more object files and perhaps some library
|
1468 |
|
|
files, you might want to link them together to produce a ROM image / program
|
1469 |
|
|
file. "Open8_link" is the program you use for that. Here's how you use it:
|
1470 |
|
|
|
1471 |
|
|
"Open8_link [-divsS]{b/r} "
|
1472 |
|
|
|
1473 |
|
|
Choose 'b' for program file or 'r' for ROM image linking.
|
1474 |
|
|
|
1475 |
|
|
Link file is a text file that contains information about the files you want
|
1476 |
|
|
to link together. Here's the format:
|
1477 |
|
|
|
1478 |
|
|
1. You must define the group for the files. Put the name of the group
|
1479 |
|
|
inside brackets. Valid group definitions are
|
1480 |
|
|
|
1481 |
|
|
[objects]
|
1482 |
|
|
[libraries]
|
1483 |
|
|
[header]
|
1484 |
|
|
[footer]
|
1485 |
|
|
[definitions]
|
1486 |
|
|
|
1487 |
|
|
2. Start to list the file names.
|
1488 |
|
|
|
1489 |
|
|
[objects]
|
1490 |
|
|
main.o
|
1491 |
|
|
vbi.o
|
1492 |
|
|
level_01.o
|
1493 |
|
|
...
|
1494 |
|
|
|
1495 |
|
|
3. Give parameters to the library files:
|
1496 |
|
|
|
1497 |
|
|
[libraries]
|
1498 |
|
|
bank 0 slot 1 speed.lib
|
1499 |
|
|
bank 4 slot 2 map_data.lib
|
1500 |
|
|
...
|
1501 |
|
|
|
1502 |
|
|
Here you can also use "base" to define the 65816 CPU bank number
|
1503 |
|
|
(like .BASE works in Open8_as):
|
1504 |
|
|
|
1505 |
|
|
[libraries]
|
1506 |
|
|
bank 0 slot 1 base $80 speed.lib
|
1507 |
|
|
bank 4 slot 2 base $80 map_data.lib
|
1508 |
|
|
...
|
1509 |
|
|
|
1510 |
|
|
You must tell Open8_link the bank and the slot for the library files.
|
1511 |
|
|
|
1512 |
|
|
4. If you want to use header and/or footer in your project,
|
1513 |
|
|
you can type the following:
|
1514 |
|
|
|
1515 |
|
|
[header]
|
1516 |
|
|
header.dat
|
1517 |
|
|
[footer]
|
1518 |
|
|
footer.dat
|
1519 |
|
|
|
1520 |
|
|
5. If you want to make value definitions, here's your chance:
|
1521 |
|
|
|
1522 |
|
|
[definitions]
|
1523 |
|
|
debug 1
|
1524 |
|
|
max_str_len 128
|
1525 |
|
|
start $150
|
1526 |
|
|
...
|
1527 |
|
|
|
1528 |
|
|
If flag 'v' is used, Open8_link displays information about ROM file after a
|
1529 |
|
|
succesful linking.
|
1530 |
|
|
|
1531 |
|
|
If flag 'd' is used, Open8_link discards all unreferenced FREE and SEMIFREE
|
1532 |
|
|
sections. This way you can link big libraries to your project and Open8_link
|
1533 |
|
|
will choose only the used sections, so you won't be linking any dead code/data.
|
1534 |
|
|
|
1535 |
|
|
If flag 's' is used, a symbol information file is created.
|
1536 |
|
|
If flag 'S' is used, a symbol information file with breakpoints is created.
|
1537 |
|
|
|
1538 |
|
|
If flag 'i' is given, Open8_link will write list files. Note that you must
|
1539 |
|
|
compile the object and library files with -i flag as well. Otherwise Open8_link
|
1540 |
|
|
has no extra information it needs to build list files. Here is an example of
|
1541 |
|
|
a list file: Let's assume you've compiled a source file called "main.s" using
|
1542 |
|
|
the 'i' flag. After you've linked the result also with the 'i' flag Open8_link
|
1543 |
|
|
has created a list file called "main.lst". This file contains the source
|
1544 |
|
|
text and the result data the source compiled into. List files are good for
|
1545 |
|
|
debugging.
|
1546 |
|
|
|
1547 |
|
|
Make sure you don't create duplicate labels in different places in the
|
1548 |
|
|
memory map as they break the linking loop. Duplicate labels are allowed when
|
1549 |
|
|
they overlap each other in the destination machine's memory. Look at the
|
1550 |
|
|
following example:
|
1551 |
|
|
|
1552 |
|
|
...
|
1553 |
|
|
.BANK 0
|
1554 |
|
|
.ORG $150
|
1555 |
|
|
|
1556 |
|
|
...
|
1557 |
|
|
LD A, 1
|
1558 |
|
|
CALL LOAD_LEVEL
|
1559 |
|
|
...
|
1560 |
|
|
|
1561 |
|
|
LOAD_LEVEL:
|
1562 |
|
|
LD HL, $2000
|
1563 |
|
|
LD (HL), A
|
1564 |
|
|
CALL INIT_LEVEL
|
1565 |
|
|
RET
|
1566 |
|
|
|
1567 |
|
|
.BANK 1
|
1568 |
|
|
.ORG 0
|
1569 |
|
|
|
1570 |
|
|
INIT_LEVEL:
|
1571 |
|
|
...
|
1572 |
|
|
RET
|
1573 |
|
|
|
1574 |
|
|
.BANK 2
|
1575 |
|
|
.ORG $0
|
1576 |
|
|
|
1577 |
|
|
INIT_LEVEL:
|
1578 |
|
|
...
|
1579 |
|
|
RET
|
1580 |
|
|
...
|
1581 |
|
|
|
1582 |
|
|
|
1583 |
|
|
Here duplicate INIT_LEVEL labels are accepted as they both point to the
|
1584 |
|
|
same memory address (in the program's point of view).
|
1585 |
|
|
|
1586 |
|
|
|
1587 |
|
|
----------------------------------------------
|
1588 |
|
|
9... Arithmetics
|
1589 |
|
|
----------------------------------------------
|
1590 |
|
|
|
1591 |
|
|
|
1592 |
|
|
Open8_as is able to solve really complex calculations like
|
1593 |
|
|
|
1594 |
|
|
-((HELLO / 2) | 3)
|
1595 |
|
|
skeletor_end-skeletor
|
1596 |
|
|
10/2.5
|
1597 |
|
|
|
1598 |
|
|
so you can write something like
|
1599 |
|
|
|
1600 |
|
|
LD HL, data_end-data
|
1601 |
|
|
LD A, (pointer + 1)
|
1602 |
|
|
CP (TEST + %100) & %10101010
|
1603 |
|
|
|
1604 |
|
|
Open8_link also has this ability so it can compute the pending calculations
|
1605 |
|
|
Open8_as wasn't able to solve.
|
1606 |
|
|
|
1607 |
|
|
The following operators are valid:
|
1608 |
|
|
|
1609 |
|
|
(, ), | (or), & (and), ^ (power), << (shift left), >> (shift right), +, -,
|
1610 |
|
|
# (modulo), ~ (xor), *, /, < (get the low byte) and > (get the high byte).
|
1611 |
|
|
|
1612 |
|
|
Note that you can do NOT using XOR:
|
1613 |
|
|
|
1614 |
|
|
VALUE_A ~ $FF = 8bit NOT
|
1615 |
|
|
VALUE_B ~ $FFFF = 16bit NOT
|
1616 |
|
|
|
1617 |
|
|
Open8_as computes internally with real numbers so (5/2)*2 produces 5, not 4.
|
1618 |
|
|
|
1619 |
|
|
|
1620 |
|
|
|
1621 |
|
|
----------------------------------------------
|
1622 |
|
|
10... Open8_as Flags
|
1623 |
|
|
----------------------------------------------
|
1624 |
|
|
|
1625 |
|
|
|
1626 |
|
|
Here are short descriptions for the flags you can give to Open8_as:
|
1627 |
|
|
|
1628 |
|
|
You can supply Open8_as with some (or all or none) of the following option flags.
|
1629 |
|
|
|
1630 |
|
|
i - Add list file information. Adds extra information to the output so
|
1631 |
|
|
Open8_link can produce list files.
|
1632 |
|
|
M - Open8 generates makefile rules describing the dependencies of the main
|
1633 |
|
|
source file. Use only with flags 'o' and 'l'.
|
1634 |
|
|
q - Quiet mode. .PRINT* -directives output nothing.
|
1635 |
|
|
t - Test compile. Doesn't output any files.
|
1636 |
|
|
v - Verbose mode. Shows a lot of information about the compiling process.
|
1637 |
|
|
x - Extra compile time definitions. Open8_as does extra work by creating
|
1638 |
|
|
few helpful definitions on the fly.
|
1639 |
|
|
|
1640 |
|
|
One (and only one) of the following command flags must be defined.
|
1641 |
|
|
|
1642 |
|
|
l - Output a library file.
|
1643 |
|
|
o - Output an object file.
|
1644 |
|
|
|
1645 |
|
|
Examples:
|
1646 |
|
|
|
1647 |
|
|
[seravy@localhost tbp]# Open8_as -voi testa.s
|
1648 |
|
|
[seravy@localhost tbp]# Open8_as -oM testa.s
|
1649 |
|
|
[seravy@localhost tbp]# Open8_as -l testb.s testb.lib
|
1650 |
|
|
|
1651 |
|
|
Note that the first example produces file named "testa.o".
|
1652 |
|
|
|
1653 |
|
|
|
1654 |
|
|
----------------------------------------------
|
1655 |
|
|
11... Good things to know about Open8_as
|
1656 |
|
|
----------------------------------------------
|
1657 |
|
|
|
1658 |
|
|
|
1659 |
|
|
- Is 64 bytes too little for a string (file names, labels, definition labels,
|
1660 |
|
|
etc)? Check out "MAX_NAME_LENGTH" in defines.h.
|
1661 |
|
|
- Open8_as preprocessor doesn't expand macros and repetitions. Those are actually
|
1662 |
|
|
traversed in the assembling phase.
|
1663 |
|
|
- Open8_as's source code is mainly a huge mess, but Open8_link is quite well
|
1664 |
|
|
structured and written. So beware!
|
1665 |
|
|
- Do not write ".E" into your sources as Open8_as uses it internally to mark
|
1666 |
|
|
the end of a file.
|
1667 |
|
|
|
1668 |
|
|
|
1669 |
|
|
----------------------------------------------
|
1670 |
|
|
12... Legal Note
|
1671 |
|
|
----------------------------------------------
|
1672 |
|
|
|
1673 |
|
|
Open8_as and Open8_link is licensed as GPL software, as are any helper programs.
|
1674 |
|
|
|
1675 |
|
|
Code in the examples section is licensed under the BSD license.
|
1676 |
|
|
|
1677 |
|
|
|