aboutsummaryrefslogtreecommitdiff
path: root/tests
Commit message (Collapse)AuthorAgeFilesLines
* Preserve the 'accessed' member on macro argumentsMiquel Sabaté Solà2026-07-073-0/+27
| | | | | | | | | | | | | | | Macro arguments get tampered with every time a new call has to be bundled. Deep down this is done by cloning the underlying object, but this resets any increase on the 'accessed' member, giving always the impression that macro arguments are never accessed. Fix this by at least preserving this member when cloning a macro argument. Note that this is neither the most elegant solution, and probably not the most correct. As in, it will probably get into a non-precise count after some calls. But at least it will be a non-zero value, which is more than enough to what this is actually used for. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Refer to the original file for unused objectsMiquel Sabaté Solà2026-06-053-0/+16
| | | | | | | | | | | | | | | | | | | When warning users on unused objects (e.g. variables, proc's), we have to pick up the source of origin for this warning. In places where the original PNode is not available, then we go with the last source we have at hand, as that's the usual way to go (i.e. the error occurred at the current source/context). That being said, for unused objects that's not desirable, because we might otherwise claim the error to happen on the file we first targetted, but it's way more useful to understand where the object was defined. Hence, when defining a variable, address or proc, let's actually store the PNode associated with it as well. This way the checker can hopefully get the source from this PNode and be more clear to the user. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* ci: override LC_ALL for a more consistent 'sort'Miquel Sabaté Solà2026-04-301-1/+1
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* tests: adapt to the new 'unused' checksMiquel Sabaté Solà2026-04-303-2/+18
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Send an error for unused .proc'sMiquel Sabaté Solà2026-04-283-0/+7
| | | | | | | | | | | | | | | | | We cannot safely detect all scenarios in which there is dead code, but we can safely do it for .proc's. Even if they are not called directly, they might be referenced via jump tables and shenanigans like that. Long story short, if you are not referencing a .proc in any meaningful way, then we have dead code. A pattern could also be given in which a function that was too long has been splitted into smaller functions which are not called directly. This is, in my opinion, an anti-pattern (as we generally expect an rts or a jmp from .proc's), and anyways can be avoided via the use of __fallthrough__ if the programmer is really set to write this kind of code. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* tests: update submodules to their latest commitsMiquel Sabaté Solà2026-04-253-0/+0
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow scoped names in __fallthrough__Miquel Sabaté Solà2026-04-242-0/+10
| | | | | | Fixes 4f1a9c660108 ("Add the .fallthrough control statement") Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* tests: add jetpac.nes to the end-to-end testsMiquel Sabaté Solà2026-04-241-0/+0
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Implement the asan:stack statementMiquel Sabaté Solà2026-04-0810-0/+20
| | | | | | | | | | | | | | This statement allows programmers to reserve a memory range for the stack. This is useful to reserve a memory region which is not attached to any variable, and: 1. It is a way to safely reserve space on the $0100 page. 2. The --stats/--write-info flags will be able to add up the memory space reserved for the stack. 3. Future tooling might be able to use this value as a way to detect stack overflows. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Re-create the values for bundle call argumentsMiquel Sabaté Solà2026-03-103-0/+49
| | | | | | | | | | | | | | | | | | Bundle call arguments were fine most of the times, when arguments could be processed as-is and there were no issues with arguments being overwritten by successive calls. This was not the case, though, whenever a given instruction was delayed into a PendingNode status. In this case, the argument would get the last value, and in some extreme cases that definition might not have been there any more. Prevent all of this by providing a list of PendingDefine's, which are a way to re-create these call-only arguments as they were initially found. These PendingDefine's are then created on "crunch" on each PendingNode. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: ignore names from macro argumentsMiquel Sabaté Solà2026-03-091-0/+13
| | | | | | | These are usually capitalized, and thus they are not going to be following the usual zp_/m_/wr_ pattern. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow using a byte for indirect jumpsMiquel Sabaté Solà2026-02-113-0/+18
| | | | | | | They should be expanded to a 16-bit address from the zero-page. The fact that the assembler was complaining about it was simply erroneous. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: Fix validation on indirect jumpsMiquel Sabaté Solà2026-02-111-0/+1
| | | | | | | | | | | | | | There were two bugs involved at the same time. First, for some reason, the "matches" clause was negated, which defeats the purpose of the check. This even resulted in a bad test run which was accepted because I just did not caught it before. Second, pure indirect addressing mode is only available for the "jmp" instruction. Hence, there's no need for that "matches" at all, and even less to filter that based on "jsr" which doesn't even implement this addressing mode. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: don't complain on arithmetic with addressesMiquel Sabaté Solà2026-02-062-2/+3
| | | | | | | This was already the case for plain addresses, but it was not being considered in the case of an arithmetic operation. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Make the fallthrough error more explicitMiquel Sabaté Solà2026-02-031-3/+3
| | | | | | | Add the target and effective addresses into the message, so it's more clear how different they are. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Avoid invalid identifiers in proc/macro/scopeMiquel Sabaté Solà2026-02-033-0/+16
| | | | | | | | This was apparently neglected and you were able to pick invalid identifiers to identify procs, macros and scopes. Ensure this does not happen again and provide tests for it. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Change .fallthrough to __fallthrough__Miquel Sabaté Solà2026-02-022-8/+8
| | | | | | | | | | | | | Implementing it as a control statement has the bad thing that it's impossible to be compatible with other assemblers such as ca65, as you cannot create dummy control statements or something like that in there. Instead of that, we define it with the special underscores which are still valid for identifiers, and give a "compiler-specific thingie" flair to it. This also has the benefit that the parser can be a bit more strict. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Add the .fallthrough control statementMiquel Sabaté Solà2026-02-025-0/+54
| | | | | | | | | | | | | | | | This is exclusive to 'nasm' and it allows the developer to explicitly tell the assembler than a "fall through" condition is actually desired: it's not a mistake. This comes in two flavors. The first, without arguments, just makes this explicit without much enforcement. The second allows you to pass an argument which is the name of the function or label you are expecting to fall through. The assembler will error out if the fall through address is not the expected one, hence telling the programmer whenever the fall through condition they thought in the past is no longer true (e.g. the function has moved somewhere else in the code). Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Warn on pointless (un)conditional branchingMiquel Sabaté Solà2026-02-023-0/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | Sometimes performing some 'jmp'/'jsr' can be quite pointless, and the programmer might not be fully aware of this because of the layout of the code. Imagine: .proc foo ;; code jmp bar .endproc ;; Documentation, comments, extra space, etc. .proc bar ;; whatever .endproc The 'jmp' in the code above tries to perform a call stack optimization, but it's actually not needed because the next instruction after 'jmp' is the one inside of 'bar', but that's obfuscated because of the layout. In these sort of cases (and also for 'jsr' and branches) warn the programmer about it so it can remove that instruction. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow constants in asan:reserve statementsMiquel Sabaté Solà2025-12-152-0/+21
| | | | | | | | | | | | | | | | This way, if you define a constant like: MY_BUFFER_LEN_IN_BYTES = $10 You can then declare your buffer like so: zp_buffer = $00 ; asan:reserve MY_BUFFER_LEN_IN_BYTES And then further in the code you can rely on just using the constant for bound checking, and then the address sanitizer will check on bound checks via static analysis as well. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: Add fixes on absolute/indirect addressingMiquel Sabaté Solà2025-09-032-0/+5
| | | | | | The check was not being applied on certain conditions. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Apply asan:ignore also when bundlingMiquel Sabaté Solà2025-09-031-0/+2
| | | | | | | This way instructions which might make use of bare memory numbers can freely ignore the address sanitizer when it actually makes sense. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add a check for variable namesMiquel Sabaté Solà2025-09-032-0/+29
| | | | | | | This check ensures that asan-friendly names actually match their expected scope. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Validate that memory access is done via variablesMiquel Sabaté Solà2025-09-032-0/+41
| | | | | | | | | | | | | The address sanitizer is now able to detect whenever in an instruction a memory access is done without using variables. This is now detected for all instructions except for branching, which falls outside of this scope. Moreover, simple arithmetics is allowed and bounds are checked for simple cases. That being said, more involved bound checks should be done with other tools (e.g. emulators). Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add a warning for each unused variableMiquel Sabaté Solà2025-09-023-0/+19
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Rebump end-to-end tests to work via git submodulesMiquel Sabaté Solà2025-08-185-0/+62
| | | | | | | | | | This provides a more up-to-date experience, while also allowing to test more cases. Moreover, the latest flags from 'xa65' are being used. All in all, both 'code.nes' and 'aoc2023.nes' appear to be working after the latest fixes. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* nasm: Implement the -D flagMiquel Sabaté Solà2025-01-224-0/+18
| | | | | | | This allows users to define variables directly from the command line, which is useful for testing purposes. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* tests: Add aoc2023.nes to end-to-end testsMiquel Sabaté Solà2025-01-221-0/+0
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* tests: Update code.nes so -Werror can be passedMiquel Sabaté Solà2025-01-131-0/+0
| | | | | | | | | Update the underlying code.nes test data so it uses a tighter configuration for NROM which in turn frees nasm from complaining about empty segments. This makes room to allo for -Werror so we catch warnings that might appear in the future. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* tests: Bundle end-to-end tests into a tarballMiquel Sabaté Solà2025-01-1011-1359/+0
| | | | | | | | This way I can simply compress all the examples to traverse with a single file, and thus no longer polluting this repository from code from other repositories. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add missing binary for end-to-end testsMiquel Sabaté Solà2025-01-091-0/+0
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Implement the .include statementMiquel Sabaté Solà2025-01-094-0/+462
| | | | | | | | | | | | | | This needed some heavy lifting when it comes to how files were located. This means that statements like .include/.incbin now take into consideration a new list made out of SourceInfo, which holds enough information to translate from which file a node comes from. This has also been added into errors, so they are more informative on what went wrong. In order to tests this, besides all the regular unit tests, a new e2e test has been added. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Rename to tools.nesMiquel Sabaté Solà2024-12-252-4/+4
| | | | | | | | | | Let's continue with the good ol' tradition of being terrible at naming things. I have also renamed another project which was referenced here, so update all references as well. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Add support for UxROM chipsMiquel Sabaté Solà2024-12-202-0/+279
| | | | | | I have also added an end-to-end test for it. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Introduce end-to-end testsMiquel Sabaté Solà2024-12-203-0/+618
For now I have added the most simple example for an NES/Famicom game, which I already had on a private repository (that I plan to open source soonish). Tests simply run `nasm` on known source files and compares the results with an .nes ROM file that has the exact bytes that we expect. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>