Expressions
Expressions
can be made from decimal numbers, hex numbers by using "$", binary
numbers by using "%", single ASCII characters with a "'" (single
quote), and label names.
Any of these values can be mixed
with math operators +-*/, ! (bitwise OR), & (bitwise AND), ^
(exclusive OR), \ (modulo), and unary -. The vertical bar | can be
used in place of !.
There are four logical operators that
will return values of either 0 (false) or 1 (true). These are <,
>, =, and # (not equal). These operators are primarily for
conditional assembly .IF statement use.
There are also
special unary operators that refer to the low byte, high byte, and
bank byte (24-bit highest byte) of the calculated expression. these
operators are <, >, and ^.
There is no operator
precedence. All math is evaluated left to right, with the exception
of leading unary operators <, >, ^, and - which are done after
the rest of the expression has been evaluated.
Do not put any
spaces in the middle of expressions. Spaces are considered by MAE to
be separators between different expressions.
Examples of
valid expressions:
LDA #'A-$20 ;=
$21 LDA #-1 ;= $FF
LDA #-1+2 ;= $FD (the unary - is done
last) LDA #%101&3 ;= 1 LDA
#>$1234+1 ;= $12 LDA #>$1234+256 ;=
$13 LDA #^$123456 ;= $12 LDA #>$123456
;= $34 (mid byte) LDA #1>3
;= 0 (false)
All of these expression types can be used
in .BY statements as well. Like:
LOWS .BY
<LABEL1 <LABEL2 <LABEL3 HIGHS .BY >LABEL1
>LABEL2 >LABEL3 .BY
15+3!%1000
etc...
|
Labels
The
first character of a label may be any letter, or the symbols @, _,
or ?. All remaining characters may also include numbers plus the '.'
symbol. Labels may be up to 15 characters long.
Label names,
and for that matter all text entered with the assembler, can be
entered in upper or lower case. Labels are not
case-sensitive.
When the first character of a label is '?',
the label is a 'local label'. Locals are defined only in the source
code segment between two global (i.e. non-local) labels. References
to local labels cannot cross a global label
definition.
Internally, the assembler creates local labels by
appending the local onto the end of the previous global label. Thus
in the following code segment:
DELAY LDX
#100 ?L DEX
BNE ?L
'?L' is a local label, and will be
entered in the symbol table as DELAY?L. Knowing how the label is
stored, allows you to access it from the debugger or the Esc-V
expression evaluator. You can also code a direct reference to the
label DELAY?L if you need to access the local from the other side of
the global label DELAY.
Locals are not printed in X-reference
or symbol table listings, which makes them very useful for simple
loop and branch structures where you don't want to think up unique
label names for all occurrences.
|
Addressing
Modes
All
6502 and 65816 addressing modes are supported. Any addresses that
evaluate less than $100 will use zero-page modes when possible.
Zero-page labels must be defined before being used, because when MAE
encounters a reference to a label which is not yet defined, it will
assume absolute addressing. If that label is later defined to be
zero-page, MAE will use zero-page addressing on pass 2, but it won't
know that it used absolute addressing on pass 1, and thus the
program addresses from this point on will be
incorrect.
Beginning with version 1.2, MAE checks for such
phase errors by verifying that program labels are at the same PC
address on pass 2 as they were on pass 1. If a mismatch is found, a
PHASE error will be displayed. Also new in version 1.2, is the .ZP
pseudo-op, which pre-defines a label as zero-page type. This can be
useful if you have labels defined in multiple modules, and the label
needs to be used prior to the module where it is
defined.
There is also a way to force 8 bit, 16 bit, or 24
bit addresses using the operators <, !, and >. (Yes, I know
this is inconsistent with the immediate operators for low, high and
bank bytes -- I didn't write the 65816 assembler specifications).
This can be really useful for forcing absolute 16 bit addressing on
zero page labels, to add 1 cycle in time critical applications. For
the 65816, it can force direct page addressing for non-ZP labels,
(which of course requires you to move the direct page register to
the proper page address). ALL 24-bit addresses must be preceded by
the > character.
The operands for the 65816 MVP and MVN
instructions should be simple bank bytes -- not full addresses.
Ex:
MVP $40 $80 moves memory from
bank $40 to bank $80, using the addresses in X and
Y.
Or:
MVP ^SRC ^DEST Use the
bank byte of the source and destination
addresses.
|
Pseudo-Ops
Note
that only 2 letters are required, but if additional letters are
present they will be truncated without assembly errors. For example,
you may use pseudo-ops like '.byte' and '.org'. Personally, I really
like having the pseudo-ops the same width as all 6502 instructions,
and only use 2 letters.
.02 Set
6502-only mode. In this mode, all 65816-specific instructions will
be flagged as "NOT 6502" errors. The code will still be assembled in
these cases, however it will not run properly on 6502 based
machines.
.24 Sets
the symbol table and program counter to use 24 bit addresses. This
is only useful for 65816 programs, and may crash your machine if you
try to use it without having a 65816 CPU.
.816 Set
65816 mode, so that non-6502 instructions will not be flagged as
errors. The initial setting of the .02 versus .816 assembly mode
depends upon which processor version of MAE you are running. The
opening menu display shows the current version number, and also an
indication of whether it is a 6502 or 65816 version of the program.
The initial assembly mode will match this.
.AB The
assembler will generate byte-sized values for accumulator-related
immediate constants. (Default)
.AW The
assembler will generate word-sized values for accumulator-related
immediate constants. This is only useful for 65816
programs.
.BA byte For
bank addressing, you can specify an operand to force assembler
generated object code into bank select RAM. This byte will be stored
into location $D301 when storing bytes of object code into
RAM.
.BI filename Includes
the contents of a binary disk file into the assembly. If this file
does not contain a DOS binary header, it will be assembled as
in-line data at the current PC. Otherwise, a file that contains a
header will be loaded at its load address.
.BY [+byte]
bytes and/or ASCII Store
byte values in memory. ASCII strings can be specified by enclosing
the string in either single or double quotes.
If the first
character of the operand field is a '+', then the following byte
will be used as a constant and added to all remaining bytes of the
instruction. Ex: .BY +$80 1 10 $10
'Hello' $9B
will generate: 81
8A 90 C8 E5 EC EC EF 1B
Values in .BY statements may also be
separated with commas for compatibility with other assemblers.
Spaces are allowed since they are easier to type.
See also
.SB which creates ATASCII screen codes, and .CB which creates
strings in which the last byte is EOR'ed with $80.
.CA byte This
is to allow for assembly directly into a bank select cartridge
environment. The byte is placed in the X register, and a STA $D500,X
is performed when object code bytes are stored into memory. The only
catch, is that the assembler needs to be able to return the bank
select cartridge to normal. There is currently a 'STA $D5DC' for
this purpose, but this may not be the right address for your
cartridge setup. You should search the disk file for this
instruction, ($8D $DC $D5), and replace it with the appropriate
address.
NOTE: The standard public version of MAE resides
partially in the cartridge address space, and as such this pseudo-op
will not work properly. Custom versions of MAE that reside in
different areas of system RAM, such as just above your LOMEM, can be
provided upon request.
.CB [+byte]
bytes and/or ASCII This
is in the same format as the .BY pseudo-op, except that the last
character on the line will be EOR'ed with $80.
.CL Close
output object code file. When using the .OU pseudo-op to create
object code files on disk, the file will normally be closed at the
end of assembly. However, if you wish to close the file before that,
it can be forced closed with the .CL pseudo-op. You may use this to
create multiple output files in one assembly, or to place something
in RAM in addition to the disk file.
.DC word
byte Define
constant-filled block. This will fill an area of size 'word' with
the constant 'byte'.
.DS word Define
storage. This will reserve an area of storage equal to size
'word'.
.EC Do
not display macro generated code in the assembly listing. Only the
macro call itself will appear.
.EL Used
after a conditional .IF statement, this marks the "ELSE" portion of
assembly. See the section on conditional
assembly for
more details.
.EJ Eject
-- Send a form feed code to eject the page in an assembly
listing.
.EN This
is an optional pseudo-op to mark the end of assembly. It can be
placed before the end of your source file to prevent a portion of it
from being assembled.
.EN can also be used to mark the end of
a .IF conditional assembly section, (as in .ENDIF). Because
pseudo-ops are only recognized to two characters, the .EN command
will perform an ENDIF function when encountered within a conditional
assembly section, and will end the assembly otherwise. The "***"
ENDIF operator used in pre-1.1 versions of MAE is still supported,
and actually preferred since there is no ambiguity here. It is also
a little more visible at the source level.
.ES Display
the object code resulting from Macro expansions.
.FL floating
point numbers Stores
6-byte BCD floating point numbers for use with the OS FP ROM
routines.
.HE hex
bytes Store
hex bytes in memory. This is a convenient method to enter strings of
hex bytes, since it does not require the use of the '$' character.
The bytes are still separated by spaces however, which I feel makes
a much more readable layout than the 'all run together' form of hex
statement that some other assemblers use. Example:
.HE 0 55 AA FF
.IB The
assembler will generate byte-sized values for index register-related
immediate constants. (Default)
.IW The
assembler will generate word-sized values for index register-related
immediate constants. This is only useful for 65816
programs.
.IF expression The
expression will be evaluated, and if true, (non-zero), the
statements following the .IF, up to a .EL or .EN (or ***) will be
assembled. If the expression is false, then the block of statements
will not be assembled. See the section on conditional
assembly for
more details.
.IN filename Include
additional files in the assembly. Only the main source file can
contain .IN pseudo-ops. You cannot nest them. Default drive
processing works the same here as it does when loading files from
the editor, and so you will usually not need any 'Dn:' types of
filespecs. The file name only should be sufficient. No quotes are
needed either.
.LC Turn
off (clear) the display of the assembly listing.
(Default)
.LL Display
the assembly listing on this line only, even if the full listing is
turned off. This can be extremely handy to display the program
counter value at important positions in the source
file.
.LO longwords Stores
longwords, (3 byte values) in memory.
.LS Turn
on (set) the display of the assembly listing.
.MC adr Move
Code to a different address than the .OR assembly origin. If you are
assembling to RAM, your code will be stored starting at the address
after the .MC pseudo-op. When assembling to disk, the .MC address
will be used when creating the binary file headers, affecting where
the code will be loaded into.
!!!name .MD Begin
macro
definition.
Described in a separate section.
.ME End
macro
definition.
.MG Mark
the current .IN include file as Macro Global. This keeps this file
in memory throughout the assembly, which is required if the file
contains macros that are referenced in other included
files.
.OC Turn
off (clear) the storing of object code in memory.
.OR adr Sets
the origin address for the assembly.
Note: If there is a
label on this line, it will be given the value of the new origin.
This is not the same as in Mac/65 which could use its origin
directive to reserve space (*= *+1). You should use the .DS
pseudo-op for reserving space.
.OS Turn
on (set) the storing of object code in memory.
(Default)
.OU filename
Create
an output disk file for the object code. Regretfully, this file is
made up of individual 256 byte segments much like Mac/65 does. I
apologize for the laziness here on my part, but it really was a lot
easier to do this way. You should run some type of strip program to
de-segment the file for optimal size and speed. The .OU pseudo-op
should be placed above the .OR pseudo-op.
.PR "text" Print
a text message to the screen on pass 1 of the assembly. This is
generally used with the .VA pseudo-op when prompting for values to
be entered from the keyboard.
.SB [+byte]
bytes and/or ASCII This
is in the same format as the .BY pseudo-op, except that it will
convert all bytes into ATASCII screen codes before storing them. The
ATASCII conversion is done before any constant is added with the '+'
modifier.
label .VA Will
print a '?', and then accept input from the keyboard. You may enter
any value, which will be given to the label in front of the
.VA.
.WO words Stores
words in memory. Multiple words can be entered.
label .ZP Pre-defines
a label as zero-page type. This can be useful if you have labels
defined in multiple modules, and the label needs to be used prior to
the module where it is defined. Normally, this would create a phase
error during assembly whenever MAE encounters a forward label
reference (where it will assume absolute addressing) which later
turns out to be zero page. The error can be prevented by specifying
such labels as .ZP in the first module. Note that .ZP usage must
precede the actual label definition.
SET label =
expression Set
the specified label to a new value. This instruction allows a label
to be redefined with different values during the assembly. Any label
can be SET.
|
Macros
Macros
must be defined before they are used in your source. The definition
looks like this:
!!!name .MD ;
body of the macro .ME
Where
'name' is the name of the macro. The three exclamation marks are a
special macro identifier, and must precede the macro name. The body
of the macro definition will follow, and should be ended with a .ME
pseudo-op.
The macro definition must be resident in memory
when it is called. If you link multiple source files with .INclude
pseudo-ops
,
then you need to ensure that any macro definitions are forced to be
memory resident by using .MG within the file that contains the
macros. Typically, you can put all your definitions in one file, put
in the .MG option, and then include it at the beginning of your
assembly. The root source file, that is, the one that is in memory
when you issue the Esc-A assemble command, is always memory resident
anyway and thus macros defined in your root source file are always
available to other included files without the need for
.MG.
Beginning with MAE version 1.1, the assembler now has
free-format and full text substitution macros. Macro parameters can
be anything, and will be passed to the macro routine in their
original text form. The number of parameters passed by the macro
call is not rigidly enforced, and in fact the macro definition no
longer has to specify the number of expected parameters. Within the
body of the macro, parameters are accessed by using a ':' followed
by a number from 1 to 9, corresponding to the order of parameters on
the calling line. (Parameters are separated by spaces, and nothing
else). A special macro parameter, ':0' can be used to get the actual
number of parameters passed in. When a macro is expanded, any ':n'
strings that are not within quotes will be replaced with the text
from the calling line. Text within quotes will normally be left
as-is, which means there needs to be a special method of getting a
macro parameter expanded inside of quote marks. Two double quotes in
a row, "", will be replaced with one double quote, and subsequent
macro parameters will be expanded. Then use another set of two
double quotes to close. See the macro examples below for more
details on how this works.
An individual macro may pass up to
9 parameters, but there is also a limit on the total number of
parameters including all nesting levels. This limit is 16. If a
macro uses 8 parameters, then any nested macros it calls can use at
most 8 additional parameters.
Any labels defined within a
macro must use a special form. Because macros can be expanded
multiple times, a special label type exists to avoid errors from
multiple label definitions. These label types start with three
periods, followed by any normal label name. These special macro
labels will be given unique numbers with each macro expansion to
keep them separate. You can consider them local labels to each macro
expansion.
Here's an example of a macro to increment a two
byte value:
!!!IND .MD INC
:1 BNE ...SKP
INC 1+:1 ...SKP .ME
To call this macro, you would
use:
IND $80
Since a
macro call will pass any text characters, you could call the same
macro with:
IND
$80,X
Note that the structure of the second INC instruction
in the macro body is important here for this to work correctly. If
the line were written "INC :1+1", it would get expanded to "INC
$80,X+1" which is not valid.
Here are more examples that
don't do anything specific code-wise, but serve to demonstrate
various macro techniques. The calling line will be listed first,
followed by the definition and what it will actually be expanded
to.
PRT "HELLO" $9B "THERE"
$9B
!!!PRT .MD JSR
PRINT
;JSR PRINT .BY :1 :2 :3 :4 :5
:6 :7 :8 0
;.BY "HELLO" $9B "THERE" $9B 0
.ME
Parameters that are not defined on the calling
line are simply replaced with null strings. They do got generate
errors. The PRINT subroutine in this example would pull the return
address off the stack, display the string that it points to until 0
is reached, and then push that address back on the stack so program
flow continues with the next line of code.
TST $80
!!!TST .MD
.BY :1 .BY $80 ;direct
substitution .BY ":1" .BY
":1" ;strings inside quotes
;are not expanded .BY
"":1"" .BY "$80" ;two quotes get converted
;to one, and the
;parameter gets expanded
;since it is not
;between quote marks.
Here's a more complicated
example that can be used as a debugging aide during
development.
ASSERT INDEX CC
#$80
!!!ASSERT .MD .IF
DEBUG PHP
PHP PHA
PHA LDA :1 LDA
INDEX CMP :3 CMP
#$80 B:2 ...OK BCC ...OK
JSR PRINT JSR PRINT .BY
"Assert Failed: " "":1 :2 :3"" 0
.BY "Assert Failed: " "INDEX CC
$80" 0 ...OK PLA PLP
***
The idea behind the ASSERT macro, is that it can
be used to verify the value of key variables, notify the programmer
when the value is not in range, and all the code disappears when you
assemble the final version simply by setting the DEBUG flag to
0.
There are more macro examples in the supplied include file
MACROS. If you create some really useful macros, please send them to
me and let me know if they can be included in future MAE
distributions.
|
Error
Messages
These
are the error messages that can be produced by the assembler. Error
messages are marked with an '!', and also include the source line
number that they occurred on. If you are assembling a single file,
or if the errors occurs in your main file, you will be able to use
the editor ^H command to jump directly to the errors. For errors
that occur in included files, you will need to load in that file,
and jump to those line numbers manually using the ^G goto line
number command.
BRANCH Branch
instruction out of range.
OPCODE Error
in opcode field. This can be either a bad 65816 instruction, bad
pseudo-op, or an undefined macro.
DUP Duplicate
label definition.
EOF End
of File error. All assemblies must end with a .EN pseudo-op. This
should be in the main source file, not in any included files. This
error can also occur if a conditional or macro definition is pending
at the .EN.
UNDEF Undefined
label reference.
NEST Nesting
error. .MD macro definitions cannot contain additional definitions.
.IN included files may not include additional .IN files. Endif "***"
mark without associated .IF statement.
OPERAND Error
in operand field.
ADR MODE Addressing
mode not supported.
BAD LABEL Bad
characters in label name.
MACRO OV Macro
overflow in either the number of expansions, or level of nested
expansions.
SYM OV Symbol
table overflow.
PARMS Number
of macro parameters in the call does not match the
definition.
LABEL MISSING Missing
label on either a SET pseudo-op or in an = equate
definition.
NOT 6502 This
instruction is only valid on 65816 processors, and will not run on
6502-based computers. This error is only generated if you have used
the .02 pseudo-op to generate 6502-only code.
PHASE Zero-page
variables must be defined, or pre-defined with .ZP, before they are
used.
|
General
Information
Filenames
default to the current drive number which can be changed. (input of
'FILE' = 'D1:FILE') A full filespec will override the
default.
Non destructive prompt character (.) for ease in
full screen editing. Also, the prompt does not interfere with
command decoding. If the cursor is moved up to redo a prior command,
the '.' does not need to be deleted.
Upper and Lower case
accepted.
The debugger is ZP clean, so all of ZP is available
for the user.
You can look at RAM under the OS, by resetting
the bit in $D301, as long as you are using SpartaDOS or some method
of handling interrupts when the OS is disabled.
The debugger
uses the E: handler, which can allow two screen debugging with some
80 column devices. (Your program is displayed through the Atari,
while debugging output is on the 80 column device.) Currently, the
XEP80
does
not work very well in this manner, because its screen drivers
require the Atari DMA to be turned off. You can partially support
this by adding an external user function to toggle DMA. More
information about this will be given in a later section. For
machines without an 80 column device, the debugger supports flipping
between two display lists, one for the E: screen, and one for your
program. In all cases, there can be potential conflicts when trying
to debug programs that use the E: handler themselves, as both the
debugger and your program struggle for the same locations. The
debugger's design is admittedly not ideal for use in this situation,
but it works out well for programs that create their own
screen.
Any continuous displays can be paused and stepped one
line at a time with the space bar. Press 'C' to return to continuous
display. ESC, RETURN, or BREAK will stop the display. While the
display is paused, the V command for switching view screens, and
also the U user function, can both be used.
ALL addresses and
data bytes can be entered in HEX (default), in DECIMAL with #
(#1234), in BINARY with % (%10011010), in ASCII with ' ('A) or as a
label currently defined in the MAE symbol table with . (.LABEL).
Arithmetic operators +-*/&!\^ can also be used, and will be
performed left to right. Any combination of these can be mixed at
any time in a completely free format scheme, with no limits on
length. (Ex: 2000-#256+'W/100) Very little will be mentioned about
this feature later on, but ALL numbers for ALL commands accept this
versatile entry system.
All commands use spaces as
delimiters. A '?' indicates a command error. Parameter uses for
commands are abbreviated to:
adr: a 16 bit
address. by: an 8 bit byte. ('by' with numbers indicates a
string of bytes.) bit: a 0 or a 1. char: an ASCII
character.
Quantities in [brackets] are optional parameters.
Default values will be used if they are not entered. All
non-bracketted values must be entered. Any other upper case
characters or symbols should be entered as stated.
'Current
address' refers to the last displayed or changed address, (+$1), and
is separate from the current program counter or
PC.
|
Commands
Display Memory
M[M] [adr] [adr][/] Displays
8 bytes of hex and ASCII when using M, or 16 bytes of ASCII only
when using MM. Displays 3 lines worth if you enter only one address,
otherwise it will display up to the second address, if entered.
Displays from current address if no parameters. '/' = to $FFFF. The
'/' can be used on all other commands as well. Does not display
ASCII control characters when output is being sent to an external
device.
The hex bytes in the hex and ASCII display (but not
the ASCII bytes), or the ASCII bytes in the ASCII-only display, may
be changed using standard screen editing.
When displaying hex
and ASCII from a 24-bit address, the last two bytes of ASCII will
not be displayed, due to screen width limitations.
Peek Memory
P adr1 [adr2..] [*] Special
memory display that allows multiple addresses to be entered, and
only prints one byte per address. * causes a continuous print of the
list of addresses, and is really useful for finding keycodes from
$D209, or examining any locations that have changing data. Push
Break to abort the continuous peek.
Change Memory
:adr by1 [by2..by8] The
change memory command ':' can be entered directly, or edited from
the display memory command. Only 8 data bytes will be changed. You
can substitute the character = for the adr, which will then use the
current address. This allows you to enter successive lines of bytes
without requiring any other addresses. Ex:
:600 1 2 3 4 5 6 7 8 := 9 A B C D E F
ASCII Mem Change
C adr ASCII_STRING Stores
ASCII string at adr.
Disassemble
D [M][X][R] [adr] Disassembles
memory starting at adr, or the current adr if not entered. When
disassembling 65816 code, instructions that change the register
sizes will automatically be detected, and adjust the immediate
operands in the listing accordingly. When beginning a disassembly
however, it will not know the current state of the register sizes
and will default to 8 bits. The M, X, and R options in the command
line will force 16-bit M, X, and both Registers to be used at the
starting address. The single instruction that gets disassembled as
part of the register display or trace mode will always be correct,
since the register sizes can be obtained directly from the processor
status register.
The disassembly code, (the instructions --
not the hex bytes), can be modified using normal screen editing.
This gives you a single line assembler process that is a direct link
to the syntax processor in the main assembler
section .
Therefore, it uses the same format, and has all of the same features
as any one line of code that you could enter in the assembler
section. You can use labels, < and > operators, and even
pseudo-ops
!
You can enter branch instructions with an address like "*+8 ", which
means the current PC +8. The only restriction is that you cannot use
a macro call.
Single line assembly can be started from
scratch, (as opposed to editing an existing disassembly), by typing,
"-adr ." followed by an Assembly mnemonic. (The '.' is necessary).
Such as:
-600 .LDA #0
Because the period
is a marker for the beginning of the instruction field, entering a
pseudo-op will require two periods. Such as:
-600 ..HE 55 AA FF
This gives you additional methods for
putting bytes into memory. Since the regular Change Memory command
is limited to 8 bytes, you can use the above .HE format when you
want to enter more bytes than that. Or use .BY when you want to
enter mixed strings of ASCII, HEX, and DECIMAL. Maximum line entry
length is always limited to 80 characters though. Other pseudo-ops
that can be useful are, .DC for blocks of constant data, and .SB for
ATASCII screen code bytes. You can also enter the .24, .AB, .AW,
.IB, and .IW pseudo-ops to control the size of the operands that you
enter, just as you would need to do in the assembler. None of the
other pseudo-ops produce useful results, and some can be hazardous
to use.
From within the single line assembler, you may enter
'*' as the first mnemonic character to continue disassembly from
that address forward.
Display Registers
R Displays
6502 registers in this form:
,A X Y NV-BDIZC
SP ;AB 5D FA 10110001 FF 7014 LDA #$00
The
65816 version of MAE displays registers in this form:
,NVMXDIZCE 0000 00 00 ;00AB 005D 00FA FF
7014 LDA #$00
Status flags will be inverse when they are set,
and normal when clear. The remaining numbers on the top line are the
Direct Page register, the DBR, and the PBR. The upper byte of the
stack pointer is not displayed. 16-bit numbers for registers A, X,
and Y are displayed on the next line, however only the A register
will currently show the correct 16-bit value. Full 16-bit support
for X and Y will be provided when there is an OS upgrade readily
available to handle the native mode interrupts.
Note: The
Direct Page register and DBR are currently inactive, and will always
display 0. The PBR will display the proper value, but can not be
changed by editing the register display. Currently, it can only be
set by entering a 24-bit address into the G or I debugger
commands .
Change Registers
; register bytes Supports
screen editing of R command. Status flags can be modified in bit
form. When entering values directly, a comma will skip to the next
register, and you don't need to enter all the values. EX: ';55'
will change the A register to 55. ';,,20' will change Y to
20.
When setting flags in the 65816 version, you can enter
either normal or inverse flag characters, or enter 0's or 1's, and
can freely mix the two.
Goto
G[S] [adr] [*brkpt] [C by] [r by] [Pf bit] Run
program at adr, or PC if not entered. At any time during execution,
the Break key will return to the debugger and display the current
registers and PC. Use the 'S' option to run code that ends in an
RTS. (Note: When using the S option, the PC adr in the register
display on return is an internal address, not the address where the
actual RTS occurred.)
A breakpoint will create a return point
to the debugger whenever a particular address or condition is
reached. *brkpt will place a 00 (BRK) at the breakpoint address. For
this reason, breakpoints can not be used for programs in ROM. A '?'
will be printed in this case. The breakpoint must also be set at an
opcode rather than an operand location so that it will execute. The
rest of the parameters add conditions to the breakpoint.
C +
by Counts the number of times the breakpoint is reached. Execution
continues until the BRK is passed the specified number of times.
Breakpoints can also test for specific conditions by specifying (r)
reg name and (by) byte it must contain in order to BRK. Processor
flags can also be tested by 'P' + flag character + (bit) for
condition. Use the flag characters as in the register
display.
The breakpoint will be skipped over until the
specific condition is reached. When both count and condition options
are used, the count will apply to the number of times the condition
is met. Execution speed will be slightly slower than real time in
this mode. Actual speed will depend on how often the program is
interrupted to check conditions.
NOTE: A peculiar bug in the
6502 chip causes breakpoints to be intermittently skipped over. When
the BRK interrupt occurs, the program counter+2 is pushed on the
stack, but instead of jumping through the interrupt vector, the OS
will occasionally just return to the program at PC+2. This is
usually a very rare occurrence, but can happen more often when using
conditional breakpoints on very small and quick loops, thus BRK
interrupts are occurring very rapidly. It took many years before I
was able to really understand what was going on, and be assured that
the problem was indeed in the 6502, and not a bug in the debugger. I
eventually found written documentation of the problem from other
sources.
ADDITIONAL NOTE: This bug does not occur on the
65816 processor!
Go command
examples. G 2000 = Run program
at $2000 G 4000 *4124 = Run at $4000, and break at
$4124 G *3100 A'Q = Run at current PC and break at
3100
when A register equals ASCII 'Q' G *4200 C10 PZ1 = Run at
PC and break at 4200 the 16th
time the zero flag is set
Remove Breakpt
* Brkpts
remove themselves, and replace what was there when the BRK is
executed. However, in case the program stops at other than the
brkpt, * will remove it. This can occur when the Break key is
pressed, conditional or count values are not reached, or when the
BRK is set in an operand rather than an opcode. Setting a new brkpt
with the G command will also remove an unused BRK.
Exit to DOS
X [char] When
no additional characters are entered, the BRK vector at $206 will be
restored to whatever it was when MAE was started. If you would like
to keep the BRK vector trapped by the debugger, you may enter any
character after the X. (I could not come up with a decisive and
memorable letter to use for this purpose, so I leave it to you to
choose your own.)
Return to Assembler
A
Fill Memory
F adr1 adr2 [by1] [by2 by3...] Fill
memory with 0 if no data bytes. Otherwise enter 1 byte, or a
sequence of any number of bytes to fill with.
Transfer Mem
T adr1 adr2 adr3 Move
memory from adr1 through adr2 to adr3. Handles overlapping
moves.
Hunt for Chars
H adr1 adr2 by1 [by2...][?]
Hunt for String
H adr1 adr2 'ASCII string [?] Hunt
memory for ASCII string or string of hex bytes up to length of 30.
Use '?' for a wildcard to match anything. Note that the default wild
card byte is also $3F hex, meaning that any searches with 3F in a
hex string will be treated as a wildcard as well. See the next
command for changing the wildcard character in cases of
interference. Realize the number entry system will let you search
for things like "A9 'A", (as in LDA #'A), but not the reverse of
this. Entering "'A A9" will put the hunt into full ASCII form, and
search for the literal string that you typed in. The second example
can actually be entered in the form "? 'A A9", using a wildcard to
avoid the initial ' identifier. For one more example, let's say you
wanted to search for a JSR to a MAE defined label. This can be
entered as "20 .<LABEL .>LABEL".
Searches through the
OS ROM area will automatically skip $D000-$D7FF. So you may simply
enter a search range of $C000-FFFF.
Change wild card
? char Change
the wild card for the Hunt command to 'char'. This is used in case a
character in the search string needs to be '?' or HEX
3F.
Compare mem
K adr1 adr2 adr3 Compare
memory from adr1 to adr2 with memory starting at adr3. Displays all
addresses with differences.
DEC to HEX
# decimal number
HEX to DEC
$ by Displays
hex values of decimal numbers and vice versa.
Change Output
O [filespec] Send
output to screen and filespec. O by itself returns to just screen
output. Use "O P:" to send output to the printer.
Re-open Editor IOCB
E This
is useful for returning to the text screen from a graphics mode, or
80-column display, or to reset the screen after changing RAMTOP. The
other IOCB's used are: #3 disk reads, #4 disk writes, and #6
external output.
Change View
V When
debugging a program that creates a new display list, the V command
can toggle between the program's screen and the debugging text
screen. The debugger stores the display list address for the text
screen, initially at $BC20, and updates this whenever the E command
is used. The V command checks this address against what is currently
in the display list pointer, to decide whether it needs to restore
the text screen, (saving the previous value), or return to the last
saved value of your program's screen. While the debugger doesn't
initially know where your program's screen is going to be, it picks
this information up the first time you issue the V command with your
program's screen active.
In some cases, swapping the display
list pointer may not be sufficient to display both screens in their
proper format. Such as when using different character sets, or
different GPRIOR modes. For this reason, operation of the V function
can be extended through two user accessible vectors at $BFF7 and
$BFFA. $BFFA will be called when switching to your program's screen,
and $BFF7 will be called when switching back to the debugger's
screen. You can insert JMP intructions here that point to extra
routines that update whichever other hardware locations are
needed.
Query MAE symbol table
Q adr
(Sorry, I was running out of letters) Search the
current symbol table for a label that matches the value entered for
adr. If found, the label will be printed. This is basically the
reverse procedure for symbol table lookup, and as such will only
work well when the requested value has only one label associated to
it.
Trace Instr
I [adr] Traces
program an instruction at a time. Trace normally works on programs
in ROM, except 'G' and 'R' options as noted below. After each step,
the debugger will wait for one of the following keypresses to
control the tracing mode:
|
Space |
-
Steps one instruction at a time. |
C |
-
Continuous trace. |
D |
-
Disassemble next instructions. Useful for previewing code that
you are about to step through. The program counter will remain
at its current location. |
G |
-
Execute all instructions up to current 'D' command listing.
Use to quickly execute loops or other structures. First use
'D' to find a spot past the structure, then 'G' will execute
everything up to that point. This command puts a Breakpoint at
the end position, and therefore cannot be used if the program
is in ROM. |
S |
-
Execute entire subroutine as one step. |
R |
-
Return from subroutine. Use this command if you are already in
a subroutine, and wish to return to the previous level. A BRK
will be placed at the instruction the subroutine returns to,
and therefore cannot be used for programs in ROM. |
L |
-
Like the return from subroutine, but does an RTL return from
24-bit subroutine calls. |
P |
-
Peek the value of the operand of the current instruction.
Operand calculation is crude, using simple absolute or direct
page addressing on the operand value. It does not attempt to
calculate indexed or indirect operand addressing. Thus, if you
do a P on an instruction like "STA ($80),Y", it will return
the contents of location $80 -- which can theoretically be
useful, but the function is intended for use on instructions
with simple absolute or direct page addressing
modes. |
Q |
-
Perform a Q debugger command on the operand of the current
instruction. If the operand value is defined in the current
MAE symbol table, the label name will be printed. You can use
this on JMP, JSR and branch instructions to get an idea where
you're going, and also on any memory references that have you
thinking, "What the heck is *that*?" |
U |
-
Execute the user function. The carry will be clear, and $F0
will contain the PC for the currently displayed
instruction. |
V |
-
Execute the V command to change DLIST views. |
X |
-
Ignore instruction. Skip to the next one without
executing. |
ESC,
RETURN, or BREAK |
exits trace
mode. | |
Change Default Drv
/ 1-9 All
default drive accesses change to drive number entered, including
uses in the assembler section. The starting default drive number
will be the same as the current SpartaDOS drive.
Binary Load
L [@adr][-adr] filename Load
DOS II binary file where it was saved, or at @adr if entered. Prints
a '?' if the file is not DOS II format. Loads appended files, but
@adr only works on 1st part. -adr loads raw data with no header
using a straight CIO transfer. Both PC and default address are set
to the load address.
Binary Save
S [-]adr1 adr2 [@adr3] [+]file Save
DOS II binary file from adr1 to adr2. If @adr3 is entered, it will
be used as the header allowing the file to load in at a different
address than where it was saved. Use '-' for a CIO save without
header. If + is entered, append to existing file.
Directory
\ [name or spec]
(Sorry, I *am* out of letters) Displays disk
directory. Default of Dn:*.*. A filespec of D2: =
D2:*.*
Sector Read
R adr sector# [ending sector]
Sector Write
W adr sector# [ending sector] Direct
sector I/O to default drive. Reads single and double density disks
automatically including single density sectors 1-3 of a DD
disk.
Evaluate Exp.
= by1(+-*/&!^\)[by2..] (no spaces) Prints
hex and decimal values of expression evaluated left to right. Can
also be used for ASCII convert. (='A)
User Function
U [adr1] [adr2] [adr3] Accepts
up to 3 24-bit parameters, which will be stored at $F0, $F7, and
$F3. $F7 and $F3 will be 0 if not entered, while $F0 will have the
current address if not entered. In addition, the carry flag will be
set if no parms. Then jumps to the end address of the debugger-3.
($BBFD in top of RAM version) User function expects an RTS
return.
When the user function is called from a paused Trace
or other display, the carry will be clear, and $F0 will contain the
PC or current address respectively.
|
The
Debug80 User Function
There
is a file on the disk called DEBUG80. This loads into the area for
the debugger's user function, and can be loaded either from DOS, or
from the debugger with the L command. This function is intended to
help debug Atari programs while using the XEP80. As mentioned
earlier, the driver for the XEP80 will not run unless the Atari's
DMA turned off. DEBUG80 provides a toggle for the DMA control, so
that the program screen can be turned on or off as
needed.
XEP80 debugging is still very limited, because you
cannot issue any commands while the Atari DMA is enabled. Any
attempts to do so, will corrupt the XEP80 screen, and probably
require turning the power to the XEP80 off and on to recover it. You
can only toggle the DMA when the screen display is paused, like from
a memory dump or trace mode. Still, you may find applications where
it is very helpful to view debugging information and the screen
display at the same time, and this extension will let you do
this.
|
64
& 80 Column Drivers
64
and 80 column modes are not available on 64K
machines.
Default 64 and 80 column drivers are now included
as COL64.OBJ and COL80.OBJ. These use the ANTIC bit compatible
handlers, and the 'A' fonts. If you don't have a compatible RAM
upgrade, or wish to use the other font choice, please follow the
directions below to create new versions of COL64.OBJ and
COL80.OBJ.
HAND64.OBJ and HAND80.OBJ are drivers for 64 and
80 column screens. They take advantage of ANTIC memory banking so
that their use does not reduce the available memory for source and
symbol table. They reside in the base memory range of $5600-$7FFF.
If you have a memory upgrade that is not ANTIC-bit compatible, then
you must use HAND64X.OBJ and HAND80X.OBJ. These versions will have
to place the screen and dislay list from $9500-$B6FF. Code and data
will be $6FF0-$79FF. To run the X versions of the handlers, you will
need to reconfigure MAE's text buffer to end at $94FF instead of
$B6FF using CONFIG.COM
.
Copy
either HAND64.OBJ or HAND64X.OBJ to a new file named COL64.OBJ, and
copy HAND80.OBJ or HAND80X.OBJ to COL80.OBJ. You now need to add
character sets to these files.
There are two character set
choices for both the 64 and 80 column handlers. A character set must
be appended to the end of the handler's .OBJ file before the handler
can be used. These files are COL64A.FNT, COL64B.FNT, COL80A.FNT, AND
COL80B.FNT. These files should be viewable and editable in standard
font editing packages. Choose a font file for each handler, and
copy-with-append the fonts to the COL64.OBJ and COL80.OBJ files that
you created above. The handlers are now ready for
use.
|
NEW
FOR VERSION 1.1
Cybergate,
my ISP, discontinued their service in my area. Thus, I have another
new EMail address: mailto:jharris@poboxes.com?Subject=MAE
Manual on Thunderdome
New
distribution method and installation procedure. Please read INSTALL.DOC
for
details.
Configuration utility CONFIG.COM
now
provided.
MAE now has full text substitution macros. This
adds a tremendous amount of power and flexibility to the macro
processor. The syntax is completely different, so please see the
macro
section of
ASM.DOC.
The ':' character can no longer be used in label
names, due to conflicts with the new macro processing. The ';'
character can't be used either, but was mistakenly listed as a valid
label character in the docs. This hasn't been usable as a label
character for many years.
Conditional
assembly has
been changed to be more standard, and more complete. IFE, IFN, IFP
and IFM have been removed and replaced with .IF, .ELSE, and .ENDIF.
Complementing the .IF statement are four new expression operators,
<, >, =, and # (not equal). <, >, and = join the list of
symbols that are no longer allowed as part of a label name. I am
sorry for any inconvenience or confusion these changes may be
causing, but I suppose their use was non-standard to begin with.
Lastly, .IF statements can now be nested up to seven levels deep.
Please see the conditional
assembly section
of ASM.DOC for full details.
Editor key
macros can
now be saved to and loaded from disk files.
New config bit
for editor to start with Caps lock on or off.
Improved screen
handling to do minimal text redraws when cutting and pasting.
Improves screen redraw speed, most noticably on XEP80
and
software 64/80
column modes .
|
NEW
FOR VERSION 1.0
I
have a new EMail address: jharris@cybergate.com
40 column
limit on source code lines has been removed, although text is still
limited to 79 columns. Lines will scroll horizontally to display the
extra columns.
There are two software screen drivers
provided, that allow 64
column and 80 column editing
on a high-speed Gr.8 screen. If your machine has Antic-compatible
bank select RAM, using the drivers will not decrease the size of
your source text buffer! The drivers were written by Itay Chamiel.
Thanks Itay! Installation of these software drivers, as well as
support for 64K
machines ,
is described in the file INSTALL.DOC
.
Disassembly
supports 16-bit operands. See the D
command in
DEBUG.DOC for details.
24-bit address support in debugger,
including hex and decimal values for the "=" math
function.
Because of 24-bit address support, I had to move
the locations of address variables. This affects the User function
parameters, and I apologize for any inconveniences. The parameters
that used to be at $F0, $F2, and $F4 are now at, $F0, $F7, and $F3.
I know the order is unusual, but there are internal
reasons.
Debugger memory display command changed somewhat due
to screen width limitations with 24-bit addresses. New ASCII-only
mode supported. See DEBUG.DOC
for
details.
While tracing, a new option L has been added to RTL
from 24-bit subroutine calls. (65816 version of MAE
only).
New assembler pseudo-ops
.CByte
for making ASCII strings with the most significant bit set on the
last character. Also .FLoat for defining constants in the OS
floating point format.
New editor
command Ctrl-;
can be used to comment or uncomment a block of text by adding or
removing ";" characters at the start of each line. Mark the start of
the block with Ctrl-Z, and then press Ctrl-; at the end of the
block. You can also mark one line at a time by using Ctrl-; without
a Ctrl-Z block mark.
Editor command Ctrl-D, which used to
just duplicate a single line, can now be used to duplicate an entire
block if there is a Ctrl-Z block mark set. This makes it consistant
with the operation of Ctrl-;.
Shifted 1200XL function keys
should now work for moving to the beginning or end of lines, or the
beginning or end of the file.
Cursor column position is
retained while scrolling in the editor.
MAE was not fully ZP
clean, but should be now.
The debugger will use High-speed
SpartaDOS SIO routines, if present. Unfortunately, sector reading
and writing will no longer work on the old 400/800 operating system
as a result, unless you are using SpartaDOS.
In the editor,
Ctrl-N did not work properly when pressed on a blank
line.
Conditional assembly could get messed up when source
code contained a label on a line by itself.
.BI pseudo-op was
broken in version .99.
New version of Hyper E: included,
which fixes an incompatibility with TextPro, and adds support for
the SDX CON: device.
|
NEW
FOR VERSION 0.99
65816
opcodes and tracing are now supported in the debugger. There is
still no support for 24-bit address entry, so technically, the
debugger can be considered 65802-compatible.
There are new
pseudo-ops
in
the assembler. ".02" can be used when you need to assemble 6502-only
code. When this opcode is active, all 65816 specific instructions
will be flagged with a "NOT 6502" error. ".816" selects the
65816 assembly mode. The initial assembly mode is set to whichever
processor version of the MAE assembler you are using. The initial
version sign-on message shows the processor version of MAE, which
will also be the default assembly mode.
There has been a
significant increase in assembly speed. MAE will be about twice as
fast, depending on the size of your source files. Small files will
show less of an improvement, whereas larger files will show an even
bigger difference. Assembly time is closer to a linear relationship
to source file size, whereas it used to be somewhat
exponential.
There have been big changes in memory
configuration, resulting in twice as much symbol table space, a
little more source space, and all of main memory from $4000-$7FFF
free to the user. The region from $400-$5FF is no longer used by
MAE. The debugger has been moved to bank select memory now, reducing
the main memory usage to $B700-$BBFC. In its place however, MAE uses
up to three banks of extended memory for optimal configuration. Due
to these and other changes, the format of the memory configuration
bytes at the start of the file has changed. Consult MAE.DOC for full
details. MAE actually still runs in 64K machines, and will continue
to do so, but the amount of RAM available for source text has
dropped from 17K down to only 14K for 64K'ers.
Two new
operators have been added to the assembler and debugger expression
evaluators. You can now use "^" for exclusive or, and "\" for
modulo. Because of this, these characters can no longer be used in
label names.
There are two new editor
functions .
You can move an individual line of text up or down with respect to
surrounding lines. Press Shift-Ctrl-[ to move a line up, and
Shift-Ctrl-] to move it down. In a similar function, you can move a
label by itself up or down to adjacent lines. Press Shift-Ctrl-( to
move the label up, or Shift-Ctrl-) to move the label down. Lines
that start with comments or other labels will automatically be
skipped.
Full SpartaDOS directory listings are now
supported.
The "*" at the start of a marked text block would
not get erased on lines that did not begin with a label. Also, the
location of the block start was not getting updated when surrounding
text was edited.
There was a bug which prevented macros from
being recognized when they were defined after a .IN included
files.
JVC and JVS macros were missing from the example
MACROS
file.
There
was a bug that could sometimes clear your entire source text if you
used the Esc-V menu option to get the value of a label which was
undefined. This bug only occurred after an assembly aborted with one
of a few fatal error types.
I didn't realize that MyDOS could
use ':' characters as subdirectory path separators. This confused
MAE's ':' search routine to determine if full filespecs (or just
file names) were being entered. The effect was that MAE would not
load files properly from subdirectories unless you used '>' for
path separators. It works better now, unless you have subdirectory
names that are one or two characters long. If you had a directory
named "T", and tried to load "T:FILE", it would think you were
referring to a T: device. Thus, it is recommended that you either
always use the '>' character as a path separator, or enter
complete filespecs. Either "T>FILE" or "D2:T:FILE" will work
fine.
Fixed two problems with using "." to get the value of
defined labels from the debugger. Because control was passed to the
assembler's expression evaluator, the default number base became
decimal instead of hex. Thus, if you entered ".LABEL+10" in the
debugger, you would get the value at LABEL+$A, and not LABEL+$10.
Processing is now returned to the debugger once the label has been
decoded, making the rest of the line behave consistantly in regards
to hex numbers. Also, expressions like ".>LABEL" were returning
the wrong value.
The debugger command V has been changed, and
is easier to add user extensions into. Please consult DEBUG.DOC
for
details.
The editor could corrupt bookmarks and ^J marks if
they were within a text block that got deleted, and close to the top
of the file.
MAE was not restoring the BRK IRQ vector when it
exited, and it now does this by default. Because it is sometimes
desirable to leave the BRK vector installed, such as for trapping
BRKs in programs called from DOS, you can follow the X command in
the debugger with any other character to exit with BRK trapping
still active. Note that you must be careful to not overwrite any
part of the MAE program, including bank select RAM, if you want MAE
to successfully trap BRK instructions that occur after you leave the
assembler.
The debugger should no longer lock up if it
encounters a BRK when output is redirected to an SIO device. Also,
the inconsistancy with supplying filespecs in the O command has been
removed. All filespecs are now treated the same way, for supplying
Dn: in front of any input that does not in itself contain a ":"
character. To send output to the printer, you should now enter "O
P:".
|
NEW
FOR VERSION 0.95
Conditional
breakpoints were not working in the .95 version.
The 65816
version of MAE has a new register display that shows 16-bit
registers for A, X, and Y. Processor status bits are now displayed
as normal characters for bits that are off, and inverse characters
for bits that are on. When changing bits, either normal/inverse, or
0's & 1's may be typed, and are freely mixable. The Emulation
Mode shadow bit is also displayed, and can be changed. Make sure you
have native mode interrupt handlers available before changing this
bit. Also note that this bit, just like the rest of the status
register display, only affects the state of programs run or traced
from the debugger. Clearing the E bit will not instantly put the
machine into native mode, but native mode will be set as soon as any
user programs are run or traced.
In the memory configuration
bytes, entering 0 for the text buffer start or end would use the
value from LOMEM or MEMTOP respectively. Now, this ability also
applies to the symbol table addresses.
1200XL function keys
were not working, and should be fixed now.
It was pointed out
to me that memory expansions above 128K use the high bit of $D301,
which is a problem for the way I programmed the .BA pseudo-op. Thus,
.BA now stores the entire byte at $D301, and a new pseudo-op, .CA,
has been added for bank select cartridge support. I also realized
that support for bank select carts is worthless when the assembler
resides in the cartridge address space. My personal version is
located at my LOMEM, and so I didn't realize the problem here. If
anyone wants a custom version of the assembler located at a
different address, please let me know and I will be happy to provide
it for you.
The .WO and .LO pseudo-ops support multiple
addresses now.
There are misc. small cleanups, such as .EN is
no longer required at the end of the source text, "()" characters
are no longer necessary for enclosing parameters of a macro
definition, and other cosmetic changes.
Disregard the earlier
note about default drive detection being different in the .95
version. MAE still detects Sparta's default drive correctly, even if
MAE is started from a different
drive.
|
NEW
FOR VERSION 0.93
When
assembling code to disk, the .MC pseudo-op can now be used to make
the object code load at a different address than where it is
assembled, much like the way the function already worked in
RAM.
When recording key macros in the editor, you must now
use Ctrl-3 to end recording, instead of Esc. This allows Esc menu
commands to be entered into macros, primarily to support a chain of
assemble commands when your program contains several modules. The
next version of the assembler should allow loading and saving macros
to disk, which will further enhance the macro
usefulness.
Hunt routine in the monitor now automatically
skips over the area from $D000-$D7FF. So you can search the OS using
$C000-$FFFF and not generate any hardware accesses.
Hunt and
Memory display routines would not always stop when the address
reached $FFFF. This has been fixed.
I removed the automatic
OS routine detection from the trace function. Now, you must use the
S key to trace through OS functions in one step, just like any other
subroutine. You can also use the R key if you are already within the
OS code. The reason for doing this, is that it makes things more
consistant, and also allows you to trace code in the $C000-$FFFF
area if you need to.
Pseudo-ops are now available in the
debugger's single line assembler.
The debugger
now
includes a built-in function for switching between display lists for
the debugging text screen, and your program's screen. It uses the
letter "V", for change View. Both V and the "U" user function can be
called from both the trace mode, as well as any paused memory or
disassembly listing. The "%" key did not work as a wildcard in the
debugger, since it was interpretted as the start of a binary number.
I have changed the default wildcard to "?" in both the debugger
and
editor
.
This propagated through a few of the debugger
command key assignments,
along with a few other changes as well. Overall, I feel the key
assignments have been improved, and they won't be changed from now
on. Here is a sumnmary of the changes:
? -
Change Wildcard = - Evaluate expression
V - Change display view \ - Disk
Directory
The editor uses the same wildcard configuration
byte as the debugger. You can use the debugger's "?" command, or a
Cntl-? in the editor to change the wildcard character. Both modules
will use the new assignment.
1200XL function keys are now
supported for moving the cursor.
You may enter Ctrl-key
graphic symbols or international characters into the editor by
pressing Ctrl-A, and then the key you wish to enter.
Now uses
an improved method for detecting the default drive when first
loaded. This should be compatible with all SpartaDOS versions, and
cause no problems for non-Sparta DOSes. It also allows you to
specify a different default drive from the command line, such as,
"MAE D2:".
The MAE.COM file now comes with a RUNAD address
installed. The SpartaDOS bug that prevented using the RUN command to
return to a program which used RUNAD has been fixed in 3.2g and
later, so I have decided to include RUNAD in the file
now.
Fixed a stack corruption problem when disk I/O errors
occurred during assembly with a .IN include file.
Improved
documentation.
|
|