CPU-Z80-Assembler

 view release on metacpan or  search on metacpan

CHANGES  view on Meta::CPAN

	  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

CHANGES  view on Meta::CPAN

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

MANIFEST  view on Meta::CPAN

.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

MANIFEST  view on Meta::CPAN

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 )