CPU-Z80-Assembler
view release on metacpan or search on metacpan
lib/CPU/Z80/Assembler.pm view on Meta::CPAN
use Asm::Preproc;
use Asm::Preproc::Lexer;
use CPU::Z80::Assembler::Program;
use CPU::Z80::Assembler::List;
use Text::Tabs; # imports expand(), unexpand()
use Regexp::Trie;
use vars qw(@EXPORT $verbose);
our $VERSION = '2.25';
our $verbose;
our $fill_byte = 0xFF;
use base qw(Exporter);
@EXPORT = qw(z80asm z80asm_file z80preprocessor z80lexer);
#------------------------------------------------------------------------------
=head1 SYNOPSIS
use CPU::Z80::Assembler;
$CPU::Z80::Assembler::verbose = 1;
$CPU::Z80::Assembler::fill_byte = 0xFF;
$binary = z80asm(q{
ORG 0x1000
LD A, 1
...
});
$binary = z80asm_file($asm_file);
$binary = z80asm(@asm_lines);
$binary = z80asm('#include <file.asm>');
open($fh, $file); $binary = z80asm(sub {<$fh>});
$lines = z80preprocessor(@asm_lines); $line = $lines->next;
$tokens = z80lexer(@asm_lines); $token = $tokens->next;
=head1 DESCRIPTION
This module provides functions to assemble a set of Z80 assembly instructions
given as a list or as an iterator, or a Z80 assembly source file.
=head1 EXPORTS
All functions are exported by default.
=head1 FUNCTIONS
=head2 z80asm
This function takes as parameter a list of either text lines to parse,
or iterators that return text lines to parse.
The list is passed to C<z80lexer>, that in turn calls C<z80preprocessor> to
handle file includes, and then splits the input into tokens.
The stream of tokens is passed on to L<CPU:Z80::Assembler::Parser|CPU:Z80::Assembler::Parser> that parses the
input and generates the object image in L<CPU::Z80::Assembler::Program|CPU::Z80::Assembler::Program>.
Assembly macro expansion is handled at this stage by L<CPU::Z80::Assembler::Macro|CPU::Z80::Assembler::Macro>.
The assembly program is composed by a list of L<CPU::Z80::Assembler::Segment|CPU::Z80::Assembler::Segment>, each
representing one named section of code. Each segment is composed by a list of L<CPU::Z80::Assembler::Opcode|CPU::Z80::Assembler::Opcode>, each representing one assembly instruction.
The output object code is returned as a string.
If the $CPU::Z80::Assembler::verbose variable is set, an output listing is generated
by L<CPU::Z80::Assembler::List|CPU::Z80::Assembler::List> on standard output.
Assembly is done in five steps:
=over 4
=item 1
input is preprocessed, scanned and split into tokens
=item 2
tokens are parsed and converted to lists of opcodes
=item 3
addresses for each opcode are allocated
=item 4
relative jumps are checked for out-of-range jumps and replaced by absolute
jumps if needed
=item 5
object code is generated for each opcode, computing all expressions used; the expressions are
represented by L<CPU::Z80::Assembler::Expr|CPU::Z80::Assembler::Expr>.
=back
=cut
#------------------------------------------------------------------------------
sub z80asm {
my(@input) = @_;
my $list_output = ($CPU::Z80::Assembler::verbose) ?
CPU::Z80::Assembler::List->new(
input => \@input,
output => \*STDOUT) :
undef;
my $program = CPU::Z80::Assembler::Program->new();
my $token_stream = z80lexer(@input);
$program->parse($token_stream);
my $bytes = $program->bytes($list_output);
$list_output->flush() if $list_output;
return $bytes;
}
#------------------------------------------------------------------------------
=head2 z80asm_file
This function takes as argument a Z80 assembly source file name and returns
the binary object code string.
lib/CPU/Z80/Assembler.pm view on Meta::CPAN
A relative jump instruction can always be used. The assembler automatically
replaces it with an absolute jump if the distance is too far, or if the given
flag is not available, e.g. C<jr po,NN>.
A C<djnz NN> instruction is converted to C<dec b:jp nz,NN> if the distance is too far.
=head3 stop
This extra instruction (which assembles to 0xDD 0xDD 0x00) is provided
for the convenience of those using the L<CPU::Emulator::Z80> module.
=head2 Pseudo-instructions
=head3 defb
Accepts a list of expressions, and evaluates each as a byte to load to the
object file.
=head3 defw
Accepts a list of expressions, and evaluates each as a 16-bit word to load to the
object file, in little-endian order.
=head3 defm, deft
Accepts a list of literal strings, either single- or double-quoted.
The quoted text can not include the quotes surrounding it or newlines.
The characters are loaded to the object file.
=head3 defmz
Same as C<defm>, but appends a zero byte as string terminator after each string.
=head3 defm7
Same as C<defm>, but "inverts" (i.e. bit 7 set) the last character of the string,
as string terminator.
=head3 equ, =
Labels are created having the value of the address they are created at.
Alternatively labels may be assigned expressions by using C<equ> or C<=>. The
expressions use the Perl operators and can refer to other labels by name, even
if they are defined further on the file. The C<$> can be used in the expression
to represent the current location counter.
label = $ + 8
otherlabel = label / 2 + 3
=head3 org
Tell the assembler to start building the code at this address.
If it is not the first instruction of the assembly, the gap to the previous
location counter is filled with C<$CPU::Z80::Assembler::fill_byte>.
If absent, defaults to 0x0000.
=head3 include
Recursively include another file at the current source file.
=head2 Macros
Macros are supported. See L<CPU::Z80::Assembler::Macro|CPU::Z80::Assembler::Macro> for details.
=head1 BUGS and FEEDBACK
We welcome feedback about our code, including constructive criticism.
Bug reports should be made using L<http://rt.cpan.org/>.
=head1 SEE ALSO
L<CPU::Z80::Assembler::Macro|CPU::Z80::Assembler::Macro>
L<CPU::Z80::Assembler::Parser|CPU::Z80::Assembler::Parser>
L<CPU::Emulator::Z80|CPU::Emulator::Z80>
=head1 AUTHORS, COPYRIGHT and LICENCE
Copyright (c) 2008-2009,
David Cantrell E<lt>F<david@cantrell.org.uk>E<gt>,
Paulo Custodio E<lt>F<pscust@cpan.org>E<gt>
This software is free-as-in-speech software, and may be used,
distributed, and modified under the terms of either the GNU
General Public Licence version 2 or the Artistic Licence. It's
up to you which one you use. The full text of the licences can
be found in the files GPL2.txt and ARTISTIC.txt, respectively.
The Spectrum 48K ROM used in the test scripts is Copyright by Amstrad.
Amstrad have kindly given their permission for the
redistribution of their copyrighted material but retain that copyright
(see L<http://www.worldofspectrum.org/permits/amstrad-roms.txt>).
=head1 CONSPIRACY
This software is also free-as-in-mason.
=cut
#------------------------------------------------------------------------------
1;
( run in 1.314 second using v1.01-cache-2.11-cpan-ceb78f64989 )