Has someone secretly replaced you withrainwarrior wrote:Most likely even existing games could be patched to meet a reasonable subset of capabilities
PowerPak mapper 30 implementation
Moderators: B00daW, Moderators
Re: PowerPak mapper 30 implementation
I was assuming four pages for the save, with stated capacity being two pages and two extra used as the head and tail for wear leveling. I thought one would have to use more than one page anyway in order for the save to persist even if the Control Deck powers down during saving. Furthermore, a partially written page is hard to avoid on a board with no PRG RAM, as each page is bigger than the 2 KiB internal work RAM.
Folgers Crystals a Front Fareast representative?
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: PowerPak mapper 30 implementation
Well, the PowerPak isn't the same as a PC emulator where most relevant resources are effectively unlimited.tepples wrote:Has someone secretly replaced you withFolgers Crystalsa Front Fareast representative?
So, comparing it to an FFE copier device may be apt? Though really the problem is that PowerPak was designed to be able to compatibly reproduce what already existed in carts. Flash is a new constraint that it wasn't prepared for.
So... yes, a "flash trainer" patch seems completely reasonable to me for the situation? Though obviously a game written with the subset in mind wouldn't have to be patched, that's the point I'm making here.
If you need to test flash, run on a flash board. Those are relatively inexpensive and easy to use at this point. If you want to play a game, the difference between flash and some compatible subset is unimportant. For the latter it's a lot more practical to just patch a problem game than expect exiting emulators to change.
I feel like there's probably a simpler way to address that problem...tepples wrote:I thought one would have to use more than one page anyway in order for the save to persist even if the Control Deck powers down during saving.
Re: PowerPak mapper 30 implementation
So trying this out on the Everdrive, the hardware implementation was actually dead-easy, and in an evening I could get Black Box challenge saving my progress.
Haven't tried it for the Powerpak yet, but don't expect much problems there either.
The implementation just recognises the write-byte sequence as documented in https://wiki.nesdev.com/w/index.php/UNROM_512 or in the official data sheet for the PRG-flash chip.
No handling of cleared pages has been attempted, nor trying to emulate the "everything written is a binary and with $FF after clearing".
That does mean the rule would be "make sure to write every byte you intend to read back after clearing". That means it's not really emulating. But honestly, I can't see why this would be a limitation for 99.9% of the software we'll see used on mapper30.
I'm happy to discuss improved schemes to get it slightly more compatible. But only for valid software intended to ship in the near future. And that does NOT include devil's-advocate-tech-demos intended to show flaws we already know exist with this implementation.
However, as is often the case, the simplicity of getting hardware working betrays the other-people's-code troubles when it comes to fixing the software to make the saves truly persistent...
For the Everdrive, there's not much I can do without Krikzz's assistance to update the Everdrive OS.
So I've tried tackling the Powerpak instead, seeing how the full source code is available at http://nespowerpak.com/
I've managed to write to the CF-card in a hacked .MAP module of my own, and that's fairly straightforward. But an unexpected nasty surprise has cropped up: It appears that to load directories, the Powerpak boot ROM regularly trashes the PRG-ROM space. All following the logic that this is a free RAM area the OS can use at will, because the data is never used after you've finished playing the game...
The routines needed to load the LASTNES.TXT file in the POWERPAK directory (which is what you need in order to know the cluster number to seek to to read/write the iNES file) are even hard-coded to set the bank number to the PRG area.
Duplicating those full routines into a .MAP module of my own is not feasible, because modules can only be 1kB in size. Hence my current attempts have been trying to copy the "pre-amble" of various OS functions into a .MAP module to set the bank to the WRAM instead, then jumping into a later phase in each function. This makes me feel quite uneasy, as I would be baking in assumptions about code not moving around inside the boot ROM. Though I suppose in practice the boot ROM is unlikely to change with the Powerpak software having been in a de-facto abandonware state for years now.
But after a few attempts at this, it occurred to me that there's still no way I can fix this without changing the boot ROM. Any module the boot ROM will load using the CardLoadModule function after reset will trash PRG-ROM when trying to read the POWERPAK directory, even when booting into the Q.MAP options screen that makes queries you for whether to save. By the time that has happened and my .MAP module is in control, the damage is already done. So the only way to fix it would be to change the boot ROM itself.
And apparently you need a CopyNES to flash the Powerpak boot rom? I still haven't got the one I bought years ago assembled. And even if I did, I can't expect people to get one just to get saving working in Mapper30 games. That's just a no-go for this implementation.
So my next "creative" idea for how to resolve this is yet-another hack: Have the mapper30 implementation on Powerpak enable writing to BOTH the WRAM and the PRG-ROM simultaneously for the first 8kB bank.
Assuming this is possible (and I guess it should be if you just enable the write sigal for both chips). By the time all the boot OS has done it's trashing of the PRG-ROM and loaded the LASTNES.TXT data for me, I can restore the PRG-ROM contents using the WRAM page that the Powerpak respects. While in theory a FAT directory could hold up to 65536 entries, as long as people don't put random crap in the POWERPAK directory of their CFs , the boot ROM shouldn't get a chance to trash enough of the PRG area.
This would obviously take advantage of Mapper30 being spec:ed as a mapper that has no WRAM, meaning no possibility for future WRAM upgrades to Mapper30 are possible to get working on this Powerpak implementation.
But I suppose that's a necessary evil, unless someone has a better idea... suddenly that "hack" of jumping to a WRAM trainer which directly writes the CF card doesn't seem as far-fetched.
Haven't tried it for the Powerpak yet, but don't expect much problems there either.
The implementation just recognises the write-byte sequence as documented in https://wiki.nesdev.com/w/index.php/UNROM_512 or in the official data sheet for the PRG-flash chip.
No handling of cleared pages has been attempted, nor trying to emulate the "everything written is a binary and with $FF after clearing".
That does mean the rule would be "make sure to write every byte you intend to read back after clearing". That means it's not really emulating. But honestly, I can't see why this would be a limitation for 99.9% of the software we'll see used on mapper30.
I'm happy to discuss improved schemes to get it slightly more compatible. But only for valid software intended to ship in the near future. And that does NOT include devil's-advocate-tech-demos intended to show flaws we already know exist with this implementation.
However, as is often the case, the simplicity of getting hardware working betrays the other-people's-code troubles when it comes to fixing the software to make the saves truly persistent...
For the Everdrive, there's not much I can do without Krikzz's assistance to update the Everdrive OS.
So I've tried tackling the Powerpak instead, seeing how the full source code is available at http://nespowerpak.com/
I've managed to write to the CF-card in a hacked .MAP module of my own, and that's fairly straightforward. But an unexpected nasty surprise has cropped up: It appears that to load directories, the Powerpak boot ROM regularly trashes the PRG-ROM space. All following the logic that this is a free RAM area the OS can use at will, because the data is never used after you've finished playing the game...
The routines needed to load the LASTNES.TXT file in the POWERPAK directory (which is what you need in order to know the cluster number to seek to to read/write the iNES file) are even hard-coded to set the bank number to the PRG area.
Duplicating those full routines into a .MAP module of my own is not feasible, because modules can only be 1kB in size. Hence my current attempts have been trying to copy the "pre-amble" of various OS functions into a .MAP module to set the bank to the WRAM instead, then jumping into a later phase in each function. This makes me feel quite uneasy, as I would be baking in assumptions about code not moving around inside the boot ROM. Though I suppose in practice the boot ROM is unlikely to change with the Powerpak software having been in a de-facto abandonware state for years now.
But after a few attempts at this, it occurred to me that there's still no way I can fix this without changing the boot ROM. Any module the boot ROM will load using the CardLoadModule function after reset will trash PRG-ROM when trying to read the POWERPAK directory, even when booting into the Q.MAP options screen that makes queries you for whether to save. By the time that has happened and my .MAP module is in control, the damage is already done. So the only way to fix it would be to change the boot ROM itself.
And apparently you need a CopyNES to flash the Powerpak boot rom? I still haven't got the one I bought years ago assembled. And even if I did, I can't expect people to get one just to get saving working in Mapper30 games. That's just a no-go for this implementation.
So my next "creative" idea for how to resolve this is yet-another hack: Have the mapper30 implementation on Powerpak enable writing to BOTH the WRAM and the PRG-ROM simultaneously for the first 8kB bank.
Assuming this is possible (and I guess it should be if you just enable the write sigal for both chips). By the time all the boot OS has done it's trashing of the PRG-ROM and loaded the LASTNES.TXT data for me, I can restore the PRG-ROM contents using the WRAM page that the Powerpak respects. While in theory a FAT directory could hold up to 65536 entries, as long as people don't put random crap in the POWERPAK directory of their CFs , the boot ROM shouldn't get a chance to trash enough of the PRG area.
This would obviously take advantage of Mapper30 being spec:ed as a mapper that has no WRAM, meaning no possibility for future WRAM upgrades to Mapper30 are possible to get working on this Powerpak implementation.
But I suppose that's a necessary evil, unless someone has a better idea... suddenly that "hack" of jumping to a WRAM trainer which directly writes the CF card doesn't seem as far-fetched.
Re: PowerPak mapper 30 implementation
This does raise a certain point though. According to the wiki, the Mapper30 interpretation sort-of-overloads the battery bit to mean two distinct things:One thing this makes me realize is that I think NESMaker games have the battery backed bit set in the header by default. I notice because the PowerPak offers to save it after long-reset. (Not really a problem... but it's probably just saving garbage from $6000. I think the real fix for this is really NESMaker shouldn't set that bit unless games actually use a save.)
1) That the game may write to the flash-ROM for saves
2) That "no bus conflicts should be emulated. On the other hand, bus conflicts should be emulated if the battery flag is cleared."
But the current ROMs produced by NESMaker rely on bus conflicts NOT being present. I just verified this by trying some of the "ByteOff" competition entries, and they all write to $C000.
I suppose we could ask JoeG to make NESMaker more compatible, by adding a $FF to that $C000 memory location? The even-more-compatible way to have a full 256-byte table might be seen as too much of a waste in the crammed fixed bank.
As things stand though, this puts me in a bit of a dilemma as to whether I should emulate these bus conflicts or not. On one hand, I'm all for correctness. But on the other hand, I know that the majority of Mapper30 games coming out will be NESMaker games. And I have a sort of personal stake in this as well: The fact that I think selling all those low-end Mapper30 cartridges to the NESMaker folks is really a missed golden opportunity to bring the two really Powerful NES flash cart solutions we've had around for years to a wider audience, and allow more homebrewers who want to target MMC3 and beyond to benefit from digital distribution.
And making a less-compatible-with-NESMaker works against that end. As long as that annoying battery bit is set, it won't be a problem. But the moment someone figures out that clearing it avoids creating garbage .sav files, we'll also get more ignorant comments about the limitations of Powerpak / Everdrive Mapper30 compatibility, and how the "true" Mapper30 flash cartridges are the only way to go.
Which makes me sort-of-lean toward a re-interpretation of Mapper30 coding guidelines as just-make-no-assumptions-about-bus-conflicts. Programming your game to avoid bus conflicts and only writing to $C000 should ensure it works both on a flashable mapper30 cartridge, and on the slightly cheaper alternative. After all, this is what emulators have done for years. And as stated before, the Powerpak / Everdrive mappers are just emulators in a slightly different form, with somewhat more vague specs than a discrete board.
What do you think?
Re: PowerPak mapper 30 implementation
I was under the impression that the Power Pak never enforced bus conflicts anyway...
Re: PowerPak mapper 30 implementation
Hmm, thinking about this again you might be right.I was under the impression that the Power Pak never enforced bus conflicts anyway...
I figured that because the memories are "TTL compatible" and their I/Os connected directly to the cart edge, the usual bus conflict behavior could be triggered by just leaving /OE low.
But checking the datasheet, it is still a CMOS device - you'd have a hard time finding true TTL parts these days. Which means it most likely doesn't have the bitwise-AND property of NMOS, despite the "TTL compatibility".
But if that's the case, then I'm even more sceptical of the "bus conflicts should be emulated if the battery flag is cleared" rule. The Mapper30 flash ROM data sheet linked to on the wiki page is a "TTL-compatible" CMOS part. If bus conflicts don't conform the bitwise-AND principle, then I'm not sure what the point of emulating bus conflicts that wouldn't even behave the same on an actual repro cartridge are. To emulate a condition that would only be true if you happened to make a repro using a rare 512kB 1980s EPROM?
So maybe this recommendation to emulate bus conflicts should be removed altogether from https://wiki.nesdev.com/w/index.php/UNROM_512?
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: PowerPak mapper 30 implementation
What do you mean "rare 1908s EPROM"? The RetroUSB boards made and released many games with had bus conflicts, did they not? That's the reason bus conflicts are stated. It was not some arbitrary choice, that's just what the hardware was.Bananmos wrote:If bus conflicts don't conform the bitwise-AND principle, then I'm not sure what the point of emulating bus conflicts that wouldn't even behave the same on an actual repro cartridge are. To emulate a condition that would only be true if you happened to make a repro using a rare 512kB 1980s EPROM?
So maybe this recommendation to emulate bus conflicts should be removed altogether from https://wiki.nesdev.com/w/index.php/UNROM_512?
The InfiniteNESLives ones are essentially always flashable, since that's how they have to be programmed. I realize the case you're thinking about is a distributed NES maker game in some read only configuration. Well, that's a new variation that hasn't existed before. (BTW, as far as I've seen NES maker's ROMs have their battery flag set?)
For compatibility emulators don't really have to emulate bus conflicts at all. For accuracy, it's required though. There's a lot of prior RetroUSB releases where that applied.
This is more or less the same situation as some other discrete mappers which had some bus-conflict-free variations. For that we just used the iNES 2 submapper field to specify bus conflicts or not:
Submappers for mappers 2,3,7
Give it a submapper and they can add that information to the header. Emulators that don't want to care about bus conflicts can ignore it, and maybe just make a note that bus-conflict free is a sensible default for submapper 0 (i.e. unspecified).
Re: PowerPak mapper 30 implementation
To be clear, I'm not questioning whether boards with bus conflicts are still being released. Of course they are.What do you mean "rare 1908s EPROM"? The RetroUSB boards made and released many games with had bus conflicts, did they not? That's the reason bus conflicts are stated. It was not some arbitrary choice, that's just what the hardware was.
All I'm saying is that if they don't follow the same oldskool NMOS behavior of "GND wins over +5V so you get a bitwise AND behavior" then there's not much emulators can do here to emulate it "properly". And if we're in undefined behavior area where you can't rely on bus conflicts behaving in an expected way because of chip differences, then the best sensible default is to just not emulate bus conflicts at all.
But this is just speculation. I haven't actually confirmed whether modern boards flash chips with TTL compatible output do or don't behave in the NMOS-fashion. If they do, perhaps my original idea of allowing bus conflicts on the Powerpak still has merit...
Re: PowerPak mapper 30 implementation
Even modern CMOS parts are still usually better at pulling down than up; e.g. Microchip PIC parts are capable of sinking about 2.5x as much current as sourcing. Similarly when making MOSFETs, "hole mobility" is about a third that of "electron mobility", so for an equivalent size and doping concentration in n-type and p-type MOSFET the n-type one will be capable of sinking three times as much current. Maybe some modern parts with really really hefty superdrivers could overpower the 2A03's pulldowns ... but I still wouldn't think it's likely.
I was under the impression—though I have absolutely no idea why—that the PowerPak didn't generate bus conflicts to preserve its own longevity ... if there's enough time to figure out the value in RAM before the CPU is hogging the data bus, maybe it could still emulate it, though.
I was under the impression—though I have absolutely no idea why—that the PowerPak didn't generate bus conflicts to preserve its own longevity ... if there's enough time to figure out the value in RAM before the CPU is hogging the data bus, maybe it could still emulate it, though.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: PowerPak mapper 30 implementation
To be honest, if the bus conflict behaviour isn't AND, then it's never actually been given an implementable specification. Further complication perhaps that FCEUX's implementation appears to just use 0 if there is any conflict, which I assume isn't correct either, though this is likely why NES maker ROMs use the battery flag, if you say it relies on a lack of bus conflicts. (Mesen seems to have some specification of bus conflicts but I'm not sure if this virtual function is used for anything?)
So... all that just adds credence to the thought that the unspecified default should be emulated without bus conflicts.
...though the unfortunate reality is that the most prevalent implementation (FCEUX / FCEUmm) is going to reject anything that relies on lack of bus conflicts without the battery flag until the next cycle of updates, whenever that is.
Regardless of what the recommended emulator implementation is for unspecified, I would still recommend that homebrew developers plan for bus conflicts, and NES maker too should probably stop relying on the battery flag as a workaround, but I can't dictate what they feel is important.
So... all that just adds credence to the thought that the unspecified default should be emulated without bus conflicts.
...though the unfortunate reality is that the most prevalent implementation (FCEUX / FCEUmm) is going to reject anything that relies on lack of bus conflicts without the battery flag until the next cycle of updates, whenever that is.
Regardless of what the recommended emulator implementation is for unspecified, I would still recommend that homebrew developers plan for bus conflicts, and NES maker too should probably stop relying on the battery flag as a workaround, but I can't dictate what they feel is important.
- rainwarrior
- Posts: 8062
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: PowerPak mapper 30 implementation
I modified my mapper 2 submapper test for mapper 30. This tentatively presumes the same submapper assignment as with the other 3 discrete mappers (0="unspecified", 1=no conflict, 2=conflict)
It also checks the presence or absence of the banking register at $8000. That should be entirely dictated by the battery flag, though.
Prebuilt ROMs are in the zip.
Looking at FCEUX and Mesen as existing implementations reveals to me how fragile and incomplete the common implementations are right now. The test of $8000 in particular seems to corrupt the flash for FCEUX, which it really shouldn't... (unless I did something catastrophically wrong).
It also checks the presence or absence of the banking register at $8000. That should be entirely dictated by the battery flag, though.
Prebuilt ROMs are in the zip.
Looking at FCEUX and Mesen as existing implementations reveals to me how fragile and incomplete the common implementations are right now. The test of $8000 in particular seems to corrupt the flash for FCEUX, which it really shouldn't... (unless I did something catastrophically wrong).
- Attachments
-
- 30_test_src.zip
- (26.85 KiB) Downloaded 412 times
Re: PowerPak mapper 30 implementation
Agreed. And I'd even go as far to say developers should go the 100% safe route and use a full 256-byte identity table to have an easy way to have the ROM exactly match the CPU value (as opposed to relying on NMOS behavior with a lone $FF byte).Regardless of what the recommended emulator implementation is for unspecified, I would still recommend that homebrew developers plan for bus conflicts, and NES maker too should probably stop relying on the battery flag as a workaround, but I can't dictate what they feel is important.
It might be seen as a "waste" of 256 bytes, but the identity table can be very useful for loads of other operations like "ADC Identity,X", saving you a few cycles and perhaps even bytes in the long run.
But even a lone $FF byte is an improvement in terms of compatibility.
Re: PowerPak mapper 30 implementation
It is, the base class will apply "AND" bus conflicts to register writes when this function returns true: https://github.com/SourMesen/Mesen/blob ... r.cpp#L816rainwarrior wrote:(Mesen seems to have some specification of bus conflicts but I'm not sure if this virtual function is used for anything?)
Re: PowerPak mapper 30 implementation
So my hacky solution for a mirrored write to WRAM for the first 8kB of PRG looks kind of successful: I can now successfully start Black Box Challenge from the CF card on my Powerpak, save the game, exit it by holding the power button, have my module write it back to the CF, and finally re-load the save the next time I start the game from a power-on . So looks like the bare bones of this is working 
There's quite a few things to iron out though... for some reason the simple Everdrive state machine for detecting the write sequence isn't working correctly on the Powerpak, and I have no idea why. So I've currently made it ignore the write sequence and pass any writes to $8000, which obviously isn't acceptable for a release as it might easily corrupt your game.
I'm also not really testing the writes to the lowest 8kB fully, as BBC never writes this one. Rather I'm only testing that the 6502 code which copies PRG to WRAM before loading the mapper and uses the first 8kB of WRAM when writing to the CF is working.
I also need to look at fixing the menus for flash-saving. I think I might actually just restrict it to auto-saving whenever Mapper30 is detected, as being able to select a new save file might trigger the problem of the boot ROM corrupting the PRG, if the user has all their ROMs in one / a few directories. Limiting it to autosave means it'll only ever try to read the root and the POWERPAK directory. (and yes, if those have thousands of files / directory entries then you are still screwed)
I'm running out of steam a bit now, but hope to have something working by next weekend.
I'll also try have a look at those mapper30 tests... is there any chance of adding some flash writing tests to those as well? Black Box Challenge has a very long unskippable intro sequence so it's not that great for debugging.
(I suppose I could quite easily write a simple one myself from the wiki example, but I'm a bit worried that I don't have a true mapper30 dev cart for more rigid testing of this feature)
There's quite a few things to iron out though... for some reason the simple Everdrive state machine for detecting the write sequence isn't working correctly on the Powerpak, and I have no idea why. So I've currently made it ignore the write sequence and pass any writes to $8000, which obviously isn't acceptable for a release as it might easily corrupt your game.
I'm also not really testing the writes to the lowest 8kB fully, as BBC never writes this one. Rather I'm only testing that the 6502 code which copies PRG to WRAM before loading the mapper and uses the first 8kB of WRAM when writing to the CF is working.
I also need to look at fixing the menus for flash-saving. I think I might actually just restrict it to auto-saving whenever Mapper30 is detected, as being able to select a new save file might trigger the problem of the boot ROM corrupting the PRG, if the user has all their ROMs in one / a few directories. Limiting it to autosave means it'll only ever try to read the root and the POWERPAK directory. (and yes, if those have thousands of files / directory entries then you are still screwed)
I'm running out of steam a bit now, but hope to have something working by next weekend.
I'll also try have a look at those mapper30 tests... is there any chance of adding some flash writing tests to those as well? Black Box Challenge has a very long unskippable intro sequence so it's not that great for debugging.
(I suppose I could quite easily write a simple one myself from the wiki example, but I'm a bit worried that I don't have a true mapper30 dev cart for more rigid testing of this feature)
Re: PowerPak mapper 30 implementation
I did notice one thing that caused some stack corruption crashes in emulators for me: you are doing "ldx $ff / txs" instead of "ldx #$ff / txs"Looking at FCEUX and Mesen as existing implementations reveals to me how fragile and incomplete the common implementations are right now. The test of $8000 in particular seems to corrupt the flash for FCEUX, which it really shouldn't... (unless I did something catastrophically wrong).
But apart from that minor bug, I found your test suite really useful. So much that I added 5 new tests for the flash: sector erase, simple write (writes without relying on AND-op behavior), AND-op dependent write, write protection check, and chip identification.
I'll PM you the source changes, and if you're happy with them maybe an updated version can be added to the wiki?
(I suppose it would be a good idea to test it on a real Mapper30 cartridge, just to be sure. Although I grabbed the example flash code straight from the UNROM512 wiki and just converted it to ca65, so there shouldn't be too much margin for error)