/
trasm.txt
562 lines (450 loc) · 24.3 KB
/
trasm.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
<SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES>
_______ _ _
[___ ___]____ [_] ____ | | __ ____
~~~| |~~| __]| | / ___]| |/ / / ___]
| | | |~ | || |___ | |\ \ \___ \
|_| |_| |_| \____]|_|~\_][____/
~~ ~~ ~~ ~~~~~ ~~ ~~ ~~~~~
<SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES><SNES>
65816 Tricks Assembler Version 1.11 (Bug fix for 1.10)
(C)opyright 1994 1000 Miles [Tricks]
Internet: norman_yen@idream.tfbbs.wimsey.com
IRC: minus
Updated on 02-14-94
*** NOTE:
All additions and changes to the instructions have a '>'
symbol preceding each line.
*** WARNING:
This is PUBLIC DOMAIN. The author does not provided any
guarantees or warranties in the use of this program. The author
is not liable for any damage caused by this program or any other
programs enclosed with this archive. USE AT YOUR OWN RISK!
Introduction
============
The Tricks Assembler is a cross-assembler for compiling
65c816 assembly into binary for use on the Super Nintendo
Entertainment System (Super Famicon) on a PC computer.
Whether someone can produce something on a professional
level with this utility is a mystery to me (if you do, let
me know!).
This assembler is based on a previous assembler which I
wrote called SNES Assembler. What I've done is taken the
same ideas and rewritten the entire assembler and removed
several bugs that existed in the old code. This newer
assembler has a few more abilities over the old one. As
well it has capabilities that are similiar to those found
on other platforms like the Atari ST and Amiga. Converting
source codes from other assemblers should be fairly simple.
I've been successful in converting both SNES Wish '92 and
the HDMA Demo to work with TricksASM with little
modification.
Here's a few of the technical aspects about the assembler.
Tricks Assembler is written in Turbo Pascal 6.0.
Requires atleast 400KB of conventional memory to run, memory
hog.
Maximum symbol names is 8192, each symbol can be 18
characters and is stored in uppercase. Do not use 'A' as
a symbol name.
Order of operations: *, /, mod, & (and), << (shl), >> (shr),
+, -, | (or), xor.
Practically no eror checking is performed on operands so if
you use the wrong characters you might get an unexpected
value.
The WDM and COP instructions are not implemented in the
assembler.
3 Pass assembling.
Assembling Options
==================
There are a few options available when assembling your source
code.
-$ ... Generate symbol table (default off)
Will write a text file containing all of the
symbols used with both their hex and decimal
values.
-d ... Display assembly (default off)
You can display the lines as they are being
assembled. Having this off speeds things up.
-f ... Show forward reference (default on)
Whether or not you want to show the forward
reference error during pass 1 of assembly.
-l ... Generate source listing (default off)
This will generate a complete source listing
of your file. Just about everything is
converted into uppercase, the exception is
anything enclosed in quotation marks.
-p ... Pad SMC file to 32K (default off)
Most utilities that handle SMC files require
that your file be a multiple of 32768 bytes.
If your file does not turn out that way you
may encounter problems using some parallel
port sending utilities.
-s ... Send file to I/O port (default off)
When TricksASM is done assembling and no
errors occured in the final pass the SMC file
will automatically be sent over to the console
backup unit through the parallel port. If you
make use of any reset code in your file it will
not work with this method of parallel port
sending. I'm working on a solution to this.
> -z ... Internal debugging (default off)
> This is basically for debugging the assembler.
> If you find that the assembler freezes on you
> you can try assembling your source with this
> option on and you will get an output of what
> is happening during the assembling process.
> It'll help locate where the assembler is
> locking up at.
Files
=====
*.BIN The raw binary file without the vector tables
and 512 byte header.
*.ERR The error list during the assembling process.
*.LST Source listing as the assembler would see it.
(optional, see Assembling Options -l)
*.SYM Listing of all the symbols used in the source
code.
(optional, see Assembling Options -$)
*.SMC The executable file you can load up on your
console backup unit. This has the 512 byte
header.
When the SMC file is created the file can be no smaller than
33280 bytes. The reason for this is that almost all decent
parallel port sending utilities extract information from the
cartridge information area located in the last page of the
first bank. A utility cannot move to that area if it does
not exist. As well, the vector tables are also located in
the last 28 bytes of the first bank.
Arithmetic Operators
====================
You are free to use most of the basic operators like addition
(+), subtraction (-), division (/) (integer), and multi-
plication (*). On top of those you have your logical
operators like and (&), or (|), xor, and mod. You also have
your bit-wise operators like shift left (<<) and shift-right
(>>).
Since the assembler is really picky about order of operations
it is best to use parenthesis around the logical and bit-wise
operators. For example, say you want to get the high byte of
the word value $8011.
LDX #($8011>>8)&$ff
If you tried it without the parenthesis you would of gotten
some wild value.
You should also be careful about extra characters in your
operands. A small typo can have drastic effects as the
assembler has very little error checking for unexpected
characters in the operand field. You could get some weird
values if this happens. (That's why it is a good idea to
generate a source listing so you can see where the assembler
is going wrong.)
Operand Lengths, 8-, 16-, or 24-bit?
====================================
The assembler has no way of telling whether you want an
8-bit, 16-bit, or 24-bit operand unless you specifically
force an operand length with the .B, .W, or .L suffixes on
the instructions.
.B for byte
.W for word
.L for long (24-bits)
If you do not add these in, TricksASM will always try and
produce the smallest length possible. For example if the
operand was $45 the operand length would be 8-bits. If you
added .W to the end of your instruction the operand would
become $0045. Here's an example.
LDA #$45
Would turn out as A9 45 in the source listing.
LDA.W #$45
Would turn out as A9 45 00 in the source listing.
Basically there is no way of telling whether you are in
native or emulation mode or if the accumulator/index is
8-bit or 16-bit.
Pseudo-Ops
==========
<xxx> = <yyy> . The equate symbol defines what a symbol is
or equal. Basically it assigns the value in
<xxx> EQU <yyy> <yyy> to the variable/symbol <xxx>. The
variable or symbol name can have a maximum
of 18 characters.
Example
TempByte = $80 ; 128
> BAS <xxxx> .... Change the current assembly address to
> or the value specified for code that is to be
> BASE <xxxx> ... relocated to address <xxxx>. TricksASM
> will pretend any code between the BASE and
> END pseudo-op is suppose to reside at a
> different address. You might find this
> useful if you intend to copy routines into
> the work RAM or lower RAM. If you fail to
> mark the ending of the routine with an END
> statement your code will all be assembled
> with the wrong addresses.
>
> Example #1
> ORG $8000
> ; do your stuff
> Main jsr VBlank
> jmp Init
> ; do your stuff
> ; base change
> BASE $1800
> Vblank
> - lda $4210
> and #$80
> beq -
> rts
> END
> ; do your stuff
> Init
>
> The assembly listing would look like this.
>
> 008000 ORG $8000
> 008000
> 008000 20 00 18 MAIN JSR VBLANK
> 008003 4C 0E 80 JMP INIT
> 008006
> 008006
> 001800 BASE $1800
> 001800 VBLANK
> 001800 AD 10 42 - LDA $4210
> 001803 29 80 AND #$80
> 001805 F0 F9 BEQ -
> 001807 60 RTS
> 00800E END
> 00800E
> 00800E INIT
>
> For the more imaginative programmers you
> could use this instruction for declaring
> records. Just set the base to zero and
> create a bunch of variables using DSB, DSW
> or DSD. Assign a symbol as the base address
> for the variables and when you want to
> access something in the record just add the
> proper symbol.
>
> Example #2
> BASE $0000
> PName DSB 32 ; 32 bytes
> Age DSB 1 ; 1 byte
> Phone DSB 12 ; 12 bytes
> Sex DSB 1 ; 1 byte
> END
>
> List = $1000
> ....
> lda List+Age
> ldy List+Sex
>
> You can stack a maximum of 8 bases addresses.
BIN <file> .... Append a binary file to the current address.
or To be on the safe side you should try and
INCBIN <file> . keep the file you want to append down to 32K
in size. Appending files larger than that
might have weird side effects with the
current address pointer. You can enclose
your file name in quotations if you like.
Example #1
bin sintable.dat
or
incbin sintable.dat
Example #2
bin "font1.dat"
COU <xx> ...... Sets the country code located in the header.
or The corresponding country for each value was
COUNTRY <xx> .. derrived from the Magicom File Uploader (AKA
Send v2.3) utility written by R. Bubba
Magillicutty.
Hex $00 = Japan
01 = USA(/Canada)
02 = Europe, Oceania, Asia
03 = Sweden
04 = Finlan
05 = Denmark
06 = France
07 = Holland
08 = Spain
09 = Germany, Austria, Switzerland
0a = Italy
0b = Hong Kong, China
0c = Indonesia
0d = Korea
Example
cou $01 ; USA
or
country 1 ; USA
DC.B <xx> ..... Defines a series of byte values for that
or address. You can put a single byte or
DCB <xx> ...... multiple bytes by separating each value with
or a comma. You can also enclose text within
DB <xx> ....... brackets and ASCII values will be used.
Example
Text DC.B 'Hello there Mister',0
DC.D <xx> ..... Defines a series of double word values for
or that address. You can put a single dword or
DCD <xx> ...... muliple dwords by separating each value with
or a comma. A dword is 4 bytes long or 2 words.
DD <xx> ....... you can use text as well but if you do TRASM
will only take each character an extend it's
value out to 4 bytes.
DC.W <xx> ..... Defines a series of word values for that
or address. You can put a single word or
DCW <xx> ...... multiple words by separating each value with
or a comma. You can also enclose text within
DW <xx> ....... brackets and ASCII values will be used but
the high byte will be set to $00. In
otherwords, if you use text the value won't
be from two characters, but from a single
character extended out to word length.
> DS.B <xx> ..... Declares a string of bytes for use as
> or variable space. The bytes are initialized
> DSB <xx> with zeros. Since variables can only exist
> in RAM this might serve little purpose other
> than for data which is to be relocated.
> DS.D <xx> ..... Declares a string of double words for use as
> or variable space. The dwords are initialized
> DSD <xx> with zeros. Since variables can only exist
> in RAM this might serve little purpose other
> than for data which is to be relocated.
> DS.W <xx> ..... Declares a string of words for use as
> or variable space. The words are initialized
> DSW <xx> with zeros. Since variables can only exist
> in RAM this might serve little purpose other
> than for data which is to be relocated.
INT ........... Defines the interrupt vector table located at
or the last 28 bytes of the first bank. Each
INTERRUPT ..... vector is word length, in low/high byte
format. There are 6 interrupts you can set.
ABO (ABORT) - Abort vector
BRK (BREAK) - Break vector
COP - Co-processor vector
IRQ - Interrupt request vector
NMI - Non-maskable interrupt vector
RES (RESET) - Reset vector
You can set them all to a single value by
using the word ALL. To mark the ending of
your vector definition table you must use
the word END. All vectors are initialized
with the value of $0000. If you do not use
INT in your source code no interrupts will
be written in the vector table in your SMC
file.
You might want to note that on the 65816 you
can assign interrupt vectors for both
emulation and native mode. I've mapped both
native and emulation mode vectors to the same
value. One exception is that the BRK and IRQ
vector share the same value in emulation
mode.
Example
org 32768
Start lda #$7f
sta $2115
int
all = $0000
res = Start
nmi = Scroller
end
Scroller
....
NAM <title> ... Defines the cartridge title that is store in
or the header. A maximum of 20 characters can be
NAME <title> .. be used, anything more will be truncated. As
or you can see you have your choice of what
TIT <title> ... pseudo-op to use. You can enclose your title
or in quotations if you want to use spaces or
TITLE <title> . lower/uppercase.
Example
nam "Galaxy Rangers"
or
title 'Galaxy Rangers'
ORG <xxxx> .... Sets the starting address of the following
code. This is the first thing TRASM looks
for and it doesn't find it the starting
address will default to $008000 (32768).
Besides using this to establish the starting
address you can also force the assembler to
pad the file all the way up to the specified
address in the operand. This is handy for
music data that is ripped from a game and
cannot be relocated to another address.
Example #1
org $8000 ; start address=32768
Start jmp Start ; Start=32768
Example #2
org $8000 ; start address
.... ; program continues
org $58000 ; pad file up to
; $58000
music bin music1
PAD [<xxxx>] .. This can be used with or without an operand.
Using PAD without the operand will force the
code to be padded with nulls up to the next
32K boundary. If an operand is used it must
fall between $8000 and $ffff and the current
address must be less than the operand.
Otherwise the PAD will be ignored.
Example #1
org $8000
Start ; Start=32768
pad
NextStart ; NextStart=90304
Example #2
org $8000
Start ; Start=32768
pad $8800
NextStart ; NextStart=38416
> SRC <file> .... Append a source file to the current address.
> or If you save routines in files by themself you
> INCSRC <file> . can use this command to have the source
> included into the file without it physically
> being in the main source code. You can stack
> a maximum of 8 source files. At the end of
> each file you will be informed of how many
> lines were in the source file.
>
> Example
> src snesinit.asm
VER <xx> ...... Defines the version number stored in the
or header. The actual value in the header is
VERSION <xx> .. one less than the specified operand.
Example
ver 1
or
version $01
> Fixed Bugs
> ==========
>
> Problems with the extra spaces at the end of a line caused
> version of TricksASM prior to this one to crash. This bug
> has been fixed and your system should not hang forcing you to
> reset.
>
> More "blank space" related freezing has been debugged. Found
> this problem after assembling Tic-Tac-Toe from Amos.
>
> Please report any bugs to the email address listed at the
> end of this document.
Updates
=======
New versions of Tricks Assembler can be found on the Infinite
Dreams BBS at +1-604-733-6432. We also have a file area for
SNES programming files, demos, and utilities. I'll try to
send new versions to the famidev site on busop.cit.wayne.edu.
Closing Words
=============
TRASM was made mainly for my use but I've tried to stretch
the abilities so that other people would be comfortable with
using it as well. If you find some problems let me know as
I'd like to make it as bug-free as possible.
> TricksASM should not freeze on you very often anymore as I've
> found that the main problem was with extra spaces in lines or
> blank lines with spaces. It was stuck in an infinite loop.
> The bug has been squashed and your source codes should be
> have a smoother time getting assembled.
You can contact me through the Internet by leaving mail to:
norman_yen@idream.tfbbs.wimsey.com
or
norman_yen@mindlink.bc.ca
Or you can catch me on the IRC as 'minus'.
Norman Yen
AKA 1000 Miles [Tricks]