Programming NES games in C article

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

User avatar
Nioreh
Posts: 116
Joined: Sun Jan 22, 2012 11:46 am
Location: Stockholm, Sweden

Post by Nioreh » Sat Jan 28, 2012 7:32 am

Thanks Shiru, but I think this version introduced another bug. Now I have to hold the A-button to get any other button to register.

Bug appears on nestopia and real hardware. Not in FCEUX.

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru » Sat Jan 28, 2012 7:47 am

Fixed, temporary files are updated.

User avatar
Nioreh
Posts: 116
Joined: Sun Jan 22, 2012 11:46 am
Location: Stockholm, Sweden

Post by Nioreh » Sat Jan 28, 2012 8:36 am

Wow, that was fast. Thanks!

albailey
Posts: 177
Joined: Thu Jul 13, 2006 3:15 pm

Post by albailey » Fri Mar 16, 2012 8:12 am

Shiru, do you have the source code anywhere for the runtime.lib code?

Namely, I am interested in seeing what popa and popax do.

I noticed when looking at the code for some of the neslib.s (I was looking at oam_spr) routines that there are lots of calls to "jsr popa" because that call takes 4 arguments.

Typically jsr can be a bit heavy (6 cycles for JSR plus another 6 for its RTS) and I wanted to see if any of the routines could be optimized.

Al

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru » Fri Mar 16, 2012 1:56 pm

It is in the CC65 sources, you can download them, there are many functions. I quote these two here:

Code: Select all

;
; Ullrich von Bassewitz, 25.10.2000
;
; CC65 runtime: Pop a from stack
;

       	.export	  	popa
	.importzp	sp

        .macpack        cpu

.proc	popa

.if (.cpu .bitand ::CPU_ISET_65SC02)
	lda	(sp)
.else
	ldy 	#0              ; (2)
 	lda	(sp),y		; (7) Read byte
.endif
      	inc	sp              ; (12)
       	beq	@L1             ; (14)
	rts                     ; (20)

@L1:	inc	sp+1
	rts

.endproc

Code: Select all

;
; Ullrich von Bassewitz, 25.10.2000
;
; CC65 runtime: Increment the stackpointer by 2. For performance reasons,
; 		this modules does also contain the popax function.

       	.export		popax, incsp2
	.importzp	sp

        .macpack        cpu

; Pop a/x from stack. This function will run directly into incsp2

.proc	popax

	ldy  	#1
   	lda	(sp),y	   	; get hi byte
       	tax	     	   	; into x
.if (.cpu .bitand ::CPU_ISET_65SC02)
	lda	(sp)		; get lo byte
.else
   	dey
   	lda	(sp),y		; get lo byte
.endif

.endproc



.proc	incsp2

        inc     sp              ; 5
        beq     @L1             ; 2
        inc     sp              ; 5
        beq     @L2             ; 2
        rts

@L1:    inc     sp              ; 5
@L2:    inc     sp+1            ; 5
        rts

.endproc

Makdaam
Posts: 2
Joined: Sun Apr 08, 2012 11:02 am

Post by Makdaam » Sun Apr 08, 2012 11:10 am

Thanks for the great article, however I've got some problems with linking:

Code: Select all

$ ld65 --version
ld65 V2.13.9 - (C) Copyright 1998-2009, Ullrich von Bassewitz

