Konami made some of the best games for the MSX computer platform. Unfortunately, the market being what it is, those cartridges have become expensive collectibles rather than cheap games, which takes all the fun out of it. Before we can build a bootleg cart, we need to understand Konami’s unique mapper. My goal for this project was to make a functional cartridge that could play Konami’s Knightmare II: The Maze of Galious. Although I think the game is interesting and ambitious, this was mostly because blog friend famiclone loved the game, and I owed him an MSX in exchange for the lovely ColecoVision and busted 48k Spectrum he sent me. Failure to Launch For a couple years now, I’ve wanted to play [1]The Maze of Galious on an MSX. Galious is a side-scrolling action-adventure game with some long gameplay, multiple characters, and some fiendish puzzles. Blog friend famiclone has been really interested in it, and I wanted to see what all the fuss is about, too. At first, I looked at the used market to see if I could buy a cartridge. The absolute lowest I’ve seen a (very worn) cartridge listed for over the years is ¥4800. In retrospect, after all this adventure, that doesn’t seem like much, but “spending fifty bucks instead of learning something” is not the name of this blog. As you have probably inferred, the obstacle was understanding the mapping scheme in use. I’d soldered together a bunch of homebrew MSX cartridges before, but they were always a simple “bare ROM” on a pre-made board that is keyed off of slot-select. No fancy mappers, and limited to 64k at most. I certainly did not program the software on those cartridges – MSX programming is an experience I am saving for the future! I set about trying to figure out the paging scheme in use, by piecing together MSX.org wikis and squinting at pictures of other mega-ROM boards. But everything was very confusing, and it seemed like with every step forward, I’d end up having to pull the design apart and redo it from scratch, or end up with way too many parts. So what changed? I got talking to [2]bsittler, a huge MSX fan, about the MSX. When he heard about the project, blog friend bsittler sent me [3]some Konami-style cases from Retro Game Restore that he had lying around the property. This act of generosity was the spark that motivated me to actually finish this project up enough to send it to fab. Thank you! The version-one PCB as it was sent to JLCPCB. It reads "Oyanami Megabit Mapper for Legitimate Purposes." I made Microchip send me a sample DIP32 SST39SF040 EEPROM, which was very nice of them to provide. Thank you, too, Microchip! For my initial run I decided to try Galious. I could also have done Metal Gear, but I only wanted to have MSX1 games on this initial cart. Mapping for These Territories What is a cartridge mapper, and why do we need one? A lot of early MSX games are similar to most ColecoVision cartridges: a bare ROM on a PCB, without any fancy logic. As cartridges got bigger, they no longer fit entirely into the Z80 CPU’s 64k of address space. Some page-switching had to be added. It’s just what it sounds like: instead of looking at a whole book’s worth of information laid out on a table all at once, we cut that information into pages, and then flip the book to look at one page at a time. In other words, one address in the Z80 space could now point to multiple different addresses on the ROM. This was an inevitable development: anyone who knows programmers can tell you that they always need more memory (both ROM and RAM!) Long-time readers will remember that we’ve delved into cartridge page-switching routines before, such as [4]the explanation of how UNROM cartridges worked on the NES. Page switching was built into the MSX standard’s design from the start. ASCII Corporation, which originated the standard, had a whole lot of programmers on staff and they got what they wanted. MSX’s basic “slot” scheme makes it easy to access two 64k cartridges while still keeping BIOS ROM and RAM available. MSX Slot Mapping Because the MSX came relatively late in 1983, the design of the standard benefited from seeing the limitations of other Z80-based systems. Many parts were inspired by my beloved NEC PC-6001, but ASCII picked and chose some reasonably sane choices. For our purposes at the moment, one of the more significant features of the MSX design is the slot system, which allows manufacturers to specify a huge memory map that can be “paged” in and out at runtime. I had tried to fit the slot system into my head on many previous occasions. It is hard to go into any discussion of the MSX hardware standard without seeing words like “slot,” “mapper,” “page,” and “segment” thrown around, often interchangeably. Things made more sense once I talked to bsittler, who has had a long history tinkering with the MSX and features a near-infinite amount of patience for my dumb questions. Here, then, are the basic rules as I understand them: 1. The MSX divides the 64kB Z80 address space into four 16kB “pages.” 2. Each page can choose between one of four “slots” to point to, which usually (but not always) correspond to “built in,” “cartridge slot 1,” “cartridge slot 2,” and “miscellaneous.” 3. To set the pages, you write a byte to I/O port $a8 to tell it what slot to display at which page^[5]1. Page 3 ($c0000 to $ffff ) is the most significant half-nibble of that byte. I wrote a quick example, based on [6]my 16kB Sony HB-101, that you can play with on your own to see what I mean: Click on slots on the left-side table in order to map them into the MSX's Z80 address space on the right. Assign MSX Slots Slot 0 Slot 1 Slot 2 Slot 3 Page $C000 - $FFFF 16k RAM Cart Slot 1 Cart Slot 2 Nothing Page $8000 - $BFFF Nothing Cart Slot 1 Cart Slot 2 Nothing Page $4000 - $7FFF Main ROM (top) Cart Slot 1 Cart Slot 2 Hit-Bit Organizer Page $0000 - $3FFF Main ROM (bottom) Cart Slot 1 Cart Slot 2 Nothing Current Memory Map Page Mapped to... Page $C000 - $FFFF ... Page $8000 - $BFFF ... Page $4000 - $7FFF ... Page $0000 - $3FFF ... Slot-Changing Instructions The critical point I didn’t get on previous attempts was that each page can only use slots in its row. For example, on this example of the Sony HB-101, you can’t map the main ROM into high memory. I had been confused before why everything seemed to still be in the same order, despite there seemingly being a lot of flexibility in the design of an MSX-standard computer. If you put the above example into the configuration where RAM, the BIOS ROM, and the cartridge are all assigned into the memory map at the same time (i.e. OUT ($a8), 0b00010100), you’ll find that the lowest address available to the cartridge is $4000 . This is why MSX ROM cartridges decode their initialization code at $4000 . It’s where the MSX BIOS will look for it when it mounts the slot. There is a [7]“slot-expander” peripheral to further subdivide these slots if you need more space. The MSX2 has a lot of additional fancy mapper schemes built into the standard as well, but I don’t understand those yet, so we’re not going to cover those in this article. Under the standard MSX scheme, a cartridge is split into four 16k slots, which means that your theoretical game can be a whopping 64 kilobytes without requiring any additional fancy mapping schemes, which add cost to every cartridge. That’s a huge amount of space, if you’re used to the Nintendo NROM, which limited cartridges to a measly 16k of program space. Konami Bon Ami Unfortunately for the MSX planners, games kept getting bigger and bigger… When Konami started making 128-kilobyte games, they had to implement an extra mapping scheme of their own. That’s where the “MegaROM” mapper comes in: it lets you page-switch one megabit (128 kilo bytes) of cartridge ROM so that it can be fully accessed by the MSX through the 64k of slots that it makes available to the cartridge. The MegaROM mapper design. The four 16k slots of the cartridge are expanded to point to arbitrary 16k segments in a ROM. Under the Konami scheme, we divide the 1Mbit ROM into eight 16k segments. Each 16k slot of the MSX cartridge’s slot space can now choose to point to one of eight 16k segments of the ROM on the cartridge. This design is very similar to that of the MSX’s own mapper! There is just one caveat: on the early Konami mappers, the $4000 to $7fff slot is always mapped to the first segment of the ROM. This is because the MSX will look at this slot first in order to boot a cartridge, so it has to contain the boot code for the game when the MSX turns on. Why is this fixed, then? Why not make it configurable and just default to segment zero? It’s probably because Konami would otherwise have to add logic to detect when the MSX is starting up, and reset all these registers to zero^[8]2. I’m glad they didn’t do this, because it would have made it much harder for me to implement, but more on that in a bit. The Guts of Page Switching Now that we know logically how things are supposed to work from the software side of the MSX, how do we actually implement a mapper in hardware? At the most basic level, a page-switching scheme controls the upper address bits of the RAM or ROM that we want to switch. For instance, you can think of a 32k RAM chip as being four chunks of 8k, arranged in a line. A 32k RAM chip split into four 8k chunks. Instead of being driven directly by the CPU, we instead drive those lines from some sort of latch. When we want to look at a different chunk of the RAM, we change the latch’s settings, and it changes how it’s driving the mapped RAM/ROM’s address lines. The Konami mapper needs a pretty fancy latch, but it’s still a part we can just get off the shelf. Let’s ditch the generalities and get down to how it specifically works.. The Magic 74LS670 Most of the homebrew MegaROM cartridges are based around the 74LS670. That part is called a “4x4 register file,” which is a very Texas Instruments name for what is basically four 4-bit latches stuck together in one teeny tiny chip. To use the ‘670, you set two address pins (2^2 = 4 registers) and then can enable read or write. Enabling write sets the registers inside the chip for the given address, and enabling read expresses the content of that register on the output pins. It’s a pretty useful part, especially when you realize that you can write to a different register than you’re reading from at the same time. You can almost think of it as a crude, very small dual-port SRAM. Unfortunately, it’s a little harder to get these days: Digi-Key is asking over $11 for it in HCT DIP, and most varieties are simply discontinued. My supplies all came from salvage. I think it could be a cool project to try and build one of these using a PLD. The Struggle I had tried making one of these before, because I figured it was something simple like the UNROM mapper. Previously, I had started figuring it out from [9]the MSX.org description of the mapper’s addresses, but I kept making very complex decode circuits. This time around, I looked at [10]this thread complaining about a non-working MegaROM schematic and decided to take a peek. I was surprised to find that they didn’t route A[14] at all, and started to puzzle that out on paper. Eventually, I figured out that A14 doesn’t usefully distinguish any access. Here, let me show you: Address Segment A13 A14 A15 $4000 Always 0 0 1 0 $6000 Variable 1 1 0 $8000 Variable 0 0 1 $a000 Variable 1 0 1 As you can see from the table, A[14] isn’t needed to decide between “paged” and “unpaged” access. If A13 or A15 are high, then we know it’s trying to read a paged segment, and we should activate the 74LS670 to set the upper address lines to whatever it has set. Otherwise, the ‘670 doesn’t turn on, and the upper address lines on the ROM would be left low (more on this in a second.) A[14] is just not necessary to know. Once I figured this out, the penny dropped on the decoding. Although it’s not my design, I figure it’s okay to crib from other designs as long as I’m actually learning from them. Now that I know how it works, it would be easy to expand to a “Konami 16” mapper (for 256k games) or even something more complicated. Arrival In order to rough out the PCB dimensions, I measured a Gerber of another MSX cartridge using the KiCad Gerber viewer. However, I got the hole diameter slightly wrong for the case: I measured 4mm, but the cases provided were 4.5-ish mm when they arrived. Even so, the edge connector was correct and fit properly into the system, so we can still test it! The initial PCB is installed into the black HB-101. For testing, I grabbed the closest MSX to hand: a black Sony HB-101 that I knew to have exceptionally dirty and glitchy cartridge slots. Perfect! Unfortunately, the HB-101 didn’t want to boot my new cartridge, even after repeatedly cleaning those slots. Instead, the BIOS would just jump to the built-in Sony HitBit organizer menu every time, indicating it couldn’t read the cart, or just didn’t like what was going on there. I decided that I would grab my copy of Tiny Slot Checker and see if anything legible was coming back from the cart. Tiny Slot Checked [11]Tiny Slot Checker is a fantastic MSX utility written by Tiny Yarou, a Japanese hobbyist. Basically, it scans the MSX’s memory space and displays what it thinks is installed in each of the MSX’s slots. Critically, for our purposes, it includes a hex viewer. My plan was to use this hex viewer to inspect the cartridge slot containing my prototype Oyanami. That way, I’d be able to see if the cartridge is able to be read at all. And if the paging scheme was wrong, I’d maybe even be able to figure out what segment of the ROM it was looking at instead of the one containing the boot code. Tiny Slot Checker reported that slot 2 was populated. It tries to make an educated guess about the contents of the slot, and can fingerprint many games and BIOS ROMs. In this case, it had no idea what was in that slot, so it just displayed ?. Page 0 Page 1 Page 2 Page 3 Slot 0 Main (BIOS) Main Empty Empty Slot 1 (Tiny Slot Checker) Empty This Tool Empty Empty Slot 2 (our cart) Empty ? ? Empty Slot 3 Empty HitBit Tools Empty RAM Every MSX cartridge must start with ASCII "AB" ($41 $42 ) in order to be identified by the BIOS as a bootable ROM. We also know that this magic string must be mounted at $4000 on the cartridge, because that’s where the MSX looks to boot a cart. I inspected Page 1, Slot 2 of the cartridge with Tiny Slot Checker’s hex viewer. Instead of AB, I saw $C1 $84 $21 $C1 ! I went back to my modern computer, and plugged that string into the search function in [12]my favourite hex editor, Hex Fiend. The only place in the entire 4Mbit ROM where that byte string could be found was at the address $72000 , which means that when we accessed the ROM on the cart, A[13], A[16], A[17], and A[18] are all stuck high. Don’t be a DIP For starters, that meant that my DIP-switch for choosing games also wasn’t working, because it’s the only thing that controls A[17] and A[18] on the ROM. Oh, did I forget to mention that DIP switch earlier? I added it when I realized that it was the same price to get a 4-megabit SST39SF040 as it is a 1-megabit SST39SF010. This way, I could put four Konami MegaROM games on the same cart, which I think everyone agrees is more. The DIP switch is its own kind of mapper, in that it controls the A[17] and A[18] lines of the ROM, splitting the 4Mbit ROM into four equal 1Mbit chunks (remember again that 2^2 = 4.) It’s just that it’s actuated with my greasy human fingers instead of an efficient, perfect machine. When the ROM switch is closed, it will short A17 and A18 low, defeating two 10k pullups. Unfortunately, it's only closed when it's "on," which is the opposite of what you'd expect. Once I checked my schematic, I realized I had wired the switch up backward. When the ROM switch is closed, it will short A17 and A18 low, defeating two 10k pullups. Unfortunately, it’s only closed when it’s “on,” which is the opposite of what you’d expect. So that’s one bug found. I turned off the computer and flipped both DIP-switches to “ON.” If my theory was correct, I should now only see A[13] and A[16] high in page 1, or $12000 . That’s not what I got. The byte string $5b , $68 , $67 , $61 was found at $1e000 – which sets A[13], A[14], A[15] and A[16]. Where did A[14] and A[15] come from all of a sudden? Page 2 was decoding to the segment at $18000 , which shouldn’t be possible, because it’s supposed to be a fixed mapping to $00000 ! Wild Pointers Could Not Drag Me Away From Boot Momentarily devoid of higher-order thought, I decided to power cycle the system and see if the pages moved around. If it was randomly changing, I could assume something was uninitialized or being driven by a floating pin. After letting the machine sit for awhile, I turned it back on to find that the same pages were shown in the same spots. What was going on, I asked the heavens, but they refused to bestow me with any better insights. With my sanity returning, I decided to look at pictures of other MegaROM cartridges. I found a picture of a MegaFlashROM PCB, which stirred some memories. Surprising myself, I found a 512K Konami MegaFlashROM cartridge PCB that I had forgotten about in my MSX cartridges box. Whoops. I could’ve just built this in the first place. With more luck, I immediately noticed that the 512K FlashMegaROM has a pretty prominent resistor network. Through the magic of datasheets and the continuity test, I determined that the FlashMegaROM cartridge is in fact pulling the segmented lines (all the high address outputs from the ‘670s) low! It was only now that I remembered the datasheet for the ‘670 said it was tri-state: it can output true, false, or nothing at all. If I don’t select the ‘670, it doesn’t drive the output lines at all, leaving the ROM’s input address lines floating, and picking up whatever cosmic radio-frequency strangeness that also tells my cat what to do. In other words, all the segmented address lines on my ROM were floating whenever I did an access to the “fixed” segment. You know, the segment that contains the boot code for the cart. By adding the pull-downs, those address lines are driven low by default, which keeps things consistent. Normally, I would expect floating address pins to be completely random, but this was very consistent. My best guess is that, because Tiny Slot Checker is reading the ROM sequentially, quick enough to prevent decay of any internally latched matrix addresses, and always in the same order, there is some aspect of the ROM’s internal addressing logic that makes this fairly deterministic (if still useless.) If you have a better theory, please let me know. I bodged a 10k onto the paged-A13 output of the 670, and suddenly I was now reading from $1c000 – A[14], A[15], and A[16] high, but not A[13]. Progress! Okay, let’s bodge ‘em all. Four bodged 10k resistors are going from the various paged address pins to ground. You can also see my sharpie mark indicating that the mounting hole is too dang small. After some creative routing of 10ks to avoid shorts, I had wired up all four of the paged address pins. I turned on the system to see what Tiny Slot Checker would make of it, but I was surprised to see… a Konami logo^[13]3! The title screen for Salamander The MSX was booting into Salamander! The logo for Maze of Galious And with a quick adjustment of the DIP-switches, Galious! Finishing Touches There’s one thing missing, as long as you ignore the fact that the PCB doesn’t work properly out of the box: a cartridge label. Form over function, that’s what I always say. I decided to try and get a custom sticker made, and I went to a Canadian manufacturer, [14]Sticker Beaver. I’ve been meaning to use this shop for something for quite some time now, and I figure this was as good as a time as any. The sparkly Oyanami stickers arrived in a package with a Sticker Beaver promo brochure and some samples. After a lot of learning curve in Inkscape, and a little bit of back-and-forth with the proofs, I had these [15]holographic glitter stickers cut and sent to me. Even on the free shipping plan, it only took about three business days to arrive, but it was like waiting for Christmas morning. The sticker is applied to the Oyanami cartridge shell. It looks sparkly and beautiful. While I was waiting for the stickers, I had time to debug the board. Now that I knew what was wrong, I made some tweaks to the cartridge PCB. I added a resistor network to provide the pull-downs (rolling the DIP-switch resistors into it in the process,) and fixed the mounting holes. Then I reordered it from JLCPCB, this time choosing ENIG gold plating. These new Oyanami Gold cartridges cost more money to make because of the ENIG, but I think we can all agree that they look pretty cool. And now they fit in the case! The gold version-2 cartridge stuck into a case. That is, as long as you don’t want to socket your ROMs; there’s not quite enough height, a common complaint about MSX cartridges. This one is soldered down. Maze of Galious Ah, the part of the project where I get to play a game for five minutes! I did a quick check to make sure the game was bootable, then spent thirty minutes digging out my AV capture/splitter rig and its hydra of cables and messing with OBS to record a short clip. Although Galious involves a lot of keyboard action (for instance, F1 to open the sub-screen menu,) all the movement, combat, and tricky platforming is easier with a d-pad. That’s where [16]the FM2AND6 comes in: A white game controller, reading "FM2AND6," is sitting on top of the stark black National CF2700 MSX. Made by blog friend OMPeaRetro, the FM2AND6 is a familiar controller layout that’s got a new PCB inside. It offers a no-brainer setup for 2-button games on old Japanese PCs, including the MSX, and 6-button games on the FM Towns. You’ll hear more about it later, but for now it’s going to help Popolon and Aphrodite dole out the harshness. IFRAME: [17]https://www.youtube.com/embed/ht72N8Vc1zE?si=QmGodM6B0Zixy4KM Conclusion The finished cartridge is inserted into the HB-101, and a sparkly reflection can be seen on the gloss black of the case. This was a fun project to do! It all came together fairly quickly, thanks to the help of some smart friends. And playing these old Konami games is a lot of fun. You can download [18]the cartridge KiCad files for yourself from the GitHub repository. There’s also a bunch of [19]Gerbers on the release page, which can be sent directly to fabrication. Now if only I could reflash this cart on the fly… and load games from a host PC… and… and… and… References 1. https://en.wikipedia.org/wiki/The_Maze_of_Galious 2. https://www.msx.org/users/bsittler 3. https://retrogamerestore.com/store/msx_cart_shell/ 4. https://www.leadedsolder.com/2020/07/28/portopia-repro.html 5. file:///tmp/lynxXXXXHti2mB/L3475491-4394TMP.html#fn:bios-not-port 6. https://www.leadedsolder.com/tag/hb101 7. https://www.msx.org/wiki/Category:Slot_Expanders 8. file:///tmp/lynxXXXXHti2mB/L3475491-4394TMP.html#fn:other-mappers 9. https://www.msx.org/wiki/MegaROM_Mappers#Konami_MegaROMs_without_SCC 10. https://www.msx.org/forum/msx-talk/hardware/konami-mapper-circuit-diagram 11. http://www.tiny-yarou.com/slotchecker.html 12. https://hexfiend.com/ 13. file:///tmp/lynxXXXXHti2mB/L3475491-4394TMP.html#fn:tsc-boot 14. https://stickerbeaver.ca/ 15. https://stickerbeaver.ca/stickers/glitter-stickers/ 16. https://ompearetro.com/shop/ols/products/fm2and6-custom-controller-for-fm-towns-and-other-japanese-pcs 17. https://www.youtube.com/embed/ht72N8Vc1zE?si=QmGodM6B0Zixy4KM 18. https://github.com/barbeque/oyanami-msx-megarom 19. https://github.com/barbeque/oyanami-msx-megarom/releases