Archive for May, 2008

Joypad reading timings

Friday, May 30th, 2008

Yesterday, Tomy reported a bug on real hardware about the joypad reading in the rom I provided. It happens that I moved the pad reading into an event managed by my event engine processed during NMI. My first tough like Tomy is that there might be a problem reading the pad during NMI interrupt. It was time to read the docs…

The SNES documentation is quite clear about that. Pad should be read 215 (214.55) µs after the VBlank started (NMI Interrupt is trigered at start of VBlank). They state that it’s a good practice to read the pad after DMA of at least 576 byte.

One other precaution is to not set the joy enable register during VBlank, if it’s not the case readed data might not be valid.

I tried to put it after the proccessEvents(); function but it still seem to not work properly. So I finally set it after the waitForVBlank in the big while loop in main.c. I will analyse some games next week to clarify how they really doing it cleanly.

I still need to finalize the tests with tomy from Tototek. Thanks Tomy for all your testing.

++ Lint

FIXED … action [PART III]

Thursday, May 29th, 2008

A quick fix is avalaible here for the yesterday release.

There was 2 problems. One for everybody because of a bad tile transformation of the debugFont. And the other one was only visible in BSnes. The later bug was due to a bad size of tile being copied to DMA and direct write VRAM for each character writed in debug screen. Now i update the buffer (debugMap) and i DMA copy it in one shot in VRAM.

 

So now that everything is fixe, please enjouy the code. I modified a bit the routetine for writing to screen. Don’t forget to make your string finishing with a “\0″. I added also support for new line and line bigger than 32 character. No scroll support when too much is writed to the screen. It might come quick I think.

ROM 3 fix teaser

 

Enjoy !

 

++ Lint

WDC C Compiler for 65816 in action [PART III]

Wednesday, May 28th, 2008

Hi all,

It’s been a while that I haven’t posted working code on my blog. As promised i come with mosaic and fade effect and very small debug output. I will come bacl on debug fonctionnality a bit later. The two gfx effect I provide here are more than just the effects it’s a whole event managing system trigered by the NMI interrupt. I had some issue with NMI for about a week but now everything is starting to become clear in my mind (I will come back with this problem in an other post).

The event managing system is quite simple to use. Here is the function prototype and the structure used to store the events :

void initEvents(void);
extern event* addEvent(char (*callback)(word counter),
	int noDuplicateCallback);
extern void removeEvent(event *eventElement);
extern void processEvents(void);

typedef struct event{
    word VBlankCount;
    char (*callback)(word counter);
    struct event *previousEvent;
    struct event *nextEvent;
} event;

As you can see there is an initEvents that need to be called before adding events. The processEvents function need to be called in the NMI handler. The events them self are simply stored in a double linked list for managing ease.

To add a function it’s very simple you just need to provide a callback function that take an int as argument. This argument will be the VBlank/NMI count since the add of the event. An other parameter allow to specify that you don’t want to add a event if it’s already in the event list. Here is an example on how to add an event and an event callback function for fading out :

addEvent(&fadeOut, 1);

char fadeOut(word counter) {
    static byte fadeOutValue;

    if(counter == 0) {
        // init fade value
        fadeOutValue = 0x0f;
    } else {
        fadeOutValue--;
    }

    *(byte*) 0x2100 = fadeOutValue;    

    if(fadeOutValue == 0x00) {
        return EVENT_STOP;
    } else {
        return EVENT_CONTINUE;
    }
}

I’m sure you saw the EVENT_CONTINUE and EVENT_STOP. In fact the callback function is needed to return a char that specify the processEvents function if the event still need to stay in the event list or if it should be removed. The removeEVent function is called internally in processEvents.

So now managing events triggered by VBlank/NMI is all easy.

So now the debugging facilities… Hmm not yet totally implemented like I wished. The font is there, the basic function is there… So what’s missing ? printf like functions for being able to display on the debug screen, some more code and memory space to backup VRAM and CGRAM so we are able to restore the previous screen config properly, many code cleaning is needed in debug part.

So I just make this realease, even if everything is not coded as I wished, but it’s been a while that I promised a release. So expect more debug stuff to become reality.

