
-------------------------------------
Turbo Macro Pro, General Overview
-------------------------------------

 The Turbo Macro Pro (TMP) toolset consists of several different but very
similar versions, each one made for a specific machine/hardware config.
The tools in the current release of TMP are:

 TMP      v1.2 - for c64 with no REU expander.
 TMP+REU  v1.2 - for c64 with an REU (1764, 1700, 1750), which offers
                 128k, 256k, or 512k of extra himem.
 JB REU   v1.1 - emergency jumpbacker for REU/R2 source re-entry
 TMP(x2)  v1.2 - for a dual c64 system where coding occurs on one
                 machine, and assembled data is transmitted over
                 a custom cable to a second machine for execution.
 TMP(r2)  v1.2 - for a dual c64 system where the coding machine also
                 has an REU (this merges the REU and X2 mods).
 TMP+DTV  v1.2 - for the DTV joystick system which offers an extra
                 64k bank of himem.
 JB DTV   v1.1 - emergency jumpbacker for DTV source re-entry
 TMP+PTV  v1.2 - for the PAL DTV (PTV for short) and Hummer which offers
                 an extra 2 megs of himem (only the top 512k are used
                 by TMP).
 JB PTV   v1.1 - emergency jumpbacker for PTV source re-entry
 TMPPREFS V1.2 - preferences editor for altering and saving a customized
                 TMP v1.2 binary.

 The tools also work on a c128, in c64 mode of course.

 In addition to the actual assembler tools, there is also an emergency
restore tool for each different configuration of extra memory. These
tool are called 'jumpbackers' - they enable the user to detect existing
instances of TMP in the extra memory banks of the REU, DTV, or PTV and
retrieve that back into the c64's main memory, effectively re-entering
the tool where it was last left off. The jumpbacker can be used in cases
where a user is executing assembled code and the c64 main memory becomes
corrupted or otherwise, preventing any built-in jumpback routine from
working. See below for a more detailed explanation of how this fits in
with the extra memory features of TMP.

 Each version of TMP is entered in the same way, by jmp'ing to $8000 from
inside a monitor or toolcart (e.g. Super Snapshot) or by executing from
BASIC using 'sys 8*4096'. This starts the TMP program, which initializes
various things and places you directly into the interactive editor. One
important feature of TMP (and all versions of TA/TAM) is that re-entrance
into the program does not initialize or erase your source code data; you
can exit and re-enter the program multiple times and each time you are
back to where you left off within the source code.


-------------------------------------
Turbo Macro Pro, Extra RAM Concepts
-------------------------------------

 While TMP offers a number of additonal features and bug fixes against
