NESDev and Strangulation Records messageboards
Forum Index | FAQ | New User | Login | Search

Previous ThreadView All ThreadsNext Thread*Show in Threaded Mode


SubjectHelp! new  
Posted bykain falanx G
Posted on9/17/03 4:11 PM
From IP203.87.129.232  



I'm trying to make an emulator, and I'm stuck!
I can display the title screens of some games (like Nuts & Milk, Digdug and Popeye) but it stops there, and I get flooded with invalid opcodes.
Even the Super Mario title screen loads up with wrong scroll values, and hangs after (i.e. the coin isn't changing colors).

I traced this event and it supposedly happens when a BRK instruction is encountered. Here's my BRK function, is there anything wrong with it?

Related defines :
#define setBflag() (P|=0x10)
#define setIflag() (P|=0x04)

The break function :
void brk00(void){
PC++;
ram[0x100+S--] = (unsigned char)(PC>>8);
ram[0x100+S--] = (unsigned char)(PC&0xff);
setBflag();
ram[0x100+S--] = P;
setIflag();
PC = ram[0xfffe]+(ram[0xffff]<<8);
cyclenum+=7;
}

This (almost) always jumps to $FFF0 and executes repeated amounts of trash to lead into another BRK (thus overflowing my stack eventually).

If you have the time, please get a copy of the (broken) emulator at http://savet3hsmileys.tripod.com/testnes.zip .
I have added a trace and trace-until-vblank feature to help find this bug(?), and if you don't mind, please try it do tell me what problem you find. An additional note is that I use 29667 clock cycles per frame. Is that ok?a

Also, I did not implement mirroring in the 6502 ram (it's implemented in the PPU VRAM). Will that cause some problems?
And about writing & reading to NES registers ($2000 and the like), should I detect a write and a read at every access (i.e. asl or lsr on a register as a write and eor'ing it as a read) or should I only monitor sta,stx,sty and lda,ldx,ldy commands?

Another thing, about NES sound. I'm just learning how to make sounds in DOS. What should I try to study for emulating NES sound? I found some tutorials on Diret Playback, single cycle DMA, and auto-init DMA, and they look REALLY complicated, so I'd like to ask you experts here on which one I should study for NES sound emulation.

Finally, I've seen some emulators run games on the same speed an slooow computers, just that the graphics get jumpy. From what I've gathered, this is done through frame skipping. Can anyone link me to a some information on it?

I REALLY like to program, and even if there a kajillion NES emulators out there, I'd really like to complete mine, so please help. I could use all the help I can get. Sorry if I asked too many questions.

*thinks*
And NES movies, got any info on file format for it? (NESticle or Famtasia)


Der Wille zur Macht
Chikara e no Ishi

"The Will To Power"


SubjectRe: Help!  
Posted byMemblers
Posted on9/17/03 7:15 PM
From IP68.58.99.218  



Very few (if any) games use the BRK instruction. Super Mario Bros. definitely does not.

Not mirroring CPU RAM might work OK for most games, I don't know of any games that use the mirrored RAM, but it is possible on the NES.

If you want it to be accurate, you could detect every read and write to the registers (why not treat them as normal memory, except they have a different meaning when read? Sorry, I've never done PC programming, so I dunno). But often the LD- and ST- instructions are the only ones used.

Isn't there a standard NES movie format? (NSM or something? Or maybe that was only save-states..)




SubjectRe: Help! new  
Posted byDisch
Posted on9/17/03 11:53 PM
From IP66.127.105.177  



> I'm just learning how to make sounds in DOS.

Ack!

DOS = evil. Focus on Windows... or Linux.. or Mac... or any other OS that still exists. Learning DOS specific stuff is useless.

Streaming sound output is pretty straightforward in Windows using C/C++. It gets a little tricker when you use DirectSound... so if you want to keep it simple you can use the Windows waveOut routines.

Here's a link to the start of the related info on MSDN:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/multimed/htm/_win32_waveoutopen.asp


The functions of interest are:

waveOutOpen
waveOutProc --- this is optional, I don't use it when steaming sound
waveOutPrepareHeader
waveOutWrite
waveOutUnprepareHeader
waveOutReset --- this is useful, but not necessary
waveOutClose


If you want I can throw together a quickie tutorial on how to stream sound (I've been bored =P).


Once you know how to stream sound... you need to generate it. Brad Taylor's doc hosted here on nesdev does a more than adequate job with that. It may take a few re-reads for it to finally sink in, but it really covers everything quite nicely.




SubjectRe: Help! new  
Posted byLaughy
Posted on9/18/03 04:44 AM
From IP63.196.194.251  



Disch if you mention waveoutopen and the like again it's the end for you. I tried using that thing to stream sound and let me just so I AIN'T DOING THAT AGAIN. Although I would be interested to see your little tutorial :)

It seemed like I couldn't stream the sucker no matter what. For a 44.1 wave 8-bit mono wave I had to send waveoutwrite like 1MB/sec in order to keep it happy. And then you have to make a block manager and all AHH IT'S ALL COMING BACK TO ME MAKE IT STOP.

*Hugs directsound*




SubjectRe: Help! new  
Posted byDisch
Posted on9/18/03 06:03 AM
From IP66.127.105.177  



waveOut is great... MUCH easier than DirectSound. If you don't want... you don't need to create and manage a seperate thread for sound with waveOut... it calls waveOutProc whenever one WAVEHDR completes (then you can fill up another one and send it right back.. if you have 4 or 5 WAVEHDRs, the sound plays smooth)

I don't know what your problem was =P. 44.1 KHz 8-bit mono wave only needs 44100 bytes a second =P

Anyway... I'll throw up the little doc tomorrow...

...must....sleep....




SubjectRe: Help! new  
Posted byLaughy
Posted on9/18/03 8:42 PM
From IP63.196.194.251  



"waveOut is great... MUCH easier than DirectSound."

LIES! lol. Does NotSoFatso use directsound or waveout? Also what's your email Disch I'll send you my l33t emulator.

Oh to answer your frame skipping question Kain, most emulators will allow you to skip rendering of certain frames on the screen. This totally depends on what you are using to show the graphics (let's just hope that it's directdraw). Instead of sending directdraw your graphics to draw for a frame, you skip doing that a certain amount of times, depending on the setting you choose. This can speed up games since it takes a lot of processing power for directdraw to show stuff on the screen (but a lot less processing power than notsofatso, Disch's NSF player).

;)






SubjectRe: Help! new  
Posted byDisch
Posted on9/18/03 10:12 PM
From IP66.127.105.177  



> Does NotSoFatso use directsound or waveout

Neither. NotSo just generates the sound and sends it to Winamp's output plugin. The output plugin is the one that uses either DS or waveout (or neither, in the case of diskwriters).


> but a lot less processing power than notsofatso

Bah!

Most of that is Winamp (or communicating with Winamp). The standalone app I built the core with ran a lot faster.




SubjectRe: Help! new  
Posted byDisch
Posted on9/18/03 10:13 PM
From IP66.127.105.177  



whoops!

e-mail is:
disch_ [at] yahoo.com

I'd love to see the emu =)




SubjectRe: Help! new  
Posted byBig Time
Posted on9/19/03 03:12 AM



>Finally, I've seen some emulators run games on the same speed an slooow computers, just that the graphics get jumpy. From what I've gathered, this is done through frame skipping. Can anyone link me to a some information on it?

Yes. Rather than sending you a link to someplace I don't know about, how about I explain some basics. To take full advantage of frameskipping, your PPU core has to have a "dummy" mode added to it. This mode will basically allow the PPU to still respond to I/O from the CPU, but will not render any output to the screen (well, actually there's two PPU related buffers (the frame and the image)- both of which will be left untouched).

Additionally, if you want your frameskip to be automatic, you'll need a way of figuring out how much time passed during the frame render (and this also requires you to determine the framerate of the VGA mode you're using). In the case of a slow computer, the render will always take longer than one frame, and this will be immediately noticed when the PPU routine is all done, and you get that timestamp value from whatever function your development software gives you access to. After this, it's a simple matter of emulating any number of PPU frames from that point on, in dummy mode, until the # of emulated frames finally equals or is greater than the # of elapsed frames. Here's a pseudo-coded example of what I'm talking about:

repeat
UpdateVideo; (this does the page swapping, and the video buffer filling)
ResetPPU;
EmulatedFrames=0
SetDummyMode; (this disables pixel rendering in the PPU core)
while ((GetProcTimeStamp-OldTime)/TimePerFrame) > EmulatedFrames do
ExecCPU;
ResetPPU;
EmulatedFrames++;
end;
ClearDummyMode;
OldTime:=GetProcTimeStamp;
ExecCPU;
until ~


Of course, this is just somthing I threw together, so don't come down hard on me if it doesn't really work (though it should).




SubjectMore questions new  
Posted bykain falanx G
Posted on9/19/03 09:54 AM
From IP203.87.129.232  



Wow, you people are really helpful. Thanks a lot.

Sorry if I post VERY LONG messages, but since I have a limited i-net access, I type these up offline and just post them as is. Well, here goes.

The brk thing is annoying. I was using _Bnu's 6502 docs I got from Zophar, and while I found some typos, I didn't see that RTI is supposed to be opcode 40 and EOR absolute is 4d, not the other way around which the 6502 docs from here made by RTK/CricketNE showed me.

I got a lot of games working now (even some with some scrolling), but I have some problems (again).

How do I get the tile number for 8x16 sprites? Following Y0shi's docs, I got the even numbered tiles from pattern table 0, and odd from table 1. The way I did it is to get the upper half from the said pattern table, then use the next tile from the SAME pattern table as the lower half. I tested it on Digdug, and it seemed to work ok, but when the score shows up (when an enemy dies) I see trash instead of the score. Even worse when I try Battle City, the tanks show ok, but the bullets and the force fields are all messed up.

Super Mario also doesn't work. Mario doesn't even bother to show up. The coin is now glowing, and I see Sprite #0 there, but no mario. I think the problem is that I'm using only basic scrolling (via $2005), no V,T,HT,VT,etc. (because I can't understand where to use these values). I downloaded Loopy's the "Skinny on Scrolling" doc, but it was even more cryptic than the PPU addressing one by Brad Taylor. I've read something about a loopy_2005.txt, but I can't find anywhere on your site. Can anyone link me to a copy?

Galaga doesn't work either. Nothing ever shows up except the scrolling star sprites in the background.

Also, split screen scrolling seems to mess up a little. I'm using Galaxian and Circus Charlie to test this. After the VINT, I don't render for 21 scanlines, then start rendering, at the 22nd scanline, 3 pixels per clock cycle, at 341 pixels per scanline, right? This causes the Circus Charlie status bar to be cut in half due to scrolling (somewhat like in Nesticle, only worse), but Galaxian works ok. So I take out the extra 21 scanlines (render immediately) and the Circus Charlie status bar stops scrolling, but the uppermost enemies in Galaxian stop moving as well. Did I mess up somewhere in the computation? FCE Ultra gets this right.

Also, I can't play games with a trainer. I just ignore the extra 512 bytes, then load the PRG-ROM and CHR-ROM from there, but the game doesn't work. Am I supposed to use them for something?

Oh and finally, if anyone has the "Mahjong (J).nes" rom, I haven't seen an emulator that can emulate it properly. The pause screen shows up WITH the title screen on most emu's (even mine), and when you pause in-game, instead of seeing the pause screen, it displays trash. I tried this on FCE Ultra and Famtasia, as well as Nesticle, and the results were the same. I'd like to have tried it on iNes and LoopyNES but I don't have those.

If you want to see the problems I posted in action, I have a copy of my emulator at http://savet3hsmileys.tripod.com/

*thinks*
Just a thought. The equation for the clock cycle of the sprite #0 hit
CC = (y+21)*341 + x
has been bugging me for quite a while. Doesn't this give you the upper left corner of the sprite, and not exactly the collision pixel? Would using this equation cause some problems or is that just ok?



Der Wille zur Macht
Chikara e no Ishi

"The Will To Power"


SubjectRe: Help! new  
Posted bykain falanx G
Posted on9/19/03 09:56 AM
From IP203.87.129.232  



I would love to see that tutorial. I'm planning to make both a DOS port and a Windows port for my emu (probably a Linux one too if I get a new hard drive to install it in), so it would really help.

Der Wille zur Macht
Chikara e no Ishi

"The Will To Power"


SubjectRe: More questions new  
Posted byloopy
Posted on9/19/03 4:01 PM
From IP192.156.9.34  



>Also, I can't play games with a trainer. I just ignore the extra 512
>bytes, then load the PRG-ROM and CHR-ROM from there, but the game
>doesn't work. Am I supposed to use them for something?

If a game has a trainer, you need to use it. The game won't work if you just ignore it. I think the trainer is loaded at $6000, I don't remember. It's in the iNES format spec.

I wouldn't worry about "loopy" scrolling yet. The vast majority of NES games out there use the standard method of scrolling (via $2005).. worry about making them work first.




SubjectRe: Help! new  
Posted byDisch
Posted on9/19/03 6:59 PM
From IP66.127.105.177  



http://www.angelfire.com/sd2/disch/waveOut.txt

I tried to explain it the best I could. Hope it's useful ^_^




SubjectRe: Help! new  
Posted bydXtr
Posted on9/19/03 7:19 PM
From IP194.47.158.135  



just what I was looking for! a tutorial on the waveout. thanks :)

sorry for misspellings


SubjectRe: More questions new  
Posted byBig Time
Posted on9/19/03 8:55 PM



>The brk thing is annoying

There's a doc on the main page about it. If it's not clear enough, let me know (I wrote it).


>How do I get the tile number for 8x16 sprites?

Here's an explanation of the 8x16 mode, which I hope will clear that up:

The LSB of the tile index determines pattern table selection, but otherwise, consider it to equal zero when using the tile index value to calculate the tile address for 8x16 sprites. This means that ALL pattern data used for any sprites have to be aligned to 2-tile boundaries. Hope that clears it up.


>Just a thought. The equation for the clock cycle of the sprite #0 hit
>CC = (y+21)*341 + x
>has been bugging me for quite a while. Doesn't this give you the upper left corner of the sprite, and not exactly the collision pixel?

"CPUcollisionCC = ((Y+21)*341+X)/3"

This is not to indicate that it has anything to do with calculating the primary object collision (hit) location. This formula is simply used to convert an absolute X/Y pixel coordinate on the screen, into the equivelant CPU clock cycle number at which the PPU is actually rendering that pixel.


>Would using this equation cause some problems or is that just ok?

This is how my emulator *still* does primary object collision detection, and man, I can't believe how well so many games work with this cheap implementation! Bottom line: object collision calculations can definetely be based solely on OBJ 0's Y coordinate. When you need to address your emulator's scrolling issues however, make sure object 0 collisions are infact working properly.




SubjectRe: More questions new  
Posted bykain falanx G
Posted on9/20/03 11:42 AM
From IP203.87.129.232  



Scrolling works now (split-screen scrolling is just a little off, cutting some status bars in half).
I'd really like to have some information on "loopy" scrolling. Even if it is too much for me to handle now, I'd really appreciate any help on it.

Also, many thanks for the tutorial Disch. That's twice now. The CMP table for the carry flag seeme a little bit off though.

I can now play Super Mario Brothers, and other scrollers. One of the games I am having problems with now is Galaga.

Der Wille zur Macht
Chikara e no Ishi

"The Will To Power"


SubjectRe: More questions new  
Posted byASMGuy
Posted on9/20/03 4:46 PM



What was causing Mario not to show up?
My emu is having that problem.

Thanks,
- Mike






SubjectRe: More questions new  
Posted byLaughy
Posted on9/20/03 9:06 PM
From IP64.161.57.113  



You can get the looping scrolling doc here:
http://nesdev.parodius.com/loopyppu.zip




SubjectRe: More questions new  
Posted bykain falanx G
Posted on9/21/03 3:29 PM
From IP203.87.129.232  



>>otherwise, consider it to equal zero when using the tile index value
>>This means that ALL pattern data used for any sprites have to be aligned to 2-tile boundaries.
>>Hope that clears it up.

It sure did! I wasn't setting to LSB to zero, so all entries from pattern table 1 were 1 tile off. Thanks!


>>What was causing Mario not to show up?
>>My emu is having that problem.

My problem was that the flags in SBC were not being properly set.


Der Wille zur Macht
Chikara e no Ishi

"The Will To Power"


SubjectRe: More questions new  
Posted byhcs
Posted on9/26/03 00:12 AM
From IP204.33.51.85  



>Bottom line: object collision calculations can definetely be based solely on OBJ 0's Y coordinate

An even better method which isn't much more expensive is to base it on a line where sp0 has a set pixel, as it couldn't possibly be on any other line.

-hcs


Previous ThreadView All ThreadsNext Thread*Show in Threaded Mode
Jump to

Memblers' homepage             Contact Me

Forums powered by WWWThreads Demo