PIC16 EMULATOR AND NES MUSIC PLAYER

First published at https://youtube.com/watch?v=P82Zf31joPk

In this tool-assisted education video I create an emulator for the PIC16F628A chip.
In the emulator design I aimed for a data-driven design where efficient code is produced from concise and easy-to-read data at compile-time.
Read more...

Downloadable files

  • example_payloads.zip : Sample .HEX files (payloads) I made for those who want to either build my emulator, or to craft the circuit themselves.
  • schemav2.png : The circuit diagram of the device I built using this chip (and which I am also emulating).
  • song_converter.zip : The .PHP program I wrote that converts NES songs into datafiles for the program. Use this only if you are interested in rebuilding the program that runs on the PIC, or studying how it works.
  • emulator-source-youtube.zip : The very same source code that you see in the video.
  • emulator-source-original.zip : The emulator source code before the simplification changes I did it for YouTube video. Includes also a disassembler that can be enabled with a #define.
  • pic16f628a_2009doc.pdf : The official documentation (datasheet) for PIC16F628A, provided by Microchip Technology Inc.
  • simulated20-wily.mp3 : The Dr. Wily song, as produced by my program that runs on the chip, before I began counting cycles to make the player pitch stable regardless of branches taken.
  • simulated20-cut.mp3 : The Cut Man song with the same version as above.
  • simulated20b-wily.mp3 : The Dr. Wily song in a later revision of the player program.
  • simulated20e-wily.mp3 : The Dr. Wily song in the latest revision of the player program.
  • programpic.cc : The Arduino program that I used (with small modifications) for writing into the PIC chip.
  • editor.zip : I used this editor in the video. (And only in the video.) I always make small changes to the editor whenever I make a new video, and this, too, is slightly different from the others. I can be barely bothered to document it though :) Only download this if you are a fanatic DOS user. The keyboard bindings are documented here: https://bisqwit.iki.fi/jutut/kuvat/programming_examples/e_editor/keys.txt
  • nesplayer-PORTABLE.zip : The program that runs on PIC, before I started converting it into assembler code to get a better sampling rate. If you want to port the NES music player to some other hardware, start here! This one can be compiled with GCC on any platform, such as PC. Makefile is supplied for convenience. It outputs 8-bit PCM sound into stdout at 19531.25 Hz sampling rate (5 MHz divided by 256). It also includes the LED functions, so you can see how I did that.
    This is basically a C port of the CAPCOM music engine featured in Mega Man I and Mega Man II, but rewritten from scratch by me with software synthesis in mind, and with some features stripped (such as vibratos / pitch slides).
  • nesplayer-final.zip : The actual program that runs on PIC, and its Makefile and other resources. It must be compiled on Microchip's PICC (XC8) compiler. I tried SDCC first, but unfortunately it does not optimize well enough. Optimizing for size is a paramount for this program, since the program memory in the chip is so small. I stopped optimizing when I finally found a way to make it small enough to play the entire Dr. Wily song.

Example workflow

# Download and decompress files

S=https://bisqwit.iki.fi/jutut/kuvat/programming_examples/pic/
for s in {song_converter,emulator-source-youtube,nesplayer-{final,prototype}}.zip; do wget $S/$s && unzip -n $s ; done
# or:
export S=https://bisqwit.iki.fi/jutut/kuvat/programming_examples/pic/
echo {song_converter,emulator-source-youtube,nesplayer-{prototype,final}}.zip | xargs -n1 sh -c 'curl -O $S/$@ && 7za x -y $@' x

# Compile emulator (Note: GCC 4.7 or newer is required. Clang++-3.3 is also fine.)

g++ -std=c++11 -O3 -o emulator {cpu,hexfile,memory,emu}.cc

# Choose song

php song_conversion/songdata.php song_conversion/2_17_MUS_Fight.txt > songdata.h

# Compile payload (the program that would be written to and running on the PIC16f628a).
# Note: You need Microchip's PICC (XC8) compiler to rebuild the PIC version of the payload.

make test.hex
# Alternatively, you could download example_payloads.zip and copy one of those files into test.hex.

# Run emulator (warning: LOUD SOUND)

./emulator | sox -t u8 -r20e6 -c1 - -t s16 -r44100 -c2 - | mplayer -demuxer rawaudio -

# Compile the C version of the payload (you can use any compiler that supports C99)

gcc test-conly.c -o test -O2 -I. -std=c99
# or:
tcc test-conly.c -o test -O2 -I.

# Run C version of payload (warning: LOUD SOUND)

./test | sox -t u8 -r19531.25 -c1 - -t s16 -r44100 -c2 - | mplayer -demuxer rawaudio -
# or:
./test | mplayer -demuxer rawaudio -rawaudio rate=19531:channels=1:samplesize=1 -
# or:
./test | aplay -fu8 -r19531 -c1
# or:
./test | ffplay -  -f u8 -ar 19531.25 -ac 1
# or:
./test | ffmpeg -f u8 -ar 19531 -ac 1 -i -  -f mp3 - | mpg123 -

Copyright (C) 2014 Joel Yliluoma