You can test the events in the archive by launching the rom.smc file and pressing up or down to play with mosaic and fade effects. Pressing left make the screen scroll left while right make it stop. The is a small isuue with the fluidity of the left scrolling. I don’t know if it’s a NMI timing issue in the emulators or if it’s my code. If someone can test that on real hardware you are welcome to give me feedback with a comment on this post.

Full archive is available here as usual. There is now a makefile provided instead of the make.bat, if any problem get in touch with me.

See ya, Lint

My wishlist

Wednesday, May 21st, 2008

There is a few items that I’m currently really interested in. Most of those stuff are not really ***RARE***, but I don’t really have tons of money to go in those items. So … if you see one of those, if you own of those, just get in touch with me.

It’s been a few weeks that im looking for a copy of WILD GUNS for SNES. It’s really a wonderfull game that was released at the and of the SNES official life. Not a lot of cartridge were produced and then it’s a bit difficult to find at a good price. I don’t need boxed game with instructions. Cart only is ok … in pal, US or japan favor. Here is a youtube video to show you what type of gameplay it has.


YouTube - Link toWild Guns SNES review

More wish list comming soon … with certainly some ***RARE*** stuff.

See ya, Lint

Debug Teaser

Friday, May 16th, 2008

I finally finished to plot the font for my debugger. Hmmm not really a debugger. Currently it will just be a buffer that you can feed with stuff you wanna to print out. Then when pressing L+R+Start you will have access to what you decided to output.

Debugger teaser

If you use  my C functions to setup screen, you will be able to restore the whole thing when unpressing the dedicated buttons. Can be quite practical. Don’t worry the debugger will have way more feature.

Still need to clean up code and then will work on the mosaic and fade effects. I keep you updated…

See ya, Lint

New website discoveries

Thursday, May 15th, 2008

Yesterday I discovered a new forum. Well not really a new forum but one that I never noticied before. As you know nesdev.parodius.com is good reference about various documentaion on the NES and even some in the SNES area. Gato pointed me out that there was a forum associated with the site.

Nesdev Logo

The forum is like the site, being oriented at NES dev but there is a forum slot dedicated to SNES.

Enjoy the nesdev bbs.

++ Lint

WDC Classic C Libs

Wednesday, May 14th, 2008

I recently got a comment through the comments of my latest post. Gato seems to have problems using C libs provided with the WDC compiler. What are really those C libs and what are the functionnality they provide? There is plenty of website providing more info on those libs. Don’t hesitate to use Google for more info about them.

I will now show only a part of the C standart librairy :  stdlib.h and string.h.

Stdlib.h - Commonly used Library Functions. Some example of functions :

int abs(int _j);
	- absolute value of integer
int atoi(const char *_nptr);
	- convert a string to an integer
long int atol(const char *_nptr);
	- convert a string to a long integer
void exit(int _status);
	- normal exit & close files
void free(void *_ptr);
	- causes the space pointed to by ptr to be deallocated.
void ftoa(double _val, char *_buf, int, int);
	- convert floating point to ascii
void *malloc(size_t _size);
	- allocate with block size
int rand(void);
	- integer random numbers (0 – 32565)
void *realloc(void *_ptr, size_t _size);
	- expand memory block
void srand(unsigned int _seed);
	- seed integer random number generator

String.h - String conversion Functions and Memory Functions. Some example of functions :

void *memchr(const void *_s, int _c, size_t _n);
	- search memory for character
int memcmp(const void *_s1, const void *_s2, size_t _n);
	- compare memory
void *memcpy(void *_dst, const void *_src, size_t _n);
	- copy memory, byte access, allows overlap
void *memmove(void *_dst,const void *_src, size_t _n);
	- move memory, byte access, allows overlap
void *memset(void *_s, int _c, size_t _n);
	- fill a block of memory with a character
char *strcat(char *_dst, const char *_src);
	- string concatenate
int strcmp(const char *_s1, const char *_s2);
	- compare strings
char *strcpy(char *_dst, const char *_src);
	- copy string
char *strstr(const char *_s1, const char *_s2);
	- search for one string in another
