Archive for the ‘Software dev’ Category

SNES Central news + NSF Replayer status

Monday, June 30th, 2008

This morning I discovered that one of the site that I consider as the best SNES ressource (especially about proto and alpha/beta release) did a small news on myself. Go check it : www.snescentral.com

Thanks guys, it is a good gift for me. Yeps, It’s my birthday today. I’m 34 years old today.

A little update on my SNES work : sound engine is soon going to be able to run. I already corrected many lines of code that were causing trouble. The whole NSF init process is almost finished (I hope tonight or tomorow morning 😉 ). Then I will attack the player itself, but since it’s based on the same process so it will be painless.

I still hope to finish this week my NSF Replayer work. I will try to make a package and a small doc so anybody can use it or improve it.

++ Lint

SNES Sound engine hell …

Thursday, June 26th, 2008

It’s been almost 2 weeks that I’m in a battle with sound engines on SNES. The sound CPU in the SNES is a SPC-700 chip designed by Sony. After my last post, I said to myself : “It would be nice to setup music now”. I tough it was a great idea since sound was almost the last thing that I hadn’t yet implemented on the SNES (except from some PPU feature).

I started looking after sound engine and tracker that suport the SPC-700 chip.

To my big surprise, there is no tracker available at all. No sound engine packaged and usable out of the box. After a small discussion with D4S, he told me a few facts about SPC-700 :

  • It’s not easy to understand
  • Transfer routine making it not easy to play other format
  • Definitively no dedicated tracker

While digging for sound engine I found out 3 engine that might be usefull to look at :

XMSNES

This engine is supposed to take .xm and transform it to another format to make it playable on the SNES. The problem is that the file that are being converted need to contains almost no effects and have many other limitation. Then the main problem is that it don’t really sound nice on the real SNES hardware. Since real hardware support is for my a pre-requisite, I left that engine out.

CDOTY / SME Engine by Nevitsky

Cdoty realeased a while ago the source code for his “frog feast” game on the SNES. In this game he used the SME Engine coded by Nevitsky. The problem is that there is absolutely no documentation at all and that the sounds need to be converted and I didnt found out the software to convert them. Once again I left out that one.

NSF Replayer

Sometimes google help you to find stuff on the internet. This timegoogle wasn’t my best friend while searching SNES sound engine. YouTube was a good buddy with me making me discovering the NSF Replayer for SNES. The NSF Replayer is NSF player for the SNES that playback music from NES game on the SNES. The engine is playing quite well on real hardware and after a few serach I found some forum posts that were talking about it. There is no real doc but the code is quite explicit.

I’m currently implementing the engine in the WDC sdk. I’m having isuue with code relocation but it should be fixed quite soon. So yes I’m loosing time for my 26th July deadline to implemnting the first level of kung fu master on the SNES, but at least I will have a sound engine.

One other great thing with this engine is that I have the NSF kung fu master soundtrack already ready to be played by the engine. The NES soundtrack sound really like the arcade version.

As soon as the engine is running I will make a new release, I promise. I hope to have it running by middle of next week.

See ya,

Lint

WDC C Compiler for 65816 in action [PART IV]

Friday, June 13th, 2008

Finally i take some time to describe what’s new in the fourth release.

First i wanna give you the rom and source code archive.

The code have patched since the pre release and now it should work on real hardware without any flow. There is just some sprite priority problems with ZNES. I will fix that sometimes. Since past stable realease I have corrected a lot of bad code in te event handling functions.

The biggest improvement is the sprite handling. I have ripped a part of the Kung Fu Master sprite and descide to implement walk, down and punch hit. I declared the whole sprite table in memory and i have a function that transfer it by DMA. Here is the structure in C :

typedef struct OBJECTData {
    byte HPos;
    byte VPos;
    byte nameLow;
    byte nameHigh:1;
    byte color:3;
    byte priority:2;
    byte HFlip:1;
    byte VFlip:1;
} OBJECTData;

typedef struct OBJECTProp {
    byte size:1;    // Size Large/Small
    byte HPos:1;    // H-Position MSB
} OBJECTProp;

typedef struct OAMData {
    OBJECTData data[0x80];
    OBJECTProp prop[0x80];
} OAMData;

