Comments (8)
Here's some loose thoughts:
The typical shadowing routine for a MMIO register on a one-register mapper (UNROM, CNROM, etc.) would be (written with ASM this time):
tax
sta _BANK_SHADOW
sta __rom_poke_table, x
In this situation, there's only one point during which an NMI can fire where the shadowed register no longer matches the real register: the write between _BANK_SHADOW
and rom_poke_table
.
The easy way to resolve that is to always write the shadow to the ROM at the beginning of NMI:
lda _BANK_SHADOW
tax
sta __rom_poke_table, x
This has the nice property of unlocking two new functionalities:
- the ability to write to the ROM without writing to _BANK_SHADOW, creating a bank change that will automatically undo itself at NMI, but invalidating getters,
- the ability to write to _BANK_SHADOW without writing to the ROM, creating a delayed bank change that will only apply at NMI.
Combined with re-applying _BANK_SHADOW at the beginning of NMI, this allows for "change CHR bank until vertical blank" handlers, as well as "change CHR bank at vertical blank" handlers - both very useful constructs! To borrow terms from the MMC1 bank implementation, I'm going to refer to the former as a "split".
Re-applying _BANK_SHADOW at the beginning of NMI also means that getters and setters will work correctly inside an NMI. The only case where they won't work correctly is "splits" - this should be appropriately documented; however, CHR banks don't tend to be paged in/out the same way a PRG bank would across calls, which makes me believe this won't be much of a problem in real-world use.
from llvm-mos-sdk.
This will work fine enough for those discrete mappers whose register corresponds to only one value (CNROM, UNROM). For UNROM-512, though, one needs to rethink it: we don't want a situation in which, say, writing _BANK_SHADOW to the register on set_prg_bank
also changes the CHR bank.
from llvm-mos-sdk.
More broadly this issue also should include IRQ handlers; I'm not sure what the current scope of behaviors are, but this case is considerably easier to handle, since interrupt state can be pushed/popped around critical sections and interrupts disabled to keep shadows and the MMIO registers observably identical.
from llvm-mos-sdk.
More broadly, from discussion in #198, if we can't identify a need for CHR shadowing, and the cost of keeping it consistent against NMI and IRQ is too high, it may be a good idea to either withdraw such functionality or mark it as possibly stale in the case of interrupts.
from llvm-mos-sdk.
I'm might be being too persnickety about IRQs; we can wrap various routines in PHP; SEI; ... ;PLP
if we want things to always work, but that imposes a 9 cycle and 3 byte cost to essentially every banking function that doesn't use the even more expensive retry approach I picked for MMC1 and MMC3. I'd leave it open to someone more experienced to the Nesdev community whether this is worth it.
from llvm-mos-sdk.
I think bank changing is sufficiently uncommon for this 9 cycle/3 byte cost to be acceptable. Worst-case, set/swap/split_chr_bank_unsafe
could be added which pushes the interrupt wrapping and other potential safety mechanisms on the end user.
However, I'm not experienced at NES development myself, either.
from llvm-mos-sdk.
I think it might be worth re-opening this issue (or creating a new one), as while #198 fixes the much more pressing NMI part of the issue, it does nothing about IRQs.
from llvm-mos-sdk.
Closing this one for now; I had become sufficiently far removed from the issue that I had forgotten how special handling of interrupts in C was in llvm-mos. None of the SDK banking functions are annotated with the relevant interrupt attributes, so none of them are safe to call from an IRQ or NMI. Even if they were, they'd still need the AXY calling convention to be practical. So, there may actually be too much logic in these functions to make them reentrant, at least in how they're legal to be called today (a descendant call of _start).
from llvm-mos-sdk.
Related Issues (20)
- Assembling invalid 6502 op-code without error message. HOT 2
- Providing programmatic access to program length HOT 1
- Broken links for file that has a filename that begins with an underscore
- ARM64 macOS binaries HOT 6
- cx16 kernal name confusion: cx16_k_savehl vs cbm_k_savehl HOT 5
- PCE: pce_joypad_read() only returning low nibble? HOT 4
- atari8-stdcard "--whole-archive linking" regression
- bitrot in wiki porting page HOT 2
- Trying to define a smaller MMC3 ROM results in a wrong sized output HOT 1
- MMC3 IRQ setup doesn't work "out of the box"
- Add new platform(s): Foenix F256 Jr & K HOT 5
- Separate out SDK test workflow from packaging
- start address is indeterminate (because of zp data section)? HOT 1
- Write a simplified libretro runner
- Complete the libc using pieces from pdclibc HOT 1
- Investigate making `text.fixed` for libcalls
- Automatically generated linker scripts lack CMake integration HOT 1
- Verify negative tests fail for the "right" reasons
- Reading directly from memory HOT 2
- Create a test workflow that runs on PRs
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from llvm-mos-sdk.