mirror of
https://github.com/fachat/xa65.git
synced 2024-06-17 20:29:32 +00:00
beta 3
This commit is contained in:
parent
c46dae2105
commit
77471ee3d9
30
xa/ChangeLog
30
xa/ChangeLog
|
@ -399,25 +399,35 @@ xa-2.3.14
|
|||
|
||||
xa-2.4.0
|
||||
|
||||
* Listing feature.
|
||||
* Listing feature in plain text or HTML.
|
||||
* Add -E commandline option to not stop after 20 errors, but show all
|
||||
of them
|
||||
of them.
|
||||
* Introduce -X compatibility set commandline option, to distinguish
|
||||
between MASM and CA65 compatibility options.
|
||||
between MASM and CA65 compatibility options; also adds C option for
|
||||
0x and 0 to specify hex or octal. As a result, -M is now deprecated,
|
||||
and colons in comments may become the default in a future version.
|
||||
* Implement CA65 "cheap local labels", ":=" label definitions,
|
||||
and various pseudo opcodes (.include, .import, .importzp,
|
||||
.zeropage, .proc (anonymous only), .endproc, .code, .org, .reloc).
|
||||
* -U option to allow all undefined labels in relocation mode; this
|
||||
allows exporting them to an o65 file and link at a later time.
|
||||
allows exporting them to an o65 file and link at a later time (or
|
||||
specify one at a time with -L).
|
||||
* Globals may also be specified manually with -g.
|
||||
* #error allows preprocessor-level assertions.
|
||||
* .assert allows assembler-level assertions.
|
||||
* Better fix for segfault with smaller arity macro issue.
|
||||
* Main Makefile fixes.
|
||||
* Fixed parallel make in tests, incorporating a patch from Sergei
|
||||
Trofimovich.
|
||||
* Some 2.3.x features still allowed with -XXA23, which is obviously
|
||||
deprecated.
|
||||
* The quote escape character is now the \ (backslash), except if -XXA23.
|
||||
* Recursive /* */ comments are no longer allowed, except if -XXA23.
|
||||
* XA_MAJOR and XA_MINOR predefined macros, except if -XXA23.
|
||||
* Testsuite expanded.
|
||||
|
||||
-- André Fachat <afachat@gmx.de> 13 October, 2023
|
||||
|
||||
* Deprecated options (16-bit mvn/mvp argument, -S, -x) finally removed.
|
||||
If you need this support, you must use 2.3.x.
|
||||
* Makefile fixes.
|
||||
* Parallel make disabled for testing (fixes failures, makes output
|
||||
easier to parse). Parallel make obviously works fine for building.
|
||||
|
||||
-- André Fachat <afachat@gmx.de> 13 October, 2023
|
||||
-- Cameron Kaiser <ckaiser@floodgap.com> XXX
|
||||
|
||||
|
|
|
@ -38,8 +38,8 @@ killxa:
|
|||
xa:
|
||||
(cd src && LD=${LD} CC="${CC} ${CFLAGS}" ${MAKE})
|
||||
|
||||
load:
|
||||
(cd loader && CC="${CC} ${CFLAGS}" ${MAKE})
|
||||
#load:
|
||||
# (cd loader && CC="${CC} ${CFLAGS}" ${MAKE})
|
||||
|
||||
uncpk:
|
||||
(cd misc && CC="${CC} ${CFLAGS}" ${MAKE})
|
||||
|
@ -55,7 +55,7 @@ mingw: clean
|
|||
|
||||
clean:
|
||||
(cd src && ${MAKE} clean)
|
||||
(cd loader && ${MAKE} clean)
|
||||
#(cd loader && ${MAKE} clean)
|
||||
(cd misc && ${MAKE} mrproper)
|
||||
rm -f xa *.exe *.o65 *.s core
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ Fabian Nunez. For mingw, use
|
|||
|
||||
make mingw
|
||||
|
||||
(but do it from within MSYS2).
|
||||
|
||||
Similarly, Amiga and Atari ST compilation should still also function with
|
||||
their particular compatible packages.
|
||||
|
||||
|
|
2
xa/TODO
2
xa/TODO
|
@ -12,7 +12,7 @@ o The listing feature is not bug-free yet:
|
|||
E.g. a CA65 ".scope" will appear as ".(" in the listing
|
||||
- The assembler has no pre-processor handling, so pp constants are
|
||||
resolved at parse time. Thus they appear as their value
|
||||
in the listing.
|
||||
in the listing.
|
||||
- One situation is ".listbytes unlimited",
|
||||
which will show as ".listbytes 0" in the listing
|
||||
|
||||
|
|
4
xa/attic/README
Normal file
4
xa/attic/README
Normal file
|
@ -0,0 +1,4 @@
|
|||
These are files that have been superseded and may be removed in the future.
|
||||
|
||||
loader/ Rewritten as tests/loader/
|
||||
|
BIN
xa/attic/loader/rom65.ok
Normal file
BIN
xa/attic/loader/rom65.ok
Normal file
Binary file not shown.
|
@ -13,9 +13,12 @@ prints file information for files in the o65 object format.
|
|||
|
||||
.SH OPTIONS
|
||||
.TP
|
||||
.B \-V
|
||||
.B \-v
|
||||
Print undefined and global labels.
|
||||
.TP
|
||||
.B \-vv
|
||||
Print undefined and global labels, and relocation tables.
|
||||
.TP
|
||||
.B \-P
|
||||
Print the segment end addresses (suitable for the
|
||||
.BR xa (1)
|
||||
|
|
|
@ -9,7 +9,7 @@ ldo65 \- linker for o65 object files
|
|||
|
||||
.SH DESCRIPTION
|
||||
.B ldo65
|
||||
is a linker for files in the `o65' object format, formerly
|
||||
is a linker for files in the o65 object format, formerly
|
||||
.B ld65
|
||||
but renamed to avoid conflicts with the
|
||||
.B cc65
|
||||
|
@ -32,9 +32,23 @@ man page for an explanation.
|
|||
Set output filename. The default is
|
||||
.BR a.o65 \&.
|
||||
.TP
|
||||
.B \-L name
|
||||
Allow label
|
||||
.B name
|
||||
to remain undefined, even after linking.
|
||||
This option may be specified multiple times for multiple labels.
|
||||
.TP
|
||||
.B \-U
|
||||
Allow any label to remain undefined, even after linking.
|
||||
.TP
|
||||
.B \-G
|
||||
Suppress writing of globals.
|
||||
.TP
|
||||
.B \-g name
|
||||
Only export global
|
||||
.BR name .
|
||||
This option may be specified multiple times for multiple globals.
|
||||
.TP
|
||||
.B \-\-help
|
||||
Show summary of options.
|
||||
.TP
|
||||
|
|
|
@ -19,6 +19,9 @@ object format.
|
|||
Set output filename. The default is
|
||||
.BR a.o65 \&.
|
||||
.TP
|
||||
.B \-v
|
||||
Verbose output.
|
||||
.TP
|
||||
.B \-b? addr
|
||||
Relocate segment
|
||||
.B ?
|
||||
|
|
312
xa/man/xa.1
312
xa/man/xa.1
|
@ -49,19 +49,21 @@ use the special filename
|
|||
to output to standard output.
|
||||
.TP
|
||||
.B \-P filename
|
||||
Set listing filename, default is none. use the special filename
|
||||
Set listing filename. The default is none; use the special filename
|
||||
.BR \-
|
||||
to print the listing to standard output.
|
||||
.TP
|
||||
.B \-F html
|
||||
Set listing format, default is plain. The only other currently supported format is
|
||||
.BR html
|
||||
.B \-F format
|
||||
Set listing format; default is
|
||||
.BR plain .
|
||||
The only other currently supported format is
|
||||
.BR html .
|
||||
.TP
|
||||
.B \-e filename
|
||||
Set errorlog filename, default is none.
|
||||
Set errorlog filename; default is none.
|
||||
.TP
|
||||
.B \-l filename
|
||||
Set labellist filename, default is none. This is the symbol table and can
|
||||
Set labellist filename; default is none. This is the symbol table and can
|
||||
be used by disassemblers such as
|
||||
.BR dxa (1)
|
||||
to reconstruct source.
|
||||
|
@ -71,20 +73,63 @@ Add cross-reference list to labellist (requires
|
|||
.BR \-l ).
|
||||
.TP
|
||||
.B \-Xcompatset
|
||||
Enables compatibility settings to become more (not fully!) compatible with other 6502 assemblers.
|
||||
Currently supported are compatibility set "MASM" and "CA65".
|
||||
"MASM" allows colons to appear in comments. This does not affect colon interpretation elsewhere.
|
||||
"CA65" allows the ":=" label definition (instead of "="), It adds the "unnamed labels" and also the
|
||||
"cheap local labels" using
|
||||
the "@" character. This, however, disables the "@" 24-bit enforcement.
|
||||
"C" enables the usage of "0xHEX" and "0OCTAL" C-style number encodings. Note that you can combine
|
||||
compatibility sets e.g. with "-XCA65 -XC".
|
||||
Enables compatibility settings to become more (not fully!) compatible with other 6502 assemblers and codebases.
|
||||
Currently supported are compatibility sets
|
||||
.BR MASM ,
|
||||
.BR CA65
|
||||
and
|
||||
.BR C ,
|
||||
with
|
||||
.B XA23
|
||||
available as a deprecated option for codebases relying on compatibility with
|
||||
the previous version of
|
||||
.BR xa .
|
||||
Multiple compatibility sets may be specified and combined, e.g.,
|
||||
.B \-XMASM
|
||||
.BR \-XXA23 .
|
||||
.IP
|
||||
.B \-XMASM
|
||||
allows colons to appear in comments for MASM compatibility.
|
||||
This does not affect colon interpretation elsewhere and may become the default in a future version.
|
||||
.IP
|
||||
.B \-XCA65
|
||||
adds syntactic features more compatible with
|
||||
.BR ca65 (1).
|
||||
It permits
|
||||
.B :=
|
||||
for defining labels (instead of plain
|
||||
.BR = ),
|
||||
and adds support for unnamed labels and "cheap" local labels using the
|
||||
.B @
|
||||
character, but disables its other meaning for 24-bit mode (see
|
||||
.B ASSEMBLER
|
||||
.BR SYNTAX ).
|
||||
.IP
|
||||
.B \-XC
|
||||
enables the usage of
|
||||
.B 0xHEX
|
||||
and
|
||||
.B 0OCTAL
|
||||
C-style number encodings.
|
||||
.IP
|
||||
.B \-XXA23
|
||||
restores partial compatibility with
|
||||
.B xa
|
||||
2.3.x. In particular, it uses
|
||||
.B ^
|
||||
for quote escapes instead of 2.4's
|
||||
.BR \e ,
|
||||
allows nested multi-line comments, and disables all predefined
|
||||
.B xa
|
||||
preprocessor macros. This option is inherently deprecated and may be removed
|
||||
in the next 2.x or 3.x release.
|
||||
.TP
|
||||
.B \-M
|
||||
Allow colons to appear in comments; for MASM compatibility. This does
|
||||
not affect colon interpretation elsewhere. This option is deprecated. Use
|
||||
.BR -X
|
||||
instead.
|
||||
This option is deprecated; use
|
||||
.B \-XMASM
|
||||
instead. Allows colons to appear in comments for MASM compatibility. This does
|
||||
not affect colon interpretation elsewhere, and may become the default in a
|
||||
future version.
|
||||
.TP
|
||||
.B \-R
|
||||
Start assembler in relocating mode, i.e. use segments.
|
||||
|
@ -148,27 +193,12 @@ Characters may need to be quoted for your shell (example:
|
|||
).
|
||||
.TP
|
||||
.B \-\-help
|
||||
Show summary of options.
|
||||
Show summary of options
|
||||
.RB ( -?
|
||||
is a synonym).
|
||||
.TP
|
||||
.B \-\-version
|
||||
Show version of program.
|
||||
.LP
|
||||
The following options are
|
||||
.BR deprecated
|
||||
and will be removed in 2.4 and later versions:
|
||||
.TP
|
||||
.B \-x
|
||||
Use old filename behaviour (overrides
|
||||
.BR \-o ,
|
||||
.B \-e
|
||||
and
|
||||
.BR \-l ).
|
||||
.TP
|
||||
.B \-S
|
||||
Allow preprocessor substitution within strings (this is now disallowed
|
||||
for better
|
||||
.BR cpp (1)
|
||||
compatibility).
|
||||
|
||||
.SH ASSEMBLER SYNTAX
|
||||
|
||||
|
@ -204,9 +234,15 @@ decimal value
|
|||
.TP
|
||||
.B $234
|
||||
hexadecimal value
|
||||
.RB ( 0x234
|
||||
accepted with
|
||||
.BR -XC )
|
||||
.TP
|
||||
.B &123
|
||||
octal
|
||||
.RB ( 0123
|
||||
accepted with
|
||||
.BR -XC )
|
||||
.TP
|
||||
.B %010110
|
||||
binary
|
||||
|
@ -248,7 +284,14 @@ statements such as
|
|||
.IP
|
||||
.B * = $c000
|
||||
.LP
|
||||
which sets the program counter to decimal location 49152. With the exception
|
||||
which sets the program counter to decimal location 49152. If
|
||||
.B \-XCA65
|
||||
is specified, you can also use
|
||||
.B :=
|
||||
as well as
|
||||
.BR = .
|
||||
.LP
|
||||
With the exception
|
||||
of the program counter, labels cannot be assigned multiple times. To explicitly
|
||||
declare redefinition of a label, place a - (dash) before it, e.g.,
|
||||
.IP
|
||||
|
@ -263,6 +306,52 @@ for block instructions). A label may also be hard-specified with the
|
|||
.B \-L
|
||||
command line option.
|
||||
.LP
|
||||
If
|
||||
.B \-XCA65
|
||||
is specified, "cheap" local labels may be used and/or redefined, marked by the
|
||||
.B @
|
||||
prefix. Additionally, unnamed labels may be specified with
|
||||
.B :
|
||||
(i.e., no label, just a colon); branches may then reference these unnamed
|
||||
labels with a colon and plus signs for forward branching or minus signs
|
||||
for backward branching. For example (from the
|
||||
.B ca65
|
||||
documentation),
|
||||
.LP
|
||||
: lda (ptr1),y ; #1
|
||||
.BR
|
||||
cmp (ptr2),y
|
||||
.BR
|
||||
bne :+ ; -> #2
|
||||
.BR
|
||||
tax
|
||||
.BR
|
||||
beq :+++ ; -> #4
|
||||
.BR
|
||||
iny
|
||||
.BR
|
||||
bne :- ; -> #1
|
||||
.BR
|
||||
inc ptr1+1
|
||||
.BR
|
||||
inc ptr2+1
|
||||
.BR
|
||||
bne :- ; -> #1
|
||||
.BR
|
||||
|
||||
.BR
|
||||
: bcs :+ ; #2 -> #3
|
||||
.BR
|
||||
ldx #$FF
|
||||
.BR
|
||||
rts
|
||||
.BR
|
||||
|
||||
.BR
|
||||
: ldx #$01 ; #3
|
||||
.BR
|
||||
: rts ; #4
|
||||
.LP
|
||||
Redefining a label does not change previously assembled code that used the
|
||||
earlier value. Therefore, because the program counter is a special type of
|
||||
label, changing the program counter to a lower value does not reorder code
|
||||
|
@ -335,10 +424,14 @@ less than or equal to (7)
|
|||
less than (7)
|
||||
.TP
|
||||
.B =
|
||||
equal to (6)
|
||||
equal to (6);
|
||||
.B ==
|
||||
also accepted
|
||||
.TP
|
||||
.B <> ><
|
||||
does not equal (6)
|
||||
does not equal (6);
|
||||
.B !=
|
||||
also accepted
|
||||
.TP
|
||||
.B &
|
||||
bitwise AND (5)
|
||||
|
@ -389,7 +482,8 @@ for those opcodes that support it (i.e., keep as 16 bit word)
|
|||
.B @
|
||||
render as 24-bit quantity for 65816 (must specify
|
||||
.B \-w
|
||||
command-line option, must not specify the CA65 compatibility).
|
||||
command-line option, must not specify
|
||||
.BR \-XCA65 ).
|
||||
.B This is required to specify any
|
||||
.B 24-bit quantity!
|
||||
.TP
|
||||
|
@ -449,8 +543,9 @@ comments, such that
|
|||
.B ; a comment:lda #0
|
||||
.LP
|
||||
is understood as a comment followed by an opcode. To defeat this, use the
|
||||
.B \-M
|
||||
command line option to allow colons within comments. This does not apply to
|
||||
.B \-XMASM
|
||||
compatibility mode to allow colons within comments; this may become the
|
||||
default in a future version. Colon statement separation does not apply to
|
||||
.B /* */
|
||||
and
|
||||
.B //
|
||||
|
@ -546,19 +641,22 @@ or precede it with
|
|||
.B &
|
||||
to declare it within the previous level only (or globally if you are only
|
||||
one level deep). Sixteen levels of scoping are permitted.
|
||||
.B \&.)
|
||||
is equivalent to
|
||||
.B .block
|
||||
or
|
||||
.B .proc
|
||||
. The latter is similar to the ca65 pseudo-opcode, but only anonymous blocks
|
||||
are supported.
|
||||
.IP
|
||||
.B \.block
|
||||
is accepted as a synonym for
|
||||
.BR \&.) ,
|
||||
as well as
|
||||
.B \.proc
|
||||
(but you cannot specify an explicit scope name as in
|
||||
.BR ca65 ;
|
||||
only anonymous blocks are supported).
|
||||
.TP
|
||||
.B \&.)
|
||||
Closes a block. This is equivalent to
|
||||
Closes a block.
|
||||
.B .bend
|
||||
or
|
||||
.B .endproc
|
||||
are accepted as synonyms.
|
||||
.
|
||||
.TP
|
||||
.B \.as \.al \.xs \.xl
|
||||
|
@ -587,14 +685,44 @@ generate errors if
|
|||
.B \-w
|
||||
is not specified.
|
||||
.TP
|
||||
.B .include "filename"
|
||||
Includes another file in place of the pseudo opcode. Same as the preprocessor
|
||||
.B \.assert expression,"message"
|
||||
Evaluates
|
||||
.B expression
|
||||
and if it is false (i.e., evaluates to zero), prints
|
||||
.B message
|
||||
as a fatal error, terminating assembly immediately.
|
||||
For example, a block of assembly code
|
||||
that creates high ROM might have
|
||||
.IP
|
||||
\&.assert *<$fffa, "hit vectors"
|
||||
.IP
|
||||
to ensure that assembled code does not leak into the 6502 high vectors. If
|
||||
the preceding code is too long, the assertion will be false, and the
|
||||
condition will be detected in a controlled fashion. Any operation may be
|
||||
used as part of the expression, including logical comparisons such as
|
||||
.BR = ,
|
||||
.BR == ,
|
||||
.BR < ,
|
||||
.BR <= ,
|
||||
.BR > ,
|
||||
.BR >= ,
|
||||
.B !=
|
||||
and
|
||||
.BR <> .
|
||||
.TP
|
||||
.B \.include "filename"
|
||||
Includes another file in place of the pseudo-op, as if the preprocessor had
|
||||
done so with an
|
||||
.B #include
|
||||
directive (see
|
||||
.BR PREPROCESSOR ).
|
||||
|
||||
.LP
|
||||
The following pseudo-ops apply primarily to relocatable .o65 objects.
|
||||
The following pseudo-ops apply primarily to relocatable
|
||||
.B .o65
|
||||
objects.
|
||||
A full discussion of the relocatable format is beyond the
|
||||
scope of this manpage, as it is currently a format in flux. Documentation
|
||||
scope of this manpage. Documentation
|
||||
on the proposed v1.2 format is in
|
||||
.B doc/fileformat.txt
|
||||
within the
|
||||
|
@ -602,16 +730,32 @@ within the
|
|||
installation directory.
|
||||
.TP
|
||||
.B .text .data .bss .zero
|
||||
These pseudo-ops switch between the different segments, .text being the actual
|
||||
code section, .data being the data segment, .bss being uninitialized label
|
||||
space for allocation and .zero being uninitialized zero page space for
|
||||
allocation. In .bss and .zero, only labels are evaluated. These pseudo-ops
|
||||
These pseudo-ops switch between the different segments,
|
||||
.B .text
|
||||
being the actual code section,
|
||||
.B .data
|
||||
being the data segment,
|
||||
.B .bss
|
||||
being uninitialized label space for allocation and
|
||||
.B .zero
|
||||
being uninitialized zero page space for allocation. In
|
||||
.B .bss
|
||||
and
|
||||
.BR .zero ,
|
||||
only labels are evaluated. These pseudo-ops
|
||||
are valid in relative and absolute modes.
|
||||
.TP
|
||||
.B .code
|
||||
For CA65 compatibility this is currently mapped to ".text".
|
||||
For
|
||||
.B ca65
|
||||
compatibility, this is currently mapped to
|
||||
.BR .text .
|
||||
.TP
|
||||
.B .zeropage
|
||||
For CA65 compatibility this is currently mapped to ".zero".
|
||||
For
|
||||
.B ca65
|
||||
compatibility, this is currently mapped to
|
||||
.BR .zero .
|
||||
.TP
|
||||
.B .align value
|
||||
Aligns the current segment to a byte boundary (2, 4 or 256) as specified by
|
||||
|
@ -620,7 +764,7 @@ value
|
|||
(and places it in the header when relative mode is enabled). Other values
|
||||
generate an error.
|
||||
.TP
|
||||
.B .fopt type,value1,value2,value3,...
|
||||
.B .fopt type, value1, value2, value3, ...
|
||||
Acts like
|
||||
.B .byt/.asc
|
||||
except that the values are embedded into the object file as file options.
|
||||
|
@ -633,14 +777,14 @@ and may also be strings.
|
|||
.TP
|
||||
.B .import label1, label2, label3, ...
|
||||
Defines the given labels as global labels which are imported and resolved during
|
||||
the link stage. Similar to the
|
||||
the link stage, like the
|
||||
.B -L
|
||||
command line parameter
|
||||
command line parameter.
|
||||
.TP
|
||||
.B .importzp label1, label2, label3, ...
|
||||
Similar to
|
||||
.B .import
|
||||
only it imports zeropage labels (i.e. byte values)
|
||||
Analogous to
|
||||
.BR .import ,
|
||||
except that it only imports zeropage labels (i.e., byte values).
|
||||
|
||||
.SH PREPROCESSOR
|
||||
|
||||
|
@ -724,8 +868,19 @@ may interpret too early until the file actually gets to
|
|||
.B xa
|
||||
itself for processing.
|
||||
.LP
|
||||
The following preprocessor directives are supported.
|
||||
|
||||
The following predefined macros are supported, except if
|
||||
.B \-XXA23
|
||||
is specified:
|
||||
.TP
|
||||
.B XA_MAJOR
|
||||
The current major version of
|
||||
.BR xa .
|
||||
.TP
|
||||
.B XA_MINOR
|
||||
The current minor version of
|
||||
.BR xa .
|
||||
.LP
|
||||
The following preprocessor directives are supported:
|
||||
.TP
|
||||
.B #include """filename"""
|
||||
Inserts the contents of file
|
||||
|
@ -750,6 +905,9 @@ Computes the value of expression
|
|||
.B expression
|
||||
and prints it into the errorlog file.
|
||||
.TP
|
||||
.B #error message
|
||||
Displays the message as an error and terminates assembly.
|
||||
.TP
|
||||
.B #define DEFINE text
|
||||
Equates macro
|
||||
.B DEFINE
|
||||
|
@ -979,8 +1137,8 @@ and
|
|||
use two eight bit parameters, the only instructions in the entire
|
||||
instruction set to do so. Older versions of
|
||||
.B xa
|
||||
took a single 16-bit absolute value. Since 2.3.7, the standard syntax is
|
||||
now accepted and the old syntax is deprecated (a warning will be generated).
|
||||
took a single 16-bit absolute value. As of 2.4.0, this old syntax is
|
||||
no longer accepted.
|
||||
.LP
|
||||
Forward-defined labels -- that is, labels that are defined after the current
|
||||
instruction is processed -- cannot be optimized into zero
|
||||
|
@ -1014,20 +1172,6 @@ be prepended with the
|
|||
prefix. Otherwise, the assembler will attempt to optimize to 16 bits, which
|
||||
may be undesirable.
|
||||
|
||||
.SH "IMMINENT DEPRECATION"
|
||||
The following options and modes will be
|
||||
.B REMOVED
|
||||
in 2.4 and later versions of
|
||||
.BR xa :
|
||||
.LP
|
||||
.B \-x
|
||||
.LP
|
||||
.B \-S
|
||||
.LP
|
||||
the original
|
||||
.B mvn $xxxx
|
||||
syntax
|
||||
|
||||
.SH "SEE ALSO"
|
||||
.BR file65 (1),
|
||||
.BR ldo65 (1),
|
||||
|
|
|
@ -124,7 +124,6 @@ file65 file;
|
|||
unsigned char cmp[] = { 1, 0, 'o', '6', '5' };
|
||||
unsigned char hdr[26] = { 1, 0, 'o', '6', '5', 0 };
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
void usage(FILE *fp)
|
||||
{
|
||||
|
@ -140,7 +139,6 @@ void usage(FILE *fp)
|
|||
" -U accept any undef'd labels after linking\n"
|
||||
" -L<name> accept specific given undef'd labels after linking\n"
|
||||
" -g<name> only export the globals defined with (multiple) -g options\n"
|
||||
" -v verbose output\n"
|
||||
" --version output version information and exit\n"
|
||||
" --help display this help and exit\n",
|
||||
programname);
|
||||
|
@ -188,13 +186,6 @@ int main(int argc, char *argv[]) {
|
|||
while(i<argc && argv[i][0]=='-') {
|
||||
/* process options */
|
||||
switch(argv[i][1]) {
|
||||
case 'v':
|
||||
j=1;
|
||||
while (argv[i][j]=='v') {
|
||||
verbose++;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 'G':
|
||||
noglob=1;
|
||||
break;
|
||||
|
@ -304,19 +295,6 @@ printf("tbase=%04x+len=%04x->%04x, file->tbase=%04x, f.tlen=%04x -> tdiff=%04x\n
|
|||
printf("zbase=%04x+len=%04x->%04x, file->zbase=%04x, f.zlen=%04x -> zdiff=%04x\n",
|
||||
zbase, tzlen, (zbase + tzlen), file->zbase, file->zlen, file->zdiff);
|
||||
*/
|
||||
|
||||
if (verbose > 0) {
|
||||
printf("Relocating file: %s\n", file->fname);
|
||||
printf(" text: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->tbase, file->tbase + file->tdiff, file->tdiff, file->tlen);
|
||||
printf(" data: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->dbase, file->dbase + file->ddiff, file->ddiff, file->dlen);
|
||||
printf(" bss: from %04x to %04x (diff is %04x, length is %04x)\n",
|
||||
file->bbase, file->bbase + file->bdiff, file->bdiff, file->blen);
|
||||
printf(" zero: from %02x to %02x (diff is %02x, length is %02x)\n",
|
||||
file->zbase, file->zbase + file->zdiff, file->zdiff, file->zlen);
|
||||
}
|
||||
|
||||
/* update globals (for result file) */
|
||||
ttlen += file->tlen;
|
||||
tdlen += file->dlen;
|
||||
|
@ -699,21 +677,17 @@ int len_reloc_seg(unsigned char *buf, int ri) {
|
|||
|
||||
unsigned char *reloc_globals(unsigned char *buf, file65 *fp) {
|
||||
int n, old, new, seg;
|
||||
char *name;
|
||||
|
||||
n = buf[0] + 256*buf[1];
|
||||
buf +=2;
|
||||
|
||||
while(n) {
|
||||
name = buf;
|
||||
/*printf("relocating %s, ", buf);*/
|
||||
while(*(buf++));
|
||||
seg = *buf & 0x07;
|
||||
seg = *buf;
|
||||
old = buf[1] + 256*buf[2];
|
||||
new = old + reldiff(seg);
|
||||
if (verbose > 1) {
|
||||
printf("%s:%s: old=%04x, seg=%d, rel=%04x, new=%04x\n",
|
||||
fp->fname, name, old, seg, reldiff(seg), new);
|
||||
}
|
||||
/*printf("old=%04x, seg=%d, rel=%04x, new=%04x\n", old, seg, reldiff(seg), new);*/
|
||||
buf[1] = new & 255;
|
||||
buf[2] = (new>>8) & 255;
|
||||
buf +=3;
|
||||
|
|
23
xa/src/xal.c
23
xa/src/xal.c
|
@ -707,9 +707,6 @@ int ll_pdef(char *t)
|
|||
return(E_NODEF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write out the list of global labels in an o65 file
|
||||
*/
|
||||
int l_write(FILE *fp)
|
||||
{
|
||||
int i, afl, n=0;
|
||||
|
@ -719,39 +716,25 @@ int l_write(FILE *fp)
|
|||
fputc(0, fp);
|
||||
return 0;
|
||||
}
|
||||
// calculate number of global labels
|
||||
for (i=0;i<afile->la.lti;i++) {
|
||||
ltp=afile->la.lt+i;
|
||||
if((!ltp->blk) && (ltp->fl==1)) {
|
||||
n++;
|
||||
}
|
||||
}
|
||||
// write number of globals to file
|
||||
fputc(n&255, fp);
|
||||
fputc((n>>8)&255, fp);
|
||||
// iterate over labels and write out label
|
||||
for (i=0;i<afile->la.lti;i++)
|
||||
{
|
||||
ltp=afile->la.lt+i;
|
||||
if((!ltp->blk) && (ltp->fl==1)) {
|
||||
// write global name
|
||||
fprintf(fp, "%s",ltp->n);
|
||||
fputc(0,fp);
|
||||
|
||||
// segment byte
|
||||
afl = ltp->afl;
|
||||
// hack to switch undef and abs flag from internal to file format
|
||||
// if asolute of undefined (< SEG_TEXT, i.e. 0 or 1)
|
||||
// then invert bit 0 (0 = absolute)
|
||||
if( (afl & (A_FMASK>>8)) < SEG_TEXT) {
|
||||
afl^=1;
|
||||
}
|
||||
// remove residue flags, only write out real segment number
|
||||
// according to o65 file format definition
|
||||
afl = afl & (A_FMASK >> 8);
|
||||
/* hack to switch undef and abs flag from internal to file format */
|
||||
/*printf("label %s, afl=%04x, A_FMASK>>8=%04x\n", ltp->n, afl, A_FMASK>>8);*/
|
||||
if( (afl & (A_FMASK>>8)) < SEG_TEXT) afl^=1;
|
||||
fputc(afl,fp);
|
||||
|
||||
// value
|
||||
fputc(ltp->val&255, fp);
|
||||
fputc((ltp->val>>8)&255, fp);
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ relmode/ tests concerning switches between segments and absolute mode
|
|||
mvnmvp/ Test MVN MVP unusual addressing mode ('816)
|
||||
dos51/ Regression test, label scoping, "real world code"
|
||||
cpktest/ Regression test, label listing, "real world code"
|
||||
listing/ Test of listing feature
|
||||
op816/ Regression test for '816 opcodes (thanks Alessandro Gatti)
|
||||
branch/ Branch range test
|
||||
masmcom/ Another test for -M that generates totally valid code
|
||||
|
@ -49,6 +50,8 @@ alxl/ Various '816 width tests (includes Samuel Falvo's test)
|
|||
pparity/ Tests of preprocessor macro arity (with Emil Johansson's test)
|
||||
recucom/ Recursive comments test
|
||||
aserror/ Tests of .assert and #error syntax/function
|
||||
loader/ Old ../loader tests, moved into test suite proper
|
||||
reset_segment/ Verifies conditions under which a segment is reset
|
||||
|
||||
Cameron Kaiser, André Fachat
|
||||
|
||||
|
|
19
xa/tests/loader/Makefile
Normal file
19
xa/tests/loader/Makefile
Normal file
|
@ -0,0 +1,19 @@
|
|||
|
||||
all: loader example test2 rom65
|
||||
clean:
|
||||
rm -f loader test2 example a.o65 rom65
|
||||
|
||||
loader: loader.a65 file.def
|
||||
../../xa loader.a65 -o loader
|
||||
|
||||
example: test.a
|
||||
../../xa -R test.a -o example
|
||||
|
||||
test2: test2.a
|
||||
../../xa test2.a -o test2
|
||||
|
||||
rom65: test.a
|
||||
# ugly!
|
||||
( cd .. && ../mkrom.sh -O "-G" -S "-bd 1234" -R loader/rom65 loader/test.a loader/test.a )
|
||||
../hextool -cmp=rom65.ok < rom65
|
||||
|
8
xa/tests/loader/README
Normal file
8
xa/tests/loader/README
Normal file
|
@ -0,0 +1,8 @@
|
|||
|
||||
In this directory you find two test files, i.e. test.a and test2.a for
|
||||
xa. test.a is assembled into the file "example", which is loaded by the
|
||||
relocator "loader", when started on a C64. Don't try to execute this
|
||||
file, it's just for testing.
|
||||
|
||||
|
||||
|
BIN
xa/tests/loader/ex2
Normal file
BIN
xa/tests/loader/ex2
Normal file
Binary file not shown.
BIN
xa/tests/loader/example2
Normal file
BIN
xa/tests/loader/example2
Normal file
Binary file not shown.
36
xa/tests/loader/file.def
Normal file
36
xa/tests/loader/file.def
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
/* These definitions are without the two leading version/marker bytes,
|
||||
* length is without options
|
||||
*/
|
||||
#define HDR_MAGIC 0
|
||||
#define HDR_VERSION 3
|
||||
#define HDR_MODE 4
|
||||
#define HDR_TBASE 6
|
||||
#define HDR_TLEN 8
|
||||
#define HDR_DBASE 10
|
||||
#define HDR_DLEN 12
|
||||
#define HDR_BBASE 14
|
||||
#define HDR_BLEN 16
|
||||
#define HDR_ZBASE 18
|
||||
#define HDR_ZLEN 20
|
||||
#define HDR_STACKLEN 22
|
||||
#define HDR_LEN 24
|
||||
|
||||
#define A_ADR $80
|
||||
#define A_HIGH $40 /* or'd with the low byte */
|
||||
#define A_LOW $20
|
||||
#define A_MASK $e0 /* reloc type mask */
|
||||
#define A_FMASK $0f /* segment type mask */
|
||||
|
||||
#define SEG_UNDEF 0
|
||||
#define SEG_ABS 1
|
||||
#define SEG_TEXT 2
|
||||
#define SEG_DATA 3
|
||||
#define SEG_BSS 4
|
||||
#define SEG_ZERO 5
|
||||
|
||||
#define FM_OBJ %00010000
|
||||
#define FM_SIZE %00100000
|
||||
#define FM_RELOC %01000000
|
||||
#define FM_CPU %10000000
|
||||
|
909
xa/tests/loader/loader.a65
Normal file
909
xa/tests/loader/loader.a65
Normal file
|
@ -0,0 +1,909 @@
|
|||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Loader for 6502 relocatable binary format
|
||||
*
|
||||
* The loader supports 16 bit o65 version 1 files without undefined
|
||||
* references. Also it doesn't like pagewise relocation and 65816
|
||||
* code, because there are different/additional relocation entries.
|
||||
*
|
||||
* The support routines, that have to be changed are at the end of the
|
||||
* file. The stuff in this file is in absolute format (well, you have to
|
||||
* bootstrap from something :-)
|
||||
* The support routines for the file handling are for the operating system
|
||||
* OS/A65, as of version 1.3.10b. The first part of the file (wrapped in
|
||||
* "#ifdef C64") shows how to use it with a C64, for example.
|
||||
*
|
||||
* The subroutine 'loader' is called with a file descriptor, that has a
|
||||
* meaning for the support routines, in the X register.
|
||||
* The file must already be open. Also binit must have been called before.
|
||||
* The loader doesn't close the file.
|
||||
*
|
||||
* Support routines are:
|
||||
* binit a = hi byte start address memory to handle,
|
||||
* x = hi byte length of memory to handle
|
||||
* balloc a/y = length of block -> x = memory descriptor
|
||||
* bfree x = memory block descriptor to free
|
||||
* getbadr x = memory descriptor -> a/y address of memory block
|
||||
*
|
||||
* zalloc a = length of needed zeropage block. returns a=address
|
||||
* zfree a = address of block to free
|
||||
*
|
||||
* fgetc x = file descriptor, returns read byte (c=0) or error (c=1)
|
||||
* The error is passed through; fgetc blocks if no data
|
||||
* available
|
||||
* fgetb x = filedescriptor, a/y = address of block descriptor,
|
||||
* i.e. a word start address and a word length of block.
|
||||
* returns (c=0) or error in accu (c=1).
|
||||
*
|
||||
**************************************************************************/
|
||||
|
||||
/**************************************************************************
|
||||
* This part is a binding for a C64
|
||||
* to show how it works
|
||||
*/
|
||||
|
||||
#define C64
|
||||
|
||||
#ifdef C64
|
||||
|
||||
sysmem =$033c
|
||||
syszp =$57
|
||||
|
||||
|
||||
.word $0801
|
||||
*=$801
|
||||
.word nextl
|
||||
.word 10
|
||||
.byt $9e, "2080",0
|
||||
nextl .word 0
|
||||
.dsb 2080-*, 0
|
||||
|
||||
c64load .(
|
||||
lda #>PRGEND+255
|
||||
ldx #>$A000-PRGEND
|
||||
jsr binit ; init memory handling
|
||||
|
||||
lda #7
|
||||
ldx #<fname
|
||||
ldy #>fname
|
||||
jsr $ffbd ; setfnpar
|
||||
|
||||
lda #2
|
||||
ldx #11
|
||||
ldy #0
|
||||
jsr $ffba ; setfpar
|
||||
|
||||
jsr $ffc0 ; open
|
||||
bcs end
|
||||
|
||||
ldx #2
|
||||
jsr $ffc6 ; chkin
|
||||
bcs end
|
||||
|
||||
jsr loader ; don't care about x, chkin did it
|
||||
|
||||
php
|
||||
pha
|
||||
jsr $ffcc ; clrch
|
||||
lda #2
|
||||
jsr $ffc3 ; close
|
||||
pla
|
||||
plp
|
||||
end rts
|
||||
|
||||
fname ;.asc "example",0
|
||||
.byt $45, $58, $41, $4d, $50, $4c, $45, 0
|
||||
.)
|
||||
|
||||
fgetc .(
|
||||
jsr $ffcf
|
||||
php
|
||||
pha
|
||||
bcc carry
|
||||
lda #"C"
|
||||
jsr $ffd2
|
||||
pla
|
||||
pha
|
||||
carry
|
||||
jsr hexout
|
||||
lda #$20
|
||||
jsr $ffd2
|
||||
pla
|
||||
plp
|
||||
rts
|
||||
.)
|
||||
|
||||
hexout .(
|
||||
pha
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
lsr
|
||||
jsr nibout
|
||||
pla
|
||||
nibout and #$0f
|
||||
clc
|
||||
adc #$30
|
||||
cmp #$3a
|
||||
bcc ok
|
||||
adc #$41-$3a-1
|
||||
ok jmp $ffd2
|
||||
.)
|
||||
|
||||
zalloc .(
|
||||
cmp #$80 ; save from $90 upward = OS, below is only basic
|
||||
bcs end
|
||||
lda #$10
|
||||
end rts
|
||||
.)
|
||||
|
||||
zfree .(
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
#endif
|
||||
|
||||
/**************************************************************************
|
||||
* Here is the real loader code
|
||||
*/
|
||||
|
||||
#include "file.def"
|
||||
|
||||
#define E_NOMEM <-40
|
||||
#define E_FVERSION <-41
|
||||
|
||||
loader .(
|
||||
p1 =syszp
|
||||
p2 =syszp+2
|
||||
-syszp +=4
|
||||
|
||||
tmp =sysmem
|
||||
file =sysmem+1
|
||||
-sysmem +=2
|
||||
header =sysmem
|
||||
-sysmem +=HDR_LEN
|
||||
textb =sysmem ; memory block ID
|
||||
texta =sysmem+1 ; address of block
|
||||
textl =sysmem+3 ; address of block
|
||||
textd =sysmem+5 ; difference to assemble address
|
||||
-sysmem +=7
|
||||
datab =sysmem
|
||||
dataa =sysmem+1
|
||||
datal =sysmem+3
|
||||
datad =sysmem+5
|
||||
-sysmem +=7
|
||||
bssb =sysmem
|
||||
bssa =sysmem+1
|
||||
bssd =sysmem+3
|
||||
-sysmem +=5
|
||||
zeroa =sysmem
|
||||
zerod =sysmem+1
|
||||
-sysmem +=3
|
||||
|
||||
stx file
|
||||
jsr fgetc
|
||||
bcs end
|
||||
sta tmp
|
||||
jsr fgetc
|
||||
bcs end
|
||||
tay
|
||||
lda tmp
|
||||
cpy #0
|
||||
bne rt
|
||||
cmp #1
|
||||
beq load
|
||||
rt lda #E_FVERSION ; ok, but not this version
|
||||
end sec
|
||||
rts
|
||||
|
||||
load .(
|
||||
lda #<header
|
||||
sta p1
|
||||
lda #>header
|
||||
sta p1+1
|
||||
lda #<HDR_LEN
|
||||
sta p1+2
|
||||
lda #>HDR_LEN
|
||||
sta p1+3
|
||||
|
||||
ldx file
|
||||
lda #<p1
|
||||
ldy #>p1
|
||||
jsr fgetb
|
||||
bcs end
|
||||
|
||||
; header loaded, check magic and version
|
||||
lda header+HDR_MAGIC
|
||||
cmp #$6f
|
||||
bne end
|
||||
lda header+HDR_MAGIC+1
|
||||
cmp #"6"
|
||||
bne end
|
||||
lda header+HDR_MAGIC+2
|
||||
cmp #"5"
|
||||
bne end
|
||||
lda header+HDR_VERSION
|
||||
cmp #0
|
||||
bne end
|
||||
lda header+HDR_MODE+1
|
||||
and #%11110000
|
||||
bne end
|
||||
; now allocate buffers
|
||||
lda header+HDR_TLEN
|
||||
ldy header+HDR_TLEN+1
|
||||
sta textl
|
||||
sty textl+1
|
||||
jsr balloc
|
||||
stx textb
|
||||
bcs no_text2
|
||||
jsr getbadr
|
||||
sta texta
|
||||
sty texta+1
|
||||
sec
|
||||
sbc header+HDR_TBASE
|
||||
sta textd
|
||||
tya
|
||||
sbc header+HDR_TBASE+1
|
||||
sta textd+1
|
||||
|
||||
lda header+HDR_DLEN
|
||||
ldy header+HDR_DLEN+1
|
||||
sta datal
|
||||
sty datal+1
|
||||
jsr balloc
|
||||
stx datab
|
||||
bcs no_data2
|
||||
no_text2 bcs no_text1
|
||||
jsr getbadr
|
||||
sta dataa
|
||||
sty dataa+1
|
||||
sec
|
||||
sbc header+HDR_DBASE
|
||||
sta datad
|
||||
tya
|
||||
sbc header+HDR_DBASE+1
|
||||
sta datad+1
|
||||
|
||||
lda header+HDR_BLEN
|
||||
ldy header+HDR_BLEN+1
|
||||
jsr balloc
|
||||
stx bssb
|
||||
bcs no_bss
|
||||
no_text1 bcs no_text
|
||||
no_data2 bcs no_data
|
||||
jsr getbadr
|
||||
sta bssa
|
||||
sty bssa+1
|
||||
sec
|
||||
sbc header+HDR_BBASE
|
||||
sta bssd
|
||||
tya
|
||||
sbc header+HDR_BBASE+1
|
||||
sta bssd+1
|
||||
|
||||
lda header+HDR_ZLEN
|
||||
jsr zalloc
|
||||
bcs no_zero
|
||||
sta zeroa
|
||||
sec
|
||||
sbc header+HDR_ZBASE
|
||||
sta zerod
|
||||
lda #0
|
||||
sta zerod+1
|
||||
|
||||
jmp do_load
|
||||
|
||||
&no_file lda zeroa
|
||||
jsr zfree
|
||||
no_zero ldx bssb
|
||||
jsr bfree
|
||||
no_bss ldx datab
|
||||
jsr bfree
|
||||
no_data ldx textb
|
||||
jsr bfree
|
||||
no_text rts
|
||||
|
||||
do_load ; load options (i.e. ignore them now)
|
||||
jsr fgetc
|
||||
bcs no_file
|
||||
cmp #0
|
||||
beq load_text
|
||||
tay
|
||||
dey
|
||||
optl jsr fgetc
|
||||
bcs no_file
|
||||
dey
|
||||
bne optl
|
||||
beq do_load
|
||||
|
||||
load_text ; load text segment
|
||||
ldx file
|
||||
lda #<texta
|
||||
ldy #>texta
|
||||
jsr fgetb
|
||||
bcs no_file
|
||||
|
||||
ldx file
|
||||
lda #<dataa
|
||||
ldy #>dataa
|
||||
jsr fgetb
|
||||
bcs no_file
|
||||
; check number of undefined references
|
||||
ldx file
|
||||
jsr fgetc
|
||||
&no_file2 bcs no_file
|
||||
cmp #0
|
||||
bne no_file ; we have some -> not handled
|
||||
ldx file
|
||||
jsr fgetc
|
||||
bcs no_file
|
||||
cmp #0
|
||||
bne no_file
|
||||
; ok, text segments loaded, now relocate
|
||||
lda texta
|
||||
sec
|
||||
sbc #1
|
||||
sta p1
|
||||
lda texta+1
|
||||
sbc #0
|
||||
sta p1+1
|
||||
jsr trel
|
||||
|
||||
lda dataa
|
||||
sec
|
||||
sbc #1
|
||||
sta p1
|
||||
lda dataa+1
|
||||
sbc #0
|
||||
sta p1+1
|
||||
jsr trel
|
||||
|
||||
lda texta ; return start of text segment
|
||||
ldy texta+1
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
trel .(
|
||||
ldx file
|
||||
jsr fgetc
|
||||
no_file1 bcs no_file2
|
||||
cmp #0
|
||||
beq reloc_rts
|
||||
cmp #255
|
||||
bne t1
|
||||
lda #254
|
||||
clc
|
||||
adc p1
|
||||
sta p1
|
||||
bcc trel
|
||||
inc p1+1
|
||||
jmp trel
|
||||
t1 clc
|
||||
adc p1
|
||||
sta p1
|
||||
bcc t1a
|
||||
inc p1+1
|
||||
t1a ; p1 is the relocation address
|
||||
ldx file
|
||||
jsr fgetc
|
||||
bcs no_file1
|
||||
tay
|
||||
and #A_MASK
|
||||
sta tmp
|
||||
tya
|
||||
and #A_FMASK
|
||||
jsr getreldiff
|
||||
ldy tmp
|
||||
cpy #A_ADR
|
||||
bne t2
|
||||
|
||||
ldy #0
|
||||
clc
|
||||
adc (p1),y
|
||||
sta (p1),y
|
||||
iny
|
||||
txa
|
||||
adc (p1),y
|
||||
sta (p1),y
|
||||
jmp trel
|
||||
t2
|
||||
cpy #A_LOW
|
||||
bne t3
|
||||
ldy #0
|
||||
clc
|
||||
adc (p1),y
|
||||
sta (p1),y
|
||||
jmp trel
|
||||
t3
|
||||
cpy #A_HIGH
|
||||
bne trel
|
||||
sta p2
|
||||
stx p2+1
|
||||
ldx file
|
||||
jsr fgetc
|
||||
clc
|
||||
adc p2 ; just get the carry bit
|
||||
ldy #0
|
||||
lda p2+1 ; relocate high byte
|
||||
adc (p1),y
|
||||
sta (p1),y
|
||||
jmp trel
|
||||
|
||||
reloc_rts
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
getreldiff .( ; comparing with SEG_UNDEF would give a way
|
||||
; to get label value here for undefined refs
|
||||
cmp #SEG_TEXT
|
||||
bne notext
|
||||
lda textd
|
||||
ldx textd+1
|
||||
rts
|
||||
notext cmp #SEG_DATA
|
||||
bne nodata
|
||||
lda datad
|
||||
ldx datad+1
|
||||
rts
|
||||
nodata cmp #SEG_BSS
|
||||
bne nobss
|
||||
lda bssd
|
||||
ldx bssd+1
|
||||
rts
|
||||
nobss cmp #SEG_ZERO
|
||||
bne nozero
|
||||
lda zerod
|
||||
ldx zerod+1
|
||||
nozero rts
|
||||
.)
|
||||
|
||||
.)
|
||||
|
||||
/**************************************************************************
|
||||
* Here come the support routines
|
||||
*
|
||||
* first is a simple and basic implementation of fgetb, just using fgetc
|
||||
*/
|
||||
|
||||
fgetb .(
|
||||
p =syszp
|
||||
-syszp +=2
|
||||
file =sysmem
|
||||
l =sysmem+1
|
||||
-sysmem +=3
|
||||
|
||||
stx file ; x=file, a=zp-adr of address, y=zp-adr of len
|
||||
sta p
|
||||
sty p+1
|
||||
ldy #3
|
||||
lda (p),y
|
||||
sta l+1
|
||||
dey
|
||||
lda (p),y
|
||||
sta l
|
||||
dey
|
||||
lda (p),y
|
||||
pha
|
||||
dey
|
||||
lda (p),y
|
||||
sta p
|
||||
pla
|
||||
sta p+1
|
||||
|
||||
loop ldx file
|
||||
jsr fgetc ; this is a simple implementation
|
||||
bcs end
|
||||
ldy #0
|
||||
sta (p),y
|
||||
inc p
|
||||
bne l0
|
||||
inc p+1
|
||||
l0
|
||||
lda l
|
||||
bne l1
|
||||
dec l+1
|
||||
l1 dec l
|
||||
|
||||
lda l
|
||||
ora l+1
|
||||
bne loop
|
||||
clc
|
||||
end
|
||||
rts
|
||||
.)
|
||||
|
||||
/**************************************************************************
|
||||
* support for memory allocation
|
||||
*
|
||||
* These routines are taken from a preliminary SLIP implementation, as of
|
||||
* OS/A65 version 1.3.10b
|
||||
*/
|
||||
|
||||
#define MAXSLOT 8
|
||||
|
||||
/**********************************************************************/
|
||||
/* New memory management for IP buffers */
|
||||
/* exports */
|
||||
/* binit */
|
||||
/* balloc, bfree, btrunc, bsplit, brealloc */
|
||||
/* getbadr, getblen */
|
||||
|
||||
#define MINBUF 8
|
||||
#define MINMASK %11111000
|
||||
|
||||
.(
|
||||
|
||||
slotladr =sysmem
|
||||
slothadr =sysmem+MAXSLOT
|
||||
slotllen =sysmem+MAXSLOT*2
|
||||
slothlen =sysmem+MAXSLOT*3
|
||||
-sysmem +=MAXSLOT*4
|
||||
|
||||
flist =sysmem
|
||||
slot =sysmem+2
|
||||
-sysmem +=3
|
||||
|
||||
p =syszp
|
||||
p2 =syszp+2
|
||||
p3 =syszp+4
|
||||
p4 =syszp+6
|
||||
-syszp +=8
|
||||
|
||||
/* init memory management */
|
||||
&binit .(
|
||||
sta p+1 ; hi byte startadress buffer
|
||||
stx p2+1 ; hi byte length of buffer
|
||||
|
||||
lda #0
|
||||
tay
|
||||
l0 sta slotladr,y
|
||||
sta slothadr,y
|
||||
iny
|
||||
cpy #MAXSLOT
|
||||
bcc l0
|
||||
|
||||
sta p
|
||||
tay
|
||||
sta (p),y
|
||||
iny
|
||||
sta (p),y
|
||||
iny
|
||||
sta (p),y
|
||||
iny
|
||||
lda p2+1
|
||||
sta (p),y
|
||||
|
||||
lda p
|
||||
sta flist
|
||||
lda p+1
|
||||
sta flist+1
|
||||
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
/* a/y = size of buffer to be allocated -> x buffer-ID */
|
||||
&balloc .(
|
||||
/* walk along freelist, and take first matching buffer
|
||||
length is made a multiple of 8 (for freelist connectors */
|
||||
|
||||
pha
|
||||
jsr getbslot
|
||||
pla
|
||||
bcc gotslot
|
||||
lda #E_NOMEM
|
||||
rts
|
||||
gotslot
|
||||
stx slot
|
||||
|
||||
adc #MINBUF-1
|
||||
and #MINMASK
|
||||
sta slotllen,x
|
||||
tya
|
||||
adc #0
|
||||
sta slothlen,x
|
||||
|
||||
lda #0
|
||||
sta p2
|
||||
sta p2+1
|
||||
lda flist
|
||||
sta p
|
||||
lda flist+1
|
||||
sta p+1
|
||||
l0
|
||||
ldy #2
|
||||
lda (p),y
|
||||
sec
|
||||
sbc slotllen,x
|
||||
sta p3
|
||||
iny
|
||||
lda (p),y
|
||||
sbc slothlen,x
|
||||
sta p3+1
|
||||
bcs found
|
||||
|
||||
lda p
|
||||
sta p2
|
||||
lda p+1
|
||||
sta p2+1
|
||||
ldy #1
|
||||
lda (p2),y
|
||||
sta p+1
|
||||
dey
|
||||
lda (p2),y
|
||||
sta p
|
||||
ora p+1
|
||||
bne l0
|
||||
|
||||
oops lda #E_NOMEM
|
||||
sec
|
||||
rts
|
||||
|
||||
found
|
||||
/* ok, we found a free buffer: p points to the buffer, p2 to the
|
||||
previous one. p3 is the length of the free buffer minus the
|
||||
needed size. If the buffer is longer than needed, create a
|
||||
new free buffer, then link new buffer to freelist */
|
||||
|
||||
lda p /* save buffer address */
|
||||
sta slotladr,x
|
||||
lda p+1
|
||||
sta slothadr,x
|
||||
|
||||
lda p3 /* check length */
|
||||
ora p3+1
|
||||
beq nocreate
|
||||
|
||||
lda p /* get address of new free buffer */
|
||||
clc
|
||||
adc slotllen,x
|
||||
sta p4
|
||||
lda p+1
|
||||
adc slothlen,x
|
||||
sta p4+1
|
||||
|
||||
ldy #0 /* copy next pointer */
|
||||
lda (p),y
|
||||
sta (p4),y
|
||||
iny
|
||||
lda (p),y
|
||||
sta (p4),y
|
||||
|
||||
iny /* set new length */
|
||||
lda slotllen,x
|
||||
sta (p),y
|
||||
lda p3
|
||||
sta (p4),y
|
||||
iny
|
||||
lda slothlen,x
|
||||
sta (p),y
|
||||
lda p3+1
|
||||
sta (p4),y
|
||||
|
||||
lda p4
|
||||
sta p
|
||||
lda p4+1
|
||||
sta p+1
|
||||
|
||||
nocreate
|
||||
lda p2
|
||||
ora p2+1
|
||||
beq freestart
|
||||
|
||||
ldy #0
|
||||
lda p
|
||||
sta (p2),y
|
||||
iny
|
||||
lda p+1
|
||||
sta (p2),y
|
||||
clc
|
||||
bcc geta
|
||||
freestart
|
||||
lda p
|
||||
sta flist
|
||||
lda p+1
|
||||
sta flist+1
|
||||
clc
|
||||
geta
|
||||
lda slotladr,x
|
||||
ldy slothadr,x
|
||||
rts
|
||||
.)
|
||||
|
||||
/* free buffer (ID=xr) */
|
||||
&bfree .(
|
||||
lda slothadr,x
|
||||
sta p3+1
|
||||
lda slotladr,x
|
||||
sta p3
|
||||
ora p3+1
|
||||
beq end2
|
||||
|
||||
ldy #2
|
||||
lda slotllen,x
|
||||
sta (p3),y
|
||||
iny
|
||||
lda slothlen,x
|
||||
sta (p3),y
|
||||
|
||||
lda #0
|
||||
sta slothadr,x
|
||||
sta slotladr,x
|
||||
|
||||
lda flist
|
||||
ora flist+1
|
||||
bne ok /* no free buffer so far? */
|
||||
|
||||
lda p3
|
||||
sta flist
|
||||
lda p3+1
|
||||
sta flist+1
|
||||
ldy #0
|
||||
tya
|
||||
sta (p3),y
|
||||
iny
|
||||
sta (p3),y
|
||||
end2 clc
|
||||
rts
|
||||
ok
|
||||
lda #0
|
||||
sta p2
|
||||
sta p2+1
|
||||
lda flist
|
||||
sta p
|
||||
lda flist+1
|
||||
sta p+1
|
||||
|
||||
/* we have to find the place where to put the buffer in the
|
||||
ordered free list. Then we have to check if we can merge
|
||||
free buffers */
|
||||
loop
|
||||
lda p3+1
|
||||
cmp p+1
|
||||
bcc found
|
||||
bne next
|
||||
lda p3
|
||||
cmp p
|
||||
bcc found
|
||||
next
|
||||
lda p
|
||||
sta p2
|
||||
lda p+1
|
||||
sta p2+1
|
||||
ldy #0
|
||||
lda (p2),y
|
||||
sta p
|
||||
iny
|
||||
lda (p2),y
|
||||
sta p+1
|
||||
ora p
|
||||
bne loop
|
||||
beq found
|
||||
end
|
||||
clc
|
||||
rts
|
||||
|
||||
found /* p2 is the buffer before the one to be freed, p the one behind.
|
||||
p3 is the buffer to be inserted */
|
||||
|
||||
lda p2
|
||||
ora p2+1
|
||||
bne fok
|
||||
; insert before the first free buffer so far
|
||||
ldy #0
|
||||
lda flist
|
||||
sta (p3),y
|
||||
iny
|
||||
lda flist+1
|
||||
sta (p3),y
|
||||
lda p3
|
||||
sta flist
|
||||
ldy p3+1
|
||||
sty flist+1
|
||||
jsr bmerge
|
||||
clc
|
||||
rts
|
||||
fok ; insert to list
|
||||
ldy #1
|
||||
lda p+1 ;lda (p2),y
|
||||
sta (p3),y
|
||||
dey
|
||||
lda p ;lda (p2),y
|
||||
sta (p3),y
|
||||
lda p3
|
||||
sta (p2),y
|
||||
iny
|
||||
lda p3+1
|
||||
sta (p2),y
|
||||
|
||||
lda p3
|
||||
ldy p3+1
|
||||
jsr bmerge
|
||||
lda p2
|
||||
ldy p2+1
|
||||
jsr bmerge
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
/* get adress of buffer */
|
||||
&getbadr .(
|
||||
lda slotladr,x
|
||||
ldy slothadr,x
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
/* get length of buffer */
|
||||
&getblen .(
|
||||
lda slotllen,x
|
||||
ldy slothlen,x
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
/* get free buffer-ID slot */
|
||||
getbslot .(
|
||||
ldx #0
|
||||
l0
|
||||
clc
|
||||
lda slotladr,x
|
||||
ora slothadr,x
|
||||
beq found
|
||||
inx
|
||||
cpx #MAXSLOT
|
||||
bcc l0
|
||||
found
|
||||
rts
|
||||
.)
|
||||
|
||||
/* check if two buffers (i.e. a/y plus following) can be merged */
|
||||
bmerge .(
|
||||
sta p
|
||||
sty p+1
|
||||
ldy #2
|
||||
clc
|
||||
lda (p),y
|
||||
adc p
|
||||
sta p3
|
||||
iny
|
||||
lda (p),y
|
||||
adc p+1
|
||||
sta p3+1
|
||||
ldy #0
|
||||
lda (p),y
|
||||
cmp p3
|
||||
bne nomerge
|
||||
iny
|
||||
lda (p),y
|
||||
cmp p3+1
|
||||
bne nomerge
|
||||
merge
|
||||
ldy #2
|
||||
clc
|
||||
lda (p3),y
|
||||
adc (p),y
|
||||
sta (p),y
|
||||
iny
|
||||
lda (p3),y
|
||||
adc (p),y
|
||||
sta (p),y
|
||||
ldy #0
|
||||
lda (p3),y
|
||||
sta (p),y
|
||||
iny
|
||||
lda (p3),y
|
||||
sta (p),y
|
||||
nomerge
|
||||
clc
|
||||
rts
|
||||
.)
|
||||
|
||||
.)
|
||||
|
||||
PRGEND
|
||||
|
BIN
xa/tests/loader/rom65.ok
Normal file
BIN
xa/tests/loader/rom65.ok
Normal file
Binary file not shown.
36
xa/tests/loader/test.a
Normal file
36
xa/tests/loader/test.a
Normal file
|
@ -0,0 +1,36 @@
|
|||
|
||||
.fopt 1, "filename"
|
||||
.(
|
||||
.text
|
||||
&absv = 4
|
||||
lda #>test+4
|
||||
bne test
|
||||
*=$8000 ;*
|
||||
lda <test
|
||||
lo bvc lo
|
||||
*=
|
||||
test
|
||||
lda (0),y
|
||||
jmp (test)
|
||||
.word *
|
||||
|
||||
.data
|
||||
+bla
|
||||
.word test
|
||||
.byt <test-8, >test-8
|
||||
.)
|
||||
.text
|
||||
nop
|
||||
|
||||
; .fopt 1, "filename"
|
||||
|
||||
lda bsslab
|
||||
lda zerolab
|
||||
lda #absv*2
|
||||
.bss
|
||||
bsslab
|
||||
.dsb 20,1
|
||||
.zero
|
||||
zerolab
|
||||
.dsb 20
|
||||
|
28
xa/tests/loader/test2.a
Normal file
28
xa/tests/loader/test2.a
Normal file
|
@ -0,0 +1,28 @@
|
|||
|
||||
*=$8000
|
||||
.(
|
||||
; .text
|
||||
lda #>test+4
|
||||
bne test
|
||||
;*=*
|
||||
lda <test
|
||||
;*=
|
||||
test
|
||||
lda (0),y
|
||||
jmp (test)
|
||||
; .data
|
||||
+bla
|
||||
.word test
|
||||
.byt <test-1, >test-1
|
||||
.)
|
||||
; .text
|
||||
nop
|
||||
lda bsslab
|
||||
lda zerolab
|
||||
; .bss
|
||||
bsslab
|
||||
.dsb 20,1
|
||||
; .zero
|
||||
zerolab
|
||||
.dsb 20
|
||||
|
3
xa/tests/loader/test3.a
Normal file
3
xa/tests/loader/test3.a
Normal file
|
@ -0,0 +1,3 @@
|
|||
|
||||
lda #label
|
||||
lab2
|
Loading…
Reference in New Issue
Block a user