Unlike both, they're really inexpensive: 65¢/@100. At this price, it starts being worth considering replacing designs that would use multiple discrete logic ICs with one GreenPAK.
Silego's newest GreenPAK models have started to get just big enough (Up to 15 latches and 10 LUTs, up to 25 LUTs) to start being Interesting, but still really cramped.
So I'd thought I'd share a bit of the golfing I've done. None have been tested in hardware. I should do that.
So, first, the easy thing: an almost-MMC1, supporting MMC1 mirroring control, four bits of PRG banking (512K 32) and two-by-four bits for CHR banking (64K 4+4). No changing PRG or CHR banking style, no PRG-RAM, no &$80s bit that will reset banking style. Still uses the serial interface, because doing so let me double capacity for both PRG and CHR (by adding one output for each).
• Write to $8000: write twice, little end first, same meaning as bottom two bits of MMC1 register at $8000
• Write to $A000 or $C000: write four times, same meaning as bottom four bits of MMC1 registers at $A000 or $C000
• Write to $E000: write four times, little end first, unlike MMC1 instead specifies one of sixteen 32 KiB PRG banks
Unlike the MMC1, writes are NOT buffered and instead they flow through continuously.
"Hey, wait, that trade-off sucks!"
Yeah, it does. Tomorrow I'll post the I/O-limited variant that doesn't use the serial interface. (As a result, it has enough spare logic to implement 16+16F PRG banking instead)
Code: Select all
$8000-$9FFF: [.... ..MM] - 0,1,2,3 = 1scA, 1scB, V, H $A000-$BFFF: [.... .CCC] - 4K CHR bank at $0000 $C000-$DFFF: [.... .CCC] - 4K CHR bank at $1000 $E000-$FFFF: [.... .PPP] - 16K PRG bank at $8000
Is there enough logic on a greenpak to support a full MMC1 replacement? I do see that MMC3 wouldn't be possible due to available resources, but how about using several, how many would be needed?
And is there a way to synthesize logic from code, or do you have to use their Tool with that designer interface?
This does look interestening, especially considering that you could also use this for a SNES Cartridge, question is how many Pins do you have available to make a kind of switch for LO/HIROM mapping?
No—what I've already shared is close to the upper bound. They're limited enough that designs tend to run out of both I/O and logic.elseyf wrote:Is there enough logic on a greenpak to support a full MMC1 replacement?
Way too many. The largest GreenPAK only has 15 latches, and a full-sized MMC3 needs 4×8+2×7+2×6+2×8 = 74 latches just for banking and IRQs.I do see that MMC3 wouldn't be possible due to available resources, but how about using several, how many would be needed?
... with one special cheap trick that I'll share later.
The open-source YOSyS has been growing support for that, but not the specific model I've been playing with.And is there a way to synthesize logic from code, or do you have to use their Tool with that designer interface?
The "right" way to do that is to preprocess and interleave your data such that you need a single multiplexer.how many Pins do you have available to make a kind of switch for LO/HIROM mapping?
The largest GreenPAKs have 18 I/O, so you could just fit 8 output lines into one. But is that cheaper than two 74'157s or 74'257s, though?
Two variants. One requires an external 74'161 and 74'32 (say, from an UNROM donor): The other requires two external octal tristatable latches ('373, '374, '573, '574).
I borrow a trick from the implementation of the NINA-001, using two tristatable latches (specifically '173s on Impossible Mission 2)—connect PPU A12 to the +OE input on the latch holding the bank value for CHR bank 1, and PPU/A12 to the +OE input on the other latch Both of these are I/O limited, but there's abundant spare logic inside. I just had no ideas for what would be useful to do with it.
Code: Select all
$A000-$AFFF: Set 16K PRG bank at $8000-$BFFF (16K at $C000-$FFFF fixed to last bank) $B000-$CFFF: Set 4K CHR bank at $0000-$0FFF $D000-$EFFF: set 4K CHR bank at $1000-$1FFF
Tonight (since I forgot to post this one last night): an MMC3-class IRQ generator
- (7.4 KiB) Downloaded 201 times
Although the GreenPAK provides a delightful wealth of random counters, it doesn't provide a way to configure them at run time¹. Each counter block has its own unique count and that's it.
So if you want a real counter, you have to spend logic—lots of it—on it.
My MMC3-class IRQ uses every bit of logic in here. I even had to shave the counter down from 8 bits to 7 in order to fit.
And I had to use an LFSR instead of a binary counter. Using an LFSR means that you basically have to have a look-up table to convert between the LFSR's Galois field and ordinary binary. But I figured using 128 bytes (or 256 if you need to go both ways) for that wasn't too bad.
The counter is clocked by the processed output of a "pipe delay"; PPU A12 is latched on every rising edge of M2, and the three most recent latched values are ORed together. This means that IRQs will fire up to 1cy later than a real MMC3. (If I'd had the spare logic, I could have used a 4-LUT to OR the three latched forms with PPU A12 instead)
Code: Select all
$5000-$5FFF: [ICCC CCCC] - writes to 7 LSB set the current LFSR state. /IRQ is asserted while the current state is all 1s ($7F) Reads return the current LFSR state. The MSB (visually next to the /IRQ output) allows for polling for /IRQs while interrupts are disabled. Writing 0 disables IRQs (because of how LFSRs work) Note that there's a race condition between "CPU loads the latch" and "PPU A12 clocks the latch". If there's any possibility of the two colliding, write the value twice! $6000-$7FFF: external interface to RAM or latch for mapper 140(≈GNROM) bankswitching. Generation of CPU /RD allows self-flashable PRG.
Tonight or tomorrow: recapitulating NROM-368
The GreenPAK4 SPI module can read and write one of the counters. With GreenPAK5 I think you're supposed to use i2c, I haven't looked into that.Although the GreenPAK provides a delightful wealth of random counters, it doesn't provide a way to configure them at run time¹. Each counter block has its own unique count and that's it.
The SPI module in my design is heavily used slightly abused, for scanline counter, and for 2 independent PRG banks. One of the banks is latched when you write to its register. The other PRG bank is kind of weird, and is based one whatever you last wrote to the SPI port. Since the SPI cycle needs 8 writes (and possibly the reset write), it does requite a lot of writing. Though I've tried to include a shortcut, there's a reset register that will reset the bank to zero. So at least there is one PRG switch that's quick.
One of the other funny optimizations I put in, was using the carry outputs of the left-over counters to select the CHR pages. To use it, you write to one register to increment, and another one to reset them.
Where have I seen that before? *cough*NES MMC1*cough*Genesis Z80 banking*cough*Memblers wrote:The other PRG bank is kind of weird, and is based one whatever you last wrote to the SPI port. Since the SPI cycle needs 8 writes (and possibly the reset write), it does requite a lot of writing.
Again with the MMC1 inspiration. It might not actually be that bad.Though I've tried to include a shortcut, there's a reset register that will reset the bank to zero.
Ssssshh!!!Memblers wrote:With GreenPAK5 I think you're supposed to use i2c, I haven't looked into that.
My NROM-368 recap is a simple extension of the original one-74'85 memory map: Reads from $4000-$4013 and $4018-$FFFF are permitted
Writes to $4800-$FFFF are permitted
Sector size is shrunk (assuming an SST39SF010A) down to 2 KiB by duplication of address lines (connect PRG A1 to CPU A0, PRG A0 and A2 to CPU A1, &c)
Thus: all sectors are erasable except the partial one.
Flash unlock sequence is now $AA→[$AAAA] and $55→[$9555]
Tonight/tomorrow: the stupid trick
We can get a full MMC3/VRC4 experience out of a GreenPAK.
Remember how I said that, like FPGAs, the GreenPAKs run out of RAM? Sure, they have a one-time-programmable ROM, but it's used to preload the RAM.
As long as it's configured to be permissible, each of the LUTs can have their tables set using I²C. So all you need is something that can talk I²C to it to change banking.
Since we lost two of our pins to the I²C interface, we're even more heavily I/O limited now. That's why I've implemented only 2×16 PRG banking (256 KiB max) and 8×1 CHR banking (32 KiB max—I'm assuming CHR-RAM). And the LUTs are transposed from how the NES would find useful. (i.e. you can't just say "this byte specifies what CHR bank is present from $0000-$03FF"; instead you have to say "here's the value for CHR A10 for each of the eight CHR banks"). And the LUTs are partially but not entirely contiguous: e.g. 3LUT0-3LUT4 are five sequential bytes, but 3LUT5-3LUT10 are a separate block of six bytes.
It gets crazier. The I²C master can change the entire configuration of the GreenPAK (as long as it's allowed to). Connectivity, LUT contents, counter limits. Want a mapper that will automatically change banks at scanline N? Want to use the 7 counters as a polyphonic sound IC?
The only thing you can't do after the fact is change how it's soldered.
Next time: a fast I²C interface, hopefully. (I'm not done yet)