CPU-Z80-Assembler
view release on metacpan or search on metacpan
The output is the new Parser.pm module with about 7K states and 20K lines
of Perl code --> PERFORMANCE PENALTY.
* Remove ParserTable.pm : whole Parser.pm is now generated by
tools\build_Parser.pl
* Expr.pm parser now checks for the correct syntax. The previous parser just
extracted balanced parentheses.
* Lexer.pm :
- accept db, dw, dt, dm as alias to defb, defw, deft, defm
- remove quotes from STRING token value
* Line.pm : added back is_equal() and is_different()
* Macro.pm :
- return the list of newline tokens parsed inside of a macro
definition back to the stream, so that the assembly listing contains
also these lines.
- replace statement_end() by /[:\n]/ -> performance
* Program.pm, Segment.pm : new org() and add() methods to be called by code
generator.
The lexer is still the performance botleneck, together with the heavy usage
of HOP::Stream.
%Time ExclSec CumulS #Calls sec/call Csec/c Name
43.7 0.500 3.052 71417 0.0000 0.0000 HOP::Stream::tail
33.6 0.385 0.665 98780 0.0000 0.0000 HOP::Stream::head
24.6 0.282 0.466 170197 0.0000 0.0000 HOP::Stream::is_node
22.4 0.257 1.214 17902 0.0000 0.0001 CPU::Z80::Assembler::Lexer::__ANON__
21.3 0.244 0.257 67163 0.0000 0.0000 HOP::Stream::is_promise
20.7 0.237 2.173 34954 0.0000 0.0001 CPU::Z80::Assembler::Macro::__ANON__
20.4 0.234 0.250 9 0.0260 0.0278 CPU::Z80::Assembler::Macro::BEGIN
19.6 0.225 0.225 242140 0.0000 0.0000 UNIVERSAL::isa
18.6 0.213 3.250 71417 0.0000 0.0000 HOP::Stream::drop
2.05_02 2009-04-25
* Line.pm, Token.pm :
- go back to Class::Struct instead of Class::Class (bad performance of the
later)
- do not use "eval(Data::Dump::dump())" for clone - bad performance
- add overload for 'bool' and '0+' - '""' was being used, and is too slow
because it uses Data::Dump::dump() internally
1.03 2008-06-25
* Bugfixes from Paulo Custodio:
see https://rt.cpan.org/Ticket/Display.html?id=36991
1.02 2008-06-22
* Added INCLUDE
* Added support for #comments at start of line
(for C pre-processor friendliness)
1.01 2008-06-14
* Macro parameters no longer clash with labels
whose names start the same as a parameter.
eg, a param $r no longer clashes with label
$rr
* Likewise labels
1.0 2008-06-13
* Original release
.github/workflows/perltest.yml
ARTISTIC.txt
bin/z80masm
CHANGES
lib/CPU/Z80/Assembler.pm
lib/CPU/Z80/Assembler/Expr.pm
lib/CPU/Z80/Assembler/JumpOpcode.pm
lib/CPU/Z80/Assembler/List.pm
lib/CPU/Z80/Assembler/Macro.pm
lib/CPU/Z80/Assembler/Opcode.pm
lib/CPU/Z80/Assembler/Parser.pm
lib/CPU/Z80/Assembler/Program.pm
lib/CPU/Z80/Assembler/Segment.pm
Makefile.PL
MANIFEST This list of files
MANIFEST.SKIP
README
t/assemble.t
t/binmode.t
t/Expr-parse.t
t/hash-comments_.t
t/issue_1.t
t/JumpOpcode.t
t/labels_.t
t/Lexer-comments.t
t/Lexer-crlf.t
t/Lexer-include.t
t/Lexer-tokens.t
t/list.t
t/Macro-error.t
t/Macro-locals.t
t/Macro-mul8x8.t
t/Macro-params.t
t/Macro.t
t/Opcode.t
t/opcodes.t
t/ORG-instrs.t
t/pod-coverage.t
t/pod.t
t/Preprocessor-include.t
t/Program-jumps.t
t/Program-label.t
t/Program-locate.t
t/Program-org.t
lib/CPU/Z80/Assembler.pm view on Meta::CPAN
=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:
lib/CPU/Z80/Assembler.pm view on Meta::CPAN
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,
lib/CPU/Z80/Assembler/Macro.pm view on Meta::CPAN
# $Id$
package CPU::Z80::Assembler::Macro;
#------------------------------------------------------------------------------
=head1 NAME
CPU::Z80::Assembler::Macro - Macro pre-processor for the Z80 assembler
=cut
#------------------------------------------------------------------------------
use strict;
use warnings;
use CPU::Z80::Assembler::Parser;
use Iterator::Simple::Lookahead;
lib/CPU/Z80/Assembler/Macro.pm view on Meta::CPAN
}
sub name { defined($_[1]) ? $_[0][0] = $_[1] : $_[0][0] }
sub params { defined($_[1]) ? $_[0][1] = $_[1] : $_[0][1] }
sub locals { defined($_[1]) ? $_[0][2] = $_[1] : $_[0][2] }
sub tokens { defined($_[1]) ? $_[0][3] = $_[1] : $_[0][3] }
#------------------------------------------------------------------------------
=head1 SYNOPSIS
use CPU::Z80::Assembler::Macro;
my $macro = CPU::Z80::Assembler::Macro->new(
name => $name,
params => \@params_names,
locals => \%local_labels,
tokens => \@token_list);
$macro->parse_body($input);
$macro->expand_macro($input);
=head1 DESCRIPTION
This module provides a macro pre-processor to parse macro definition statements,
lib/CPU/Z80/Assembler/Macro.pm view on Meta::CPAN
Asm::Preproc::Token->error_at($token, "unmatched braces")
if $parens != 0;
return @tokens;
}
#------------------------------------------------------------------------------
=head1 SYNTAX
=head2 Macros
Macros are created thus. This example creates an "instruction" called MAGIC
that takes two parameters:
MACRO MAGIC param1, param2 {
LD param1, 0
BIT param2, L
label = 0x1234
... more real instructions go here.
}
Within the macro, param1, param2 etc will be replaced with whatever
lib/CPU/Z80/Assembler/Parser.pm view on Meta::CPAN
use constant {
ARGS => 0, PROG => 1, INPUT => 2, # to decode args in parser functions
};
our $VERSION = '2.25';
use CPU::Z80::Assembler;
use CPU::Z80::Assembler::Expr;
use CPU::Z80::Assembler::Macro;
use CPU::Z80::Assembler::Opcode;
use CPU::Z80::Assembler::JumpOpcode;
use Asm::Preproc::Token;
use base "Exporter";
our @EXPORT = qw( z80parser );
#------------------------------------------------------------------------------
=head1 NAME
lib/CPU/Z80/Assembler/Parser.pm view on Meta::CPAN
sub _action_macro_arg_24 {
$_[ARGS][0]->value
}
# macro_args_optional : "[macro_args]?"
sub _action_macro_args_optional_26 {
defined($_[ARGS][0]) ? $_[ARGS][0] : []
}
# macro_body : "{"
sub _action_macro_body_27 {
$_[INPUT]->unget($_[ARGS][0]); # push back starting token
my $macro = CPU::Z80::Assembler::Macro->new();
$macro->parse_body($_[INPUT]);
return $macro;
}
# opcode : bit "[inline_const]" 0 "," "(" iy "+" "[expr_DIS]" ")" "[end]"
sub _action_opcode_100 {
_add_opcode(@_, 0xFD, 0xCB, $_[ARGS][7], 0x46);
}
# opcode : res "[inline_const]" 4 "," "(" iy ")" "," h "[end]"
sub _action_opcode_1000 {
_add_opcode(@_, 0xFD, 0xCB, 0x00, 0xA4);
lib/CPU/Z80/Assembler/Program.pm view on Meta::CPAN
program.
=head2 symbols
Hash of all symbols defined in the program. The key is the symbol name, and
the value is either a scalar for a constant, a L<CPU::Z80::Assembler::Expr|CPU::Z80::Assembler::Expr> for
an expression, or a L<CPU::Z80::Assembler::Opcode|CPU::Z80::Assembler::Opcode> for a label.
=head2 macros
Hash of macro names to L<CPU::Z80::Assembler::Macro|CPU::Z80::Assembler::Macro> objects for all defined macros.
=cut
#------------------------------------------------------------------------------
=head2 parse
$program->parse($input);
Parse the assembly program and collect the opcodes into the object. $input is
t/Macro-error.t view on Meta::CPAN
') };
is $@, "-(5) : error: expected value for macro parameter r2 at \"\\n\"\n",
"Too few arguments";
eval { z80asm('
MACRO HLAGH { NOP }
MACRO HLAGH { NOP }
') };
is $@, "-(3) : error: macro HLAGH redefined at NAME\n",
"Macro redefined";
t/Macro-params.t view on Meta::CPAN
my($bin1, $bin2);
ok $bin1 = z80asm('
MACRO HLAGH {
DEFW ss
LD A, 0
ss
}
HLAGH
'), "Macro without parameters";
ok $bin2 = z80asm('
DEFW ss
LD A, 0
ss
'), "expanded macro";
is $bin1, $bin2, "macro expansion OK";
ok $bin1 = z80asm('
MACRO HLAGH s {
DEFW ss
LD A, s
ss
}
HLAGH C
'), "Macro parameter names don't clash with labels that start with them";
ok $bin2 = z80asm('
DEFW ss
LD A, C
ss
'), "expanded macro";
is $bin1, $bin2, "macro expansion OK";
ok $bin1 = z80asm('
MACRO HLAGH r1,r2 {
DEFW ss
LD r1, r2
ss
}
HLAGH A, C
'), "Macro with 2 parameters";
ok $bin2 = z80asm('
DEFW ss
LD A, C
ss
'), "expanded macro";
is $bin1, $bin2, "macro expansion OK";
ok $bin1 = z80asm('
MACRO HLAGH r1,r2,r3 {
DEFW ss
LD r1, r2
LD r2, r3
ss
}
HLAGH A, C, D
'), "Macro with 3 parameters";
ok $bin2 = z80asm('
DEFW ss
LD A, C
LD C, D
ss
'), "expanded macro";
is $bin1, $bin2, "macro expansion OK";
ok $bin1 = z80asm('
( run in 0.737 second using v1.01-cache-2.11-cpan-49f99fa48dc )