Bump changelog
[debian-beebasm.git] / README.md
blobe1ee67db894a693325f94093fef1dd51b36063b4
1 # BeebAsm
2 **Version V1.09**
4 A portable 6502 assembler with BBC Micro style syntax
6 Copyright (C) Rich Talbot-Watkins 2007-2012
7 <richtw1@gmail.com>
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.   
14 This program is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of 
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 General Public License for more details.   
19 You should have received a copy of the GNU General Public License
20 along with this program, as COPYING.txt.  If not, see   
21 http://www.gnu.org/licenses
24 ## CONTENTS
26 1. [ABOUT BEEBASM](#1.-ABOUT-BEEBASM)
27 2. [BEEBASM 'PHILOSOPHY'](#2.-BEEBASM-'PHILOSOPHY')
28 3. [EXAMPLE](#3.-EXAMPLE)
29 4. [COMMAND LINE OPTIONS](#4.-COMMAND-LINE-OPTIONS)
30 5. [SOURCE FILE SYNTAX](#5.-SOURCE-FILE-SYNTAX)
31 6. [ASSEMBLER DIRECTIVES](#6.-ASSEMBLER-DIRECTIVES)
32 7. [TIPS AND TRICKS](#7.-TIPS-AND-TRICKS)
33 8. [DEMO](#8.-DEMO)
34 9. [VERSION HISTORY](#9.-VERSION-HISTORY)
35 10. [REPORTING BUGS](#10.-REPORTING-BUGS)
39  ## 1. ABOUT BEEBASM
41 BeebAsm is a 6502 assembler designed specially for developing assembler programs for the BBC Micro.  It uses syntax reminiscent of BBC BASIC's built-in assembler, and is able to output its object code directly into emulator-ready DFS disc images.
43 Many of the luxuries which come from assembling within the BBC BASIC environment on a real BBC Micro are also available here, including FOR...NEXT loops, conditional assembly (IF...ELSE...ENDIF), and all of BASIC's numerical functions, including SIN, COS and SQR - very useful for building lookup tables directly within a source file.
45 BeebAsm is distributed with source code, and should be easily portable to any platform you wish.  To build under Windows, you will need to install MinGW (http://www.mingw.org), and the most basic subset of Cygwin (http://www.cygwin.org) which provides Windows versions of the common Unix commands.  Ensure the executables from these two packages are in your
46 Windows path, and BeebAsm should compile without problems.  Just navigate to the directory containing 'Makefile', and enter 'make code'.
51 ## 2. BEEBASM 'PHILOSOPHY'
53 BeebAsm is not like most modern assemblers, in that it doesn't just accept a source file, and output the corresponding object code file - after all, what use is a raw 6502 executable file on a PC, outside of an emulated BBC Micro environment?
55 Although BeebAsm *is* able to do this, this isn't the way it was intended to be used.  Instead, BeebAsm can be pointed at a BBC Micro DFS disc image (.ssd or .dsd file), and can save blocks of assembled object code directly onto the 'disc', as many or as few as you wish.  It is up to the source code to specify which blocks of assembled code to save, and with which name, just as if you were assembling from within BBC BASIC itself.
57 ## 3. EXAMPLE
59 Rather than trying to explain anything about BeebAsm now, let's leap straight into an example, as it can probably illustrate more about how BeebAsm should be used than a thousand lines of text.
61 Take the following highly contrived source file: `simple.asm`
63 -------------------------------------------------------------------------------
64 ```
65 \ Simple example illustrating use of BeebAsm
67 oswrch = &FFEE
68 osasci = &FFE3
69 addr = &70
71 ORG &2000         ; code origin (like P%=&2000)
73 .start
74     LDA #22:JSR oswrch
75     LDA #7:JSR oswrch
76     LDA #mytext MOD 256:STA addr
77     LDA #mytext DIV 256:STA addr+1
78     LDY #0
79 .loop
80     LDA (addr),Y
81     BEQ finished
82     JSR osasci
83     INY
84     BNE loop
85 .finished
86     RTS
88 .mytext EQUS "Hello world!", 13, 0
89 .end
91 SAVE "MyCode", start, end
92 ```
93 -------------------------------------------------------------------------------
95 ...and then build it with the following command:
97 `beebasm -i simple.asm -do test.ssd -boot MyCode -v`
99 This will do the following:
101 * create a new disc image called test.ssd, set to *OPT 4,3
102 * assemble the 6502 code and create an executable on the disc called 'MyCode'
103 * create a !Boot file containing '*RUN MyCode'
104 * output a listing of the assembled code
106 Note how the syntax in the source file is very much like BBC BASIC, with a few small differences which we'll look at in detail later.
108 Note also that the source code tells the assembler what should be saved - in this example, all of the assembled code (from .start to .end), with the filename 'MyCode'.  This might at first seem strange, but it's actually very simple and powerful: you have absolute control over what gets saved.  If we wished, we could assemble more code elsewhere and save it as a separate file, whilst all the defined labels remained visible to both chunks of code.
110 ## 4. COMMAND LINE OPTIONS
112 At its very most basic, you need know only one command line option:
114 `-i <filename>`
116 This specifies the name of the source file for BeebAsm to process.  In the absence of any switches specifying disc image filenames, SAVE commands in the source code will write out object files directly to the current directory.
118 `-o <filename>`
120 If this is specified, then the SAVE command can be used without supplying a filename, and this one will be used instead.  This allows BeebAsm to be used like a conventional assembler, specifying both input and output filenames from the command line.
122 `-do <filename>`
124 This specifies the name of a new disc image to be created.  All object code files will be saved to within this disc image.
126 `-boot <DFS filename>`
128 If specifed, BeebAsm will create a !Boot file on the new disc image, containing the command `*RUN <DFS filename>`.  The new disc image will already be set to `*OPT 4,3` (`*EXEC !Boot`).
130 `-opt <value>`
132 If specified, this sets the disc option of the generated disc image (i.e. the `*OPT 4,n` value) to the value specified.  This overrides the -boot option.
134 `-title <title>`
136 If specified, this sets the disc title of the generated disc image (i.e. the string set by `*TITLE`) to the value specified.
138 `-di <filename>`
140 If specified, BeebAsm will use this disc image as a template for the new disc image, rather than creating a new blank one.  This is useful if you have a BASIC loader which you want to run before your executable.  Note this cannot be the same as the `-do` filename!
142 `-v`
144 Verbose output.  Assembled code will be output to the screen.
146 `-vc`
148 Use Visual C++-style error messages.
150 `-d`
152 Dumps all global symbols in Swift-compatible format after assembly. This is used internally by Swift, and is just documented for completeness.
154 `-w`
156 If specified, there must be whitespace between opcodes and their labels. This introduces an incompatibility with the BBC BASIC assembler, which allows things like `ck_axy=&70:stack_axy` (i.e. `STA &70`), but makes it possible for macros to have names which begin with an opcode name, e.g.:
159     MACRO stack_axy
160         PHA:TXA:PHA:TYA:PHA
161     ENDMACRO
164 Things like `STA&4000` are permitted with or without `-w`.
166 `-D <symbol> `
168 `-D <symbol>=<value>`
170 Define `<symbol>` before starting to assemble. If `<value>` is not given, `-1` (`TRUE`)
171 will be used by default. Note that there must be a space between `-D` and the symbol. `<value>` may be in decimal, hexadecimal (prefixed with $, & or 0x) or binary (prefixed with %).
173 `-D` can be used in conjunction with conditional assignment to provide default values within the source which can be overridden from the command line.
175 ## 5. SOURCE FILE SYNTAX
177 Assembler instructions are written with the standard 6502 syntax.
179 A label is defined by preceding it with a `"."`, as per the BBC Micro assembler, e.g.  `.loop`
181 Instructions can be written one-per-line, or many on one line, separated by colons.  A label need not be followed by a colon.
183 Comments are introduced by a semicolon or backslash.  Unlike the BBC Micro assembler, these continue to the end of the line, and are not terminated by a colon (because this BBC Micro feature is horrible!).
185 Numeric literals are in decimal by default, and can be integers or reals. Hex literals are prefixed with `"&"`. A character in single quotes (e.g. `'A'`) returns its ASCII code.
187 BeebAsm can accept complex expressions, using a wide variety of operators and functions.  Here's a summary:
190 + - * /            Addition, subtraction, multiplication, division.
191 <<                 Arithmetic shift left; same precedence as multiplication
192 >>                 Arithmetic shift right; same precedence as division
193 ^                  Raise to the power of.
194 () or []           Bracketed expression.  Use [] to avoid confusion with
195                    6502 indirect instructions.
196 = or ==            Test equality.  Returns 0 or -1.
197 <> or !=           Test non-equality.  Returns 0 or -1.
198 < > <= >=          Other comparisons.  Returns 0 or -1.
199 AND                Bitwise AND.
200 OR                 Bitwise OR.
201 EOR                Bitwise EOR.
202 DIV                Integer division.
203 MOD                Integer modulus.
205 LO(val) or <val    Return lsb of 16-bit expression (like 'val MOD 256')
206 HI(val) or >val    Return msb of 16-bit expression (like 'val DIV 256')
207 -                  Negate (unary minus)
208 SQR(val)           Return square root of val
209 SIN(val)           Return sine of val
210 COS(val)           Return cosine of val
211 TAN(val)           Return tangent of val
212 ASN(val)           Return arc-sine of val
213 ACS(val)           Return arc-cosine of val
214 ATN(val)           Return arc-tangent of val
215 RAD(val)           Convert degrees to radians
216 DEG(val)           Convert radians to degrees
217 INT(val)           Round to integer (towards zero)
218 ABS(val)           Take the absolute value
219 SGN(val)           Return -1, 0 or 1, depending on the sign of the argument
220 RND(val)           RND(1) returns a random number between 0 and 1
221                    RND(n) returns an integer between 0 and n-1
222 NOT(val)           Return the bitwise 1's complement of val
223 LOG(val)           Return the base 10 log of val
224 LN(val)            Return the natural log of val
225 EXP(val)           Return e raised to the power of val
228 Also, some constants are defined:
231 PI                 The value of PI (3.1415927...)
232 FALSE              Returns 0
233 TRUE               Returns -1
234 * or P%            A special symbol which returns the current address being
235                    assembled at.
236 CPU                The value set by the CPU assembler directive (see below)
239 Within `EQUB/EQUS` only you can also use the expressions:
242 TIME$              Return assembly date/time in format "Day,DD Mon Year.HH:MM:SS"
244 TIME$("fmt")       Return assembly date/time in a format determined by "fmt", which
245                    is the same format used by the C library strftime().
248 The assembly date/time is constant throughout the assembly; every use of `TIME$`
249 will return the same date/time.
251 Variables can be defined at any point using the BASIC syntax, i.e. `addr = &70`.
253 Note that it is not possible to reassign variables once defined. However `FOR...NEXT` blocks have their own scope (more on this later).
255 Variables can be defined if they are not already defined using the conditional assignment syntax `=?`, e.g. `addr =? &70`. This is useful in conjunction with the `-D` command line option to provide default values for variables in the source while allowing them to be overridden on the command line. (Because variables cannot be reassigned once defined, it is not possible to define a variable with `-D` *and* with non-conditional assignment.)
257 (Thanks to Stephen Harris <sweh@spuddy.org> and "ctr" for the `-D`/conditional assignment support.)
260 ## 6. ASSEMBLER DIRECTIVES
262 These are keywords which control the assembly of the source file. 
264 Here's a summary:
266 `ORG <addr>`
268 Set the address to be assembled from.  This can be changed multiple times   during a source file if you wish (for example) to assemble two separate blocks of code at different addresses, but share the labels between both   blocks.  This is exactly equivalent to BBC BASIC's `P%=<addr>`.
271 `CPU <n>`
273 Selects the target CPU, which determines the range of instructions that will be accepted. The default is `0`, which provides the original 6502 instruction set. The only current alternative is 1, which provides the 65C02 instruction set (including `PLX`, `TRB` etc, but not the Rockwell  additions like `BBR`).
276 `SKIP <bytes>`
278 Moves the address pointer on by the specified number of bytes.  Use this to reserve a space of a fixed size in the code.
281 `SKIPTO <addr>`
283 Moves the address pointer to the specified address.  An error is generated if this address is behind the current address pointer.
286 `ALIGN <alignment>`
288 Used to align the address pointer to the next boundary, e.g. use `ALIGN &100` to move to the next page (useful perhaps for positioning a table at a page boundary so that index accesses don't incur a "page crossed" penalty.
291 `INCLUDE "filename"`
293 Includes the specified source file in the code at this point.
296 `INCBIN "filename"`
298 Includes the specified binary file in the object code at this point.
301 `EQUB a [, b, c, ...]`
303 Insert the specified byte(s) into the code.  Note, unlike BBC BASIC, that a comma-separated sequence can be inserted.
306 `EQUW a [, b, c, ...]`
308 Insert the specified 16-bit word(s) into the code.
311 `EQUD a [, b, c, ...]`
313 Insert the specified 32-bit word(s) into the code.
316 `EQUS "string" [, "string", byte, ...]`
318 Inserts the specified string into the code.  Note that this can take a comma-separated list of parameters which may also include bytes.  So, to zero-terminate a string, you can write:
321 EQUS "My string", 0
324 In fact, under the surface, there is no difference between `EQUS` and `EQUB`, which is also able to take strings!
327 `MAPCHAR <ascii code>, <remapped code>`
329 `MAPCHAR <start ascii code>, <end ascii code>, <remapped code>`
331 By default, when `EQUS "string"` is assembled, the ASCII codes of each character are written into the object code.  `MAPCHAR` allows you to specify which value should be written to the object code for each character.
333 Suppose you have a font which contains the following symbols - `space`, followed by `A-Z`, followed by digits `0-9`, followed by `.,!?-'`
335 You could specify this with `MAPCHAR` as follows:
338 MAPCHAR ' ', 0
339 MAPCHAR 'A','Z', 1
340 MAPCHAR '0','9', 27
341 MAPCHAR '.', 37
342 MAPCHAR ',', 38
343 MAPCHAR '!', 39
344 MAPCHAR '?', 40
345 MAPCHAR '-', 41
346 MAPCHAR ''', 42
348 Now, when writing strings with `EQUS`, these codes will be written out instead of the default ASCII codes.
351 `GUARD <addr>`
353 Puts a 'guard' on the specified address which will cause an error if you attempt to assemble code over this address.
356 `CLEAR <start>, <end>`
358 Clears all guards between the `<start>` and `<end`> addresses specified.  This can also be used to reset a section of memory which has had code assembled in it previously.  BeebAsm will complain if you attempt to assemble code over previously assembled code at the same address without having `CLEAR`ed it first.
361 `SAVE "filename", start, end [, exec [, reload] ]`
363 Saves out object code to either a DFS disc image (if one has been specified), or to the current directory as a standalone file.  A source file must have at least one SAVE statement in it, otherwise nothing will be output.  BeebAsm will warn if this is the case.
365 `'exec'` can be optionally specified as the execution address of the file when saved to a disc image.
367 `'reload'` can additionally be specified to save the file on the disc image to a different address to that which it was saved from.  Use this to assemble code at its 'native' address,  but which loads at a DFS-friendly address, ready to be relocated to its correct address upon execution.
370 `PRINT`
372 Displays some text.  `PRINT` takes a comma-separated list of strings or values. 
374 To print a value in hex, prefix the expression with a `'~'` character.
376 Examples:
378 PRINT "Value of label 'start' =", ~start
379 PRINT "numdots =", numdots, "dottable size =", dotend-dotstart
381                         
382 `ERROR "message"`
384 Causes BeebAsm to abort assembly with the provided error message.  This can be useful for enforcing certain constraints on generated code, for example:
386   .table
387     FOR n, 1, 32
388       EQUB 255 / n
389     NEXT
390   
391 IF HI(P%)<>HI(table)
392     ERROR "Table crosses page boundary"
393 ENDIF
396 `FOR <var>, start, end [, step] ... NEXT`
398 I wanted this to have exactly the same syntax as BASIC, but I couldn't without rewriting my expression parser, so we're stuck with this for now.
400 It works exactly like BASIC's `FOR...NEXT`.  For example:
402 FOR n, 0, 10, 2    ; loop with n = 0, 2, 4, 6, 8, 10
403   PRINT n
404   LDA #0:STA &900+n
405   LDA #n:STA &901+n
406 NEXT
409 The variable n only exists for the scope of the `FOR...NEXT` loop. Also, any labels or variables defined within the loop are only visible within it.  However, unlike BBC BASIC, forward references to labels inside the loop will work properly, so, for example, this little multiply routine is perfectly ok:
411 .multiply
412 \\ multiplies A*X, puts result in product/product+1
413 CPX #0:BEQ zero
414 DEX:STX product+1
415 LSR A:STA product:LDA #0
416 FOR n, 0, 7
417   BCC skip:ADC product+1:.skip   \\ would break BBC BASIC!
418   ROR A:ROR product
419 NEXT
420 STA product+1:RTS
421 .zero
422 STX product:STX product+1:RTS
425 `IF...ELIF...ELSE...ENDIF`
427 Use to assemble conditionally.  Like anything else in BeebAsm, these statements can be placed on one line, separated by colons, but even if they are, `ENDIF` must be present to denote the end of the `IF` block (unlike BBC BASIC).
429 Examples of use:
431 \\ build a rather strange table
432 FOR n, 0, 9
433   IF (n AND 1) = 0
434     a = n*n
435   ELSE
436     a = -n*n
437   ENDIF
438   EQUB a
439 NEXT
441 IF debugraster:LDA #3:STA &FE21:ENDIF
443 IF rom
444   ORG &8000
445   GUARD &C000
446 ELIF tube
447   ORG &B800
448   GUARD &F800
449 ELSE
450   ORG &3C00
451   GUARD &7C00
452 ENDIF
455 `{ ... }`
457 Curly braces can be used to specify a block of code in which all symbols and labels defined will exist only within this block.  Effectively, this is a mechanism for providing 'local labels' without the slightly cumbersome syntax demanded by some other assemblers.  These can be nested.  Any symbols defined within a block will override any of the same name outside of the block, exactly like C/C++ - not sure if I like this behaviour, but for now it will stay.
459 Example of use:
461 .initialise
463     LDY #31
464     LDA #0
465 .loop              ; label visible only within the braces
466     STA buffer,Y
467     DEY
468     BPL loop
469     RTS
472 .copy
474     LDY #31
475 .loop              ; perfectly ok to define .loop again in a new block
476     LDA source,Y
477     STA dest,Y
478     DEY
479     BPL loop
480     RTS
483 Labels can be defined within a scope which exist outside that scope in two ways.
485 A label defined using `'.*label'` will be globally visible:
487 .copy_10
489     LDX #10
490 .*copy_x
491     DEX
492 .loop
493     LDA from,X
494     STA to,X
495     DEX
496     BPL loop
497     RTS
500 JSR copy_10
501 LDX #20
502 JSR copy_x
504 A label defined using `'.^label'` will be visible in the parent scope:
506 .contrived
508     LDX #255
509     {
510         LDY #3
511     .^loop
512         DEX
513         BEQ exit
514         DEY
515         BNE loop
516     }
517     LDY #7
518     JMP loop ; .loop *is* visible here
519 .exit
520     RTS
522 JMP loop ; error, .loop is *not* visible here
524 For a more realistic example of the use of `'.^label'`, see `scopejumpdemo2.6502`.
526 (Thanks to Steven Flintham for the implementation of `.*` and `.^.`)
529 `PUTFILE <host filename>, [<beeb filename>,] <start addr> [,<exec addr>]`
531 This provides a convenient way of copying a file from the host OS directly to the output disc image.  If no 'beeb filename' is provided, the host filename will be used (and must therefore be 7 characters or less in length). A start address must be provided (and optionally an execution address can be provided too).
534 `PUTTEXT <host filename>, [<beeb filename>,] <start addr> [,<exec addr>]`
536 This command is the same as `PUTFILE`, except that the host file is assumed to be a text file and its line endings will be automatically converted to CR (the BBC standard line ending) from any of CR, LF, CRLF or LFCR.
538   
539 `PUTBASIC <host filename> [,<beeb filename>]`
541 This takes a BASIC program as a plain text file on the host OS, tokenises it,and outputs it to the disc image as a native BASIC file.  Credit to Thomas Harte for the BASIC tokenising routine.  Line numbers can be provided in the text file if desired, but if not present they will be automatically generated. 
543 See `autolinenumdemo.bas` for an example.
544   
545   
546 `MACRO <name> [,<parameter list...>]`
548 `ENDMACRO`
550 This pair of commands is used to define assembler macros.  Their use is best
551 illustrated by an example:
553 MACRO ADDI8 addr, val
554   IF val=1
555     INC addr
556   ELIF val>1
557     CLC
558     LDA addr
559     ADC #val
560     STA addr
561   ENDIF
562 ENDMACRO
565 This defines a macro called `ADDI8` ("ADD Immediate 8-bit") whose function is to add a constant to a memory address.  It expects two parameters: the memory address and the constant value.  The body of the macro contains an `IF` block which will generate the most appropriate code according to the constant value passed in.
567 Then, at any point afterwards, the macro can be used as follows:
569 ADDI8 &900, 1            ; increment address &900 by 1
570 ADDI8 bonus, 10          ; add 10 to the memory location 'bonus'
571 ADDI8 pills, pill_add    ; pills += pill_add
573 Macros can also be called from other macros, as demonstrated by this somewhat contrived example:
575 MACRO ADDI16 addr, val
576   IF val=0
577       ; do nothing
578   ELIF val=1
579     INC addr
580     BNE skip1
581     INC addr+1
582     .skip1
583   ELIF HI(val)=0
584     ADDI8 addr, val
585     BCC skip2
586     INC addr+1
587     .skip2
588   ELSE
589       CLC
590     LDA addr
591     ADC #LO(val)
592     STA addr
593     LDA addr+1
594     ADC #HI(val)
595     STA addr+1
596   ENDIF
597 ENDMACRO
599 Care should be taken with macros, as the details of the code assembled are hidden.  In the above `ADDI16` example, the `C` flag is not set consistently, depending on the inputs to the macro (e.g. it remains unchanged if `val=0` or `1`, and will not be correct if `val<256`).
602 `ASSERT a [, b, c, ...]`
604 Abort assembly if any of the expressions is false.
607 `RANDOMIZE <n>`
609 Seed the random number generator used by the RND() function.  If this is not used, the random number generator is seeded based on the current time and so each build of a program using `RND()` will be different.
611 ## 7. TIPS AND TRICKS
613 BeebAsm's approach of treating memory as a canvas which can be written to, saved, and rewritten if desired makes it very easy to create certain types of applications.
615 Imagine wanting to create a program which used the BBC Micro's main RAM, plus 2 sideways RAM banks.  If there was executable code in main RAM and in both banks, it's quite likely that you'd want to share label names amongst all of these blocks of code, so that main RAM routines could page in the appropriate RAM bank and call a routine in it, and likewise sideways RAM banks could call routines in main RAM.
617 Here's one way you could do that in BeebAsm:
620 \\ Declare origin of main RAM code
621 ORG &1100
623 \\ Put a guard at the start of screen
624 GUARD &5800
626 .mainstart
627   LDA #5:STA &FE30   ; page in RAM bank 2
628   JSR bank2routine
629   ...
630 .mainroutine
631   ...
632 .mainend
634 SAVE "Main", mainstart, mainend, mainentry
637 \\ Declare origin of bank 1 code
638 ORG &8000
640 \\ Put a guard after the RAM bank so we don't stray over our boundary
641 GUARD &C000
643 .bank1start
644   ...
645   JSR mainroutine
646   ...
647 .bank1end
649 SAVE "Bank1", bank1start, bank1end
652 \\ Clear memory used by previous bank
653 CLEAR &8000, &C000
655 \\ Declare origin of bank 2 code
656 ORG &8000
658 \\ Put a guard after the RAM bank so we don't stray over our boundary
659 GUARD &C000
661 .bank2start
662   ...
663 .bank2routine
664   RTS
665   ...
666 .bank2end
668 SAVE "Bank2", bank2start, bank2end
671 Because all of this code is assembled in one session, label and variable names persist across the assembly of all blocks of code.
673 For tidiness, you could move the source code for each block of code into a different file, and then just INCLUDE these in your main source file:
675 INCLUDE "main.asm"
676 INCLUDE "bank1.asm"
677 INCLUDE "bank2.asm"
680 ## 8. DEMO
682 There's a little assembler demo included called `"demo.asm"`.
683 Build it with something like:
685 ```beebasm -i demo.asm -do demo.ssd -boot Code -v```
687 and it will create a bootable disc image.
689 As well as demonstrating some of the features of BeebAsm (including building lookup tables), it's also a fairly good demo of pushing the hardware to its limits, in terms of creating a flicker-free animation, updating at 50Hz. (This is not to say that it's particularly impressive, but nonetheless, it really is pushing the hardware!!)
691 There is also a demo called `"relocdemo.asm"`, which shows how the 'reload address' feature of SAVE can be used to write self-relocating code.  This is based on the above demo, but it runs at a low address (&300).
694 ## 9. VERSION HISTORY
696 12/05/2018  1.09  Added ASSERT
697                   Added CPU (as a constant)
698                   Added PUTTEXT
699                   Added RANDOMIZE
700                   Added TIME$
701                   Added command line options: -title, -vc, -w, -D
702                   Added conditional assignment (=?)
703                   Improved error handling in PUTFILE/PUTBASIC
704                   Added optional automatic line numbering for PUTBASIC
705                   Show a call stack when an error occurs inside a macro
706                   Allow label scope-jumping using '.*label' and '.^label'
707                   Allow high bits to be set on load/execution addresses
708                   Show branch displacement when "Branch out of range" occurs
709                   Fixed bugs in duplicate filename direction on disc image
710                   Fixed spurious "Branch out of range" error in rare case
711 19/01/2012  1.08  Fixed makefile for GCC (MinGW) builds.
712                   Added COPYBLOCK command to manage blocks of memory.
713 06/10/2011  1.07  Fixed mixed-case bug for keywords (so now oddities such as
714                   INy are parsed correctly).
715                   Now function keywords require an open bracket immediately
716                   afterwards (which now means that symbol names such as
717                   HIGHSCORE, which start with the keyword HI, are valid).
718 16/06/2011  1.06  Fixed bug in EQUD with unsigned int values.
719                   Added ERROR directive.
720 25/04/2011  1.05  Added macros.
721                   Added PUTFILE and PUTBASIC (to tokenise a plaintext BASIC
722                   file, using code by Thomas Harte).
723 02/12/2009  1.04  Additions by Kevin Bracey:
724                   Added 65C02 instruction set and CPU directive.
725                   Added ELIF, EQUD.
726                   SKIP now lists the current address.
727 27/07/2009  1.03  Bugfix: Corrected the unary < and > operators to
728                   correspond to HI and LO as appropriate.
729                   Added '$' as a valid hex literal prefix.
730                   Added '%' as a binary literal prefix.
731 06/11/2008  1.02  Bugfix: now it's possible to save location &FFFF.
732                   Added 'reload address' parameter to SAVE.
733                   Properly integrated the GPL License text into the
734                   distribution.
735 14/04/2008  1.01  Bugfixes: allow lower case index in abs,x or abs,y.
736                   Fails if file already exists in output disc image.
737                   Symbol names may now begin with assembler opcode names.
738 30/03/2008  1.00  First stable release.  Corrected a few C++ compliance
739                   issues in the source code.
740 22/01/2008  0.06  Fixed bug with forward-referenced labels in indirect
741                   instructions.
742 09/01/2008  0.05  Added MAPCHAR.  Fixed SKIPTO (see, told you I was doing
743                   it quickly!).  Enforce '%' as an end-of-symbol
744                   character.  Fixed bug in overlayed assembly.  Warns if
745                   there is no SAVE command in the source file.
746 06/01/2008  0.04  Added braces for scoping labels.  Added INCBIN, SKIPTO.
747                   Added some missing functions (NOT, LOG, LN, EXP).
748                   Tightened up error checking on assembling out of range
749                   addresses (negative, or greater than &FFFF).  Now
750                   distinguishes internally between labels and other
751                   symbols.
752 05/01/2008  0.03  Added symbol dump for use with Swift.
753 20/12/2007  0.02  Fixed small bug which withheld filename and line number
754                   display in error messages.
755 16/12/2007  0.01  First released version.
760 ## 10. REPORTING BUGS
762 BeebAsm was writen by Rich Talbot-Watkins but is now maintained by the members of the 'stardot' forums. 
764 The official source repository is at https://github.com/stardot/beebasm. 
766 Please post any questions or comments relating to BeebAsm on the 'Development tools' forum at stardot: http://www.stardot.org.uk/forums/viewforum.php?f=55
768 Thank you!