Edit- Based on the responses in this thread, there are no existing mappers that do what I would like to to. I'm going to create a separate thread in the hardware forum to discuss details on developing a mapper to do this since I think it would be very powerful and useful.
Original post in italics.
I didnt want to pollute the smurfs thread with my question so here it is, although my motivations are the same (to provide decent animations).
Are there any mappers that allow the CHR data to be bank switched
(4K chunks preferred) from PRG RAM?
I've looked at Videomation (CPROM) and I dont think it would do what I want. You can swap CHR banks from RAM, but you would not be able to write to that RAM unless it was switched in.
What I want to do is write to RAM that is not being used by the PPU, and then switch it in during VBlank, and then start writing to another unused block of RAM. This way I can update the equivalent of the next frame during the frame, and not just during VBLANK. That is why I figured it needs to be able to use PRG RAM.
Al
CPROM is the only Nintendo official mapper to feature more than 8KB of CHRRAM, but you could modify boards such as SGROM (and similar boards) or TGROM (and similar boards) to handle more CHRRAM by replacing 8KB chips by 32KB ones and wire the extra adress lines to the mapper.
SGROM (and similar boards) and TGROM (and similar boards) allows the CHRRRAM to be bankswitched among 4KB and 1KB chunks repsectively, but the total size of RAM available is still 8KB so this feature is pretty much worthles.
Besides, even CPROM allowed writing to CHR RAM only during vblank. You'd need a complicated set of latches and possibly multiple CHR RAM chips in order to allow the CPU to write to one CHR bank while the PPU reads another.
The only way to write to CHR RAM is to do so through the PPU or to create your own mapper with RAM which can be accessed by both the CPU (or mapper registers) and the PPU bus.
I think this would be an interesting mapper and not terribly hard to implement in the PowerPak (using WRAM as additional CHR RAM), but it probably won't be easy to get implemented in emulators.
Since VRAM can be made accessible to the CPU using this same method, it could be pretty powerful mapper with clever programming. The only issue is keeping both RAM's in sync for normal style games which is costly in CPU time.
This could partially be solved though if the mapper has a setting to write to both RAMs at the same time (would need to be during Vblank)
kyuusaku wrote:
The only way to write to CHR RAM is to do so through the PPU or to create your own mapper with RAM which can be accessed by both the CPU (or mapper registers) and the PPU bus.
Yes this is what I was wanting. I was reading about SOROM but I;m not sure it would do what I want.
http://nesdevwiki.org/wiki/index.php/SOROM
Al
No current mapper will do what you want, you've gotta make it.
Here's how I'd do the mapper:
r $6000-7FFF - currently mapped CRAM
w $8000-FFFF - mapper write
D4-0 = select 16k bank at $8000-BFFF ($C000-FFFF fixed to last)
D5 = mirroring
D6 = CRAM0/1 mapped to $6000-7FFF (the other RAM is selected by the PPU)
D7 = tie both CRAM's /WE and /CE together (to sync RAMs during Vblank)
With SOROM would I not be able to do the following:
For odd frames:
During VBlank: bank switch to PRG RAM bank 1 ($A000-$BFFF)
During frame render: write the next CHR update to PRG RAM bank 2($C000-$DFFF)
For even frames:
During VBlank: bank switch to PRG RAM bank 2 ($C000-$DFFF)
During frame render: write the next CHR update to PRG RAM bank 1($A000-$BFFF)
I realize I would not be able to bank switch at a small granularity (I am stuck with 8K chunks) but I would still be able to accomplish the end goal which is to do massive animations without having to turn off the display.
That is assuming I can update up to 8K of PRG RAM in 1/60 of a second
EDIT- Ooops. I dont know what I am saying. $A000-$DFFF isnt PRG RAM.
Al
Rule #1: Don't update PPU memory using $2006/$2007 during rendering.
What should really be made is a dual port or pseudo-dual port CHR RAM/VRAM RAM board :) Should be possible with PowerPak.
I understand what you are saying now. I mistakenly thought all 16 KB of PRG RAM was accessable without swapping between them. Obviously its not, and I cant safely switch because part of its in use by the PPU.
Thanks,
Al
You guys are completely confusing CHRRAM with SRAM, wich are two completely different things. SOROM allows SRAM to be bankswitched, while CPROM allows CHRRAM to be bankswitched. No mapper will ever allow CHRRAM to be written to outside of VBlank, until you have a dual port SRAM. This will most likely never be possible with the power pack either.
That is not true, you can allow *ONE of TWO* CHR RAM to be written outside of Vblank by the CPU as long as it's disconnected from the PPU bus. All it takes is an address bus multiplexer and bi-directional tri-states or multiplexers on the data lines + control logic. Since WRAM is entirely connected to the FPGA in PowerPak, it is possible to use it for any general purpose storage.
The key thing is that you need a address and data bus from the CPU to the inactive CHR RAM, and an entirely separate address and data bus from the PPU to the active CHR RAM. Further, once you switch which is the active one, you need the same buses to opposite chips. This requires a lot of logic to disconnect and reconnect each bus appropriately, or a dual-ported RAM. No simple modification to an existing mapper board will do this.
kyuusaku: So the PowerPak has two SRAM chips, one usually used for CHR RAM/ROM and the other for WRAM? That'd be nifty for implementing this.
I worked on a schematic a couple years ago for a CPU-PPU RAM sharing thing. It uses 5 74HC573s, a 74HC245, a 74HC257, and a small PLD. Throw on a PRG-ROM and CIC and there's 11 chips already.
PPU can read and write with it, CPU can only write to it. I think I was last stuck on figuring out how to generate a /write signal. I never built it.
It is NOT possible to disconnect the PRG or WRAM chips in the PowerPak from the CPU bus, nor is it possible to disconnect the CHR RAM from the PPU bus. This is because the PRG and WRAM chips get address lines A0-A12 directly from the CPU (only A13-A18 come from the FPGA), while the CHR gets A3-A9 from the PPU directly (with A0-A2 and A10-A18 coming from the FPGA). The only resource in the PowerPak that can be shared between the CPU and PPU is the internal 2K of RAM (called "FRAM" if I recall correctly). This was done in anticipation of the MMC5's EXRAM.
My bad, I thought all WRAM A lines were connected and assumed that CHR RAM could be disabled...
I guess we need a more flexible FPGA device now :D
This is what I was thinking of:
It can be made with a main register, ~10x 74157, 4x 74245 and a lot of glue or a CPLD with a lot of I/O. It could actually be made entirely out of 74245 (~14) and glue too instead of the multiplexers.
Based on the responses in this thread, there are no existing mappers that do what I would like to to. I'm going to create a separate thread in the hardware forum to discuss details on developing a mapper to do this since I think it would be very powerful and useful.
Al
No mapper is able to swap CHRRAM and SRAM, as it'd require very heavy circuits, as already mentionned. Plus, the software would have to waste a lot of time copiying stuff from one RAM to the other that this wouldn't even be optimal. Well, let's be frank, no matter ever had such a feature, and I'm 99.99% sure no one ever will. While not technically impossible, it'd be so complicated, boring, and ineficiant to do that nobody would be interested, and the thing can be considered impossible. So just stop askig qustions, MIX UP CHRRAM AND SRAM *IS* IMPOSSIBLE. And YES, I DO know electronics.
You'd want to use classical CHRRAM or CHRROM a clever way instead, and at least you're sure this works. The smurfs are able to do a lot of CHRRAM writing because of PAL timing, this game couldn't even run on NTSC without major changes.
If you really want to take both CHRRAM and CHRROM advantages at once use TQROM (or a simple modification of it) that's possible because Pinbot carts aren't too rare.
You sure about smurfs? I only see up to 12 tiles being updated each frame. Battletoads updated more.
The smufts doesn't artificially make a longer VBlank, Battletoads NTSC does (I think Battletoads PAL doesn't, but I'm not sure).
Quote:
So just stop askig qustions, MIX UP CHRRAM AND SRAM *IS* IMPOSSIBLE.
That's totally uncalled for, and technically incorrect. If you're not interested in exploring this topic further, please ignore this thread rather than telling the poster to stop inquiry into it.
Bregalad wrote:
So just stop askig qustions, MIX UP CHRRAM AND SRAM *IS* IMPOSSIBLE. And YES, I DO know electronics.
Impossible to engineer as far as a one-of-a-kind prototype? No. Impossible to replicate in lots of 100 at an affordable price? Likely.
Bregalad wrote:
The smurfs are able to do a lot of CHRRAM writing because of PAL timing, this game couldn't even run on NTSC without major changes.
It works fine in NTSC mode in emulators... haven't tested on hardware.
About the topic, I do find this a bit pointless. This discussion about this "new mapper" may even live for a few more posts and threads, but it will surelly die long before something concrete is done about this, like so many other crazy ideas discussed here.
I'm not against discussing ideas and all, but sometimes I feel that people in here discuss too much about such crazy ideas, and very few of them ever come out of the paper. They could often be making better use of their time...
In the case of this thread in particular, I don't even think this discussion is justified... There are probably many other ways to do what the poster wants, simpler ways. Much simpler than designing a crazy-ass bulky cart impossible to reproduce...
One suggestion: Use MMC3 or another mapper that switches CHR ROM in 1 KiB chunks. Flicker the sprites if you have more than four independent objects, like one of the Final Fight games does. You'll eventually need to flicker anyway if you have more than two objects, as you can only fit two 32-pixel-wide objects on one scanline due to the 64-pixel limitation in the PPU's scanline buffer.
Another suggestion, if you prefer CHR RAM: Slow your game to 30 fps. Update the palette, nametable, and OAM only on every second field. This should give you at least 320 bytes (20 tiles) of CHR updates per frame: 256 on frames when you don't update the palette and nametable and 64 more on frames when you do.
Thanks for the replies fellows. You can consider the topic finished
I'll try using the tecnhnique in the smurfs thread to squeeze in 16 tile updates per vblank, and I'll be doing the Sprite DMA every 2 frames (30 fps) so that I can update both 32x32 pixel (4x4 tile) fighters. I'm a lot more comfortable with software than hardware anyways.
If I get the game going, I'll post about it.
Al
Quote:
It works fine in NTSC mode in emulators... haven't tested on hardware.
Then you should have played in on Nesticle....
The smurfts does absolutely no special technique at all, not even unrolled loops or anything. It just make good use of PAL timing as opposed to NTSC timing. Do the same thing on NTSC would be a lot more complex and require a lot of trick.
And yes, what I meant is that when you can do a trick by software or by hardware it's always better to do it by software, as it's emulatable and so on.
Create new mappers is a crazy idea but why not if they can be reproducted using the powerpack or another decently doable *real* prototype. A cart needing 27 chips of 16 pins each fitting a NES cart case and that will never be possible with the powerpack either is not what I call a doable prototype. I had trouble to route a board with arround 5 additional chips (with ROM and RAM and without even a CIC) that I never made until now, but I don't think more than ~6 additional chips is even possible, even if the chips are small and if rooting is very convenient.
Updating OAM less than every frame is a bad idea IMHO, as it might give you jerky movement. A better idea would be to update OAM every frame, but only change the character's tiles (and the tile indices in your OAM buffer) at every second frame, or possibly as rarely as every fourth frame. The principle is that jerkiness in the character's framechanges is much less noticeable than jerkiness in the overall movement. Battletoads does something like this.
Also, if you can accept having more of a letterboxed view in your fighting game, then artificially extending your vblank period by manually blanking the screen is a good solution. For a fighting game, the threat comes from the sides anyway, so the player won't feel handicapped by not being able to see as much of the sky/ground as in a platformer. Merely blanking the top and bottom 8 scanlines (which most NTSC TVs cut off anyway) will give you enough cycles to write an additional 14 tiles each frame. (just a rough calculation :)
Yes, artificial blanking is the way to go, and as Banamnos said you should update OAM every frame. Anyways, you wouldn't want the character to change graphics each single frame no matter how much limitations there is. So change each character each frame out of 4 will look abolutely normal in fact, this isn't even jerkiness at all. Updating OAM one frame out of two would be jerkiness, and it would not gain a lot of time anyway.
I you need 2 frames to update all the tiles of each fighter, then each player will have it's tiles updated every 4 frames. If you consider that the NES runs at 60 frames per second, that'd result in 15 frames per second for the animations... that's pretty good for animation. You'll hardly need animations faster than that (it would even require a lot of space in the ROM to store so many tiles).
So, if you do update their positions every frame (sprite DMA), but only change the animation frame every 4 NES frames, it will probably feel smooth enough.
The only problem with updating the graphics little by little is that you can't just overwrite the previous tiles, because you do not want to change the graphics until all the new tiles have been loaded. So, even though a player only needs 32 tiles, you'll have to dedicate 64 tiles from VRAM to it, and alternate which 32 it uses every 4 frames.
But even then, both players will only use 128 tiles, so you still have plenty of tiles for effects, blood, backgrounds, etc.
May I suggest something? In frames where there is no need to update any player tiles (this should happen once in a while), you could use the time to update some background tiles for more dynamic backgrounds, such as the people watching the fights in Street Fighter games. It will not matter if their animation is not constant.
I appreciate the suggestions.
I'm going to move ahead and start trying some of them out.
Thanks again.
Al
tokumaru wrote:
The only problem with updating the graphics little by little is that you can't just overwrite the previous tiles, because you do not want to change the graphics until all the new tiles have been loaded.
I'm pretty sure this would be unnoticeable, however I can be wrong.
Also one animation all 4 frames is pretty fast in fact. In my game I animate things all 8 frames (by changin the tile used) for my player, and sometimes even less for other objects. However, those aren't the most detailed graphics either.
You just shouldn't mix up the change of the pose, and the movement of the object. The change of the pose can be rarified, not the movement of the object.
I had a little weird, but maybe workable, idea for a PowerPak mapper that could allow the CPU to access the CHR RAM when rendering is off:
When rendering is off (or during VBlank), to make direct writes, the CPU could set up registers for bits A0-A2 and A10-A18 (since according to dvdmth, those are the only bits of the CHR RAM directly available to the FPGA). Since the CHR RAM apparently gets its other bits (A3-A9) from the PPU's address bus, those bits must be updated through the PPU's native address register ($2006).
A crazy idea I had was to have the mapper hijack sprite DMA transfers and project writes to the CHR RAM, FRAM, extra RAM - this can be up to 2KB, according to the synthesis reports from the development kit - from the custom mapper. Note that this goes with if the assumption that the DMA data writes do show up on the CPU's data bus - if this is incorrect, please correct me and if you like, skip to the last paragraph.
In the extra RAM, there would be space for 2-byte words for each of the 256 bytes for each of a couple of transfers. For CHR RAM, these words would utilize 12 bits to represent bits A0-A2 and A10-A18 - PPU reg $2006 would set bits A3-A9, but they would need to be fixed for the transfer. In FRAM and exRAM modes, these words would represent the whole address. There would be extra bits in each word to determine whether to take the previous address and increase by 1, take it and increase by 32 (like the column increase mode in PPU reg $2000), or switch to a different address. A consequence of this is that if you don't need to update sprites - but you are still rendering sprites AND need to do those special transfers, you must run sprite DMA to update the sprites anyway.
A pseudo-HDMA during rendering could also be done for FRAM (if it is accessed by the PPU) - for each of the 18 garbage reads per scanline, a byte can be transfered, allowing for up to 18 bytes to be transfered per scanline. The bytes would be loaded off from the exRAM. But I have a feeling that unfortunately, CHR RAM cannot be written easily like this - the game would need to update $2006 during exact locations in the scanline - and that would not be very pretty. Such theoretical CHR RAM writes would mean that only one byte could be transfered for every 4 PPU cycles of garbage reads (since 1 CPU cycle is 3 PPU cycles).
I don't undestand all of what you are saying, however, keep in mind that CHRRRAM is only writable and readable by the PPU itself. During rendering, the PPU will read the CHRRAM (and name tables, attribute tables, etc...) via it's PPU bus, so all those devices are unacessible by the CPU and by the mapper no matter what.
Sprite DMA performs 256 reads on the CPU bus (not the PPU bus), and the destination is OAM and cannot be changed. Only the source can be changed.
Pseudo-HDMA as you mention is just not possible, the only thing you can do from the cartridge slot during rendering is basically bankswitching stuff. The only possible effect is to bankswitch things automatically very fast to simulate things, or possibly to replace the CHRR ROM/RAM with other stuff that could give other graphics, etc... You could do a mapper that could count the scanlines and automatically bankswitch CHRROM at a certain point, or even midscanline (that's what the MMC5 does in fact). However you cannot change scrolling or anything by hardware, software must operate this.
Bregalad wrote:
I don't undestand all of what you are saying, however, keep in mind that CHRRRAM is only writable and readable by the PPU itself. During rendering, the PPU will read the CHRRAM (and name tables, attribute tables, etc...) via it's PPU bus
During vblank, does the PPU drive the CHR address bus, or does it put the lines in high-Z?
Sorry if I sounded too confusing - I'll try to clarify some of the ideas - but it may overall be more or less confusing
:
XRAM would theoretically be extra 2KB of RAM inside the FPGA - the FPGA the PowerPak uses can use up to 6KB of extra RAM. FRAM only uses 4KB of that 6KB, so an extra 2KB defined in the custom mapper schematics is possible.
For the SpriteDMA hijacks, the mapper would watch for writes to $4014 to know that SpriteDMA is about to happen - allowing the mapper to make an accurate prediction. Based on this prediction, the mapper will take each byte read by the transfer (readable from the CPU's data bus), read a word from an address look-up table inside XRAM, and write to the address specified. Because of how the PowerPak's CHR RAM A lines work, certain bits must be fixed for the transfers to CHR RAM. Technically, the sprite DMA tranfers do update the sprites with irrelevant data - that's why once you're done with these special transfers, you need to do a real sprite DMA transfer. Of course, the mapper will be told whether to or not to hijack the reads from the data bus.
As for pseudo-HDMA, I thought of this based on the fact that there are 18 useless nametable reads in every scanline - so it doesn't really matter what the PPU is accessing during those reads. If FRAM is used by the PPU (for nametables or extra attributes), the mapper could read from XRAM and write to the FRAM directly.
Bregalad, I think you might be thinking that this is trying to allow the CPU to write to PPU directly or vice verca - but I intended for these ideas to have the mapper write directly to the in-cartridge chips the PPU uses - not through the PPU itself. Although, this would not allow the mapper to write to the PPU's internal 2KB VRAM.
I think I understand part of your original post. If you want to do your idea justice, give it a chance to be understood by going slowly, first describing the goal, then how it achieves that. What I understand is that you want to increase the amount of VRAM that can be modified during vblank, using a custom mapper. You observed that a sprite DMA transfer is able to copy 256 bytes in 512 CPU clocks, something the CPU could never dream of normally. You say that during the write portion of the sprite DMA transfer, the PPU is only driving a few of the address lines, so a custom mapper could perhaps drive the other lines as it pleased, and somehow write to CHR RAM during that time. I don't really grasp the idea, since surely the entire CHR address bus is driven, and the read/write lines deasserted. I would have figured you could just have a custom mapper write to CHR RAM as it pleased during vblank, since I don't think the PPU is accessing it at all then.
blargg wrote:
I don't really grasp the idea, since surely the entire CHR address bus is driven, and the read/write lines deasserted.
If you mean CHR address bus as in the CHR RAM chip's address bus, apparently, not all of the lines are directly available within the FPGA:
dvdmth wrote:
while the CHR gets A3-A9 from the PPU directly (with A0-A2 and A10-A18 coming from the FPGA)
And IIRC, the PPU's own address bus is readable only... :/
BTW, thank you for the advice regarding explanation. It's pretty good.
I'll try to make my explanation much clearer:
DMA Transfers: The goal for this is to transfer data to CHR RAM and FRAM much faster than writing manually. The NES's own Sprite DMA register reads 256 bytes for writing to OAM in only 512 cycles. A mapper could take advantage of this and have the register indirectly write to CHR RAM and FRAM as well.
Some of the important components needed for this mapper include - a CPU clock timer, an address bus and data bus latcher, and extra 2KB internal RAM (hereby called XRAM).
The mapper must watch for writes to the register - $4014 - by watching the address bus and CPU R/W signal. Once it detects it, it will wait for the actual write to $4014 to finish. Then, it will read off the bytes transfered by reading on every odd cycle of the transfer. The mapper would do this by using a CPU clock timer and reading off the data bus.
To write the byte read from the CPU, it must get the address to write to. The mapper does this by reading off 2-byte words from XRAM. These words determine the address written. They also have a special format as to whether to increase the previous address or to directly set a new address.
Note for CHR RAM Transfers only: Because of how the CHR RAM's address lines on the FPGA work, some of the bits must be set by PPU reg $2006 - those bits are fixed throughout the whole transfer.
Once it gets the word, it can write to CHR RAM or FRAM by requesting a write through the address bus + data bus input + write signals of the chip.
Of course, there would be a way to turn on or off the behavior with a simple register. If sprite rendering is needed, the program must conserve the sprites by turning off the mapper's behavior and doing a normal sprite DMA transfer.
As for the program simply directly writing to CHR RAM as it wanted to, I think that would be a simple register set - a mapper's address register to set most of the bits, $2006 to set the other bits, and a mapper's data register.
Since you can't freely control the address lines with the PPU driving them it won't work :( It's a shame the PPU lines aren't Hi-Z since then a FIFO-DMA mapper would be possible which in many ways is even better than CPU DMA. FIFO DMA is still available for VRAM inside the FPGA though :)
kyuusaku wrote:
Since you can't freely control the address lines with the PPU driving them it won't work
Is this all caused on the whole PCB? If not, couldn't the schematics and the other files for the FPGA be changed around a bit? While apparently, some of the CHR RAM address lines don't even touch the FPGA directly, maybe changing around the FPGA's files could make the address lines that
are available to the FPGA more flexible to use.
The problem is on the NES' side, not the PowerPak
Even with address trickery you can't use the FPGA to much extent without reworking since since 13 bits are necessary to address 8KiB and the FPGA only connects to 9 bits. To control the low bits, you'll always have to use $2006 unless you want to add more A lines to the FPGA and fight the PPU.
If you're going to rework the PCB, you could put a tri-states on the A and D bus between the CHR RAM and NES. If you connected up the rest of the A lines to the FPGA too you could do almost anything :D I dunno where you'll find the I/O though.
Technically, the FPGA connects to 13 bits, but not in the way to support 8KB, though - bits A10-A18 are missing and supposedly utilizes the PPU's bus on the PCB.
I do have a question regarding a few of the CHR RAM pins that are connected to the FPGA -
Why are pins A0-A2 and A10-A11 pretty weird? I can sort of understand about A10 - based on how it's connected to "crama10" it seems to be involved in the NES bus's CIRAM A10 signal. But A11 is connected to "crama11" - where does this come from? I do sort of understand A0-A2; I think they're buffers from the PPU bus in addition to A10-A18 on the PCB. I am still curious why only these pins (A0-A2 and A10-A11) are clocked off of the NES's main CLK, while the others available on the FPGA (A12-A18) aren't.
It also seems to look like we're only talking about FIFO-DMA - what about the pseudo-HDMA? Is that possible? If that needs to be clarified better:
Pseudo-HDMA: The goal of this is to allow bytes from memory being accessed by the PPU to be transfered during rendered scanlines - similar to the SNES's HDMA. Because of the problems with CHR RAM address lines, this will only concern VRAM within the FPGA.
The concept of this is based on how there are 18 garbage nametable reads (36 PPU cycles) and 1 resting PPU cycle per scanline. Therefore, writes accessing even FPGA-VRAM can be made during those 36 PPU cycles.
For NESes only, there are at most 148 bytes that can be transfered per scanline. This is because the NES has the NES_CLK available on the cart bus - since that is 4 times faster than the PPU's clock, that would allow for 4 bytes per PPU cycle - with 37 PPU cycles, that would mean 148 bytes.
However, unless you use some NES-to-Fami converter that happened to have the NES_CLK crystal, this would not work with Famicoms because they don't have NES_CLK. That would reduce the maximum number of bytes per scanline to 18 bytes per scanline - Famicom carts can still clock off the PPU /RD signal to keep track of the garbage memory accesses - but it cannot track down the resting cycle.
There would be a timer clocked off from - either NES_CLK (for NESes only) or PPU /RD. To determine what to clock off from, the mapper will watch $2002 reads for the VBlank bit to be set. Once it sees it set ASAP, it can start clocking off its timer to sync with the PPU.
The bytes to read off would be from extra RAM internal to the FPGA (not FRAM). There would be 4 scanline entries for each transfer - an entry per scanline wouldn't fit in the 2KB.
strangenesfreak wrote:
Technically, the FPGA connects to 13 bits, but not in the way to support 8KB, though - bits A10-A18 are missing and supposedly utilizes the PPU's bus on the PCB.
If there's 13 bits connected, you can control 8KiB worth of data, just not linearly. Unfortunately this means you'll need a crazy algorithm to write $2006 and the FPGA to get your data into the RAM at the right locations. I think this would be so confusing and slowed down by CPU writes that it'd be very hard to optimize for better performance than a normal CHR RAM games heh.
strangenesfreak wrote:
It also seems to look like we're only talking about FIFO-DMA - what about the pseudo-HDMA? Is that possible?
It's possible if you write to a FPGA register after a NMI which counts until a particular Hblank. But you since you're limited to DMAing to VRAM, would it be worth it?
strangenesfreak wrote:
For NESes only, there are at most 148 bytes that can be transfered per scanline. This is because the NES has the NES_CLK available on the cart bus - since that is 4 times faster than the PPU's clock, that would allow for 4 bytes per PPU cycle - with 37 PPU cycles, that would mean 148 bytes.
Why not use the PowerPak's 20MHz clock instead? It's only ~1 MHz less than "NES_CLK" and "NES_CLK" isn't necessarily in phase with M2 anyway.
It sounds like you've got it all worked out, give it a try and show us something cool!
I don't have a PowerPak yet - maybe until Christmas or my birthday...but I might want to try create a mapper anyway, heh
Where's the PowerPak's own clock, though? I can't see it anywhere for some reason...
Can't tell you since I don't have ISE installed but it's there-- it's what clocks the block RAM.
I assume you are referring to FRAM...I checked the schematics and it appears that it's clocked by "nesclk". However, it's really strange, because for the symbol definition and schematics for FRAM, the clock is labeled "m2", but "nesclk" is being fed into "m2" for the FRAM symbol...but either way, I think it uses one of the NES's clocks and not a PowerPak internal clock.
It's the 20MHz oscillator because I don't have NES, only FC.
What you describe is certainely possible, however I'm not sure it's possible with the power pak (I'm not sure how it's wired anyway).
What you need is to have tri-state buffers between the PPU adress AND control bus and the CHR-RAM. Then the mapper could force the PPU to become tri-state (trough the tristate buffer), and highhack all dummy reads to take advantage of this time to write to CHRRAM.
However, in VBlank, the PPU line is not tristate, /RD and /WR are normally high. $2006 contol more or less directly the adress but, and whenever the CPU reads or write $2007, /RD and /WR respectively will imediately go low (exept if the adress is in $3f00-$3fff range). The data bus should always be high-Z exept when writing.
So if you're sure the PPU is only reading, you could highhack the /WR line to low (with a multiplexer or something), highhack the adress bus, and write your stuff. Having part of the adress controlled with $2006 is possible during VBlank, I doubt it's possible during HBlank.