A couple weeks ago I started trying to consolidate a list of all the ways one could usefully use 1-3 logic ICs in a discrete logic mapper. I thought I'd post the list here to see if it inspires some other ideas.
Without further ado:
1 IC
Anything usable as an inverter, such as (⅙ 7404, 05, 06, 07, 14, 16, 19, ¼ 7400, 01, 02, 03, 24, 25, 26, 28, 33, 36, 37, 38, 39, 86, ⅓ 7410, 12, 27, ½ 7413, 18, 20, 22, 23, 25, 40)
→ Avoids bus conflicts on bankswitch writes by making ROM /OE ← NOT R/W
Selecting logic such as 7420, 138, 139
→ Add up to 8KiB WRAM mapped from $6000-$7fff
→ (138, ½ 139) Split 32KiB into 16KiB RAM from $8000-$BFFF and 16KiB ROM from $C000-$FFFF
7486 (quad XOR)
→ Double effective CHR with a palette reordering of tiles by e.g. making CHR(A3) ← PPU(A11) XOR PPU(A3) (swaps colors 1 and 2).
→ Double effective CHR with a vertical flip by making CHR(A0,A1,A2) ← PPU(A11) XOR PPU(A0,A1,A2).
Any latch with an active-low clock enable, such as 74161, 74377
→ Most of Nintendo's discrete-logic mappers (AxROM, BNROM, CNROM, GNROM, MHROM)
→ Arbitrary GNROM-style mappers with 32KiB PRG banks and 8KiB CHR banks
→ Mapper-controlled 1-screen mirroring (a la AxROM)
→ Oeka Kids-style dynamic banking of CHR with zones as small as the size of an attribute byte (32x32 pixel), by connecting Latch./CLKEN ← /PPUA13 and Latch.CLK ← /RD
→ Additionally, a simple circuit (diode, resistor, capacitor) can automatically clear a 161 on reset
Any sufficiently large binary counter, such as (74)4020
→ Interrupts for 2ⁿ X every 2⁽ⁿ⁺¹⁾ X, where X could be (A12 rises = scanlines·8, cpu cycles, PPU reads)
Tristatable dual 4-input multiplexer (74'253) in lieu of CHR ROM, plus 8 ≈1kΩ resistors (or a 74244):
→ Game Genie style low-resolution graphics, where each 4-by-4 pixel zone is individually controllable and can have any color D3…D0←SEL(A3…A2,A11…A8) and D7…D4←SEL(A3…A2,A7…A4)
74'153 or 74'157, plus 8 ≈1kΩ resistors (or a 74244): (added 2013-III-10)
→ Allow selective disabling of 1kB NT RAM so-as-to split bitplanes. CIRAM/SEL ← SEL(A3,A10,A11), SEL/E ← A13, D0…D7 ← A12 through resistors or buffer
2 ICs
Any obsolete RAM such as 74170, 670, 189, 219, 289 plus decoding logic (7432) :
→ 4 (for the two 74?70) or 16 (for the three 74??9) independently controlled banks.
7485 + 74(4078) (comparator+8-input NOR)
→ Map almost 48KiB from $4020-$FFFF without bus conflicts
Any latch plus decoding logic, such as 7400, 02, 32, 133, 138 + 7474, 173, 174, 176
→ GNROM-style mappers as made by not-Nintendo
Timer/counter plus decoding logic, such as 7400 + 555/(74)4020/74123
→ Acknowledgable interrupts
Two multiplexers forming an eight-of-sixteen multiplexer (2× 74157)
→ Double effective CHR with a horizontal flip of tiles by making PPU(D0…D7) ← SELECT(PPU(A11),CHR(D0…D7),CHR(D7…D0))
Eight XOR gates (2x 7486) added 2012-IX-6
→ Double effective CHR with a palette inversion (3↔0, 1↔2) by making PPU(D0…D7) ← CHR(D0…D7) XOR A11
Any latch with an active-low clock enable plus:
Masking logic, such as 7400, 02, 08, 32
→ UxROM and similar with a fixed bank of PRG or CHR
Inverting masking logic, such as 7400, 02 (added 2013-V-2)
→ UxROM without bus conflicts and similar with a fixed bank of PRG or CHR (max 3 bits of banking)
a quad 1-of-2 multiplexer (74157)
→ Two independently controllable banks
→ Two independently controllable banks and two duplicate fixed banks
Tristatable quad 1-2 multiplexer (74'257) and four >1kΩ resistors (refinement of previous, added 2013-V-12)
→ Two independently controllable banks and two different fixed banks (128kiB PRG example: Three resistors pull ROM A14..A16 high. The last connects CPU A13→ROM A13 but can be overridden by the mux)
½ dual 1-of-4 multiplexer (74153)
→ Controllable horizontal/vertical/1screen mirroring
A single 1-of-2 multiplexer (7400)
→ Controllable horizontal/vertical mirroring (as used by Holy Diver)
Inverter (such as 7400, 7404, 7486) + 8KB RAM added 2012-IX-6
→Map 8KB RAM into PPU $0xxx and $2xxx for 4KB CHR-RAM slice and 4-screen mirroring, inverter makes NOT A12 to decode 4KB ROM (or 4KB window) in $1xxx
3 ICs
Latch, Logic, quad 1-of-2 multiplexer added 2012-IX-6
→ Split CPU or PPU space into 2ⁿ moving and (the rest) fixed bank. e.g. using a 7408: Make PPU $0000-$17FF fixed with a 2KB bank at $1800-$1FFF by SEL←PPUA12 AND PPUA11 and using the multiplexer to either pass 0,0,A12,A11 to the CHR or the latched value.
Do you have any other ideas?
edit: add link to tepples's 74'670 quad-banked design
edit: some new ideas
Last edited by lidnariq on Sun May 12, 2013 1:08 pm, edited 3 times in total.
I'm a bit curious about the "Double effective CHR" features... how exactly would those work? Would it be possible to mix the regular set with the alternate set(s)?
As for the obsolete RAMs, I proposed something using that a long time ago: Mapper 670.
As I understand the description of doubling the CHR, it'd borrow one bit from the tile number. I wonder how much effort it'd take to implement the bare minimum of something like ExGrafix using two VRAMs in parallel, one to hold the ordinary nametables and one to hold the flip bits and the like.
The FlipY one works by taking the address line that we interpret as the control line, sign-extending to to a 3-bit number, and XORing it with the 3 least significant address lines. Since A2…A0 are already known to encode tile Y coordinate, when we XOR it with 0 or 7, we either leave it unchanged or take the 2's compliment of it, i.e. 7-Y which is a vertical flip.
It's definitely combinable, if superfluous for the sprites, and probably most useful with an MMC3 or other mappers with address lines to spare.
Any of the transformer designs could also use some latched output instead of an address line, then all tiles would be transformed simultaneously.
tepples wrote:As I understand the description of doubling the CHR, it'd borrow one bit from the tile number.
But then you'd still have only 256 unique tiles to pick from... I fail to see the advantage.
I wonder how much effort it'd take to implement the bare minimum of something like ExGrafix using two VRAMs in parallel, one to hold the ordinary nametables and one to hold the flip bits and the like.
Some very interesting ideas you've got here especially with only two chips! Although I'm having a hard time picturing how some of the doubling effective CHR stuff is working exactly...
tepples wrote:I wonder how much effort it'd take to implement the bare minimum of something like ExGrafix using two VRAMs in parallel, one to hold the ordinary nametables and one to hold the flip bits and the like.
With all the decoding going managable discrete logic is out of the question for FULL MMC5 ExGraphix it'd even be a tall feat for a simple CPLD.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
By "doubling effective CHR" I meant "You start with 4KiB ROM and get something that looks like 8KiB ROM", if that makes it any clearer; it just uses an address line (from whatever provenance) as a control line.
I think we can get you something similar to ExGraphix (16 bit tile selector, but old 16x16 attribute zones) for some glue logic, a 2KiB RAM, a latch ('377) and a tristateable buffer ('245).
The glue logic would need to:
Divide the $2000-$3fff zone into two halves, mapping the internal VRAM to $2000-$2fff (with whatever mirroring) and the new nametable RAM to $3000-$3fff
Writes to $2000-$3fff would only go to one RAM or the other
(Optionally: Reads from $3000-$3fff would read from the extra ram)
Reads from $2000-$2fff would also read from the extra ram and when not from the attribute tables (PPU A9…A6 ≠ 0b1111) latch its output in the '377
The output of this latch would become CHR A19…A13
The glue logic isn't very complicated but it doesn't conveniently fit in a single 74xx part:
CIRAMSEL ← (A13 A12 == 0b10)
CE2 ← (A13 A12 == 0b11 OR A13 /RD == 0b10)
74377.Clock ← (A13 A12 /RD == 0b100 AND A9…A6 != 0b1111)
74245./Enable ← (A13 A12 /RD == 0b110)
The 2KiB RAM is probably the most awkward part.
lidnariq wrote:By "doubling effective CHR" I meant "You start with 4KiB ROM and get something that looks like 8KiB ROM", if that makes it any clearer; it just uses an address line (from whatever provenance) as a control line.
It's a really interesting idea, I'm just worried about what address line can be used that will make this useful. If you can't freely mix regular and flipped tiles, effectively having more than 256 tiles to chose from, this is meaningless (if you can't access more than 256 you could just as well have the mirrored tiles stored in the CHR normally). I'm having trouble seeing this mirroring trick being useful without extra memory to hold the mirroring bits (and possibly extra index bits). It's still impressive that it can be done with such simple logic, though.
lidnariq wrote:
→ Additionally, a simple circuit (diode, resistor, capacitor) can automatically clear a 161 on reset
Could you describe this a bit more. Does this rely on the CIC signals or is this supposed to work on any system? And is it truely reset or is it on power up only?
MottZilla wrote:Could you describe this a bit more. Does this rely on the CIC signals or is this supposed to work on any system? And is it truely reset or is it on power up only?
M2 --|>|--+-+- 74161 /CLEAR
| |
R C
| |
+-+- Ground
And yes, it works on both power-up and on reset.
R·C ≅ (2/1789772 Hz ≅ 1µs → something like R=10k C=100pF)
This schematic has actually been used by a number of pirate multicarts; it's Nintendo's first-party multicarts that so misused CIC KEY RESET
Bregalad wrote:I think he meant that M2 goes tri-state when the CPU is Reset.
However this wouldn't work on power-up, so....
No, it works fine on power-up for two different reasons:
the Vcc rail takes a while to stabilize before the 2A03 is released from reset. That's the entire point of the CIC replacement circuit discussion, or of the 0.1µF capacitor on pin 7 of the 3193, or of the 0.47µF capacitor on /RST on the famicom. They both provide ~10-100ms after Vcc rises to valid before the system is released from reset, which is more than enough time for the RC to discharge while M2 is high-impedance.
On power-up, the capacitor will be discharged, instantaneously clearing the 74'161, and the only thing that could charge it is the diode. Even if M2 goes high almost immediately, it takes something less than 30ns for /CLEAR to work.
lidnariq wrote:I think we can get you something similar to ExGraphix (16 bit tile selector, but old 16x16 attribute zones) for some glue logic, a 2KiB RAM, a latch ('377) and a tristateable buffer ('245).
You're better off with a small ~$1 CPLD to do all of this if you've already got a ~$1 gal/pal and a handful of chips... Not to mention it could help out with the awkwardness of 2KB of RAM.
I see the benefit of discrete logic with simplicity and no need for programming, but if you're reaching for some pal/gal to use as glue logic you may as well save money and part count and go for the CPLD with the configurability benefits.
Really I'd argue the same thing with ~3 or more discrete logic chips if you can handle designing the logic in a IDE and use a JTAG programmer.
If you're gonna play the Game Boy, you gotta learn to play it right. -Kenny Rogers
infiniteneslives wrote:Really I'd argue the same thing with ~3 or more discrete logic chips if you can handle designing the logic in a IDE and use a JTAG programmer.
2 ICs:
Inverter + RAM
→ Map 8KB RAM into PPU $0xxx and $2xxx for 4KB CHR-RAM slice and 4-screen mirroring, inverter makes NOT A12 to decode 4KB ROM (or 4KB window) in $1xxx
3 ICs:
Latch, Logic, quad 1-of-2 multiplexer
→ e.g. using a 7408: Make PPU $0000-$17FF fixed with a 2KB bank at $1800-$1FFF by SEL←PPUA12 AND PPUA11 and using the multiplexer to either pass 0,0,A12,A11 to the CHR or the latched value.