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 options
10
11use strict;
12use warnings;
13use File::Slurp;
14use File::Basename;
15use File::Copy;
16use Time::HiRes 'sleep';
17use Capture::Tiny 'capture_merged';
18use Test::Differences;
19use Test::More;
20require './t/test_utils.pl';
21
22my $copyrightmsg = get_copyright()."\n";
23
24#------------------------------------------------------------------------------
25# no arguments
26#------------------------------------------------------------------------------
27unlink_testfiles();
28t_z80asm_capture("", 		$copyrightmsg, 	"", 0);
29
30#------------------------------------------------------------------------------
31# -v
32#------------------------------------------------------------------------------
33my $verbose_text = <<'END';
34Reading library 'z80asm-z80-.lib'
35Predefined constant: __CPU_Z80__ = $0001
36Predefined constant: __CPU_ZILOG__ = $0001
37Assembling 'test.asm' to 'test.o'
38Reading 'test.asm' = 'test.asm'
39Writing object file 'test.o'
40Module 'test' size: 3 bytes
41
42Code size: 3 bytes ($0000 to $0002)
43Creating binary 'test.bin'
44END
45
46unlink_testfiles();
47write_file(asm_file(), " nop \n nop \n nop");
48t_z80asm_capture("-b -s -l -g -v ".asm_file(),
49				$verbose_text, "", 0);
50ok -f o_file();
51ok -f bin_file();
52is read_file(bin_file(), binmode => ':raw'), "\0\0\0";
53
54unlink_testfiles();
55write_file(asm_file(), " nop \n nop \n nop");
56t_z80asm_capture("-b -s -l -g -v ".asm_file(),
57				$verbose_text, "", 0);
58ok -f o_file();
59ok -f bin_file();
60is read_file(bin_file(), binmode => ':raw'), "\0\0\0";
61
62# check no arguments
63t_z80asm_capture("-v=x", 	"", 	<<'ERR', 1);
64Error: illegal option: -v=x
65ERR
66
67t_z80asm_capture("--verbose=x", 	"", 	<<'ERR', 1);
68Error: illegal option: --verbose=x
69ERR
70
71# not verbose
72unlink_testfiles();
73write_file(asm_file(), "nop");
74t_z80asm_capture("-b ".asm_file(), "", "", 0);
75is read_file(bin_file(), binmode => ':raw'), "\0";
76
77# check no arguments
78t_z80asm_capture("-nv=x", 	"", 	<<'ERR', 1);
79Error: illegal option: -nv=x
80ERR
81
82t_z80asm_capture("--not-verbose=x", 	"", 	<<'ERR', 1);
83Error: illegal option: --not-verbose=x
84ERR
85
86#------------------------------------------------------------------------------
87# asm extension
88#------------------------------------------------------------------------------
89for my $file ('test', 'test.asm') {
90	unlink_testfiles();
91	write_file('test.asm', "ret");
92	t_z80asm_capture("-b $file", "", "", 0);
93	is read_file(bin_file(), binary => ':raw'), "\xC9", "assemble ok";
94}
95
96unlink_testfiles();
97write_file('test.xxx', "ret");
98t_z80asm_capture("-b test.xxx", "", "", 0);
99is read_file(bin_file(), binary => ':raw'), "\xC9", "assemble ok";
100
101unlink_testfiles('test.xxx');
102
103#------------------------------------------------------------------------------
104# o extension
105#------------------------------------------------------------------------------
106for my $file ('test', 'test.o') {
107	unlink_testfiles();
108	write_file('test.asm', "ret");
109	t_z80asm_capture("-b $file", "", "", 0);
110	is read_file(bin_file(), binary => ':raw'), "\xC9", "assemble ok";
111
112	unlink(bin_file(), 'test.asm');
113	t_z80asm_capture("-b $file", "", "", 0);
114	is read_file(bin_file(), binary => ':raw'), "\xC9", "assemble ok";
115}
116
117#------------------------------------------------------------------------------
118# -s
119#------------------------------------------------------------------------------
120unlink_testfiles();
121
122my $asm = "
123	PUBLIC main
124main:	ld b,10
125loop:	djnz loop
126	ret
127";
128my $bin = pack("C*",
129	0x06, 10,
130	0x10, -2 & 0xFF,
131	0xC9
132);
133
134# no symbol table
135t_z80asm(
136	asm		=> $asm,
137	bin		=> $bin,
138	options	=> "",
139);
140
141# symbol table
142t_z80asm(
143	asm		=> $asm,
144	bin		=> $bin,
145	options	=> '-s',
146);
147
148#------------------------------------------------------------------------------
149# -l
150#------------------------------------------------------------------------------
151unlink_testfiles();
152
153$asm = "
154	PUBLIC main
155main:	ld b,10
156loop:	djnz loop
157	ret
158";
159$bin = pack("C*",
160	0x06, 10,
161	0x10, -2 & 0xFF,
162	0xC9
163);
164
165# no list
166t_z80asm(
167	asm		=> $asm,
168	bin		=> $bin,
169	options	=> "",
170	nolist	=> 1,
171);
172
173
174# list file
175t_z80asm(
176	asm		=> $asm,
177	bin		=> $bin,
178	options	=> '-l',
179	nolist	=> 1,
180);
181
182#------------------------------------------------------------------------------
183# -g
184#------------------------------------------------------------------------------
185$asm = "
186	PUBLIC main, x31_x31_x31_x31_x31_x31_x31_x31, x_32_x32_x32_x32_x32_x32_x32_x32
187main: ld b,10
188loop: djnz loop
189	PUBLIC last
190last:
191x31_x31_x31_x31_x31_x31_x31_x31: defb 0
192x_32_x32_x32_x32_x32_x32_x32_x32: defb 0
193";
194my $asm2 = "
195
196	; show DEFC alias in map file
197	PUBLIC alias_main
198	EXTERN main
199	defc alias_main = main
200
201	PUBLIC alias_last
202	EXTERN last
203	defc alias_last = last
204
205	PUBLIC func
206func: ret
207";
208$bin = "\x06\x0A\x10\xFE\x00\x00\xC9";
209
210# no -g
211t_z80asm(
212	asm		=> $asm,
213	asm2	=> $asm2,
214	bin		=> $bin,
215	options	=> "",
216);
217ok ! -f def_file(), "no ".def_file();
218
219# -g
220t_z80asm(
221	asm		=> $asm,
222	asm2	=> $asm2,
223	bin		=> $bin,
224	options	=> '-g',
225);
226ok -f def_file(), def_file();
227is_text( scalar(read_file(def_file())), <<'END', "deffile contents" );
228DEFC main                            = $0000
229DEFC x31_x31_x31_x31_x31_x31_x31_x31 = $0004
230DEFC x_32_x32_x32_x32_x32_x32_x32_x32 = $0005
231DEFC last                            = $0004
232DEFC alias_main                      = $0000
233DEFC alias_last                      = $0004
234DEFC func                            = $0006
235END
236
237#------------------------------------------------------------------------------
238# -b
239#------------------------------------------------------------------------------
240
241# no -b
242unlink_testfiles();
243write_file(asm_file(), "nop");
244
245t_z80asm_capture(asm_file(), "", "", 0);
246ok -f o_file();
247ok ! -f bin_file();
248
249# -b
250unlink_testfiles();
251write_file(asm_file(), "nop");
252
253t_z80asm_capture("-b ".asm_file(), "", "", 0);
254ok -f o_file();
255ok -f bin_file();
256is read_file(bin_file(), binmode => ':raw'), "\0";
257
258#------------------------------------------------------------------------------
259# -o
260#------------------------------------------------------------------------------
261$bin = bin_file(); $bin =~ s/\.bin$/2.bin/i;
262
263# no -o
264unlink_testfiles($bin);
265write_file(asm_file(), "nop");
266
267t_z80asm_capture("-b ".asm_file(), "", "", 0);
268ok -f bin_file();
269ok ! -f $bin;
270t_binary(read_file(bin_file(), binmode => ':raw'), "\0");
271
272# -o
273unlink_testfiles($bin);
274write_file(asm_file(), "nop");
275
276t_z80asm_capture("-b -o$bin ".asm_file(), "", "", 0);
277ok ! -f bin_file();
278ok -f $bin;
279t_binary(read_file($bin, binmode => ':raw'), "\0");
280
281# test -o with environment variables
282$ENV{TEST_ENV} = '2.bin';
283unlink_testfiles($bin);
284write_file(asm_file(), "nop");
285t_z80asm_capture('-b "-otest${TEST_ENV}" '.asm_file(), "", "", 0);
286ok ! -f bin_file();
287ok -f $bin;
288t_binary(read_file($bin, binmode => ':raw'), "\0");
289
290delete $ENV{TEST_ENV};
291unlink_testfiles($bin);
292write_file(asm_file(), "nop");
293t_z80asm_capture('-b "-otest${TEST_ENV}2.bin" '.asm_file(), "", "", 0);
294ok ! -f bin_file();
295ok -f $bin;
296t_binary(read_file($bin, binmode => ':raw'), "\0");
297
298unlink_testfiles($bin);
299
300#------------------------------------------------------------------------------
301# -d
302#------------------------------------------------------------------------------
303
304# first compiles; second skips
305unlink_testfiles();
306write_file(asm_file(), "nop");
307
308t_z80asm_capture("-d ".asm_file(), "", "", 0);
309is substr(read_file(o_file(), binmode => ':raw'), -5, 5), "\0\xFF\xFF\xFF\xFF";
310
311my $date_obj = -M o_file();
312
313# now skips compile
314sleep 0.500;		# make sure our obj is older
315t_z80asm_capture("-d ".asm_file(), "", "", 0);
316is substr(read_file(o_file(), binmode => ':raw'), -5, 5), "\0\xFF\xFF\xFF\xFF";
317
318ok(abs((-M o_file()) - $date_obj) < 0.001);	# same object
319
320# touch source
321sleep 0.500;		# make sure our obj is older
322write_file(asm_file(), "nop");
323t_z80asm_capture("-d ".asm_file(), "", "", 0);
324is substr(read_file(o_file(), binmode => ':raw'), -5, 5), "\0\xFF\xFF\xFF\xFF";
325
326ok(abs((-M o_file()) - $date_obj) > 0);	# new object
327
328# remove source, give -d -> uses existing object - with extensiom
329unlink asm_file();
330$date_obj = -M o_file();
331t_z80asm_capture("-d ".asm_file(), "", "", 0);
332is substr(read_file(o_file(), binmode => ':raw'), -5, 5), "\0\xFF\xFF\xFF\xFF";
333is -M o_file(), $date_obj;	# new object
334
335# remove source, give -d -> uses existing object - without extensiom
336unlink asm_file();
337$date_obj = -M o_file();
338my $base = asm_file(); $base =~ s/\.\w+$//;
339t_z80asm_capture("-d $base", "", "", 0);
340is substr(read_file(o_file(), binmode => ':raw'), -5, 5), "\0\xFF\xFF\xFF\xFF";
341is -M o_file(), $date_obj;	# new object
342
343
344#------------------------------------------------------------------------------
345# -r
346#------------------------------------------------------------------------------
347
348# -r
349for my $origin (0, 0x1234) {
350	my $origin_hex = sprintf("%x", $origin);
351	for my $origin_text ($origin, "0x${origin_hex}", "0X${origin_hex}", "0${origin_hex}h", "0${origin_hex}H", "\$${origin_hex}") {
352		z80asm(
353			options	=> "-b -r".$origin_text,
354			asm		=> "start: jp start",
355			bin		=> "\xC3" . pack("v", $origin),
356		);
357	}
358}
359
360# option out of range
361for my $origin (-1, 0x10000) {
362	z80asm(
363		options	=> "-b -r$origin",
364		asm		=> "start: jp start",
365		error	=> "Error: integer '$origin' out of range",
366	);
367}
368z80asm(
369	options	=> "-b -r123Z",
370	asm		=> "start: jp start",
371	error	=> "Error: invalid origin (-r) option '123Z'",
372);
373
374#------------------------------------------------------------------------------
375# -R - tested in reloc.t
376
377#------------------------------------------------------------------------------
378# -mz80
379#------------------------------------------------------------------------------
380
381t_z80asm_ok(0, "halt", "\x76");
382t_z80asm_ok(0, "halt", "\x76", "-mz80");
383
384#------------------------------------------------------------------------------
385# -mz80n
386#------------------------------------------------------------------------------
387
388t_z80asm_ok(0, "swapnib", "\xED\x23", "-mz80n");
389
390#------------------------------------------------------------------------------
391# -mz180
392#------------------------------------------------------------------------------
393
394t_z80asm_ok(0, "slp", "\xED\x76", "-mz180");
395
396#------------------------------------------------------------------------------
397# -mr2k
398#------------------------------------------------------------------------------
399
400t_z80asm_ok(0, "ex (sp),hl", "\xE3");
401t_z80asm_ok(0, "ex (sp),hl", "\xED\x54", "-mr2k");
402
403#------------------------------------------------------------------------------
404# -mr3k
405#------------------------------------------------------------------------------
406
407t_z80asm_ok(0, "push su", "\xED\x66", "-mr3k");
408
409#------------------------------------------------------------------------------
410# -mti83
411#------------------------------------------------------------------------------
412
413t_z80asm_ok(0, "invoke 0x1234", "\xCD\x34\x12");
414t_z80asm_ok(0, "invoke 0x1234", "\xCD\x34\x12", "-mti83");
415
416#------------------------------------------------------------------------------
417# -mti83plus
418#------------------------------------------------------------------------------
419
420t_z80asm_ok(0, "invoke 0x1234", "\xEF\x34\x12", "-mti83plus");
421
422#------------------------------------------------------------------------------
423# -IXIY
424#------------------------------------------------------------------------------
425
426t_z80asm_ok(0, "ld ix,0x1234", "\xDD\x21\x34\x12");
427t_z80asm_ok(0, "ld ix,0x1234", "\xFD\x21\x34\x12", "-IXIY");
428
429t_z80asm_ok(0, "ld iy,0x1234", "\xFD\x21\x34\x12");
430t_z80asm_ok(0, "ld iy,0x1234", "\xDD\x21\x34\x12", "-IXIY");
431
432#------------------------------------------------------------------------------
433
434#------------------------------------------------------------------------------
435# -I - tested in directives.t
436#------------------------------------------------------------------------------
437
438#------------------------------------------------------------------------------
439# -L
440#------------------------------------------------------------------------------
441
442# create library
443my $lib = 't/data/'.basename(lib_file());
444my $lib_base = basename($lib);
445my $lib_dir  = dirname($lib);
446
447write_file(asm_file(), "PUBLIC main \n main: ret ");
448t_z80asm_capture("-x".$lib." ".asm_file(), "", "", 0);
449ok -f $lib;
450
451$asm = "EXTERN main \n call main \n ret";
452$bin = "\xCD\x04\x00\xC9\xC9";
453
454# no -L, full path : OK
455t_z80asm_ok(0, $asm, $bin, "-l".$lib);
456
457# no -L, only file name : error
458write_file(asm_file(), $asm);
459t_z80asm_capture("-l".$lib_base." ".asm_file(), "",
460		"Error: cannot read file 'test.lib'\n", 1);
461
462# -L : OK
463t_z80asm_ok(0, $asm, $bin, "-L$lib_dir -l$lib_base");
464
465# use environment variable in -L
466$ENV{TEST_ENV} = 'data';
467t_z80asm_ok(0, $asm, $bin, '"-Lt/${TEST_ENV}" -l'.$lib_base);
468
469delete $ENV{TEST_ENV};
470t_z80asm_ok(0, $asm, $bin, '"-Lt/da${TEST_ENV}ta" -l'.$lib_base);
471
472unlink_testfiles($lib);
473
474#------------------------------------------------------------------------------
475# -D
476#------------------------------------------------------------------------------
477
478$asm = "ld a,_value23";		# BUG_0045
479
480# no -D
481t_z80asm_error($asm, "Error at file 'test.asm' line 1: symbol '_value23' not defined");
482
483# invalid -D
484for my $options ('-D23', quote_os('-Da*')) {		# quote because of '*'
485	write_file(asm_file(), "");
486	t_z80asm_capture("$options ".asm_file(), "",
487					"Error: illegal identifier\n", 1);
488}
489
490for my $options ('aaa=', 'aaa=a', 'aaa=!', 'aaa=1x') {
491	write_file(asm_file(), "");
492	t_z80asm_capture("-D${options} ".asm_file(), "",
493					"Error: invalid -DVAR=VAL option '${options}'\n", 1);
494}
495
496# -D
497t_z80asm_ok(0, $asm, "\x3E\x01", "-D_value23");
498
499# -Dvar=value
500for my $value (255, "0xff", "0XFF", "0ffh", "0FFH", "\$FF") {
501	t_z80asm_ok(0, $asm, "\x3E\xFF", quote_os("-D_value23=${value}"));		# quote because of '$'
502}
503
504# -D with environment variables
505$ENV{TEST_ENV} = 'value';
506t_z80asm_ok(0, $asm, "\x3E\x01", '"-D=_${TEST_ENV}23"');
507
508$ENV{TEST_ENV} = '127';
509t_z80asm_ok(0, $asm, "\x3E\x7f", '"-D=_value23=${TEST_ENV}"');
510
511delete $ENV{TEST_ENV};
512t_z80asm_ok(0, $asm, "\x3E\x01", '"-D=_value${TEST_ENV}23"');
513
514#------------------------------------------------------------------------------
515# -l, -x
516#------------------------------------------------------------------------------
517
518unlink_testfiles();
519
520# create a lib name that is not removed by unlink_testfiles()
521$lib = lib_file(); $lib =~ s/\.lib$/_lib.lib/i;
522unlink $lib;
523
524# create a library
525write_file(asm_file(), "
526	PUBLIC one
527one:
528	ld a,1
529	ret
530");
531
532unlink(o_file(), lib_file());
533t_z80asm_capture('-x'.lib_file()." ".asm_file(), "", "", 0);
534ok -f o_file(), o_file()." created";
535ok -f lib_file(), lib_file()." created";
536
537# create $lib
538ok copy(lib_file(), $lib), "create $lib";
539unlink(o_file(), lib_file());
540
541# link with the library
542t_z80asm_ok(0, "
543	EXTERN one
544	jp one
545", "\xC3\x03\x00\x3E\x01\xC9", "-l$lib");
546
547unlink_testfiles($lib);
548
549# test BUG_0038: library modules not loaded in sequence
550# obj1 requires libobj7 and obj3;
551# obj2 requires libobj6 and obj3;
552# obj3 requires libobj5 and obj1;
553# libobj5 requires libobj6;
554# libobj6 requires libobj7;
555# libobj7 requires libobj5;
556unlink_testfiles();
557write_file(asm_file(),  "PUBLIC A1 \n EXTERN A3 \n EXTERN A7 \n A1: defb 1,A7,A3");	# A1 at addr 0, len 3
558write_file(asm2_file(), "PUBLIC A2 \n EXTERN A3 \n EXTERN A6 \n A2: defb 2,A6,A3");	# A2 at addr 3, len 3
559write_file(asm3_file(), "PUBLIC A3 \n EXTERN A1 \n EXTERN A5 \n A3: defb 3,A5,A1");	# A3 at addr 6, len 3
560
561write_file(asm5_file(), "PUBLIC A5 \n EXTERN A6 \n A5: defb 5,A6");					# A5 at addr 9, len 2
562write_file(asm6_file(), "PUBLIC A6 \n EXTERN A7 \n A6: defb 6,A7");					# A6 at addr 11, len 2
563write_file(asm7_file(), "PUBLIC A7 \n EXTERN A5 \n A7: defb 7,A5");					# A7 at addr 13, len 2
564
565t_z80asm_capture("-x".lib5_file()." ".asm5_file(), "", "", 0);
566ok -f lib5_file();
567t_z80asm_capture("-x".lib6_file()." ".asm6_file(), "", "", 0);
568ok -f lib6_file();
569t_z80asm_capture("-x".lib7_file()." ".asm7_file(), "", "", 0);
570ok -f lib7_file();
571
572t_z80asm_capture("-l -m -b -l".lib5_file()." -l".lib6_file()." -l".lib7_file()." ".
573				 asm_file()." ".asm2_file()." ".asm3_file(), "", "", 0);
574ok -f bin_file();
575t_binary(read_binfile(bin_file()),
576		pack("C*",
577				1, 13, 6,
578				2, 11, 6,
579				3,  9, 0,
580				5, 11,
581				6, 13,
582				7,  9,
583			));
584
585unlink_testfiles();
586write_file(asm_file(),  " EXTERN abs \n call abs\n");
587write_file(asm2_file(), " PUBLIC abs \nabs: ld a,1\n ret\n");
588
589write_file(asm5_file(), " PUBLIC abs \nabs: ld a,2\n ret\n");
590
591t_z80asm_capture("-x".lib5_file()." ".asm5_file(), "", "", 0);
592ok -f lib5_file();
593
594t_z80asm_capture("-l -m -b -l".lib5_file()." ".asm_file()." ".asm2_file(), "", "", 0);
595ok -f bin_file();
596t_binary(read_binfile(bin_file()),
597		pack("C*",
598				0xCD, 3, 0,
599				0x3E, 1,
600				0xC9
601			));
602unlink_testfiles();
603
604
605# test BUG_0039: library not pulled in if PUBLIC symbol not referenced in expression
606unlink_testfiles();
607
608write_file(asm_file(),  "EXTERN A51 \n defb A51");
609
610write_file(asm5_file(), "PUBLIC A5 \n PUBLIC A51 \n A5: \n defc A51 = 51");
611
612t_z80asm_capture("-x".lib5_file()." ".asm5_file(), "", "", 0);
613ok -f lib5_file();
614
615t_z80asm_capture("-l -m -b -l".lib5_file()." ".asm_file(), "", "", 0);
616ok -f bin_file();
617t_binary(read_binfile(bin_file()), pack("C*", 51 ));
618
619
620# link objects and libs
621# library modules are loaded in alpha-sequence of labels, starting at 10
622unlink_testfiles();
623write_file(asm1_file(), "PUBLIC A1 \n A1: defb 1");
624write_file(asm2_file(), "PUBLIC A2 \n A2: defb 2");
625write_file(asm3_file(), "PUBLIC A3 \n A3: defb 3");
626t_z80asm_capture("-x".lib1_file()." ".asm1_file()." ".asm2_file()." ".asm3_file(), "", "", 0);
627ok -f lib1_file();
628
629write_file(asm4_file(), "PUBLIC A4 \n A4: defb 4");
630write_file(asm5_file(), "PUBLIC A5 \n A5: defb 5");
631write_file(asm6_file(), "PUBLIC A6 \n A6: defb 6");
632t_z80asm_capture("-x".lib2_file()." ".asm4_file()." ".asm5_file()." ".asm6_file(), "", "", 0);
633ok -f lib2_file();
634
635write_file(asm_file(),  "A0: \n ".
636						"EXTERN  A1,A2,A3,A4,A5,A6 \n EXTERN A7,A8,A9 \n ".
637						"defb A1,A2,A3,A4,A5,A6,        A7,A8,A9 \n ".
638						"defb 0 \n");
639write_file(asm7_file(), "PUBLIC A7 \n A7: defb 7");
640write_file(asm8_file(), "PUBLIC A8 \n A8: defb 8");
641write_file(asm9_file(), "PUBLIC A9 \n A9: defb 9");
642t_z80asm_capture("-l -b -l".lib1_file()." -l".lib2_file()." ".
643				 asm_file()." ".asm7_file()." ".asm8_file()." ".asm9_file(), "", "", 0);
644ok -f bin_file();
645my $binary = read_file(bin_file(), binmode => ':raw', err_mode => 'quiet');
646t_binary($binary, pack("C*",
647						13, 14, 15, 16, 17, 18, 10, 11, 12,
648						0,
649						7, 8, 9, 1, 2, 3, 4, 5, 6,
650						));
651
652# PUBLIC and EXTERN
653unlink_testfiles();
654
655write_file(asm1_file(), "
656	PUBLIC func_1
657	PUBLIC func_2
658func_1:
659	ld a,1
660func_2:
661	ld a,2
662	ret
663");
664
665write_file(asm2_file(), "
666	EXTERN  func_2
667	call func_2
668	ret
669");
670
671# link object files
672t_z80asm_capture("-b ".asm2_file()." ".asm1_file(), "", "", 0);
673t_binary(read_binfile(bin2_file()), "\xCD\x06\x00\xC9\x3E\x01\x3E\x02\xC9");
674
675# link library files
676t_z80asm_capture("-x".lib1_file()." ".asm1_file(), "", "", 0);
677t_z80asm_capture("-b -l".lib1_file()." ".asm2_file(), "", "", 0);
678t_binary(read_binfile(bin2_file()), "\xCD\x06\x00\xC9\x3E\x01\x3E\x02\xC9");
679
680#------------------------------------------------------------------------------
681# -split-bin, ORG -1: tested in directives.t
682
683
684#------------------------------------------------------------------------------
685# -mz180
686t_z80asm_ok(0, "
687	slp
688
689	mlt bc
690	mlt de
691	mlt hl
692	mlt sp
693
694	in0 b,(10)
695	in0 c,(11)
696	in0 d,(12)
697	in0 e,(13)
698	in0 h,(14)
699	in0 l,(15)
700	in0 f,(16)
701	in0 a,(17)
702
703	out0 (10),b
704	out0 (11),c
705	out0 (12),d
706	out0 (13),e
707	out0 (14),h
708	out0 (15),l
709	out0 (17),a
710
711	otim
712	otimr
713	otdm
714	otdmr
715
716	tstio 23
717
718	tst a,b
719	tst a,c
720	tst a,d
721	tst a,e
722	tst a,h
723	tst a,l
724	tst a,(hl)
725	tst a,a
726	tst a,23
727
728	tst b
729	tst c
730	tst d
731	tst e
732	tst h
733	tst l
734	tst (hl)
735	tst a
736	tst 23
737
738	test a,b
739	test a,c
740	test a,d
741	test a,e
742	test a,h
743	test a,l
744	test a,(hl)
745	test a,a
746	test a,23
747
748	test b
749	test c
750	test d
751	test e
752	test h
753	test l
754	test (hl)
755	test a
756	test 23
757
758", pack("C*",
759	0xED, 0x76,		# slp
760
761	0xED, 0x4C, 	# mlt
762	0xED, 0x5C,
763	0xED, 0x6C,
764	0xED, 0x7C,
765
766	0xED, 0x00, 10,	# in0
767	0xED, 0x08, 11,
768	0xED, 0x10, 12,
769	0xED, 0x18, 13,
770	0xED, 0x20, 14,
771	0xED, 0x28, 15,
772	0xED, 0x30, 16,
773	0xED, 0x38, 17,
774
775	0xED, 0x01, 10,	# out0
776	0xED, 0x09, 11,
777	0xED, 0x11, 12,
778	0xED, 0x19, 13,
779	0xED, 0x21, 14,
780	0xED, 0x29, 15,
781	0xED, 0x39, 17,
782
783	0xED, 0x83,		# otxx
784	0xED, 0x93,
785	0xED, 0x8B,
786	0xED, 0x9B,
787
788	0xED, 0x74, 23,	# tstio
789
790	0xED, 0x04,		# tst
791	0xED, 0x0C,
792	0xED, 0x14,
793	0xED, 0x1C,
794	0xED, 0x24,
795	0xED, 0x2C,
796	0xED, 0x34,
797	0xED, 0x3C,
798	0xED, 0x64, 23,
799
800	0xED, 0x04,		# tst
801	0xED, 0x0C,
802	0xED, 0x14,
803	0xED, 0x1C,
804	0xED, 0x24,
805	0xED, 0x2C,
806	0xED, 0x34,
807	0xED, 0x3C,
808	0xED, 0x64, 23,
809
810	0xED, 0x04,		# test
811	0xED, 0x0C,
812	0xED, 0x14,
813	0xED, 0x1C,
814	0xED, 0x24,
815	0xED, 0x2C,
816	0xED, 0x34,
817	0xED, 0x3C,
818	0xED, 0x64, 23,
819
820	0xED, 0x04,		# test
821	0xED, 0x0C,
822	0xED, 0x14,
823	0xED, 0x1C,
824	0xED, 0x24,
825	0xED, 0x2C,
826	0xED, 0x34,
827	0xED, 0x3C,
828	0xED, 0x64, 23,
829
830), "-mz180");
831
832t_z80asm_error("slp			", "Error at file 'test.asm' line 1: illegal identifier");
833t_z80asm_error("mlt bc		", "Error at file 'test.asm' line 1: illegal identifier");
834t_z80asm_error("in0 b,(10)	", "Error at file 'test.asm' line 1: illegal identifier");
835t_z80asm_error("out0 (10),b	", "Error at file 'test.asm' line 1: illegal identifier");
836t_z80asm_error("otim		", "Error at file 'test.asm' line 1: illegal identifier");
837t_z80asm_error("otimr		", "Error at file 'test.asm' line 1: illegal identifier");
838t_z80asm_error("otdm		", "Error at file 'test.asm' line 1: illegal identifier");
839t_z80asm_error("otdmr		", "Error at file 'test.asm' line 1: illegal identifier");
840t_z80asm_error("tstio 23	", "Error at file 'test.asm' line 1: illegal identifier");
841t_z80asm_error("tst b		", "Error at file 'test.asm' line 1: illegal identifier");
842
843#------------------------------------------------------------------------------
844# -mr2k
845t_z80asm_ok(0, "
846	altd ld a,31
847	ioi ld a,(0xFE)
848	ioe ld a,(0xFE)
849
850", pack("C*",
851	0x76, 0x3E, 0x1F,
852	0xD3, 0x3A, 0xFE, 0x00,
853	0xDB, 0x3A, 0xFE, 0x00,
854
855), "-mr2k");
856
857# __CPU_xxx_contants___
858#------------------------------------------------------------------------------
859write_file("test.asm", <<END);
860	if __CPU_Z80__
861	defb 1
862	else
863	if __CPU_Z80N__
864	defb 2
865	else
866	if __CPU_Z180__
867	defb 3
868	else
869	if __CPU_R2K__
870	defb 4
871	else
872	if __CPU_R3K__
873	defb 5
874	else
875	defb 6
876	endif
877	endif
878	endif
879	endif
880	endif
881END
882
883unlink "test.bin";
884t_z80asm_capture('-b test.asm', "", "", 0);
885t_binary(read_binfile("test.bin"), "\1");
886
887unlink "test.bin";
888t_z80asm_capture('-mz80 -b test.asm', "", "", 0);
889t_binary(read_binfile("test.bin"), "\1");
890
891unlink "test.bin";
892t_z80asm_capture('-mz80n -b test.asm', "", "", 0);
893t_binary(read_binfile("test.bin"), "\2");
894
895unlink "test.bin";
896t_z80asm_capture('-mz180 -b test.asm', "", "", 0);
897t_binary(read_binfile("test.bin"), "\3");
898
899unlink "test.bin";
900t_z80asm_capture('-mr2k -b test.asm', "", "", 0);
901t_binary(read_binfile("test.bin"), "\4");
902
903unlink "test.bin";
904t_z80asm_capture('-mr3k -b test.asm', "", "", 0);
905t_binary(read_binfile("test.bin"), "\5");
906
907#------------------------------------------------------------------------------
908# --
909#------------------------------------------------------------------------------
910write_file("-test.asm", "nop");
911t_z80asm_capture("-b -test.asm", "", <<END, 1);
912Error: illegal option: -test.asm
913END
914t_z80asm_capture("-b -- -test.asm", "", "", 0);
915t_binary(read_binfile("-test.bin"), "\x00");
916unlink(<-test.*>);
917
918unlink_testfiles();
919done_testing();
920
921sub quote_os {
922	my($txt) = @_;
923	if ($^O eq 'MSWin32') {
924		return '"'.$txt.'"';
925	}
926	else {
927		return "'".$txt."'";
928	}
929}
930