Skip to content

Instantly share code, notes, and snippets.

@lucasw
Last active October 30, 2021 15:07
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucasw/53ece8eed3b99beb6215b42cc686d1a7 to your computer and use it in GitHub Desktop.
Save lucasw/53ece8eed3b99beb6215b42cc686d1a7 to your computer and use it in GitHub Desktop.
Linux Nintendo NES development

Ubuntu 16.04

install cc65

mkdir ~/other
cd ~/other
git clone https://github.com/cc65/cc65
cd cc65
make
PATH=$PATH:`pwd`/bin

If need to update:

make clean
git pull
make

Install Emulator

sudo apt-get install fceux

or

sudo apt install subversion  # I didn't have this installed, since git is so prevalent...
sudo apt install scons
svn checkout https://svn.code.sf.net/p/fceultra/code/fceu/trunk fceultra-code
cd fceultra-code
scons
...
xport PATH=$PATH:`pwd`/bin

build nes examples (doesn't work)

Then get nes samples:

Don't bother with these

cd ~/other
mkdir nes
cd nes
wget https://shiru.untergrund.net/files/src/cc65_nes_examples.zip
unzip cc64_nes_examples.zip
cc65 crt0.s
crt0.s(1): Warning: Implicit `int' is an obsolete feature
crt0.s(1): Error: `;' expected
...
crt0.s(1): Fatal: Too many errors

Oops, try ca65 instead, that works

ca65 crt0.s   # create crt0.o
cc65 -Oi example1.c --add-source  # create example1.s
ca65 example1.s  # creates example1.o
ld65 -C nrom_128_horz.cfg -o example1.nes crt0.o example1.o runtime.lib 
ld65: Error: nrom_128_horz.cfg(53): Attribute expected, got '__STACKSIZE__'

replace line 53 with (looking at cc65/cfg/nes.cfg):

  __STACKSIZE__: type = weak, value = $0500; # 5 pages stack

But then get

ld65: Error: nrom_128_horz.cfg(55): Attribute expected, got 'NES_MAPPER'

Other nes cc65 examples? (doesn't work)

Try these instead? https://github.com/jmk/cc65-nes-examples.git

~/other/cc65-nes-examples$ make
ca65 crt0.s
cc65 -Oi example1.c --add-source
ca65 example1.s
rm example1.s
ld65 -C nes.cfg -o example1.nes crt0.o example1.o runtime.lib
ld65: Error: nes.cfg(82): Attribute expected, got '__STACKSIZE__'
Makefile:22: recipe for target 'example1.nes' failed
make: *** [example1.nes] Error 1
rm example1.o

These are 4 years old without an update.

https://github.com/RichardJohnn/cc65-nes-examples has a more recent fork

algofoogle examples (works!)

How about https://github.com/algofoogle/nes-gamedev-examples ?

nes-gamedev-examples/part01/ex01-c-example$ cl65 -t nes hello-nes.c -o hello.nes

That actually built a hello.nes

fceux hello.nes

Works!

@lucasw
Copy link
Author

lucasw commented Apr 8, 2017

How to export a sound effect from FamiTracker

Create the sound effect.
Reduces the rows down to minimum needed.
Go to last row in pulse 1.
Select the third column from the left.
Enter record mode.
Type 'c'
Type 0 0 in final two columns (I don't think these values matter, which is why documentation calls this Cxx)

Export as nsf, e.g. sounds.nsf

wine /home/lucasw/other/nes/famitone2/famitone2/tools/nsf2data.exe sounds.nsf
Output format: NESASM
Output mode: PAL and NTSC

1 effects found

Effect 0
Error: effect is too long, Cxx at end of the effect may be missing.lucasw@L007:~/own/nes_cc65_demo/cta.exe sounds.nsf/lucasw/other/nes/famitone2/famitone2/tools/nsf2dat
Output format: NESASM
Output mode: PAL and NTSC

1 effects found

Effect 0	NTSC	112	PAL	113

Total data size 233 bytes

There should now be a sounds.asm file.

;this file for FamiTone2 libary generated by nsf2data tool

sounds:
  .dw .ntsc
  .dw .pal
.ntsc:
  .dw .sfx_ntsc_0
.pal:
  .dw .sfx_pal_0

.sfx_ntsc_0:
  .db $89,$3f,$8a,$0f,$01,$8a,$05,$01,$8a,$0a,$01,$89,$3e,$8a,$0b,$01
  .db $89,$3f,$8a,$0f,$02,$89,$3d,$01,$89,$3b,$8a,$0d,$01,$89,$3a,$8a
  .db $0f,$01,$89,$37,$01,$80,$3f,$81,$f6,$82,$00,$89,$35,$01,$81,$84
  .db $82,$06,$89,$33,$01,$81,$53,$89,$30,$01,$80,$3e,$81,$ff,$82,$07
  .db $01,$80,$3f,$81,$13,$82,$03,$01,$81,$93,$82,$04,$01,$80,$3d,$81
  .db $23,$82,$06,$01,$80,$3b,$81,$ff,$82,$07,$01,$80,$3a,$01,$80,$37
  .db $01,$80,$35,$81,$9a,$82,$06,$01,$80,$33,$81,$ff,$82,$07,$01,$00
.sfx_pal_0:
  .db $89,$3f,$8a,$0f,$01,$8a,$05,$01,$8a,$0a,$01,$89,$3e,$8a,$0b,$01
  .db $89,$3f,$8a,$0f,$02,$89,$3d,$01,$89,$3b,$8a,$0d,$01,$89,$3a,$8a
  .db $0f,$01,$80,$3f,$81,$b9,$82,$00,$89,$37,$01,$81,$33,$82,$06,$89
  .db $35,$01,$81,$e6,$82,$05,$89,$33,$01,$80,$3e,$81,$ff,$82,$07,$89
  .db $30,$01,$80,$3f,$81,$92,$82,$02,$01,$81,$12,$82,$04,$01,$80,$3d
  .db $81,$a2,$82,$05,$01,$80,$3b,$81,$ff,$82,$07,$01,$80,$3a,$01,$80
  .db $37,$01,$80,$35,$81,$d9,$82,$05,$01,$80,$33,$81,$ff,$82,$07,$01
  .db $00

Cut and paste the bytes into an existing sound effect slot in an existing sounds.s file.
Replace .db with .byte (and indent?).

@sfx_ntsc_2:
  .byte $89,$3f,$8a,$0f,$01,$8a,$05,$01,$8a,$0a,$01,$89,$3e,$8a,$0b,$01
  .byte $89,$3f,$8a,$0f,$02,$89,$3d,$01,$89,$3b,$8a,$0d,$01,$89,$3a,$8a
  .byte $0f,$01,$89,$37,$01,$80,$3f,$81,$f6,$82,$00,$89,$35,$01,$81,$84
  .byte $82,$06,$89,$33,$01,$81,$53,$89,$30,$01,$80,$3e,$81,$ff,$82,$07
  .byte $01,$80,$3f,$81,$13,$82,$03,$01,$81,$93,$82,$04,$01,$80,$3d,$81
  .byte $23,$82,$06,$01,$80,$3b,$81,$ff,$82,$07,$01,$80,$3a,$01,$80,$37
  .byte $01,$80,$35,$81,$9a,$82,$06,$01,$80,$33,$81,$ff,$82,$07,$01,$00

It should then work with a sfx_play command.

There will be some ugly ^M linebreaks, get rid of them in vim with :set fileformat=unix

@lucasw
Copy link
Author

lucasw commented Apr 9, 2017

NES Cartridge

What is the width of the pcb?

The width of the traces?

The spacing between the traces?

Is there a low cost off the shelf cartridge break-out?

https://wiki.nesdev.com/w/index.php/Cartridge_connector

http://www.raphnet.net/electronique/nes_cart/rom.txt

FPGA cartridge

Connect every pin to a low cost fpga dev board with a lot of gpio: https://www.amazon.com/RioRand-EP2C5T144-Altera-Cyclone-Development/dp/B00LEMKR92

Also need a usb blaster to program it.

Need a 69 bits of level shifting to go from 3.3V (or 1.8V?) to the 5.0V nes voltage.

Need to have an interface (Serial over usb?) to a computer.

It has 119,808 ram bits that could be configured over a dual port and a serial connection to a host computer (or through JTAG?).
This would amount to a 15 kB cartridge at a given moment, but the ability to change the memory would overcome that. (it couldn't be used as a generic device to play any nes game, just custom applications that can stream themselves to the dual port ram).

@denisenepraunig
Copy link

denisenepraunig commented Oct 30, 2021

Thanks for your gist, I was struggling with shiru's cc65 examples but thanks to your links I found something that works :-) (macOS 11.6)

@lucasw
Copy link
Author

lucasw commented Oct 30, 2021

I should have left a link here to https://github.com/lucasw/nes_cc65_demo earlier - if you didn't already see that it may be more useful, better organized than this gist

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment