test65 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +5 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +159 -0
- data/asminc/test65.i65 +87 -0
- data/cfg/test65.cfg +37 -0
- data/exe/test65 +6 -0
- data/help.txt +24 -0
- data/lib/test65.rb +50 -0
- data/lib/test65/build_file_list.rb +37 -0
- data/lib/test65/enclosures/ca65.rb +35 -0
- data/lib/test65/enclosures/ld65.rb +46 -0
- data/lib/test65/enclosures/sim65.rb +23 -0
- data/lib/test65/enclosures/utils.rb +26 -0
- data/lib/test65/host.rb +13 -0
- data/lib/test65/perform_test.rb +45 -0
- data/lib/test65/process_args.rb +66 -0
- data/lib/test65/process_files.rb +48 -0
- data/lib/test65/process_path.rb +36 -0
- data/lib/test65/std_path.rb +15 -0
- data/lib/test65/version.rb +5 -0
- data/rakefile.rb +16 -0
- data/t65/asm_err.a65 +12 -0
- data/t65/callee.a65 +14 -0
- data/t65/caller.a65 +17 -0
- data/t65/foo.txt +3 -0
- data/t65/linker_err.a65 +13 -0
- data/t65/macro_err1.a65 +11 -0
- data/t65/macro_err2.a65 +12 -0
- data/t65/min_fail.a65 +12 -0
- data/t65/min_pass.a65 +12 -0
- data/t65/min_pass.rb +9 -0
- data/t65/pass.a65 +10 -0
- data/t65/t65_min_pass.rb +9 -0
- data/t65/t65_test_cfg.a65 +13 -0
- data/t65/t65_test_macros.a65 +37 -0
- data/t65/t65_two_files.rb +10 -0
- data/test65.gemspec +31 -0
- metadata +140 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fb249a06581fa2e69553600dc88ec52b620db6d5
|
4
|
+
data.tar.gz: cdbc6072308051d64c07c61e0c9d07ded8319b2e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cca5d442da99eb33a2fcc40f40029e4981e03fddeb037cb7b1e8b5123235b2725e0bc40a4e9927e9bb394827535048b9e5ad7d93ad360e25f99cfba2517ddc59
|
7
|
+
data.tar.gz: fdb97d5bbe8f9c7671904ab4591749740e2860d544416a04e269d13a5caac869da6c3173997d7b756b2db21b6ec0ff2ccd8cfed7fd75a7834b164514e2c5fd01
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at peter.c.camilleri@gmail.com. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2019 PeterCamilleri
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,159 @@
|
|
1
|
+
# Test65
|
2
|
+
|
3
|
+
This is a simple program written to allow the testing of 65C02 code that
|
4
|
+
I am writing for the Commander X 16 neo-retro computer.
|
5
|
+
|
6
|
+
Note: This program has recently undergone a lot of upgrades and is now ready
|
7
|
+
to release as a Ruby gem.
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
To install, first install the cc65 compiler and ensure that it is available at
|
12
|
+
the command line. You can test the required components with:
|
13
|
+
|
14
|
+
ca65 --version
|
15
|
+
ld65 --version
|
16
|
+
sim65 --version
|
17
|
+
set CC65_HOME
|
18
|
+
|
19
|
+
Then to install the gem, use:
|
20
|
+
|
21
|
+
$ gem install test65
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
test65 - Run tests of 65c02 assembler code.
|
26
|
+
|
27
|
+
Usage: test65 {options} {files}
|
28
|
+
|
29
|
+
Options:
|
30
|
+
--debug, -d Show (really) detailed debug info. Not normally required.
|
31
|
+
--help, -h, -? Display this message and exit.
|
32
|
+
--list, -l Generate list files for each test.
|
33
|
+
--map, -m Generate map files for each test.
|
34
|
+
--keep, -k Keep object and output files. Do not clean up.
|
35
|
+
--path, -p Specify the path to the test files. (Only 1 allowed)
|
36
|
+
--quiet, -q Hide messages. Used to keep the test65 tests clean.
|
37
|
+
--verbose, -v Display lots of useful progress info.
|
38
|
+
--version Display the program version and exit.
|
39
|
+
|
40
|
+
Files: An optional list of test files.
|
41
|
+
|
42
|
+
Notes:
|
43
|
+
- By default, test files are located in a folder called "t65" in the current
|
44
|
+
folder or one of its parent folders.
|
45
|
+
- Wildcards are allowed for files but not the path.
|
46
|
+
- If no files are specified, then all files matching "t65*.a65" or "t65*.rb"
|
47
|
+
in the test folder are tested.
|
48
|
+
- If files are specified, only the specified file(s) are tested.
|
49
|
+
|
50
|
+
## Test Files
|
51
|
+
|
52
|
+
The test65 utility finds test files in one of two ways:
|
53
|
+
|
54
|
+
1. The test files can be listed explicitly on the command line.
|
55
|
+
2. Test files, of the appropriate extension, located in the test folder, are
|
56
|
+
"batch" run.
|
57
|
+
|
58
|
+
The tests are located in a test folder. This can be:
|
59
|
+
|
60
|
+
1. Explicitly named using the --path option. (See above)
|
61
|
+
2. Located in the t65 folder, either off of the current folder, or one of
|
62
|
+
its parent folders.
|
63
|
+
|
64
|
+
Test files can be:
|
65
|
+
|
66
|
+
1. Assembly files with a suffix of ".a65".
|
67
|
+
2. Ruby script files with a suffix of ".rb".
|
68
|
+
|
69
|
+
Future versions may support alternate extension types for assembler (like
|
70
|
+
".asm" for example) and tests written in the "C" language with extensions
|
71
|
+
of ".c65" and maybe ".c".
|
72
|
+
|
73
|
+
## Test Scripts in Ruby
|
74
|
+
|
75
|
+
The test65 gem uses Ruby scripts to allow for cases not handled by the
|
76
|
+
conventional defaults. The basic form of these scripts is:
|
77
|
+
|
78
|
+
```
|
79
|
+
# Minimum script to pass a test.
|
80
|
+
|
81
|
+
Test65.script do
|
82
|
+
ca65 "min_pass.a65"
|
83
|
+
ld65
|
84
|
+
sim65
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
The order matters and is:
|
89
|
+
|
90
|
+
assembly and compiling then linking then simulation
|
91
|
+
|
92
|
+
If the order is wrong, there will be errors.
|
93
|
+
|
94
|
+
### Assembly
|
95
|
+
|
96
|
+
Code is assembled using the _ca65_ statement. It is supported by the
|
97
|
+
_ca65\_inc\_paths_ method. They are:
|
98
|
+
|
99
|
+
```
|
100
|
+
ca65_inc_paths <path>, <optional more paths>, <etc>, <etc>, <etc>
|
101
|
+
ca65 "source_file", "optional options"
|
102
|
+
```
|
103
|
+
|
104
|
+
Where _ca65\_inc\_paths_ is used to tell the assembler where to find included
|
105
|
+
files and _ca65_ does the work of converting the source file to an
|
106
|
+
object file.
|
107
|
+
|
108
|
+
### Linking
|
109
|
+
|
110
|
+
Code is linked using the _ld65_ statement. It is supported by the
|
111
|
+
_ld65\_lib\_paths_ and _ld65\_libraries_. Here they are:
|
112
|
+
|
113
|
+
```
|
114
|
+
ld65_lib_paths "path to libraries", <etc>, <etc>, <etc>
|
115
|
+
ld65_libraries "library", <etc>, <etc>, <etc>
|
116
|
+
ld65 "optional options"
|
117
|
+
```
|
118
|
+
|
119
|
+
Where _ld65\_lib\_paths_ tells the linker where to find library files and
|
120
|
+
_ld65\_libraries_ specifies those libraries. After any ld65 method, no further
|
121
|
+
ca65* methods are permitted. After _ld65_ no further ld65* methods are
|
122
|
+
permitted either.
|
123
|
+
|
124
|
+
### Simulation
|
125
|
+
|
126
|
+
Finally, the simulation phase runs the actual tests. This is simply:
|
127
|
+
|
128
|
+
```
|
129
|
+
sim65 "optional options"
|
130
|
+
```
|
131
|
+
|
132
|
+
When this is done, no further test statements are permitted. However it is
|
133
|
+
possible to perform multiple tests in one script file. Simply code
|
134
|
+
multiple Test65.script { ... } blocks in the one Ruby script file. They
|
135
|
+
will be run one after another, in order.
|
136
|
+
|
137
|
+
## Contributing
|
138
|
+
1. Fork it
|
139
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
140
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
141
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
142
|
+
5. Create new Pull Request
|
143
|
+
|
144
|
+
OR...
|
145
|
+
|
146
|
+
* Make a suggestion by raising an
|
147
|
+
[issue](https://github.com/PeterCamilleri/test65/issues)
|
148
|
+
. All ideas and comments are welcome.
|
149
|
+
|
150
|
+
## License
|
151
|
+
|
152
|
+
The gem is available as open source under the terms of the
|
153
|
+
[MIT License](./LICENSE.txt).
|
154
|
+
|
155
|
+
## Code of Conduct
|
156
|
+
|
157
|
+
Everyone interacting in the test65project’s codebases, issue trackers,
|
158
|
+
chat rooms and mailing lists is expected to follow the
|
159
|
+
[code of conduct](./CODE_OF_CONDUCT.md).
|
data/asminc/test65.i65
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
; Macro definitions for testing 65c02 code using sim65.
|
2
|
+
|
3
|
+
.import exit:absolute ; Make sure we have this symbol defined.
|
4
|
+
|
5
|
+
; Exit tests and return success!
|
6
|
+
.macro tests_pass
|
7
|
+
lda #0
|
8
|
+
jmp exit
|
9
|
+
.endmacro
|
10
|
+
|
11
|
+
; Exit tests and return an error code :-(
|
12
|
+
.macro tests_fail err_code
|
13
|
+
.ifconst err_code
|
14
|
+
.if (err_code < 2) || (err_code > 255)
|
15
|
+
.fatal "Invalid error code. Allowed values 2..255"
|
16
|
+
.endif
|
17
|
+
|
18
|
+
lda #err_code
|
19
|
+
jmp exit
|
20
|
+
.else
|
21
|
+
.fatal "Error code must be a constant"
|
22
|
+
.endif
|
23
|
+
.endmacro
|
24
|
+
|
25
|
+
; Exit tests and return an error code if the Z flag is cleared (ne)
|
26
|
+
.macro fail_ne err_code
|
27
|
+
.local no_error
|
28
|
+
beq no_error
|
29
|
+
tests_fail err_code
|
30
|
+
no_error:
|
31
|
+
.endmacro
|
32
|
+
|
33
|
+
; Exit tests and return an error code if the Z flag is set (eq)
|
34
|
+
.macro fail_eq err_code
|
35
|
+
.local no_error
|
36
|
+
bne no_error
|
37
|
+
tests_fail err_code
|
38
|
+
no_error:
|
39
|
+
.endmacro
|
40
|
+
|
41
|
+
; Exit tests and return an error code if the C flag is cleared (cc)
|
42
|
+
.macro fail_cc err_code
|
43
|
+
.local no_error
|
44
|
+
bcs no_error
|
45
|
+
tests_fail err_code
|
46
|
+
no_error:
|
47
|
+
.endmacro
|
48
|
+
|
49
|
+
; Exit tests and return an error code if the C flag is set (cs)
|
50
|
+
.macro fail_cs err_code
|
51
|
+
.local no_error
|
52
|
+
bcc no_error
|
53
|
+
tests_fail err_code
|
54
|
+
no_error:
|
55
|
+
.endmacro
|
56
|
+
|
57
|
+
; Exit tests and return an error code if the N flag is cleared (pl)
|
58
|
+
.macro fail_pl err_code
|
59
|
+
.local no_error
|
60
|
+
bmi no_error
|
61
|
+
tests_fail err_code
|
62
|
+
no_error:
|
63
|
+
.endmacro
|
64
|
+
|
65
|
+
; Exit tests and return an error code if the N flag is set (mi)
|
66
|
+
.macro fail_mi err_code
|
67
|
+
.local no_error
|
68
|
+
bpl no_error
|
69
|
+
tests_fail err_code
|
70
|
+
no_error:
|
71
|
+
.endmacro
|
72
|
+
|
73
|
+
; Exit tests and return an error code if the V flag is cleared (vc)
|
74
|
+
.macro fail_vc err_code
|
75
|
+
.local no_error
|
76
|
+
bvs no_error
|
77
|
+
tests_fail err_code
|
78
|
+
no_error:
|
79
|
+
.endmacro
|
80
|
+
|
81
|
+
; Exit tests and return an error code if the V flag is set (vs)
|
82
|
+
.macro fail_vs err_code
|
83
|
+
.local no_error
|
84
|
+
bvc no_error
|
85
|
+
tests_fail err_code
|
86
|
+
no_error:
|
87
|
+
.endmacro
|
data/cfg/test65.cfg
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
SYMBOLS {
|
2
|
+
__EXEHDR__: type = import;
|
3
|
+
__STACKSIZE__: type = weak, value = $0800; # 2k stack
|
4
|
+
}
|
5
|
+
MEMORY {
|
6
|
+
ZP: file = "", start = $0000, size = $0100;
|
7
|
+
HEADER: file = %O, start = $0000, size = $000C;
|
8
|
+
MAIN: file = %O, define = yes, start = $0200, size = $FDF0 - __STACKSIZE__;
|
9
|
+
}
|
10
|
+
SEGMENTS {
|
11
|
+
ZEROPAGE: load = ZP, type = zp;
|
12
|
+
EXEHDR: load = HEADER, type = ro;
|
13
|
+
STARTUP: load = MAIN, type = ro;
|
14
|
+
LOWCODE: load = MAIN, type = ro, optional = yes;
|
15
|
+
ONCE: load = MAIN, type = ro, optional = yes;
|
16
|
+
CODE: load = MAIN, type = ro;
|
17
|
+
RODATA: load = MAIN, type = ro;
|
18
|
+
PAGE_CODE: load = MAIN, type = ro, optional = yes, align = $100;
|
19
|
+
DATA: load = MAIN, type = rw;
|
20
|
+
PAGE_DATA: load = MAIN, type = rw, optional = yes, align = $100;
|
21
|
+
BSS: load = MAIN, type = bss, define = yes;
|
22
|
+
}
|
23
|
+
FEATURES {
|
24
|
+
CONDES: type = constructor,
|
25
|
+
label = __CONSTRUCTOR_TABLE__,
|
26
|
+
count = __CONSTRUCTOR_COUNT__,
|
27
|
+
segment = ONCE;
|
28
|
+
CONDES: type = destructor,
|
29
|
+
label = __DESTRUCTOR_TABLE__,
|
30
|
+
count = __DESTRUCTOR_COUNT__,
|
31
|
+
segment = RODATA;
|
32
|
+
CONDES: type = interruptor,
|
33
|
+
label = __INTERRUPTOR_TABLE__,
|
34
|
+
count = __INTERRUPTOR_COUNT__,
|
35
|
+
segment = RODATA,
|
36
|
+
import = __CALLIRQ__;
|
37
|
+
}
|
data/exe/test65
ADDED
data/help.txt
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
test65 - Run tests of 65c02 assembler code.
|
2
|
+
|
3
|
+
Usage: test65 {options} {files}
|
4
|
+
|
5
|
+
Options:
|
6
|
+
--debug, -d Show (really) detailed debug info. Not normally required.
|
7
|
+
--help, -h, -? Display this message and exit.
|
8
|
+
--list, -l Generate list files for each test.
|
9
|
+
--map, -m Generate map files for each test.
|
10
|
+
--keep, -k Keep object and output files. Do not clean up.
|
11
|
+
--path, -p Specify the path to the test files. (Only 1 allowed)
|
12
|
+
--quiet, -q Hide messages. Used to keep the test65 tests clean.
|
13
|
+
--verbose, -v Display lots of useful progress info.
|
14
|
+
--version Display the program version and exit.
|
15
|
+
|
16
|
+
Files: An optional list of test files.
|
17
|
+
|
18
|
+
Notes:
|
19
|
+
- By default, test files are located in a folder called "t65" in the current
|
20
|
+
folder or one of its parent folders.
|
21
|
+
- Wildcards are allowed for files but not the path.
|
22
|
+
- If no files are specified, then all files matching "t65*.a65" or "t65*.rb"
|
23
|
+
in the test folder are tested.
|
24
|
+
- If files are specified, only the specified file(s) are tested.
|
data/lib/test65.rb
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# test65
|
2
|
+
|
3
|
+
require 'english'
|
4
|
+
require 'getoptlong'
|
5
|
+
require 'pathname'
|
6
|
+
require 'rbconfig'
|
7
|
+
require 'full_dup'
|
8
|
+
|
9
|
+
require_relative 'test65/perform_test'
|
10
|
+
require_relative 'test65/process_files'
|
11
|
+
require_relative 'test65/process_args'
|
12
|
+
require_relative 'test65/process_path'
|
13
|
+
require_relative 'test65/build_file_list'
|
14
|
+
require_relative 'test65/std_path'
|
15
|
+
require_relative 'test65/host'
|
16
|
+
require_relative 'test65/version'
|
17
|
+
|
18
|
+
module Test65
|
19
|
+
|
20
|
+
#Figure out where the gem root folder is located
|
21
|
+
lib_path = File.dirname(File.absolute_path(__FILE__))
|
22
|
+
@gem_root = Pathname.new(lib_path).parent.to_s
|
23
|
+
@asminc = @gem_root + "/asminc" # TODO remove this variable.
|
24
|
+
|
25
|
+
# Figure out where the compiler is.
|
26
|
+
temp = ENV["CC65_HOME"]
|
27
|
+
fail "The CC65_HOME variable is not set." unless temp
|
28
|
+
@cc65_home = temp.standardize_path
|
29
|
+
|
30
|
+
# The code entry point. Run some 65c02 tests.
|
31
|
+
# Returns
|
32
|
+
# 0 for success
|
33
|
+
# Other for failure
|
34
|
+
def self.process
|
35
|
+
process_args
|
36
|
+
process_path
|
37
|
+
build_file_list
|
38
|
+
process_file_list
|
39
|
+
|
40
|
+
rescue => err
|
41
|
+
puts "Error: #{err.to_s}"
|
42
|
+
puts err.backtrace if @options[:debug]
|
43
|
+
exit(1)
|
44
|
+
|
45
|
+
ensure
|
46
|
+
# Always remove this file if it exists.
|
47
|
+
File.delete("_kwhyit") if File.exists?("_kwhyit")
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# Build the list of test and library files to be processed.
|
2
|
+
|
3
|
+
module Test65
|
4
|
+
# Find the files to be tested.
|
5
|
+
def self.build_file_list
|
6
|
+
if @arg_files.empty?
|
7
|
+
scan_files
|
8
|
+
else
|
9
|
+
check_files
|
10
|
+
end
|
11
|
+
|
12
|
+
puts "Processing #{@test_files.length} test file(s)" if @options[:verbose]
|
13
|
+
end
|
14
|
+
|
15
|
+
# Scan the path for files to be processed.
|
16
|
+
def self.scan_files
|
17
|
+
@test_files = Dir.glob(@options[:path] + "/t65*.a65") +
|
18
|
+
Dir.glob(@options[:path] + "/t65*.rb")
|
19
|
+
fail "Cannot locate any test files" if @test_files.empty?
|
20
|
+
end
|
21
|
+
|
22
|
+
# Check the list of files to be processed.
|
23
|
+
def self.check_files
|
24
|
+
@test_files = @arg_files.map do |file|
|
25
|
+
std_file = file.standardize_path
|
26
|
+
|
27
|
+
if !(found = Dir.glob(std_file)).empty?
|
28
|
+
found.map {|subfile| File.absolute_path(file) }
|
29
|
+
elsif !(found = Dir.glob(@options[:path] + "/" + std_file)).empty?
|
30
|
+
found
|
31
|
+
else
|
32
|
+
fail "Cannot locate the file #{file}"
|
33
|
+
end
|
34
|
+
end.flatten
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# An enclosure for the ca65 assembler.
|
2
|
+
class TestScript
|
3
|
+
|
4
|
+
# Setup ca65
|
5
|
+
def ca65_initialize
|
6
|
+
@options[:target] = "sim65c02"
|
7
|
+
@options[:ca65_paths] = ["#{@options[:gem_root]}/asminc"]
|
8
|
+
@options[:objs] = []
|
9
|
+
end
|
10
|
+
|
11
|
+
# Add some include paths for the assembler.
|
12
|
+
def ca65_inc_paths(*more_paths)
|
13
|
+
fail "Sequence error: ca65_inc_paths" unless @phase == :create
|
14
|
+
append_option(:inc_paths, more_paths)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Assemble some files.
|
18
|
+
def ca65(file, options="")
|
19
|
+
fail "Sequence error: ca65" unless @phase == :create
|
20
|
+
source = File.absolute_path(@options[:path] + "/" + file)
|
21
|
+
target = "--target #{@options[:target]} "
|
22
|
+
paths = build_args("-I", @options[:ca65_paths])
|
23
|
+
|
24
|
+
# Convert source assemble files into object files.
|
25
|
+
object = change_type(source, ".o")
|
26
|
+
list = @options[:list] ? "-l " + change_type(source, ".lst") : ""
|
27
|
+
command = "ca65 #{target}#{paths}#{list}#{options} -o #{object} #{source} #{@quiet}\n"
|
28
|
+
puts command if @options[:debug]
|
29
|
+
system(command)
|
30
|
+
fail "Error assembling #{source.localize_path}" unless $?.exitstatus == 0
|
31
|
+
|
32
|
+
@options[:objs] << object
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# An enclosure for the ld65 linker.
|
2
|
+
|
3
|
+
class TestScript
|
4
|
+
|
5
|
+
# Setup ld65
|
6
|
+
def ld65_initialize
|
7
|
+
@options[:lib_paths] = []
|
8
|
+
@options[:libraries] = ["sim65c02.lib"]
|
9
|
+
@options[:ld65_options] = []
|
10
|
+
@options[:config] = "#{@options[:gem_root]}/cfg/test65.cfg"
|
11
|
+
end
|
12
|
+
|
13
|
+
# Add some library paths for the linker.
|
14
|
+
def ld65_lib_paths(*more_paths)
|
15
|
+
fail "Sequence error: ld65_lib_paths" unless [:create, :link].include?(@phase)
|
16
|
+
append_option(:lib_paths, more_paths)
|
17
|
+
@phase = :link
|
18
|
+
end
|
19
|
+
|
20
|
+
# Add some library paths for the linker.
|
21
|
+
def ld65_libraries(*more_libs)
|
22
|
+
fail "Sequence error: ld65_libraries" unless [:create, :link].include?(@phase)
|
23
|
+
append_option(:libraries, more_libs)
|
24
|
+
@phase = :link
|
25
|
+
end
|
26
|
+
|
27
|
+
def ld65(options="")
|
28
|
+
fail "Sequence error: ld65" unless [:create, :link].include?(@phase)
|
29
|
+
@phase = :simulate
|
30
|
+
|
31
|
+
@output = change_type(@options[:objs][0], ".out")
|
32
|
+
@map_file = change_type(@options[:objs][0], ".map")
|
33
|
+
lib_paths = build_args("--lib-path", @options[:lib_paths])
|
34
|
+
objs = build_args(@options[:objs])
|
35
|
+
libs = build_args("--lib", @options[:libraries])
|
36
|
+
map = @options[:map] ? "-m #{@map_file}" : ""
|
37
|
+
cfg = "-C " + @options[:config] + " "
|
38
|
+
|
39
|
+
# Build the command and run it.
|
40
|
+
command = "ld65 #{lib_paths}#{libs}#{cfg}#{options} #{objs}#{map} -o #{@output} #{@quiet}\n"
|
41
|
+
puts command if @options[:debug]
|
42
|
+
system(command)
|
43
|
+
fail "Error linking #{@output.localize_path}." unless $?.exitstatus == 0
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# An enclosure for the sim65 simulator.
|
2
|
+
|
3
|
+
class TestScript
|
4
|
+
|
5
|
+
# Setup sim65
|
6
|
+
def sim65_initialize
|
7
|
+
@options[:sim65_options] = []
|
8
|
+
end
|
9
|
+
|
10
|
+
# Run the simulator to get the actual test results.
|
11
|
+
def sim65(options="")
|
12
|
+
fail "Sequence error: sim65" unless @phase == :simulate
|
13
|
+
@phase = :done
|
14
|
+
|
15
|
+
# Build the command and run it.
|
16
|
+
command = "sim65 #{options} #{@output} #{@quiet}\n"
|
17
|
+
puts command if @options[:debug]
|
18
|
+
system(command)
|
19
|
+
status = $?.exitstatus
|
20
|
+
fail "Test #{@output.localize_path} failed with error code: #{status}" unless status == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Utility methods
|
2
|
+
|
3
|
+
class TestScript
|
4
|
+
|
5
|
+
# Create a file name with a new extension.
|
6
|
+
def change_type(file, new_ext)
|
7
|
+
file.gsub(/\...?.?\z/, new_ext)
|
8
|
+
end
|
9
|
+
|
10
|
+
# Construct a series of arguments.
|
11
|
+
def build_args(prefix = nil, args)
|
12
|
+
pre = prefix ? prefix + " " : ""
|
13
|
+
args.inject("") {|str, arg| str << pre + arg + " "}
|
14
|
+
end
|
15
|
+
|
16
|
+
# Append to an option.
|
17
|
+
def append_option(key, *value)
|
18
|
+
@options[key] = ((@options[key] || []) + [value]).flatten
|
19
|
+
end
|
20
|
+
|
21
|
+
# Adjust a list of files to include the path to the test file.
|
22
|
+
def adjust(files)
|
23
|
+
files.map { |file| @options[:path] + "/" + file }
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
data/lib/test65/host.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Is this program running on a Windows host?
|
2
|
+
|
3
|
+
class Object
|
4
|
+
|
5
|
+
private
|
6
|
+
|
7
|
+
# Are we running under Windows?
|
8
|
+
def windows?
|
9
|
+
# Is this a Windows based system
|
10
|
+
@win ||= RbConfig::CONFIG['host_os'] =~ /mswin|msys|mingw|bccwin|wince|emc/
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Run a test script for the test65 program.
|
2
|
+
|
3
|
+
require_relative 'enclosures/utils'
|
4
|
+
require_relative 'enclosures/ca65'
|
5
|
+
require_relative 'enclosures/ld65'
|
6
|
+
require_relative 'enclosures/sim65'
|
7
|
+
|
8
|
+
class TestScript
|
9
|
+
|
10
|
+
# Create a test script object and set up its default options.
|
11
|
+
def initialize(options={})
|
12
|
+
@options = options.full_dup
|
13
|
+
@phase = :create
|
14
|
+
|
15
|
+
ca65_initialize
|
16
|
+
ld65_initialize
|
17
|
+
sim65_initialize
|
18
|
+
|
19
|
+
@quiet = @options[:quiet].to_s
|
20
|
+
end
|
21
|
+
|
22
|
+
# Cleanup after ourselves
|
23
|
+
def clean_up
|
24
|
+
# Remove objects and executable unless told to keep them.
|
25
|
+
unless @options[:keep]
|
26
|
+
File.delete(@output) if File.exists?(@output)
|
27
|
+
|
28
|
+
@options[:objs].each do |file|
|
29
|
+
File.delete(file) if File.exists?(file)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
# Remove listing files unless they were requested.
|
34
|
+
unless @options[:list]
|
35
|
+
@options[:objs].each do |file|
|
36
|
+
file = change_type(file, ".lst")
|
37
|
+
File.delete(file) if File.exists?(file)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Remove the map file if needed.
|
42
|
+
File.delete(@map_file) if !@options[:map] && File.exists?(@map_file)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# Process the command line arguments for the test65 program.
|
2
|
+
|
3
|
+
module Test65
|
4
|
+
# Process the command line arguments.
|
5
|
+
def self.process_args
|
6
|
+
@options = {}
|
7
|
+
|
8
|
+
opts = GetoptLong.new(
|
9
|
+
["--debug", "-d", GetoptLong::NO_ARGUMENT],
|
10
|
+
["--help", "-h", "-?", GetoptLong::NO_ARGUMENT],
|
11
|
+
["--list", "-l", GetoptLong::NO_ARGUMENT],
|
12
|
+
["--map", "-m", GetoptLong::NO_ARGUMENT],
|
13
|
+
["--keep", "-k", GetoptLong::NO_ARGUMENT],
|
14
|
+
["--path", "-p", GetoptLong::REQUIRED_ARGUMENT],
|
15
|
+
["--quiet", "-q", GetoptLong::NO_ARGUMENT],
|
16
|
+
["--verbose", "-v", GetoptLong::NO_ARGUMENT],
|
17
|
+
["--version", GetoptLong::NO_ARGUMENT])
|
18
|
+
|
19
|
+
opts.each do |opt, arg|
|
20
|
+
case opt
|
21
|
+
when "--debug"
|
22
|
+
@options[:debug] = true
|
23
|
+
when "--help"
|
24
|
+
puts IO.read(@gem_root + "/help.txt")
|
25
|
+
exit
|
26
|
+
when "--keep"
|
27
|
+
@options[:keep] = true
|
28
|
+
when "--list"
|
29
|
+
@options[:list] = true
|
30
|
+
when "--map"
|
31
|
+
@options[:map] = true
|
32
|
+
when "--path"
|
33
|
+
unless @options[:path]
|
34
|
+
@options[:path] = File.absolute_path(arg.standardize_path)
|
35
|
+
else
|
36
|
+
fail "Multiple path options are not allowed."
|
37
|
+
end
|
38
|
+
when "--quiet"
|
39
|
+
@options[:quiet] = "2> _kwhyit"
|
40
|
+
when "--verbose"
|
41
|
+
@options[:verbose] = true
|
42
|
+
when "--version"
|
43
|
+
puts "test65 Version #{VERSION}"
|
44
|
+
exit
|
45
|
+
else
|
46
|
+
fail "Invalid option: #{opt}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# A list of files to test may follow the options.
|
51
|
+
@arg_files = ARGV
|
52
|
+
|
53
|
+
# Setup some default paths
|
54
|
+
@options[:gem_root] = @gem_root
|
55
|
+
@options[:ca65_paths] = @gem_root + "/asminc"
|
56
|
+
@options[:cc65_home] = @cc65_home
|
57
|
+
|
58
|
+
rescue => err
|
59
|
+
puts "Error: #{err.to_s}"
|
60
|
+
puts err.backtrace if @options[:debug]
|
61
|
+
puts
|
62
|
+
puts IO.read(@gem_root + "/help.txt")
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# Process the test files.
|
2
|
+
|
3
|
+
module Test65
|
4
|
+
|
5
|
+
# Process the list of files
|
6
|
+
def self.process_file_list
|
7
|
+
@error_count = 0
|
8
|
+
|
9
|
+
@test_files.each do |file|
|
10
|
+
process_file(file)
|
11
|
+
end
|
12
|
+
|
13
|
+
if @error_count > 0
|
14
|
+
fail "#{@error_count} tests failed."
|
15
|
+
else
|
16
|
+
puts "OK: All tests passed."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Process a file.
|
21
|
+
def self.process_file(file)
|
22
|
+
puts file.localize_path if @options[:verbose]
|
23
|
+
|
24
|
+
case File.extname(file)
|
25
|
+
when ".a65"
|
26
|
+
script { ca65(File.basename(file)); ld65; sim65 }
|
27
|
+
|
28
|
+
when ".rb"
|
29
|
+
load file
|
30
|
+
|
31
|
+
else
|
32
|
+
fail "Don't know how to process #{file}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Process a test script.
|
37
|
+
def self.script(&block)
|
38
|
+
test_script = TestScript.new(@options)
|
39
|
+
test_script.instance_exec(&block)
|
40
|
+
rescue => err
|
41
|
+
puts err
|
42
|
+
puts err.backtrace if @options[:debug]
|
43
|
+
@error_count += 1
|
44
|
+
ensure
|
45
|
+
test_script.clean_up
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Process the path to the test files.
|
2
|
+
|
3
|
+
module Test65
|
4
|
+
|
5
|
+
# Determine the path to test files.
|
6
|
+
def self.process_path
|
7
|
+
path = @options[:path] || get_default_path
|
8
|
+
|
9
|
+
localized_path = path.localize_path
|
10
|
+
fail "Path #{localized_path} does not exist." unless File.exists?(path)
|
11
|
+
fail "Path #{localized_path} is not a folder." unless File.directory?(path)
|
12
|
+
puts "Using path: #{localized_path}" if @options[:verbose]
|
13
|
+
|
14
|
+
@options[:path] = path
|
15
|
+
end
|
16
|
+
|
17
|
+
# Get the default test file path if one was not supplied.
|
18
|
+
def self.get_default_path
|
19
|
+
search, parent = Pathname.new(Dir.pwd), nil
|
20
|
+
|
21
|
+
while true
|
22
|
+
test = search.to_s + "/t65"
|
23
|
+
|
24
|
+
if File.exists?(test)
|
25
|
+
return test if File.directory?(test)
|
26
|
+
fail "The file #{local_path(test)} is not a folder."
|
27
|
+
end
|
28
|
+
|
29
|
+
search, parent = search.parent, search
|
30
|
+
|
31
|
+
fail "Default path not found." if search == parent
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# Portable path handling methods for the Test65 program.
|
2
|
+
|
3
|
+
class String
|
4
|
+
|
5
|
+
# Convert a path into standard form.
|
6
|
+
def standardize_path
|
7
|
+
self.gsub("\\", "/")
|
8
|
+
end
|
9
|
+
|
10
|
+
# Convert a path string into local system form.
|
11
|
+
def localize_path
|
12
|
+
windows? ? self.gsub("/", "\\") : self
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
data/rakefile.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rake/testtask"
|
3
|
+
|
4
|
+
Rake::TestTask.new(:test) do |t|
|
5
|
+
t.libs << "test"
|
6
|
+
t.libs << "lib"
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
8
|
+
end
|
9
|
+
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
desc "What version of test65 is this?"
|
13
|
+
task :vers do |t|
|
14
|
+
puts
|
15
|
+
puts "test65 version = #{::Test65::VERSION}"
|
16
|
+
end
|
data/t65/asm_err.a65
ADDED
data/t65/callee.a65
ADDED
data/t65/caller.a65
ADDED
data/t65/foo.txt
ADDED
data/t65/linker_err.a65
ADDED
data/t65/macro_err1.a65
ADDED
data/t65/macro_err2.a65
ADDED
data/t65/min_fail.a65
ADDED
data/t65/min_pass.a65
ADDED
data/t65/min_pass.rb
ADDED
data/t65/pass.a65
ADDED
data/t65/t65_min_pass.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
; Test a whole bunch of macros!
|
2
|
+
|
3
|
+
.include "test65.i65"
|
4
|
+
.export _main
|
5
|
+
.pc02
|
6
|
+
|
7
|
+
.code
|
8
|
+
|
9
|
+
_main:
|
10
|
+
lda #$00
|
11
|
+
fail_ne 10
|
12
|
+
|
13
|
+
inc
|
14
|
+
fail_eq 20
|
15
|
+
fail_mi 30
|
16
|
+
|
17
|
+
dec
|
18
|
+
dec
|
19
|
+
fail_pl 40
|
20
|
+
|
21
|
+
clc
|
22
|
+
adc #$02
|
23
|
+
fail_cc 50
|
24
|
+
|
25
|
+
clc
|
26
|
+
adc #$00
|
27
|
+
fail_cs 60
|
28
|
+
|
29
|
+
clv
|
30
|
+
fail_vs 70
|
31
|
+
|
32
|
+
lda #$70
|
33
|
+
clc
|
34
|
+
adc #$70
|
35
|
+
fail_vc 80
|
36
|
+
|
37
|
+
tests_pass
|
data/test65.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require "test65/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "test65"
|
7
|
+
spec.version = Test65::VERSION
|
8
|
+
spec.authors = ["PeterCamilleri"]
|
9
|
+
spec.email = ["peter.c.camilleri@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = Test65::DESCRIPTION
|
12
|
+
spec.description = "A testing framework for work on the Commander X 16."
|
13
|
+
spec.homepage = "https://github.com/PeterCamilleri/test65"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|docs)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec
|
21
|
+
.files
|
22
|
+
.reject { |f| f.downcase == 'exe/readme.md'}
|
23
|
+
.grep(%r{^exe/}) { |f| File.basename(f) }
|
24
|
+
spec.require_paths = ["lib"]
|
25
|
+
|
26
|
+
spec.add_runtime_dependency "full_dup"
|
27
|
+
|
28
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
29
|
+
spec.add_development_dependency "rake", ">= 12.3.3"
|
30
|
+
spec.add_development_dependency "minitest", "~> 5.0"
|
31
|
+
end
|
metadata
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: test65
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- PeterCamilleri
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2020-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: full_dup
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.17'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.17'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 12.3.3
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 12.3.3
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '5.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '5.0'
|
69
|
+
description: A testing framework for work on the Commander X 16.
|
70
|
+
email:
|
71
|
+
- peter.c.camilleri@gmail.com
|
72
|
+
executables:
|
73
|
+
- test65
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- CODE_OF_CONDUCT.md
|
79
|
+
- Gemfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- asminc/test65.i65
|
83
|
+
- cfg/test65.cfg
|
84
|
+
- exe/test65
|
85
|
+
- help.txt
|
86
|
+
- lib/test65.rb
|
87
|
+
- lib/test65/build_file_list.rb
|
88
|
+
- lib/test65/enclosures/ca65.rb
|
89
|
+
- lib/test65/enclosures/ld65.rb
|
90
|
+
- lib/test65/enclosures/sim65.rb
|
91
|
+
- lib/test65/enclosures/utils.rb
|
92
|
+
- lib/test65/host.rb
|
93
|
+
- lib/test65/perform_test.rb
|
94
|
+
- lib/test65/process_args.rb
|
95
|
+
- lib/test65/process_files.rb
|
96
|
+
- lib/test65/process_path.rb
|
97
|
+
- lib/test65/std_path.rb
|
98
|
+
- lib/test65/version.rb
|
99
|
+
- rakefile.rb
|
100
|
+
- t65/asm_err.a65
|
101
|
+
- t65/callee.a65
|
102
|
+
- t65/caller.a65
|
103
|
+
- t65/foo.txt
|
104
|
+
- t65/linker_err.a65
|
105
|
+
- t65/macro_err1.a65
|
106
|
+
- t65/macro_err2.a65
|
107
|
+
- t65/min_fail.a65
|
108
|
+
- t65/min_pass.a65
|
109
|
+
- t65/min_pass.rb
|
110
|
+
- t65/pass.a65
|
111
|
+
- t65/t65_min_pass.rb
|
112
|
+
- t65/t65_test_cfg.a65
|
113
|
+
- t65/t65_test_macros.a65
|
114
|
+
- t65/t65_two_files.rb
|
115
|
+
- test65.gemspec
|
116
|
+
homepage: https://github.com/PeterCamilleri/test65
|
117
|
+
licenses:
|
118
|
+
- MIT
|
119
|
+
metadata: {}
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
requirements:
|
126
|
+
- - ">="
|
127
|
+
- !ruby/object:Gem::Version
|
128
|
+
version: '0'
|
129
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
130
|
+
requirements:
|
131
|
+
- - ">="
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
requirements: []
|
135
|
+
rubyforge_project:
|
136
|
+
rubygems_version: 2.5.2
|
137
|
+
signing_key:
|
138
|
+
specification_version: 4
|
139
|
+
summary: 'test65: A testing framework for ca65.'
|
140
|
+
test_files: []
|