1#!/usr/bin/perl
2
3# Z88DK Z80 Macro Assembler
4#
5# Copyright (C) Paulo Custodio, 2011-2020
6# License: The Artistic License 2.0, http://www.perlfoundation.org/artistic_license_2_0
7# Repository: https://github.com/z88dk/z88dk/
8#
9# Test https://github.com/z88dk/z88dk/issues/885
10# z80asm: bug in application of all operators in defined constants in some circumstances
11
12use Modern::Perl;
13use Test::More;
14use Path::Tiny;
15require './t/testlib.pl';
16
17my $got_zsdcc = `which zsdcc 2> /dev/null`;
18
19my $c_code = <<'END';
20void main(void)
21{
22__asm
23ici:
24    DEFC toto = ici %8
25__endasm;
26}
27END
28
29for my $clib ('sdcc_iy',		# zsdcc compile
30	          'new',			# sccz80 compile
31) {
32    if ($clib eq 'sdcc_iy' && !$got_zsdcc) {
33        diag("zsdcc not found, test skipped");
34    }
35    else {
36        ok 1, "-clib=$clib";
37
38        unlink_testfiles();
39        spew("test.c", $c_code);
40        run("zcc +zx -vn -clib=$clib -m --list test.c -o test");
41        test_map("test.map");
42    }
43}
44
45# core of the problem
46my $org = 100;
47unlink_testfiles();
48spew("test.asm", <<'END');
49._main
50ici:
51    DEFC toto = ici %8
52    defw _main, ici, toto
53END
54run("z80asm -m -b -r$org test.asm");
55check_bin_file("test.bin", pack("v*", $org, $org, $org % 8));
56test_map("test.map");
57
58unlink_testfiles();
59done_testing();
60
61sub read_map {
62    my($map_file) = @_;
63    ok -f $map_file, $map_file;
64    my %map;
65    for (path($map_file)->lines) {
66	/^(ici|toto|_main)\s*=\s*\$([0-9A-F]{4,})\b/ and $map{$1} = hex($2);
67    }
68    return %map;
69}
70
71sub test_map {
72    my($map_file) = @_;
73    my %map = read_map($map_file);
74    ok $map{ici}==$map{_main}, "$map{ici}==$map{_main}";
75    ok $map{toto}==$map{ici} % 8, "$map{toto}==$map{ici} % 8";
76}
77