KrzysioPlayer - Hardware NSF Player with SD/MMC flash cart

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
KrzysioPlayer - Hardware NSF Player with SD/MMC flash cart
by on (#158310)
KrzysioPlayer - Hardware NSF Player with SD/MMC flash cart support

Image Image Image Image

I would like to present my latest project that I have been working at for a few months - KrzysioPlayer - hardware NSF player based on real 6502 from Famiclone (UA6527P). `Krzysio` is my name in some funny form, thats the source of the device's name. The use case is simple: record your favourite NSF files onto SD/MMC cart, insert it into device's slot, choose the one you want to play with user-friendly interface (buttons & lcd) and listen to the REAL HARDWARE nsf music. The device is capable of playing up to 128 kB NSF Files.

Lets discuss the details. The whole device has some interesting things:
1. 6502 CPU (UA6527), clocked at 26.601712 MHZ crystal (the clock generator is build on one transistor and some R/C, like in famiclones)
1. LCD 24x2 (based on HD44780), connected directly to the CPU Bus and potentiometer for regulating its contrast
2. 8 buttons, connected to the CPU Bus via 74x245 buffer
3. 32 kB 62256 RAM, for various purposes
4. 512 kB 29f040 Flash, for storing the main operating program (firmware) and for burning selected song from MMC/SD card for playing
5. NE555 for generating 50 HZ interrupt to the CPU for executing the nsf's play routine at consecutive intervals. The NE555 is working in astable mode and is generating (aproximatelly) square wave. There is a potentiometer for slightly changing the frequency - from 40 to 60 Hz - you can play PAL and NTSC songs with proper speeds! CPU is also capable of turning off the NE555 if it doesnt want to receive interrupts
6. Xilinx XC9572 CPLD for various functions:
- address decoder: generates chip enable to the LCD/RAM/Flash, according to the address put on the bus by CPU,
- receiver and transmitter to the MMC/SD card: cpu gives signal to the CPLD to begin reading/writing 8 bits of data to the card and after some clock cycles the CPU can readback the data that has ben read by CPLD
- stores currently set banks at $8000, $9000, $a000, $b000, $c000, $d000, $e000 (5 bit number can be stored as each bank number, so the device is capable of playing 2^5 * 4 kB = 128 kB NSFs).

Building this device took me so long because I have been encountering various problems.

The first problem was how to organise the memory so that the operating system and nsf song will coexist in one address space. Becasue the NSF can use almost the whole RAM memory at $000-7ff and my player would also like to use the stack and zeropage, I decided to have switched RAM - the CPLD can switch the RAM so nsf song and the operating system can have its own stacks, zeropages, variables.

The second problem was where to put the executable code of player if nsf song rom code also have to be at $8000-$ffff. So I decided to have also switched ROM - the CPLD can switch the rom for the operating system and nsf song, according to the needs.

There MUST be also some fixed region in the memory - I decided to choose $1000-$2000 because it is not used by the nsf songs - that I will put some crutial variables and executable code that has to be vissible when RAM/ROM is switched for nsf song and nsf operating system. This regions is also very important when erasing and programming 29f040 rom memory, because when the memory is being programmed, the 6502 cannot execute code from here, so it copies the erase/program routine to the ram (at $1000-$2000) and start executing code from here.
There is of coure RAM at $6000-$7fff. The detailed address space is on the figure below:

The XC9572 CPLD is not very big programmable device - it has only 72 macrocell. One macrocell can be used to remember one bit of data or to drive one input/oputput. There are already 8 * 5 = 40 macrocells used to store the bank numbers, but there must be also space for implementing whole SPI protocol with MMC/SD card, generating !CE signals, driving higher address lines for the 29f040 rom memory. I have to did some very crazy maneouvres to fit in. Finally I did it, but I am using 100% of the resources (!!!).

The tricks are as follows:
* implementing SPI protocol communication wastes also some macrocells. The CPLD is clocked by the M2 (1.7 MHz) line from the cpu so that the effective SCLK line on SPI bus is half of that - around 800 kHz, so it takes about 16 cpu cycles to transmit/receive 8 bits to/from the SD/MMC card. Because it is not done in one clock cycle, the CPLD has to latch the 8 bits of data send from the CPU that will go to the MMC/SD. This would took 8 macrocells. I am latching only 7 of them, because the higher one is immediatelly sent to the card.

* 74245 buffer for the buttons is not driven by the chip enable signal generated from CPLD. Instead, I am using the 35 pin of the cpu - RD_$4016_!OE from the cpu - so reading state of all buttons is just reading the $4016 register

* reset signal to the ne555 is driven from the 39 pin of the cpu - $WR_4017_D0 - so enabling 50 Hz timer is just writing $01 at $4017 by cpu

* I have to also play with the options at the Xilinx IDE - for example: Optimise Balance gives better results than Optimise Density. Also the XC9572 that I am using (5V core+io) is slightly worse with comparision to the XC9572XL (3.3V core + io) because it has less internal connections - so I had to write really optimised code in VHDL.

I have implemented the FAT16 and FAT32 filesystem from SCRATCH with Long File Names (LFN) supports. So the device can list directories without any problemss.
The audio, generated from the CPU is amplified by one NPN transistor (saturated key with negative feedback), same as on Famiclones.

Erasing and Burning 128 kB NSF files takes up to 15 seconds, while smaller ones (a few kBs) are played just immediatelly.

The whole code is written from scratch in pure ASM 6502 - around 2000 lines of code, but after compilation I got around 6 kB of code.

I think it is the only one standalone hardwa NSF player (except Kevtris HARDNES)

Here are the schematic, pics and the video. Sorry for polish language in the movie.

Image Image Image Image
Re: KrzysioPlayer - Hardware NSF Player with SD/MMC flash ca
by on (#158359)
I like it. It's very cool to see the NES CPU handling everything.
Re: KrzysioPlayer - Hardware NSF Player with SD/MMC flash ca
by on (#158403)
Amazing work :) Quite fantastic that you packed so many features into the 6502 design. Hat off to you.
Re: KrzysioPlayer - Hardware NSF Player with SD/MMC flash ca
by on (#158424)
Sorry I have not finished my player. It is not a pure NSF, it also able to play MD sound files.
Re: KrzysioPlayer - Hardware NSF Player with SD/MMC flash ca
by on (#158428)
Looks cool, but did you have to remove the CPU from a NES to insert it there ? That'd be a real shame. I think it'd be even cooler if you allowed a bare 6502 to be used and simulate the 2A03 sound with the CPLD (if that's not what you're already doing).

In case anyone wonders, the pronunciation is "Kjeshio"