aboutsummaryrefslogtreecommitdiff
path: root/unmac65.rst
blob: 53308286686f28d39b2612187872fcd8ebcfbe98 (plain)
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
.. RST source for unmac65(1) man page. Convert with:
..   rst2man.py unmac65.rst > unmac65.1
.. rst2man.py comes from the SBo development/docutils package.

=======
unmac65
=======

------------------------------------------
Detokenize Atari 8-bit Mac/65 SAVEd files.
------------------------------------------

.. include:: manhdr.rst

SYNOPSIS
========

**unmac65** [*-options*] *file.m65*

DESCRIPTION
===========

**unmac65** reads files created with Mac/65's SAVE command (usually called
.M65 files) and converts them back to plain text assembly source.

OPTIONS
=======

-a
  Use ATASCII EOLs. This option is not available in Atari version,
  since it already uses ATASCII.

-c
  Convert non-printable characters constants to hex bytes.

**-cc**
  Convert all character constants to hex bytes.

-e nnn[,iii]
  Renumber the program, starting at line *nnn*, with increment *iii*.
  *nnn* must be present, and must be an integer greater than or equal
  to zero. *iii* is optional, must be positive (non-zero), and
  defaults to 10 if not given.

  Mac/65's maximum line number is 65535. unmac65 will happily renumber
  lines with no upper bound (other than unsigned int overflow), so pay
  attention.

-h
  Show command-line help.

-i
  Convert inverse video (in comments and strings) to standard ASCII.
  Lines that were converted will get a comment "*; XXX inverse*" at
  the end. This option also enables the -c option.

  If the program contained any inverse-video strings, the resulting
  output will *not* reassemble correctly; you'll have to edit it to
  e.g. change the formerly inverse video strings to a list of hex
  bytes.

  This option is not available in the Atari version.

-l
  Lowercase mnemonics and hex constants (but not labels or comments).

**-la**
  Lowercase mnemonics, hex constants, labels, and comments (but not
  strings or character constants).

-n
  No line numbers in output.

-o file
  Output to *file* (default = standard output).

-q
  Add closing single-quote to character constants. Changes this::

    LDA #'A

  ...to this::

    LDA #'A'

-p
  Omit leading . (period) from pseudo-ops (e.g. print BYTE for .BYTE).

-t
  Replace leading spaces with tabs.

**-ta**
  Replace spaces between all fields with tabs.

-v
  Verbose output (dump tokens in hex). Useful for examining damaged
  .M65 files, or debugging unmac65 itself.

Human-readable Output Options
-----------------------------

The -m, -r, and -u options are not available for the Atari, and may or
may not be useful on non-Linux OSes.

-m
  Print inverse video as pseudo-underlined, using backspace and
  underscore. Useful for piping to more(1) or less(1). Can be combined
  with -u.

-r
  Print inverse video as reverse video using xterm/ANSI compatible
  escape sequences. Can be combined with -u. Useful for piping to
  less(1) provided its -r or -R option is used.

-u
  Print ATASCII control characters as their nearest Unicode
  equivalents (encoded in UTF-8). Depending on your terminal,
  combining this option with -r may not work properly. Also, depending
  on the font(s) your terminal is using, you may see boxes instead of
  control characters. If this happens, try a different font, or a
  different terminal (the author recommends rxvt-unicode).

Options may not be bundled (use "-p -t", not "-pt").

Unlike most UNIX-flavored programs, the CLI options are
case-insensitive. This is to make life easier for users of the Atari
version, where uppercase is the normal way of doing things.

The -c, -cc, -l, -la, -n, -p, -t, -ta options are provided to assist in
porting Mac/65 programs to other assemblers, such as ca65 or dasm.
unmac65's output with none of these options (or with -n only) is
acceptable as input for the atasm assembler. This is true even if there
are inverse video strings: they look funny when viewing the file, but
atasm handles them correctly.

The -v option prints the hex bytes for each line (preceded by ";;" and
the line number) after that line's detokenized listing.

Note that the output from -m, -r, -u is intended for humans to read.
They're not very useful if you're trying to port Mac/65 code to a
different assembler, as none of them know what to do with the
underlines, ANSI codes, or pseudo-ATASCII Unicode characters.

FILE FORMAT
===========

A tokenized Mac/65 file consists of:

Header: 2 byte $FE $FE signature, followed by the 2 byte program length
in LSB/MSB format. Length doesn't include the 4 header bytes.

The rest of the file consists of lines of code. Each line is:

Line number, 2 bytes (LSB/MSB format)

Line length, 1 byte. Total length, including the line number and length
bytes.

Tokens. Length minus 3 bytes of tokens. If the line is labelled, the
label will appear first, as a tokenized string (see below).

Whether or not there's a label, the next byte is the token for a
mnemonic (or pseudo-op). Lines containing only a comment will have a
special token meaning "no mnemonic".

After the mnemonic token, 0 or more bytes of operands. Quoted strings or
labels as operands are stored as a tokenized string. Hex or decimal
constants are preceded by a token indicating the length (one or two
bytes) and the type (hex or decimal).

If there is a comment, the last byte of the operand field will be an
ASCII semicolon. The remaining bytes on the line are the comment in
ASCII form.

Tokenized strings can occur in the label or operand parts of the line.
The first byte is the length of the string in bytes, with the high bit
set (e.g. $84 for a 4-byte string), followed by that number of ASCII
bytes. The length doesn't include the first byte, so e.g. the string
"ABC" is stored as $83, $41, $42, $43. Mac/65 doesn't allow empty
strings, so a zero-length string (length byte $80) is an error.

