COOLGIRL

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
COOLGIRL
by on (#237531)
I am studying the NintendulatorNRS implementation of Mapper 342 and I noticed that it's missing the 4M of save flash. Any consequences to omitting the flash?
Re: COOLGIRL
by on (#237533)
The consequence is that you cannot save.
Re: COOLGIRL
by on (#237534)
NewRisingSun wrote:
The consequence is that you cannot save.


What does COOLGIRL enable you to save? That flash is huge.
Re: COOLGIRL
by on (#237535)
It has several games that originally had battery-backed RAM, so they all get saved to different sections of the flash memory. That makes the Coolgirl multicarts compare favorably to the "Best Games of NES" multicart (which uses the Coolboy/Mindkids mapper), which only has 8 KiB of battery-backed RAM, meaning that you lose your save any time you try another WRAM-using game.
Re: COOLGIRL
by on (#237541)
Beating a dead horse, but it really is a shame that every NES emudev has to reimplement 342+ mappers each. Some of them (*cough* VRC7 OPLL) are truly hellish to support. I *really* don't want to spend time emulating this mapper's flash chip. Flash write command queues and timings for erase cycles and suspend/resume support on them are always a royal pain to code.

So many things on PCs are nice and modular, but the closest we've ever gotten on the NES were DLLs that would only run on Windows emulators, or C source that only worked if you were writing a C/C++ emulator or wanted to write bindings to another language for them and compile it yourself.

It'd be super cool if one person could write a portable block of code to run mapper 342 with flash, and people included this file with the game, and a large number of NES emulators could just use that.

And hey, bonus, iNES no longer matters, so just leave it there anyway for compatibility.

I'm facing the same issue with MSX right now, endless mappers, only there's no iNES header to even hint at what to do.
Re: COOLGIRL
by on (#237543)
It makes you wonder if it'd be worthwhile to write the mappers in WebAssembly and have emulators run them in a JIT.
Re: COOLGIRL
by on (#237544)
byuu wrote:
So many things on PCs are nice and modular, but the closest we've ever gotten on the NES were DLLs that would only run on Windows emulators, or C source that only worked if you were writing a C/C++ emulator or wanted to write bindings to another language for them and compile it yourself.

It'd be super cool if one person could write a portable block of code to run mapper 342 with flash, and people included this file with the game, and a large number of NES emulators could just use that.
The idea of "what if we just came up with a generic language to describe the hardware" is one of those things that sounds like a solution, but in practice is always a "now you have two problems" situation. In practice, this means that every emulator would either have to treat these extended descriptors as opaque identifiers to be mapped to preƫxisting optimized code, or would have to include a logic simulator ... and, in turn, an optimizing compiler.

Unfortunately, if this language is low enough level to describe ASIC mappers, now you have a problem even worse than bad headers: bad descriptions. If the language isn't low enough, it's almost useless, because the effort to provide the abstraction of MMC5-the-IC is not really different from the effort to implement mapper 5, and the effort to implement 005-00002-010 is not really different from the effort to implement mappers 36, 132, and 173. And that's ignoring things where there just isn't good reference information, like chips-on-board, which basically have to be reverse-engineered entirely as black boxes.

Several Flash vendors provide Verilog implementations of their ICs' programming interfaces. The problem is, they're neither accurate nor precise, but instead just another way of rephrasing the corresponding JEDEC standard.


Now, just to be clear: I think it would be really cool to be able to connect random 74xx parts to random signals in an emulated NES. It's just not a good general purpose solution.

(this was my post #8250, the serial UART in the original IBM PC)
Re: COOLGIRL
by on (#237545)
byuu wrote:
It'd be super cool if one person could write a portable block of code to run mapper 342 with flash
The designer of the Coolgirl board provided an FCEUX source code file that includes the flash rewrite part, also linked to at the bottom of the mappers's wiki page.

Edit: dang, it has been deleted. I am temporarily attaching it.
Re: COOLGIRL
by on (#237550)
Quote:
It makes you wonder if it'd be worthwhile to write the mappers in WebAssembly and have emulators run them in a JIT.


The worst thing you could do is require a framework like Electron to use it. That'll ensure no one ever supports it.
My thought was always to reuse the 6502 core that every emulator already has.

Quote:
in practice is always a "now you have two problems" situation


Definitely. Even the most well-defined, simple specs end up with edge cases (see all the discussions around initial values and quirks in MSU1, which does literally only two things), and you end up with the same code not working everywhere. So now instead of emulating the mappers, people are emulating the mapper emulator.

It's just regrettable to have mappers be the thing that takes writing an NES emulator from a fun weeklong project to a 10-year nightmare, and everyone here has to go through it like a rite of passage, or give up and be forgotten.

Quote:
The designer of the Coolgirl board provided an FCEUX source code file that includes the flash rewrite part, also linked to at the bottom of the mappers's wiki page.


Mappers emulating dozens of other mappers ... that is both amazing and absolutely horrifying at the same time.
Re: COOLGIRL
by on (#237551)
byuu wrote:
Mappers emulating dozens of other mappers ... that is both amazing and absolutely horrifying at the same time.

Was it horrifying when I designed the Action 53 mapper to cover all common discretes (NROM, CNROM, UNROM, BNROM, and AOROM, with PRG ROM sizes from 128 kbit to 2 Mbit)?
Re: COOLGIRL
by on (#237554)
byuu wrote:
Beating a dead horse, but it really is a shame that every NES emudev has to reimplement 342+ mappers each...


While we're ranting, the really unfortunate part is that the majority of high numbered mappers (the strange pirate carts) contain shitty games not worth playing. And on top of that, at least at this time, the NES 2.0 ROM files are not readily available to the average emulator user. So, most people won't see the fruit of your labor and that fruit tastes like shit anyway.

On a slightly different topic, the nesdev wiki is an incredible resource. And I want to thank everyone in this community who contributed to that compendium of NES knowledge. It still has gaps though. For instance, as noted in this thread, the COOLGIRL wiki entry points to the FCEUX implementation, rather than describing how it works. The NintendularNRS implementation is port of that source that retained all the FCEUX variable names, etc. I used both source files to create an implementation for my emulator. There is nothing necessarily wrong with porting a mapper like that. However, when you convert a wiki description into code and it works as described, you feel a sense of achievement. It's your implementation. On the other hand, porting a mapper from other emulators feels like plagiarism. It feels dirty and it's depressing.

lidnariq wrote:
(this was my post #8250, the serial UART in the original IBM PC)


Ha!
Re: COOLGIRL
by on (#237556)
zeroone wrote:
the really unfortunate part is that the majority of high numbered mappers (the strange pirate carts) contain shitty games not worth playing.
The high-numbered mappers were initially assignments for circuit boards that previously existed only as UNIF MAPRs. And with almost all licensed hard- and software being documented and emulated, it is unavoidable that the last remaining frontiers would be "strange pirate carts" and other unlicensed material. That many or most of these games would not win awards for their gameplay value only serves to separate the wheat from the chaff: is one in it for the enjoyment and the challenge of hacking, documenting and emulating strange and old hardware and software, or does one just want to play games for free? Strange pirate hardware rewards the former interest well enough.
zeroone wrote:
the COOLGIRL wiki entry points to the FCEUX implementation, rather than describing how it works. (...) I used both source files to create an implementation for my emulator.
An excellent opportunity for you to share the knowledge you obtained during that process by updating the mapper 342 wiki page.
Re: COOLGIRL
by on (#237557)
zeroone wrote:
I am studying the NintendulatorNRS implementation of Mapper 342 and I noticed that it's missing the 4M of save flash. Any consequences to omitting the flash?
Resource: https://cardgenerator.io/visa-credit-card-generator/


I don't think you will be having issue in game play.
Re: COOLGIRL
by on (#237661)
lidnariq wrote:
Unfortunately, if this language is low enough level to describe ASIC mappers, now you have a problem even worse than bad headers: bad descriptions. If the language isn't low enough, it's almost useless, because the effort to provide the abstraction of MMC5-the-IC is not really different from the effort to implement mapper 5, and the effort to implement 005-00002-010 is not really different from the effort to implement mappers 36, 132, and 173. And that's ignoring things where there just isn't good reference information, like chips-on-board, which basically have to be reverse-engineered entirely as black boxes.


Hello all. I'm just starting out with the NES, but I've done some rather interesting things on the Atari 2600.

For mappers of a complexity that would fit in an low-to-mid-level CPLD chip like the XC9572XL (and that covers a *lot* of ground), I would think a relatively simple language could be sufficient while being easy to process efficiently in code that wouldn't need to care about most details of the underlying emulator.

If I were designing such a language, I'd probably use a virtual machine with 256 registers of 32 bits each, the first two of which would be initialized with CPU address/data bus contents, the next two of which would be PPU address/data, and the next ones some control signals like IRQ. The primary instructions would be:

  • Set/clear bit A of register B based upon whether a register C, masked with bit pattern D, matches E, or else do nothing/do the opposite.
  • Read A bits starting at bit B of register C, and copy/mask/or/bic/xor/add/multiply them with bits starting at bit D of register E.
  • Take 1/2/4 bits starting at bit A of register B and do a 2/4/8-way branch
  • Read memory at address given in register A (upper bits select a device; lower bits select an address within it) into register B
  • Write memory at address given in register A (as above) with lower 8 bits of register B

Something with the complexity of the DPC chip used on the Atari 2600 Pitfall II cartridge would need a fair number of instructions, and wouldn't be processed as quickly as would be possible with purpose-written C code, but a if the byte-code engine were written in engine-agnostic fashion and the NES format included a mapper number which indicated that the necessary byte-code would be embedded in the NES file, any emulator that supports the byte-code format would be able to handle such cartridges, at least on a fast enough computer, without needing to be customized for that banking scheme.

I've designed banking schemes for the Atari 2600 and implemented them in hardware and emulators. Since some NES homebrew cartridges have CPLDs on them, it would seem like the potential benefits of having one-off banking schemes designed for particular games could be even more significant on the NES than the 2600, but only if there's an easy way to make the custom schemes usable in emulators.

Incidentally, adding a means of including a mapper description within an NES file could also be useful for developers who wish to allow people to freely share the game for use on emulation but require that people wanting to use actual systems buy cartridges. If the bytecode within a .NES file included all the features needed for a game, including a few that are *very rarely* used, along with many other features that would never get exercised at all, anyone wanting to fit a working mapper into an inexpensive CPLD would need to know what features were actually needed. A programmer who was so inclined could punish users of unauthorized cartridges by e.g. arranging things so that code to register damage on the final boss monster could only be activated as a consequence of the cartridge recognizing a particular sequence of memory accesses and doing a seemingly-oddball bank-switch to land in the "damage boss monster" code.
Re: COOLGIRL
by on (#237685)
jswami123 wrote:
I don't think you will be having issue in game play.


This is true. However, if you power-cycle/reset a game with NVRAM, it displays the message, "SAVING... KEEP POWER ON!", indefinitely. I assume that if the flash emulation were functional, that message would eventually be replaced by the main menu.

lidnariq wrote:
The designer of the Coolgirl board provided an FCEUX source code file that includes the flash rewrite part, also linked to at the bottom of the mappers's wiki page.


I attempted to port the FCEUX flash code to my emulator, but it still never finishes saving. In the FCEUX source, I see it write to the SAVE_FLASH array, but it never appears to read from it. However, I do see this line:

Code:
SetupCartPRGMapping(0x11, SAVE_FLASH, save_flash_size, 1);


Does that memory map the array? Does chip 0x11 correspond to something?
Re: COOLGIRL
by on (#237688)
zeroone wrote:
jswami123 wrote:
I don't think you will be having issue in game play.

This is true. However, if you power-cycle/reset a game with NVRAM, it displays the message, "SAVING... KEEP POWER ON!", indefinitely. I assume that if the flash emulation were functional, that message would eventually be replaced by the main menu.


A typical parallel flash memory device will guarantee that while a byte is being programmed or erased, any attempt to read that byte will yield a value where bit 7 will be the opposite of the value the byte will receive after programming, and bit 6 will be the opposite of the previous value read. Once the operation is complete, reads will simply yield the final contents of the storage. Thus, if one knows what value should be in the memory, one can read it to see if the value matches. Alternatively, one can read the value twice and know that they won't match unless the operation has completed (in which case they will report the final storage contents).

I don't remember the exact sequence of operations required to erase a page of flash, but if the emulator's logic doesn't recognize it, code which repeatedly reads a byte of flash to see if it gets FF (implying the operation is complete) may wait forever if the emulator doesn't recognize the erase command. Since some flash devices support multiple erase commands, it may be that the program is using an erase command that the emulator doesn't recognize.
Re: COOLGIRL
by on (#237748)
I don't know how to test the FCEUX implementation. If it actually works, could someone explain how it reads from the flash array?
Re: COOLGIRL
by on (#237752)
It should be able to read from the SAVE_FLASH array any time one of the REG_x_CHIP flag is set to 0x11 inside COOLGIRL_Sync_PRG()...

(edit: this was my 8259th post, the Interrupt Controller inside the original PC. And now I know of no further interesting numbers than correspond to my post count for quite a while)
Re: COOLGIRL
by on (#237755)
lidnariq wrote:
It should be able to read from the SAVE_FLASH array any time one of the REG_x_CHIP flag is set to 0x11 inside COOLGIRL_Sync_PRG()...


You're right. I missed that. I'll study this further. Thanks.
Re: COOLGIRL
by on (#237761)
zeroone wrote:
lidnariq wrote:
It should be able to read from the SAVE_FLASH array any time one of the REG_x_CHIP flag is set to 0x11 inside COOLGIRL_Sync_PRG()...


You're right. I missed that. I'll study this further. Thanks.


That did the job. Thanks.