So now it’s very easy to modify and setup sprite table. Then the OAMLoad() function do the DMA transfer. That function is called on NMI Interrupt by a dedicated event.

One other big work that I have done in this release is the work on PPURegister. Here is the list of functions that I have already implemented :

ppuRegisterStatus PPUStatus;

void initRegisters(void);

void savePPUContext(ppuRegisterStatus *PPUStatus_src,
                    ppuRegisterStatus *PPUStatus_dst);
void restorePPUContext(ppuRegisterStatus PPUStatus);

void setINIDSP(word blanking, word fade);
void setINIDSPDirectValue(word value);
byte getINIDSP(void);
void setOBJSEL(word objsize, word objnameselect,
               word objnameaddrbase);
void setOBJSELDirectValue(word value);
byte getOBJSEL(void);
void setOAMADDR(word oamadrr, word oampriority);
void setOAMADDRDirectValue(word value);
word getOAMADDR(void);
void setOAMDATA(word oamdata);
void setOAMDATADirectValue(word value);
byte getOAMDATA(void);
void setBGMODE(word bgsize, word bg3, word bgmode);
void setBGMODEDirectValue(word value);
byte getBGMODE(void);
void setMOSAIC(word mosaicsize, word mosaicenable);
void setMOSAICDirectValue(word value);
byte getMOSAIC(void);
void setBG1SC(word vramDst, word screenProp);
void setBG1SCDirectValue(word value);
byte getBG1SC(void);
void setBG12NBA(word vramDstBG1, word vramDstBG2);
void setBG12NBADirectValue(word value);
byte getBG12NBA(void);
void setBG34NBA(word vramDstBG3, word vramDstBG4);
void setBG34NBADirectValue(word value);
byte getBG34NBA(void);

It’s now very simple to setup those registers without the need to play for the bit position for certain of them. Everything is handled in C, the code is really not efficient, I’m totally aware of that but the code will be optimised at a later stage of the development. As you see also I have a variable that contain a erference to all PPU registers allowing me to save and restore them. Nice feature when entering to debug screen and not having to worry about saving thing and setings them back before leaving. (The only think you need to care is VRAM, but I will try to restore that too).

I’m very pleased with this relaese, I got all I needed to get work done in a couple of days. From now on I will really focus on the Kung Fu Master port on the SNES from the Arcade version. I already have everything I need in place for doing that, except for the sound engine. I will try to integrate XMSNES to my work.

I will anyway post on a regular basis about the progress I made on the port. And whatever i see a problem that I should expose to you I will make a post about it.

See ya,

++ Lint

Early release…

Wednesday, June 11th, 2008

Why early ?!? Because I think many people wait for relaese of the new source code and ROM. I will not have time to write a post describing what I have done and how I have done it. This will come in a few days (I really hope before the weekend).

Biggest new feature is sprite handling.

So here is the ROM and source code.

++ Lint

PS : The code might be refactored when official release. As usual don’t hesitate to send a comment for any questions, bugs, suggestions …

UPDATE Status

Thursday, June 5th, 2008

Hi all,

I took time to analyse why the code wasnt’t running correctly on the SNES hardware. It’s mostly the event handling code. The addEvent and removeEvent functions were causing multiple problems when there was more than 2 events. Now everything should be fixed.

At the start of this week, I did a small TODO list with 12 items. In 4 days I cleared 10 of them. Here is the list :

Events :

  • DONE !!! review add/remove comments
  • DONE !!! add priority (0xff -> 0x00)
  • DONE !!! Allow to stop some events during debug

PPU-registers :

  • DONE !!! make a NO_VALUE define (0xffff)
  • DONE !!! implement BGMODE, MOSAIC and INIDSP
  • DONE !!! implement save_context and restore_context

DEBUG DISPLAY :

  • DONE !!! [DONT WORK IN BSNES] trigger on L+R+Start
  • DONE !!! display register value A, X and Y) before jump to debug
  • DONE !!! display event queue information
  • DONE !!! display BGMODE / MOSAIC / FADE value before debug
  • DONE !!! save and restore context on enter debug.

SPRITE :

  • POC with main character on title screen (left, right, hit)
  • add up and down control

For next release I may not release a full sprite code, but a least I hope to being able to display a sprite on the screen.

Kung fu master first draft sprite

++ Lint

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

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