1 Chip MSX How-to ================= What does the OCM hardware comprise? ------------------------------------ There's not much to the OCM. The important bits are: * 21.48 MHz input clock * Altera Cyclone EP1C12 FPGA * Altera EPCS4 serial configuration device * 32MB SDRAM * Video out (TV/VGA) * PS/2 input There are also 2 USB ports on the board. The differential I/O lines are connected directly to the FPGA. As-supplied, these ports do nothing at all. To be able to use these ports, the FPGA would have to be configured with a USB host or slave IP core. There's an SD/MMC card slot for emulation/transfer of disk images. I don't know much about this atm. How does the OCM work? ---------------------- The EP1C12 is a relatively small FPGA. As-supplied, the MSX2 core utilises 83% of the logic. This leaves a lot less room than you would at first think - once you get above 90% utilisation, you start to hit problems routing and meeting the timing requirements of real-world designs. The EP1C12 has (IIRC) about 27KB of SRAM. This is nowhere near enough RAM for the MSX2 BIOS and extended ROMs, Disk ROMs, character ROMs, etc. So where are the ROMs stored? The EPCS4 serial configuration device is a flash-based device that is used to store the FPGA configuration image. However, it is more than large enough to store an EP1C12 FPGA image - the remainder can be used by the FPGA application as serial flash storage. The OCM loads the ROMs into SDRAM when it first boots via a 512-byte "IPL" (Initial Program Load) ROM embedded in the FPGA image that runs on the Z80 (more details below). PS/2 input provides emulation of the MSX keyboard on a standard PC keyboard. The video output is quite nicely done. The same FPGA bitstream provides a couple of TV (composite) and VGA output modes, which can be switched on-the-fly with the key on the PS/2 keyboard. The default output mode is set on two of the board's DIP switches. There are also a couple of video "debug" modes, including an OSD display of the VDP registers, which can be cycled with the key. Again, there's no SD/MMC slot on my hardware, so I don't know much about this. Hardware Requirements for Porting OCM ------------------------------------- Basically, you need the "important bits" above, or a super-set there-of. You *need* some sort of input clock. Hopefully the PLL multipliers/dividers will work out OK for you. You *need* a Cyclone (EP1C12 or larger) or a Cyclone II (equivalent or larger). You *need* an EPCS4 or larger (I've used an EPCS16 for example). You *need* at least 1x 32MB SDRAM device. You could use a larger device with modifications. You *need* some sort of video output. You *need* some sort of PS/2 input. SD/MMC would be a bonus. DIP switches would be a bonus. If you are hoping to port it to a Xilinx device - good luck! Your biggest problem will be booting the ROMs. A few days ago I knew absolutely nothing about the MSX or the OCM - so I found it quite challenging to decypher _any_ of the 512-byte IPL ROM disassembly (and I _do_ know Z80 inside-out). A hint though - look at the PLDLOAD/PLDSAVE source code, that has very similar routines! You'll basically have to completely replace the IPL with something equivalent to boot your ROMs from wherever you want to boot them - but I don't understand what other magic 'bits' in the core it's twiddling in the process. The Port -------- The first step is to create a wrapper around the top-level emsx_top.vhd file. You can leave most of the signals unconnected - the cartidge slots, joysticks, USB and reserved pins for example. You really only need concern yourself with clocking/reset, SDRAM, video, PS/2 and dipswitches. I won't go into any more detail here because if you don't know what you're doing at this point, you probably shouldn't be attempting the port. *** I should note at this point that I've still got glitches with my port. For instance, my design won't boot from the EPCS without Altera's "SignalTap" compiled into the project. I'm yet to narrow down the problem, but it could be related to the lack of pull-ups on the cartridge slot "inout" ports. Or it could be SDRAM clock skew. I'm not sure. But it's a good start! The next step is to replace the PLL (unless you have the same clock frequency on your board) in pll4x.vhd. See the comments in emsx_top.vhd where the PLL component is declared. You need all 3 outputs of the Cyclone(/II) PLL. C0 should be close to 21.48MHz so the video syncs correctly and so the system runs at the correct speed. C1 and E0/C2 need to be (exactly?) 4x C0, around 85.92MHz for the SDRAM. E0/C2 should be assigned to a dedicated PLL output pin - it's likely your board has one PLL output connected to the SDRAM clock pin. Again, these frequencies don't need to be exact - within 0.5MHz if possible - but the 4x is crucial. If you're porting to a Cyclone II, you'll (probably) need to modify emsx_top and change the instance of the cyclone_asmiblock to cycloneii_asmiblock. This is the altera-supplied component that twiddles the active-serial-mode pins to the EPCS device. If you don't have dipswitches on your hardware, then hardwire convenient values for your own purposes. The default as-shipped is all '1', and if you're looking at the source to work out what does what, the code logic works with the _inverted_ values. I'd strongly suggest a manual 'reset' pushbutton/switch as well - wired to the slot reset, That should be about it for the VHDL portion. It's worth testing this before bothering to get the ROMs booting. The design thus far should enable you to see the OSD on your TV/VGA output. Try toggling the video modes and cycling through the debug modes as outlined above. If you don't get any output, or unreadable output, it's back to the drawing board. Booting from the EPCS device ---------------------------- Ah, the fun part! If you're porting to an EP1CS12, then your job is easy. If not, it's a little more involved. Firstly, there is a 256KByte Intel HEX format file called "emsx_top.hex". This contains 4x 64KB segments. The 2nd segment contains the BIOS (32KB), extended (16KB) and some other ROM. The other segments contain some other data which I assume is critical to the operation of the MSX. This file needs to be programmed into the EPCS device at the correct address. The EPCS4 is a 4Mbit or 512KByte flash device. The MSX2 ROM file is 256KB in total - that's exactly half the EPCS4. The IPL expects the hex file data to exist at offset $40000 (top half) in the EPCS device. An EP1C12 FPGA bitstream (compressed) will fit into the first half of the EPCS4. An EP2C35 FPGA bitstream (compressed) *won't* fit. If you have an EPCS4 and something other than an EP1C12, then there's no way you can configure it with the FPGA image and the MSX ROMS - it simply won't fit. The compromise is to program the original EP1C12 image with the ROMs, and always configure the FPGA via JTAG. *** A special note here: my hardware gets into a state where I can't program the FPGA via JTAG if the board is powerd up with an incompatible bitstream in the EPCS device. Fortunately, I have both JTAG and ASM ports on the board, and the EPCS device is also socketed. You may not be so lucky - I accept no responsibility for bricking your device! BTW you can configure a larger EPCS device with a .POF file designed for a smaller EPCS device. If you have a larger EPCS device, then you can fit both the FPGA bitstream and the ROM files into the device. However, you will need to modify the IPL ROM with the new offset of the ROM file in the EPCS device. To create a new .POF file, use the "Convert Programming Files" option in Quartus "File" menu. You can load the exsiting .COF file, or create a new .POF for your chosen EPCS device. You need to add both your .SOF FPGA bitstream and "emsx_top.hex" file to the .POF contents. Select "Compress" on the SOF entry and "Relative Addressing" on the hex file entry. Ensure that the "Memory Map File" option is selected and then generate the file. *** You won't be using this build of the file - see below *** Open the .MAP file produced and look at the address for the emsx_top.hex file. AFAIK it'll be at the _end_ of the device address range, so perhaps you can assume it'll be fixed for each EPCS device?!? Now to modify the IPL ROM to load the ROMs from the new base address in the EPCS device. At offset $86 in the IPL ROM instance in "iplrom.vhd" is the code: 01 00 02 ld de, 0200h The "02" at offset $88 corresponds to the '4' in $40000. The code shifts the address left 1 bit later on. Modify this byte to be 1/2 of the upper word of the offset. For example, for my EP2C35 image, the offset was $1C0000, so I replaced "02" with $0E ($1C/2). Save the IPL and re-build. You will of course have to re-generate the .POF as you did earlier. There you have it. Status ====== As I mentioned, for some reason my design only works with SignalTap built into the design. It also won't boot immediately after power-up or JTAG programming - I need to hit manual "reset" which is a switch on the board wired to the "pSltRst_n" port of emsx_top. Not sure why, although there's a comment about the reset pulse being 48ms in the source - maybe I need to extend my power-on-reset module in the top level? At one stage, when I was banging on every key on the keyboard looking for the key, it went berserk. It may well have been me simply hitting the 10MHz turbo button, or it could be a problem with clock skew on the SDRAM. Aside from that, it looks good! Now I need to hook up my compact flash to the SD/MMC port of the core design somehow - probably by emulating a SPI device and then translating the commands appropriately?!? Fun fun fun... --