char *strtok(char *_s1, const char *_s2);
	- split string into tokens

You should use those carefuylly since they may not be perfectely optimised and then take a large space into your final ROM. So now ? Maybe a small example to illustrate all this. 3 simples steps : code , compiling and finally linking.

The code - main.c

#include <stdlib.h>
#include <string.h>

void main(void) {
}

void preInit(void) {
	char string[10] = "snes";
	char test[10];

	// fill with space
	memset(test, 32, 10); 	 // screen A
	// fill half with dots
	memset(test, 46, 5);	 // screen B
	// copy with string
	memcpy(test, string, 4); // screen C
	while(1 == 1) {
	}
}

void IRQHandler(void) {
}

Compiling

Two lines for compiling, please refer to the doc for the purpose of teh differnet parameters. The -MS is for specifying the model, it is important to specify when later you need to specify the lib model.

wdc816cc -wl -wp -sop -MS main.c

Linking

wdcln -HB -M21 -V -T -Pff -C008000,0000
-U0000,0000 -Avectors=FFE4,7FE4 -Aregistration_data=FFB0,7FB0
-N startupSnes.obj main.obj -LC:\65xx_FreeSDK\lib\cs -O test.smc

The cs lib is for the Model Small that we specified while compiling.

Some function don’t seems to work properly. By example, the rand function comming from stdlib.h always return the same value. The tested string function are working perfect and are not too badly optimised. Here are some screenshot from my debugger during the 3 step of execution (Screen A, B and C), click to enlarge :

WDC C lib proof of concept

As usual you can get the full archive to download here.

See ya Lint,

PS : shoot your comments as usual !

Major WDC linker issues

Wednesday, May 7th, 2008

Once again an other issue. This time it’s about the WDC linker that seems not to be able link against C library. I already have sent a few email and ticket support to the wdc team. Still no response since my first enquiry 2 months ago. It’s been a while now that the direct to the freesdk have been removed.

So here is the source code that is having the problem and need to be linked with c.lib or cs.lib (small model) :

main.c

typedef    unsigned char    byte;
typedef    unsigned short    word;

typedef struct padStatus{
    byte right:1;
    byte left:1;
    byte down:1;
    byte up:1;
    byte start:1;    // Enter
    byte select:1;    // Space
    byte Y:1;    // X
    byte B:1;    // C
    //--------------------------------
    byte Dummy:4;
    byte R:1;    // Z
    byte L:1;    // A
    byte X:1;     // S
    byte A:1;    // D
} padStatus;

padStatus readPad(byte padNumber) {
    word test;
    // TODO fix usage of padStatus structure
    padStatus *status;

    // TODO move ot dedicated function
    // enable pad ready
    *(byte*)0x4200 = 0x01;

    // check if pad is READY !!!
    padNumber = padNumber << 1;
    test = (word) *(byte*)0x4218+padNumber << 8;
    test |= (word) *(byte*)0x4219+padNumber;

    status = (padStatus *) &test;

    return *status;
}

void main(void) {
    padStatus pad1;

    // Infinite loop
    while(1) {
        pad1 = readPad((byte) 0);

        if(pad1.up == 1) {
            *(byte*) 0x2100 = 0x00; // disable background
        } else {
                   *(byte*) 0x2100 = 0x0f; // enable background
        }
    }
}

This can be compiled with this command line :

wdc816cc -wl -wp -MS -MO -SOP main.c

The -MS is for specifying the Small code layout. So it should be linked with the “cs.lib”. But the here is the output of the linker:

wdcln -V -W -LC:\65xx_FreeSDK\lib\cs  main.obj -O test.smc
WDC 65C816 Linker Version EVALCOPY Jan 18 2006 17:36:51
   Copyright (C) 1992-2006 The Western Design Center, Inc.
Undefined symbol: __~mov

The __~mov symbol cannot be resolved but it is in the cs.lib. So I think that the linked dont link correctly. If anyone got any any idea on why. Feel free to leave a comment.

++ Lint

PS : I’m still working on the two effect and debug text output, expact an update in a few days.

FIXED !!! Look at the comments !!!