There are separate sets of tokens for mnemonics/pseudo-ops and operands.
Mnemonic/pseudo-op tokens run from 0 to $5F, and operand tokens run from
0 to $4D (with 0-$09 being "special", and a few invalid tokens in the
range $0A-$4D). See the C source for the full list (or a hex/ascii dump
of the Mac/65 ROM, which is where I got the lists to put them in the C
source). Also, you can run unmac65 with the -v option to get a
line-by-line hex dump of the tokens.

DIAGNOSTICS
===========

unmac65: line XX contains NN non-printable ATASCII characters <= $1F

Self-explanatory. Depending on what you're going to use the converted
file for, this may or may not be a problem. Non-fatal. This warning
doesn't occur in the Atari version of unmac65. Also, it doesn't occur if
the -u option is in use.

unmac65: line XX contains NN inverse ATASCII characters >= $80

Self-explanatory. Depending on what you're going to use the converted
file for, this may or may not be a problem. Non-fatal. Use the -i option
to convert inverse video to normal. This warning doesn't occur in the
Atari version of unmac65. Also, it doesn't occur if any of the -i, -m,
or -r options are in use.

unmac65: not a mac/65 file (missing $FEFE header)

Self-explanatory. Fatal error.

unmac65: corrupt or truncated file?

The length of the last line in the file is longer that the number of
bytes remaining in the file (according to the file header). Fatal error.

unmac65: unexpected EOF?

The file is shorter than the file header's program length. Probably the
file is truncated; less probably, the length header got scrambled
somehow. Fatal error.

unmac65: file is too short (N bytes)

The minimum length for a Mac/65 file is 4 bytes (which would be an empty
program containing no lines). The input file was shorter than 4 bytes.
Fatal error. (Actually, Mac/65 will never produce a 4-byte file, it's
just the theoretical minimum)

unmac65: file is valid but contains no lines of code

Self-explanatory. Mac/65 creates a file like this if the SAVE command is
given before entering any code (at startup or after a NEW). The SAVEd
file will be 5 bytes in length, and utterly useless. Non-fatal warning.

unmac65: line #lll <= prev line #mmm

The line numbers in the file are supposed to be stored in ascending
order. Somehow this file has the line numbers out of order. Non-fatal,
but probably the rest of the file will be garbage.

unmac65: internal error, state n

This is a "this should never happen" error. It indicates a bug in the
program. If you ever see this error, please notify the author, and send
a copy of the Mac/65 program that caused it. This is a non-fatal error,
but the output might be garbage.

[$nn?] or <$nn?> in the output (where nn is 2 hex digits)

These indicate unknown/invalid tokens. Either the file is damaged, or
there is a bug in the program. These are non-fatal errors. If you ever
see them, please contact the author, and send a copy of the Mac/65
program that caused them.

unmac65: ignoring extra junk at EOF

The file contains more bytes than the program length header says it
should. This usually means the file was stored on an old DOS disk or
transferred with a broken XMODEM implementation, and was padded to the
sector/block size. Alternately, the header bytes got corrupted somehow
(this is highly unlikely, especially if there are no other
errors/warnings). Non-fatal error.

Other errors are possible (e.g. disk full, I/O error reading input), but
they're not specific to unmac65; no need to list them all there.

Fatal errors result in unmac65 terminating. A non-fatal error can
usually be recovered from, though the line that caused it will probably
be printed strangely.

It's probably worth mentioning also that Mac/65 source files can contain
ATASCII graphics or escape codes, although it's not a very common
practice. If you see strange stuff and/or your terminal misbehaves when
writing to standard output, try writing to a file (-o option) instead.
See also the -m, -r, -u options for human-readable output. The Atari
version will render ATASCII graphics just fine, of course.

EXIT STATUS
===========

unmac65 will normally exit with a zero (success) status upon completion.
A non-zero status indicates a fatal error.

LIMITATIONS
===========

The main difference between Mac/65's LIST output and unmac65's output is
that Mac/65 lines up the label, mnemonic, and comment fields (if the
field contents are short enough to fit in the allotted width), while
unmac65 makes no attempt to do so. If the field alignment is important
to you, try the -t or -ta options (which insert hard tabs, unlike
mac65's spaces). A future version of unmac65 may correct this minor
flaw, but as it stands, I've tested quite a few .M65 files by running
them through unmac65, then ENTERing unmac65's listed file in Mac/65 and
reSAVEing them... In all cases, the newly created tokenized files
compare identically to the original .M65 file. If you come across a file
that doesn't do this, yet is valid (can be assembled without error by
Mac/65), please send it to me, so I can fix unmac65!

Although a few helpful options have been added for porting Mac/65
sources to other assemblers, unmac65 doesn't completely automate the
process. Depending on the assembler you're using, you may still have a
lot of manual edits to make. A future version of unmac65 may add a few
more options, but some hypothetical complex porting functions (like
"convert to ca65 format") would require implementing a much more complex
parser (such as a yacc-based recursive descent parser). Most likely this
will never happen, if only because I want the program to be usable on
the Atari itself, with its limited memory and C compiler support.

There are a few ways that an invalid file can sneak past unmac65's error
checking. The same files wouldn't load correctly in Mac/65 either, but
generally don't cause any errors in Mac/65 (just silent failure). It'd
be nice if unmac65 could act as a "M65 lint" for Mac/65 users.

unmac65 is mostly developed/tested against the OSS Mac/65 v1.01
cartridge. The various disk versions appear to use the same tokenized
format, but haven't been well tested. If you have problems, please
contact the author.

(A further limitation is that the documentation isn't very concise.
Sorry about that.)

.. include:: manftr.rst