the OriTAM, the most vital to understand is how TMP handles extra memory
in the REU, R2, DTV, and PTV mods. Each of these mods adopts a 'bank'
concept which treats the extra RAM as one or more 64k banks. TMP then
assigns to each bank some role in the code-test-code cycle. These roles
are:

 Assembly: the assembly bank is where assembled code (the machine code
  output from the assembler) is placed.

 Object  : the object bank is a non-volatile storage bank for additional
  binary object data, such as data tables, bitmaps, or even pre-assembled
  code libraries. When a separate object bank is used, TMP will copy it
  into the assembly bank *prior* to assembling. The use of an object bank
  therefore allows a user to preload all the binary data necessary only
  one time, and then code and test repeatedly without having to reload
  the binary data each time.
 
 Source  : a source bank holds a complete instance of the TMP program
  with one specific source code. TMP allows a quick way to swap between
  source banks, effectively changing the source code that is currently
  active and editable. Hardware configurations with 512k of extra RAM
  actually allow six (6) separate source codes to remain resident in
  memory at a time. Only one is active (in the c64's main memory) at any
  given moment. Whatever source code is currently active is the one that
  will be assembled to the assembly bank. Once a source code is assembled
  the user is prompted to execute the code, and if they do, TMP swaps the
  assembly bank into the c64 main memory while the active source code is
  swapped out to the assembly bank. At that moment there are actually two
  identical copies of the source code in himem - one in the assembly bank
  and one in whatever source bank it was originally assigned to. After
  this swap, the assembled code is executed. TMP will by default store
  a short routine in memory which can be jmp'd to and which will re-swap
  the assembly bank back into c64 main memory and re-enter TMP, returning
  to the code editor where it was left off prior to assembling. 
 
 There are typically 4 different extra memory size configurations:
 
 64k:  Effective in the DTV mod. Because there is only one bank available,
  TMP treats it as a combined assembly/object bank. It is not possible to
  store and swap between other source codes, and obviously the object data
  is not separated into it's own non-volatile bank; but the extra bank
  still enables a rapid code-test-code cycle at least without being
  required to reload the assembler and code after each test run.
  
 128k: Effective in the REU mod. Bank 0 is used as the assembly bank and
  bank 1 is used as the object bank. It is not possible to store and swap
  between other source codes, but the object data remains uncorrupted after
  each test run.
 
 256k: Effective in the REU mod. Bank 0 is the assembly bank. Bank 1 is
  the default object bank but this can be altered to any bank 1-3. There
  are two extra banks available to hold up to two different source codes
  at once.
 
 512k: Effective in the REU and PTV mods. Bank 0 is the assembly bank.
  Bank 1 is the default object bank but can be altered to any bank 1-7.
  There are six extra banks available to hold up to six different source
  codes at once.


-------------------------------------
Turbo Macro Pro, Dual c64 Concepts
-------------------------------------

 Our X2/R2 mods function essentially the same as similar 'dual c64' mods 
from the past which enabled development to occur on a primary or 'master'
system and then transmit and execute code over a cable to a secondary or
'slave' system. X2 refers to a version of TMP geared for users with 2 c64 
systems but no REU. R2 is a version unlike any Turbo mod before it, because 
it combines TMP+REU's powerful REU modifications with the capability to
assemble the object code to the second c64 as well.

 To use the X2/R2 mods, first install the 'x2rec' object code to the slave 
system - this code will run and wait to receive the assembled code from the 
master system. The source for the x2rec code, as well as a prebuilt binary 
located at $334, are included in the toolset. Once you have executed the 
code on the slave (e.g. jmp $334 for the prebuilt x2rec), then you are 
ready to perform a {back-arrow}+% command on your TMP instance running on 
the master system. Doing so sends the assembled object code across the X2 
cable to the slave. When the xfer is complete, the code automagically 
starts on the slave. Assuming the x2rec code is not overwritten in the 
course of testing you may simply reset and rerun the x2rec code to prepare 
for another assemble and test run. Instructions on making the cable are 
included in the 'x2rec' source code file; it is really quite simple, 
straight wiring a few pins from each user port together.


-------------------------------------
Turbo Macro Pro, Editor Overview
-------------------------------------

 The TMP editor is an almost-full screen line-based text editor. The
bottom two lines are reserved for a message line which displays program
generated errors/feedback, and a status line which displays the current
horizontal cursor position/column, the bottom of source code memory, the
editing modes re: character and line insertion, the current serial device
number, and in the case of mods supporting extra memory, the current
object and source bank numbers.

 Cursor keys work as expected, and the user is free to scroll up and
down in the source code listing. Edits can be made in place, and TMP
will automatically format each edited line, keeping the actual code
(opcodes or pseudo ops) aligned against one column. TMP will also detect
syntax errors in realtime, highlighting the offending line and give error
feedback on the message line.


-------------------------------------
Turbo Macro Pro, Editor Commands
-------------------------------------

 Special editor commands are accessed by pressing the 'command key',
followed by another key to invoke a specific command. Certain commands
will themselves invoke a submenu of additional commands. Several other
commands may prompt for user input such as filenames, memory locations,
and so on. The command key in all versions of TA, TAM, and TMP is the
{back arrow} which is located to the immediate left of the number 1 key.

 The table below shows all the commands that are invoked by first pressing
the command key, following by the key in the 'KEY' column below:

KEY    ACTION
1      exit-basic: Leaves TMP to a BASIC prompt. TMP can be re-entered
        immediately after doing this with a 'sys 8*4096'.
!      view-seq: Prompts for a SEQ filename, then displays the contents
        of the file on screen; CBM pauses output, run/stop aborts.
2      paste-separator: Outputs a 'separator' comment line to the current
        cursor line, overwriting anything else there.
3      assemble: Assembles to the assembly bank, which is bank 0 in all
        mods supporting extra RAM, or simply directly to c64 main memory
        on the unexpanded c64 mod.
#      assemble-to-object: Assembles to the current object bank; only
        enabled on mods supporting extra RAM.
4      print-source: Prompts for a filename to which a source code print
        out will be saved as a SEQ file. Instead of a filename, enter '?'
        by itself to print directly to a printer (device 4) or '*' by
       itself to output to the screen (CBM pauses output, run/stop aborts).
5      assemble-to-disk: Prompts for a filename to which assembled code
        is saved on disk.
%      assemble-to-slave: Assembles across a cable to a slave machine; only
        enabled in the X2/R2 mods.
6      make-data: Prompts for a region of memory (start and end address).
        Data in that region are read and translated into .byte statements
        which are inserted into the source code at the current cursor line.
        In mods supporting extra RAM, the data is read from the current
        object bank; otherwise the data is read from the c64 main memory.
7      set-tab-return: Takes the current cursor location and sets that as
        the column at which the cursor is placed after pressing return.
8      set-tab-source: Takes the current cursor location and sets that as
        the column at which the source code (opcode/pseudo) is aligned at.
+      add-hex: Prompts for two 16bit values, adding them and outputting
        the result in hex and decimal.
-      sub-hex: Prompts for two 16bit values, subtracting the second from
        the first and outputting the result in hex and decimal.
DEL    delete-line: Removes the entire line under cursor, moving subsequent
        lines up by one.
INST   toggle-line-insert: Switches the editing mode for line insertion;
        when off, hitting return does not insert a new blank line.
^      copy-line-buffer: Copies the line under cursor to the line buffer.
#      paste-line-buffer: Pastes the line buffer to the current cursor line.
q      cursor-left-edge: Move cursor to column 0 (the leftmost column)
w      write-seq: Prompts for a filename to which the current source is
        saved to disk as a SEQ file.
e      enter-seq: Prompts for a filename from which lines of source code
        are read off disk and inserted at the current cursor line.
r      replace-string: Prompts for search and replacement strings and then
        finds the first occurance of the search string, leaving the cursor
        at that occurance.
R      ram-submenu: Activate the expansion RAM submenu (where applicable),
        with these additional key commands:
  l    load-to-ram: Prompts for a filename. A second prompt is given for a
        load address, using the file's actual load address as a default. 
        Then the file is loaded into the current object bank at the given
        address.
  b    backup-to-bank: Prompts for an available source bank number, and
        then copies the active source code into that bank.
  o    set-object-bank: Prompts for an available RAM bank and uses that as
        the new object bank.
  s    swap-to-bank: Prompts for an available source bank number; if the
        selected bank contains a TMP/source instance, then the active
        source code is backed up to it's assigned bank and the selected
        bank is swapped into c64 main memory, becoming the new active
        source code. TMP will not allow swapping in a bank that doesn't
        already have a TMP instance in it.
  j    set-jumpback: Prompts for an address, which will be the location
        to which the jumpback routine will be copied when executing an
        assembled code. If the address is set to $0000 then TMP will not
        copy the jumpbacker at all. The default address is $0140.
t      replace-one: Executes one replacement of a just-found search string
        and then searches for the next occurance, moving the cursor to it.
y      replace-all: Executes replacements for every occurance of the search
        string located from the current cursor location to the bottom of the
        source code.
u      list-labels: Prompts for a filename to which a listing of each label
        and the memory address that it resolves to will be saved to disk as
        a SEQ file. Instead of a filename, enter '?' by itself to print
        directly to a printer (device 4) or '*' by itself to output to
        the screen (CBM pauses output, run/stop aborts). Note that the
        output is based on the label resolutions from the last time the
        source code was assembled, and if list-labels is invoked prior to
        assembling any source code, the output will be empty.
U      list-labels-vice: Identical to list-labels, except the format of the
        output is compatible for loading into the VICE emulator monitor.
i      find-label: Prompts for a string to search for as a label, then
        places the cursor at the first occurance of that string where it
        is used as a label definition.
p      preferences-submenu: Activates the preferences editor submenu
        which can be used to modify the separator style and color scheme:
         0  Edits the color used for $d020 (border).
         1  Edits the color used for $d021 (background).
         2  Edits the color used for the message line.
         3  Edits the color used for the status line.
         4  Edits the color used for regular source.
         5  Edits the color used for source with a syntax error.
         6  Edits the color used for source in the current marked block.
         s  Edits the separator template
         ^  Prompts for a filename, to which a complete copy of the newly
             customized TMP program is written to disk.
@      disk-command: Prompts for a string that is sent to the current
        serial device as a disk command, the results of which are displayed
        on the message line. Entering a '@' by itself will send a status
        command to the device.
*      view-directory: Outputs a directory listing from the current serial
        device to the screen; CBM pauses output, run/stop aborts.
a      petscii-mode: Sets the editor into a literal petscii mode; the cursor
        flashes slightly faster to indicate the setting. During this mode,
        all keypresses are taken literally as petscii sequences which are
        stored on the line. This mode is useful for entering color or
        cursor movement codes into .text strings that can be 'printed'
        from within your program. Hitting the {back-arrow} key will quit
        this mode and return to normal editing.
s      save-source: Prompts for a filename, to which the current source
        code is saved to disk as a binary PRG file.
d      increment-device: Selects the next available device number on the
        bus between 8 and 15.
f      find-string: Prompts for a string and then searches for the first
        occurance in the source code.
g      goto-mark: Prompts for a mark (1-9, s, e) and moves the cursor to
        the line number corresponding to the selected mark.
h      find-next: Finds the next occurance of the search string.
k      define-fkeys: Prompts for a redefinable function key (f3-f6) then
        allows the user to enter a new definition for the selected key.
K      reset-fkeys: The function keys f3-f6 are all reset to TMP's internal
        defaults. This is used when loading a source code that has a
        different set of key definitions than TMP.
l      load-source: Prompts for a filename, from which source code is read.
        Note, the loaded source code will *replace* any current source!
:      list-marks: Displays the current line numbers associated with each
        mark.
;      kill-mark: Prompts for a mark (1-9, s, e) and blanks out the line
        number corresponding to the selected mark.
z      undo-edit: Undos whatever current line editing has occured. This can
        only be used as long as the cursor has not left the current line
        where editing has taken place!
c      cold-start: This performs a hard reset of TMP, initializing and
        blanking out the current source code.
b      block-submenu: Activates the block commands submenu, with these
        additional key commands:
  w    write-block: Prompts for a filename to which the source code within
        the current marked block is saved to disk as a SEQ file.
  c    copy-block: Copies the current marked block to the current cursor
        position.
  m    move-block: Moves the current marked block to current cursor
        position.
  k    kill-block: Erases the current marked block
n      goto-line: Prompts for a line number and then moves the cursor to
        the entered line.
m      set-mark: Prompts for a mark (1-9, s, e) and then sets the selected
        mark to the current cursor line. 's' and 'e' stand for start and
        end; setting these marks defines a contiguous set of lines upon
        which subsequent block operations (invoked by the block-submenu)
        will operate.
=      join-line: The remainder of the current line (everything to the
        right and under the current cursor location) is moved into the
        same location on the line immediately above, deleting the old
        line in the process.
/      blank-to-end: Blanks out everything on the current line to the
        right and under the current cursor location.
RTRN   split-line: The remainder of the current line (everything to the
        right and under the current cursor location) is moved into a new
        line which is inserted immediately below the current line.
SPACE  blank-line: Blanks out the current line
CRSR-R cursor-right-edge: Moves the cursor to column 39
CRSR-L cursor-left-edge: Moved cursor to column 0
CRSR-D : Moves the cursor down by 200 lines
CRSR-U : Moves the cursor up by 200 lines
BARROW : The back arrow key, when pressed twice in a row, outputs an actual
        backarrow character.   

 The next table shows all the behaviour of additional keys that are not
combined with first pressing the command key:

KEY    ACTION
INST   toggle-char-insert: Switches the editing mode for character
        insertion; when off, new key presses overwrite instead of insert.
F1     : Moves the cursor up by 20 lines
F2     : Moves the cursor to line 0 (top of the source)
F7     : Moves the cursor down by 20 lines
F8     : Moves the cursor to the bottom of the source

 Function keys f3-f6 are redefinable, and have these default operations:

KEY    ACTION
F3     Identical to {back-arrow}+CRSR-U (cursor up by 200 lines).
F4     Assembles (as with {back-arrow}+3) and then auto executes the code.
F5     Identical to {back-arrow}+CRSR-D (cursor down by 200 lines).
F6     Identical to {back-arrow}+R which invokes the RAM submenu.


-------------------------------------
Turbo Macro Pro, Assembler Overview
-------------------------------------

 TMP's assembler component provides the mechanism for parsing and
translating source code into machine code. TMP source code consists
of the following basic elements:

 labels: Something like variable names, a label is used to refer to
  a specific memory address. Labels are assigned to a memory address
  explicitly or get assigned by the assembler as it resolves unassigned
  labels.
 
 opcodes: These are the standard 6502 mnemonics, in the form of three
  letter abbreviations.
  
 pseudo ops: Assembler directives that instruct TMP to invoke some
  advanced operation instead of merely translating an opcode into machine
  code.

 comments: Simple way to annotate source code; comments are completely
  ignored by the assembler.


-------------------------------------
Turbo Macro Pro, Assembler Details
-------------------------------------

 ------------------------------------
 - Constant Values
 
 Constant values can be expressed in either decimal, hexadecimal, binary,
or as characters depending on how the value is written. The largest
constant value TMP can recognize is $ffff (65,535).

    $  denotes a hexadecimal value
    %  denotes a binary value (limited to single bytes)
  'a'  denotes a character value, which translates to a byte
  
 Any value that is not preceded by $ or % or wrapped in quotes is treated
as a decimal value.

 -=> Examples

  $20        = hex   $20, dec   32
  $2000      = hex $2000, dec 8192
  15         = hex   $0f, dec   15
  %10001000  = hex   $88, dec  135
  '1'        = hex   $31, dec   49


 ------------------------------------
 - Labels
 
 Valid labels in TMP can be composed of any combination of letters,
numbers, and the underscore character (obtained by pressing CBM+@).
However, labels must begin with a letter, and can be no longer than
15 characters. Label names can be used in expressions (see below)
in the same manner as constant values.

 To define a label explicitly, set the label to either an absolute
memory address, to another label, or to an expression which will be
resolved into an address.

 -=> Examples

  bah = $1000   ;sets the label 'bah' to $1000.
  lab = bah     ;sets the label 'lab' to equal whatever address bah
                ; resolves to (in this case, it would also be $1000).
  tmp = bah+$8  ;sets the label 'tmp' to equal the address that the
                ; expression 'bah+$8" resolves to ($1008).

 There is a special label, which is called the 'program counter' and
is represented in source code as the asterisk (*). It is important to
set the value of * at the top of your code. When TMP assembles your
source, * is used to tell the assembler where the machine code should
be assembled to. Set the value of * just like a label:

  *   = $1000   ;sets the program counter to $1000.

 Note that unlike normal labels, you can reset the value of * anywhere
you want in your source code. Each time you redefine *, the assembler
simply uses the new value and continues assembling machien code at the
new address.


 ------------------------------------
 - Expressions

 Expressions in Turbo Macro Pro can be formed with the following operators,
all of which are binary operators (i.e. they require a value on the right
AND left side of the operator):

  +   for addition
  -   for subtraction
  *   for multiplication
  /   for division
  &   for bitwise and
  .   for bitwise or
  :   for bitwise eor

 Values used with expressions can be constant values described above, or
labels. Note that you can also use parenthesis and as you would expect
they affect the order in which the expression is evaluated:

 -=> Examples

  $20 + 4         = hex $24, dec  36
  15 - %00000011  = hex $0c, dec  12
  $ff & $f0       = hex $f0, dec 240
  (2*$10)+1       = hex $21, dec  33
  2*($10+1)       = hex $22, dec  34

 Unlike standard expressions in C/C++, there is no operator precedence.
For example, multiplication has no higher precedence than addition:

  2*$10+1         = hex $21, dec  33
  1+2*$10         = hex $20, dec  32

 In the first example above, the multiplication is resolved first,
followed by the addition. In the next example, the addition is processed
first! As this is a simplified way of resolving expressions than is more
commonly seen in programming languages, it is important to keep in mind.
Careful use of parenthesis can help make the expected results explicit. 

 The special '*' label can also be used in expressions, and it will
always resolve to whatever the current program counter is where the
assembler is outputting machine code to:

  *= $1000     ;sets the program counter to $1000
  jmp *+$03    ;assembles as jmp $1003
  jmp *        ;also assembles as jmp $1003 because the program counter
                 at this line will actually be $1003.

 The value of an expressions can also be modified by the following
characters, which must appear at the very front of the expression:

  <    denotes that the low byte of the following constant or
        expression should be taken
  >    denotes that the hi byte of the following constant or
        expression should be taken
  !    denotes an expression whose value may currently or later
        be determined as needing only 1 byte (i.e. 0-255) but
        which should be expanded into 2 bytes for the purposes
        of outputting machine code. See below for an example.

 -=> Examples

  >$0314          = hex $03
  <$0314          = hex $14
  <$0400+(6*$28)  = hex $f0

 Examples of the use of '!' are shown below. Keep in mind that the editor
will not allow you to enter a constant value like $0002 or $00ff; it will
automatically shorten it to $02 or $ff. This may be seen as a deficiency 
of the editor but you have a way around this when you really need to
specify lines like lda $0002:

  lda $02    assembles as lda $02
  lda !$02   assembles as lda $0002

 Another use of the '!' is to prevent phase errors. A phase error occurs 
when the length of code as determined by pass one and pass two of the 
assembler do not match. One way this can occur is by labels referenced 
before they are defined:

         lda bah  ; here, bah is undefined and TMP assumes it is a word 
         rts
    bah = $02     ; bah is now defined as a byte value

 Assembling this code block results in a phase error, because TMP assumes 
undefined labels represent words during the first pass. If the label is 
then found defined as a byte value, or if it actually resolves to a byte
value, then the second pass will be shorter than the first and a phase
error occurs. To prevent the phase error change the code to look like:

         lda !bah
         rts
    bah = $02

 The '!' tells TMP that the expression following should be treated as a 
word no matter how the label was defined. Obviously the best choice would 
be to define labels before referencing them but in our own experience this 
is sometimes undesired so using '!' notation will help avoid the woes of 
phase errors.


 ------------------------------------
 - Comments

 You can add comments to your source code by using the ';' (semicolon). Any 
';' found by turbo will cause the assembler to ignore whatever follows the 
';' til the end of that line. So comments can follow an opcode, or a 
psuedo-op, or they can be on a line by themselves.

 -=> Examples

   ; this is a comment
  lda #$01   ; this is a comment
  sta $d020  ; so is this!


 ------------------------------------
 - Pseudo ops:  Tables

 The table pseudo ops are the standard way to make data or string tables.
Note that values are not necessarily constrained to constants - they can
be complete expressions as shown above.

  .byte - takes a list of byte values which can be decimal, hex, binary
           or character constants and produces a table of bytes.
  .word - takes a list of word values which can be decimal or hex and
           produces a table of bytes where the words are arranged in
           low-byte hi-byte order.
  .rta  - takes a list of word values which can be decimal or hex and
           produces a table of bytes where the words are decremented
           by 1 and set in low-byte hi-byte order; this is useful for
           doing stack manipulation with e.g. return addresses.
  .text  - takes a quoted string and produces from it a table of bytes.
  .null  - takes a quoted string and produces from it a table of bytes
            terminated with a null (0) byte.
  .shift - takes a quoted string and produces from it a table of bytes
            where the last byte has its high-bit set to 1.

 -=> Examples

  .byte 25,"a",$cc   =   $19 $41 $cc
  .text "hi"         =   $48 $49
  .null "hi"         =   $48 $49 $00
  .shift "hi"        =   $48 $c9
  .word $fce2        =   $e2 $fc
  .rta $fce2         =   $e1 $fc


 ------------------------------------
 - Pseudo ops:  Conditional Assembly

 These pseudo-ops allow TMP to assemble chunks of code based on the 
evaluation of an expression - if it is equal or not equal to zero or if
it is positive or negative. You can use the functionality to selectively 
assemble code based on the value of a label, for example, or even the 
current value of the program counter.

  .if     - tests value or expression for inequality with zero.
             (same as .ifne)
  .ifne   - tests value or expression for inequality with zero.
             (same as .if)
  .ifeq   - tests value or expression for equality with zero.
  .ifpl   - tests value or expression for positive.
  .ifmi   - tests value or expression for negative.
  .endif  - marks the end of the code block that is assembled when the
             conditional test is met.

 -=> Examples

cycle = 65
     .ifne cycle-65 ;if cycle != 65
     nop            ;produce one nop
     .endif


 ------------------------------------
 - Pseudo ops:  Local Label Blocks

 The block psuedo-ops allow a very useful operation: marking a section of 
code so that it can contain its own local labels, which can be redefined 
outside of the block or within a different block! Using blocks when coding
reusable subroutines can ease their integration into new code... when the
blocked subroutine is inserted into another source, a coder needn't worry
that the labels used inside the subroutine block will conflict with any
labels already defined in the other code.

  .block  - starts a code block
  .bend   - ends a code block


 -=> Examples

tmp = $02           ;tmp is defined as $02
     lda tmp        ;assembles as  lda $02
sub                 ;our subroutine label name, 'sub'
     .block        
tmp = $ff           ;tmp is defined as $ff but only applies in the block
     clc
     adc tmp        ;assembles as  adc $ff, not adc $02!
     rts 
     .bend
     lda tmp        ;assembles as  lda $02 again...


 ------------------------------------
 - Pseudo ops:  Assembler Variables

 Assembler variables basically define special kind of label that can be
redefined (even without worrying about localized blocks). This is the
only way to change the value of a label in the same context without
getting a 'double defined' error. These are most useful when combined
with other pseudos like conditionals (see above) and goto (see below).

  .var - defines a variable identified by the label preceeding '.var',
          which is set to the value following the '.var'.

 -=> Examples

va    .var $01   ;defines a var named va with value of 1
      lda #va    ;results in lda #$01
va    .var va+1  ;redefines va to it's current value+1
      lda #va    ;results in lda #$02


 ------------------------------------
 - Pseudo ops:  Unconditional Goto

 These psuedo-ops force the assembler to jump to a given label and
continue assembling from there. This can be extremely useful for
repeating a byte or short code block 10, 100, or even more times.
Only labels flagged with a .lbl psuedo-op can be referenced by a .goto!

  .lbl   - identifies a label that can be referenced by a .goto
  .goto  - causes assembler to goto the label referenced and continue
            assembling from that point on.

 -=> Examples

cnt    .var $0100  ;cnt = $100
loop   .lbl        ;label 'loop' is prepared to be a .goto target
       nop
cnt    .var cnt-1  ;dec cnt
       .ifne cnt   ;if cnt != 0
       .goto loop  ;goto loop
       .endif      ;until all $100 nop's are assembled


 ------------------------------------
 - Pseudo ops:  Macros

 Macros are a means of inserting a larger chunk of code by using a short 
macro label followed by 0 to 8 arguments. This macro label is expanded into 
the chunk of code at assembly time, with substitutions made for arguments 
given. A macro call is identified by a '#' follwed by the macro-label.

  .macro    - starts a macro definition and automatically makes a block
               around the macro
  .segment  - starts a macro definition but without a block
  .endm     - ends a macro definition

 -=> Examples

poke   .macro    ;start macro def
       lda #\2   ;the \2 means an argument substitution, in this case the
                 ; second macro argument will replace the \2
       sta \1    ;another substitution
       .endm     ;end macro def

 In the source code, a macro call using the above would look like:

       #poke $d020,0

 Upon assembly that macro call is expanded, and substitutions are made (in 
this case \1 is replaced by $d020 and \2 is replaced by 0) resulting in the 
following assembly being generated to replace the macro call:

       lda #$00
       sta $d020

 Here is a more complex example showing recursion with macros:

table .macro     ;start macro def
cnt   .var \1+1  ;set var cnt to arg 1 plus 1
      #tab       ;a macro call within a macro!
      .endm      ;end macro def

tab   .segment   ;start macro def
cnt   .var cnt-1 ;decrement cnt
      .if cnt    ;if cnt != 0
      #tab       ;then recursively macro call itself
      .endif     ;end of the if
      .byte cnt  ;assemble a byte with current value of cnt
cnt   .var cnt+1 ;increment cnt
      .endm      ;end macro def

       #table 64 ;call the macro to create a byte table from 0 to 64


 Here is an example of using a text parameter in a macro definition and
call:

error  .macro      ;start macro def
       lda #<tx    ;lo-byte of tx
       ldy #>tx    ;hi-byte of tx
       jsr $ab1e   ;print it
       jmp end     ;skip text data
tx     .null "@1"  ;@1 is replaced by a textual argument
end    .endm       ;end macro def

       #error "doc too boring"

 So you see, use \x for numerical arguments, and @x for text arguments,
where x denotes the argument number.

 Text arguments can be even used to modify an opcode! Example:

do     .segment
       .block
loop   .endm

while  .segment    ;start macro def
       b@1 loop    ;the @1 will be replaced by a text argument
       .bend
       .endm       ;end macro def

       ldx #5      ;start of code
       #do         ;call macro do
       ldy #2
       lda #"*"
       #do         ;call macro do
       jsr $ffd2
       dey
       #while "pl" ;call macro 'while' using parameter "pl"
       lda #" "    ;print space
       jsr $ffd2
       dex
       #while "ne" ; call macro 'while' with parameter "ne"


 ------------------------------------
 - Pseudo ops:  Includes

 The .include psuedo-op allows you to assemble in large chunks of code or 
label data. For example, you could use .include to assemble in a SEQ file 
with label definitions for all of the kernal jumptable, or you could keep 
small subroutines in SEQ form and include them in as you need them.

  .include - load and assemble a specified file from disk during the
              current assembly; the file must be a SEQ file!

 -=> Example

  .include "kernel.s"


 ------------------------------------
 - Pseudo ops:  Code Offsets

 The .offs pseudo op is used to alter the 'effective location' of
assembled code, unlike redefining * which changes the location where
assembled code is put. In other words, code following a .offs will
be treated as though it were being assembled at a different memory
address even though it is still placed at the whatever the current
program counter is (as set by *). If used in a slightly odd looking
manner you can assemble code so that it will execute properly in a
different part of memory than where the code itself is located in the 
assembled output.

  .offs - change the location that code is assembled to.

 -=> Example

     (this code)   ->  (assembles as)
       * = $2000
start  bit base0       bit $2009
       bit base        bit $8000
       jmp *           jmp $2006
base0  * = $8000
base   .offs base0-*
       lda #>start     lda #$20
       jmp *           jmp $8002

 This code is assembled from $2000 to $200d; by using an expression for the 
.offs we can generate code in a contiguous memory chunk, even though part 
of the code has been assembled to execute at a different memory address (in 
this case, $8000). naturally this can be extremely useful for coding 
routines that need to execute in zero page, e.g., or for coding routines to 
run in drive memory.


 ------------------------------------
 - Pseudo ops:  Printer Control

 The printer psuedo-ops allow some control during printing of source to 
printer, disk, or screen when activated with key command {back-arrow}+4.
.proff and .pron allow you to skip printing sections of code, while
.hidemac and  .showmac let you control whether the expanded macro
gets printed or just the macro call (see below).

  .pron     - turn on printing
  .proff    - turn off printing
  .hidemac  - show unexpanded calls
  .showmac  - show expanded calls


 ------------------------------------
 - Pseudo ops:  Miscellaneous

 Though we've not yet seen a good reason for these last two, they are
nevertheless available for your use.

  .eor      - followed by some value, with which all code after the
               .eor is eor'd with.
  .end      - terminate assembling



-------------------------------------
Turbo Macro Pro, Preferences Editor
-------------------------------------

 The TMPPREFS tool is a new offering that replaces the former preferences
editor embedded within the assembler itself and previously accessed with
BA+p. TMPPREFS can load any of the six v1.2 mods, and then resave it with
settings set by you, using:

      BA+c = alter color preferences, works like v1.1 did; first pick a
             color to alter:
               0  Edits the color used for $d020 (border).
               1  Edits the color used for $d021 (background).
               2  Edits the color used for the message line.
               3  Edits the color used for the status line.
               4  Edits the color used for regular source.
               5  Edits the color used for source with a syntax error.
               6  Edits the color used for source in the marked block.
             Then you need to hit CTRL or CBM and a number key just like
             you were setting the current cursor color!
      BA+o = flip through color sets from some well known Turbo versions
      BA+2 = alter 4 character separator template
      BA+j = alter jumpback location
      BA+k = alter function key definitions
      BA+7 = alter return tab (column that cursor sits after return)
      BA+8 = alter source tab (column that opcodes/pseudos start)

 You may also use BA+d (increment-device) and BA+* (directory) which are
identical to their assembler counterparts. Once your settings are set the
way you want, use BA+s to save the newly-customized version.



 *****  v1.2  Sep'06

