aboutsummaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* asan: ignore names from macro argumentsMiquel Sabaté Solà2026-03-093-5/+19
| | | | | | | 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>
* Fix small typoMiquel Sabaté Solà2026-02-271-1/+1
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Define the global scope to a more obscure nameMiquel Sabaté Solà2026-02-251-1/+1
| | | | | | | | | | | | | | | By how we define scopes, we needed an internal name for the global scope. All the way back to my first commit 587dd5bb8036 ("Initial commit"), I simply picked "Global". That is troublesome, as it can easily be typed by a human. If a programmer writes a scope with "global" definitions via this scope, this can be messed up with nasm's internal Global scope. Change that to a more obscure name for this internal global scope. If a programmer is so dead from the inside that wants to have a scope named like that, so be it. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Fix small indentation typoMiquel Sabaté Solà2026-02-251-1/+1
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Raise an error when a control statement does not existMiquel Sabaté Solà2026-02-251-11/+10
| | | | | | | | | In this case it was silently letting it go in the hopes that the assembler would catch it, but it's better to just handle it in the parser and give a proper error instead of complicating the assembler a bit more. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow using a byte for indirect jumpsMiquel Sabaté Solà2026-02-115-11/+37
| | | | | | | 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-112-3/+2
| | | | | | | | | | | | | | 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-063-6/+20
| | | | | | | 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>
* Fix the arithmetic on indexed addressing modesMiquel Sabaté Solà2026-02-051-51/+136
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In instructions like: lda address + 1, x The assembler was picking the size from the "+ 1" side, making this part of a one-byte size and, hence, assuming it was zeropage indirect addressing instead of an absolute one. This meant that one byte was cut off the end binary, and the address was wrong altogether. Fix this by telling the assembler to assume a .size = 2; for variables which have been defined as addresses. Then, the operation evaluation can take that as an indication to set the size to 2 as well and, hence, assume absolute indirect addressing. Moreover, this bug was intertwined with another one, where arithmetic could be borked when both operands were of an unexpected size. For example: lda #(300 - 260) Here the size would've been resolved to 2 as well, but it would have also reported an error because both operands were 2-bytes long, despite the end result fitting on a single byte. Since this is an explicit immediate addressing, then it would have assumed the programmer to try that with a 16-bit value, which is wrong. This commit also fixes this bug as it was deeply intertwined to how numbers are computed on operations and how sizes are evaluated. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Document the __NASM__ and __fallthrough__ featuresMiquel Sabaté Solà2026-02-031-0/+138
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* nasm: improve message on the -D flagMiquel Sabaté Solà2026-02-031-1/+3
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Make the fallthrough error more explicitMiquel Sabaté Solà2026-02-032-4/+7
| | | | | | | 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>
* Add __NASM__ protection on the --prelude outputMiquel Sabaté Solà2026-02-031-3/+5
| | | | | | | | The __fallthrough__ macro can only be done when using ca65, not nasm, as that's a protected identifier. Hence, wrap the __fallthrough__ macro definition via an .ifndef __NASM__. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Avoid invalid identifiers in proc/macro/scopeMiquel Sabaté Solà2026-02-035-7/+81
| | | | | | | | 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>
* Ensure __fallthrough__ is not considered a valid identifierMiquel Sabaté Solà2026-02-031-1/+4
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* nasm: add the --prelude flagMiquel Sabaté Solà2026-02-021-0/+18
| | | | | | | This flag prints to the standard output some helper code that bridges nasm-exclusive features with ca65. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Change .fallthrough to __fallthrough__Miquel Sabaté Solà2026-02-026-46/+57
| | | | | | | | | | | | | 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>
* Fix typo in commentMiquel Sabaté Solà2026-02-021-1/+1
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Add the .fallthrough control statementMiquel Sabaté Solà2026-02-029-1/+164
| | | | | | | | | | | | | | | | 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>
* nasm: define the __NASM__ variableMiquel Sabaté Solà2026-02-021-0/+3
| | | | | | | This variable is defined by default in nasm and it can be used for assembler compatibility code. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* xa65: add -Werror to the --strict flagMiquel Sabaté Solà2026-02-021-1/+1
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Warn on pointless (un)conditional branchingMiquel Sabaté Solà2026-02-026-0/+116
| | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* xixanta: add context from macro expansionsMiquel Sabaté Solà2026-02-023-4/+163
| | | | | | | | | | | | | The way macro expansions work is that the evaluated bundles replace the current node, but this throws away the context of the line, the source, etc. from the original line of code. Add a stack that is pushed/popped when expanding macros, and are then cloned for each pending node and error. This way, errors have full context of the original code and can display backtraces for macro expansion. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* tests: do not generate dummy out.nes filesMiquel Sabaté Solà2026-02-021-3/+3
| | | | | | | | For tests which the resulting binary is not needed, redirect the output (i.e. the ROM file) to /dev/null. This way we don't litter the workspace with dummy out.nes files. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Fix -a/--asan flag parsingMiquel Sabaté Solà2026-02-021-1/+1
| | | | | | Fixes: 8e7993a63e32 ("assembler: Add support for asan:reserve,ignore"). Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: move the conflict check into its own loopMiquel Sabaté Solà2025-12-151-18/+30
| | | | | | | | | | | | | There was a condition race in which some conflicts would be caught but sometimes wouldn't depending on how/when `memory.memory_ranges` was being filled. Instead of this, just fill this vector with otherwise valid candidates (other checks like "is it used?" still apply in this context), and then perform the conflict check upon the already filled vector. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow constants in asan:reserve statementsMiquel Sabaté Solà2025-12-156-29/+104
| | | | | | | | | | | | | | | | 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>
* xa65: use the current timestamp for the tmp directoryMiquel Sabaté Solà2025-12-151-2/+8
| | | | | | | | | | The easy "let's count how many directories there are in /tmp" trick was prone to errors. Hence, let's make things (hopefully) easier by just appending the current timestamp in milliseconds to the directory name. Fixes: 4961b715328d ("xa65: better ensure the name of the tmp directory") Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* asan: addresses >= 0x2000 cannot be reserved spaceMiquel Sabaté Solà2025-12-151-10/+15
| | | | | | | These addresses are merely references to real APU/PPU addresses which can be used for ease of use. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Report on multi-byte values on arithmetic evaluationMiquel Sabaté Solà2025-12-151-0/+32
| | | | | | | | | | | | | | | When evaluating an arithmetic operation, check on whether it theoretically spans more than one byte, and set it on the resulting Bundle.size. It's up to the caller to decide on whether that makes sense or not. This fixes situations in which: sta $200 + 1 was marked as having 2 bytes for the size as only the "1" was being considered for the size on this operation. This would then signal the "sta" evaluation that it was zeropage instead of absolute addressing. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Forbid to .include something which is not a fileMiquel Sabaté Solà2025-12-151-17/+17
| | | | | | | This is the next step coming from commit d64ed8c531b0 ("Do not allow empty strings on .include"). Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Do not allow empty strings on .includeMiquel Sabaté Solà2025-12-151-0/+24
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* xa65: better ensure the name of the tmp directoryMiquel Sabaté Solà2025-12-141-2/+2
| | | | Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* Allow asan:reserve to receive an usizeMiquel Sabaté Solà2025-12-144-26/+34
| | | | | | | This allows for reserving memory regions which go outside of the page boundary. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* nasm: Better wording on the README fileMiquel Sabaté Solà2025-09-191-5/+19
| | | | | | | | | Instead of only bringing up the pedantic nature of nasm, also note on some of its improvements over ca65. Also, some minor grammar fixes here and there. Signed-off-by: Miquel Sabaté Solà <mssola@mssola.com>
* xixanta: Don't allow negative variables on asanMiquel Sabaté Solà2025-09-121-4/+41
| | | | | | | | | | | | | | Negative variables make no sense when it comes to do stuff like: variable = -1 lda variable That being said, as an assembler you never know the hacks and nonsense programmers are willing to endure. But we do know that if the address sanitizer is enabled, since if it's an "asan-friendly", then an explicit negative variable can be barred. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* readrom: Add detection of RAM, Timing and mirroringMiquel Sabaté Solà2025-09-121-8/+40
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* header: Add RAM and CPU/PPU Timing detectionMiquel Sabaté Solà2025-09-121-2/+141
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* header: Add one/four screen nametable supportMiquel Sabaté Solà2025-09-121-13/+74
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Update README on asan:ignore also affecting instructionsMiquel Sabaté Solà2025-09-041-9/+6
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Move and expand the README on nasmMiquel Sabaté Solà2025-09-042-33/+181
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* scripts: Remove the usage of asan in most examplesMiquel Sabaté Solà2025-09-041-18/+22
| | | | | | | | | The examples listed here don't follow the basic rules required by the address sanitizer either for learning purposes or out of simplicity. Hence, let's disable it for all cases and we'll bring it back for future repositories. Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* asan: Add fixes on absolute/indirect addressingMiquel Sabaté Solà2025-09-033-1/+11
| | | | | | 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-032-1/+15
| | | | | | | 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-034-0/+101
| | | | | | | 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-035-9/+204
| | | | | | | | | | | | | 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-027-31/+93
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* Split the --stats and the --strict flagsMiquel Sabaté Solà2025-09-023-36/+48
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* assembler: Preserve the original working directoryMiquel Sabaté Solà2025-09-021-0/+10
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>
* parser: Allow .include inside of .scopeMiquel Sabaté Solà2025-09-021-6/+21
| | | | Signed-off-by: Miquel Sabaté Solà <mikisabate@gmail.com>