$ ld65 -o main.nes crt0.o example1.o runtime.lib -C nes.cfg 
ld65: Error: Wrong data version in `runtime.lib
If I'm linking without runtime.lib I get:
"ld65: Error: nes.cfg(82): Attribute expected"
82 is the line with "__STACKSIZE__ = $0500; # 5 pages stack"

I've never developed on the NES platform (or used the cc65 binutils) before, also I'm trying to build the examples on Ubuntu.

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru » Sun Apr 08, 2012 11:21 am

I have ld65 2.13.2. Perharps you have some newer or WIP version of CC65? Where to get Windows build of this version?

Also, order of ld65 parameters could be important.

tepples
Posts: 22050
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples » Sun Apr 08, 2012 1:45 pm

Version 2.13.3 is uploaded to the FTP site. Here's the changelog summary from 2.13.2 to 2.13.3 from the 2.13.3 release announcement.

cc65:
  • Fixed some macro issues.
  • Static const local data goes into RODATA, not DATA.
  • Fix problem when converting function to void pointer.
  • Fix register info for several runtime functions. Result was invalid code.
  • Fix an error in the runtime division routine.
  • Fix internal error caused by error recovery (or lack of).
  • Fix invalid handling of signed int types in some cases.
  • Fix and improve the code for compares.
  • Disallow __asm__ on global level.
  • Fix problem with access to structs returned by functions.
  • Fix an internal error in the code generator.
ca65:
  • Fix error handling in .LEFT.
  • Fix problem with .REPEAT.
  • Fix problem with alignments >= 256 bytes.
  • Fix some macro issues.
libraries:
  • Fixed problems with 80 column mode (C128 library).
  • Remove final jump to RESTOR for all CBM platforms (cc65 libraries).
  • Merge back Olivers C interrupt handling code (cc65 libraries).
  • The LINE function mistakenly enabled the BASIC ROM (TGI driver for C64).
  • Fix some issues with conio scrolling (C128 library).
  • Add missing export for CBM510 platform (cbm510 library).
  • Merge back POSIX directory routines for the Atari (atari library).
da65:
  • Fix smbx and rmbx instructions.
general:
  • Fixed/improved several error messages (all tools).
  • Several documentation changes.
  • Several documentation fixes and improvements.

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Post by Shiru » Sun Apr 08, 2012 2:08 pm

2.13.3 also works for me, no changes were needed.

Makdaam
Posts: 2
Joined: Sun Apr 08, 2012 11:02 am

Post by Makdaam » Tue Apr 10, 2012 12:52 am

I got it from a repo at http://www.trikaliotis.net/debian... but I guess building it from source would be a better idea.

User avatar
rainwarrior
Posts: 7836
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Programming NES games in C article

Post by rainwarrior » Thu Oct 11, 2012 1:08 pm

Shiru, I was wondering what you ended up putting in your runtime.lib.

Is it just runtime/ plus common/zerobss.s ?

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: Programming NES games in C article

Post by Shiru » Thu Oct 11, 2012 9:10 pm

It is standart cc65 runtime, recomplied by me. Nothing is added there, as far as I remember - none of my code for sure. I don't really remember why I did recompile it. I think I used nes.lib initially that did contain the runtime, but a ton of unneeded stuff as well, so I replaced it with the runtime only, that does not have anything platform-specific (600 to 100K in size).

User avatar
rainwarrior
Posts: 7836
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Programming NES games in C article

Post by rainwarrior » Thu Oct 11, 2012 9:46 pm

I've been looking over it, compiling my own version. I had been using yours, but I wanted to get a better idea of what's in there.

There is basically nothing useful in the nes/ lib source, unless you want to make a text only program maybe, and I think it's a good idea to replace crt0. Luckily all the runtime/ stuff is modularized, so stuff you don't used is not linked in anyway.

Apparently there's a few things I need from common/ so far zerobss.s and copydata.s were needed. Probably I will need to add more as I go along and I get link errors, but I think most of common/ I want to leave out. I'm keeping a list as I go. I'll release source and information once I've finished my current project, so anyone who's interested might learn from it.

Shiru
Posts: 1161
Joined: Sat Jan 23, 2010 11:41 pm

Re: Programming NES games in C article

Post by Shiru » Thu Oct 11, 2012 10:11 pm

Here are the runtime sources that I used to compile the runtime.lib.

User avatar
rainwarrior
Posts: 7836
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Programming NES games in C article

Post by rainwarrior » Thu Oct 11, 2012 10:23 pm

Ah, that looks exactly like runtime/ + common/zerobss.s like I suspected. That answers my earlier question.

Post Reply