# Visual Basic > Games and Graphics Programming > Game Demos >  Nintendo Emulator v0.65 (VB6)

## Jacob Roman

After reading and researching numerous documents, and scanning other peoples source code for clues, I've produced one of the hardest projects I've ever worked on... a Nintendo Emulator. Yep, you can play the good ol 8 bit NES on your PC. It has both software rendering (StretchDIBits) and Hardware rendering (DirectX). It's practically the only NES emulator written in vb6 that actually has pure sound using DirectSound! I also put in a low pass filter for the sound. You can also seemlessly go from windowed to fullscreen and back with no issues in both software and hardware. And has Load States and Save States. I even included the classic Super Mario Bros so you can test it out right away. 

Note: in IDE mode, it'll be way too slow for testing (6-8 fps with sound on, 12-15 fps with sound off). You must compile to exe and use the exe for a full speed of 60 fps. Another thing is that you must have the vb6 version of DirectX to even use the sound or hardware mode. In other words, you must have the dx8vb.dll on your computer over in your system folder and have it registered using regsvr32.exe. This is needed if you have Windows 7 or 8. Windows Vista and below should already have it preinstalled so you don't need the file let alone have to go through a process of registering it.

Note For Windows 7 & 8 users: this will not be shown in your References. And you will only need to do these parts once ever: 
- Put the dx8vb.dll file in your Windows\SysWOW64 folder.
- Drag it into regsvr32.exe to register it in order to use it in VB6 from now on and have it shown in References. 
- Go ahead and reopen Visual Basic 6 and check the References again to see if it's there.

If it's still not there, the best approach is to run Command Prompt as an Administrator and reference it, as sometimes simply dragging a file into regsvr32 is not enough. To do this:
- Goto your Start Menu.
- click on the bottom where it says > All Programs and goto Accessories
- Right click Command Prompt. 
- Click Run as administrator (should be located under Open). 
- Next type regsvr32 "YOUR FILE PATH HERE OF DX8VB.DLL" For example:

regsvr32 "C:\Windows\SysWOW64\dx8vb.dll" 

I still have a looooong way to go before its complete but here are the version numbers history of known issues and hot fixes:

*Version 0.65*
Fixed some of the nametable scrolling issues such as Super Mario Bros' scrollboard flickeringAdded the ability to view the frames per second in windowed and fullscreen. Although ghetto, itll suffice for now.Inlined some of the subs to speed things up a notch.Minor sound calibration tweaks.

*Version 0.60*
 The ENTIRE color palette has been changed into authentic NES color to the actual NES. Although there is no true palette values from the actual NES, and too many sites produced misleading information on the palette, I found the true composite colors from a forum post, added it to my emulator, and compared it to my real NES. It was exactly the same, and the greens weren't too green like the real NES, the sky in Super Mario was exactly alike, etc. How do I know this when brightness, contrasts, and tint could be different from a TV and monitor? My computer is hooked into my TV through an HDMI cable. I can just bounce back and forth between HDMI and Video to compare.  :big yellow:  Fixed and added Noise channel. However, although sounds great on many games such as Double Dragon, I'm not hearing bricks breaking in Super Mario Bros. Added Mapper 2 support so you can play games such as Contra! Fixed the looping sound issue when you have focus on the menu. Reading and Writing from the address registers from $0000 to $FFFF has been inlined which produced a huge increase in emulator speed. No more minor slowdowns from time to time like before. Sound has been tweaked to make it a tad more authentic and consistant with the documentation. Sound Debugger got many more things added such as noise channel, and square channels now show sweep info. Code has been cleaned up a notch. Many other minor fixes I can't name from the top of my head. 

*Known Issues for v0.60:*
 Legend of Zelda is saving a save file, and loading but in game, it shows no save game exist. Possibly need to play further to really know for sure. Square channels work great but doesn't sound authentic enough. Go into a pipe to see what I mean in Super Mario Bros. Noise channel works great but doesn't sound authentic enough such as no brick breaking noise in Super Mario Bros. DMC channel has NOT been programmed yet for voice samples. Play Kung Fu and you'll notice something missing to see what I mean.

*Version 0.55*
Added Mapper 1 support for games such as
     -Double Dragon
     -Castlevania 2: Simons Quest
     -Legend of Zelda

     ..and much more. Again refer to the NES mapper list on Google to find out more Mapper 1 games.Fixed the Triangle sound channel. Now it plays and halts perfectly as should.Added a much more sophisticated sound debugger.

*Version 0.50*
 Only mapper 0 games are supported in the mean time till I perfect everything.
     -Super Mario Bros
     -1942 (J)
     -Kung Fu
     -10 Yard Fight
     -Robot Block (Stack-Up) 
     -Robot Gyro (Gyromite)
     ...etc

    Google up NES Mapper List to see a complete list to find other mapper 0 games.
 Nametable Scrolling for the background is a little messed up. So you'll see anomalies such as flickering on the score board in Super Mario  Bros ever other section of each level.The NES has 5 channels for sound. Rectangle 1, Rectangle 2, Triangle, Noise, and DMC. I shut off Noise by enabling it false cause it causes slowdown later on. This is a known issue thatll be resolved soon. I also didn't program the DMC yet. So only 3 sound channels are working. The sound itself is good but sometimes a tiny bit scratchy. 1942 (J) when paused causes the SamplingCount to skyrocket at warp speed even though no sound is playing, causing overflow if left for a short period of time.

I will be constantly updating this program with new revisions as I go along. Enjoy  :big yellow: 




*[EDIT] I will no longer delete each old project to replace it with a new one. Instead I will have up just 5 of the latest just so the number of downloads don't keep getting knocked back to 0, and you can examine the old code for educational purposes. If the project gets complete enough, I may port this to VB.Net as well just so an NES emulator in VB.Net exists if it doesn't already.*

----------


## Jacob Roman

The NES Emulator has been updated to *Version 0.55*. Here are the current fixes made:

Added Mapper 1 support for games such as
    -Double Dragon
    -Castlevania 2: Simons Quest
    -Legend of Zelda

    ..and much more. Again refer to the NES mapper list on Google to find out more Mapper 1 games.Fixed the Triangle sound channel. Now it plays and halts perfectly as should.Added a much more sophisticated sound debugger.

----------


## joaquim

ok.. i have tested, like and i have something for tell you:
1 - when the user go to the menu: pause the game inclued sound off(or you think that you are ear risk CD). play a game and go to menu and you see what i mean;
2 - let user choose the keys(joypad too, if possible);
3 - i see some(rare, but i see) flickers.
but it's great.. good job
(maybe you can share what you read for doing these :Wink: )

----------


## Jacob Roman

Sure I can share. I can share a lot :EEK!: 

As for the flickering, thats the Nametable Scrolling issue I was talking about, and its minor. Ill try and fix most of the problems you mentioned but at the moment im still tweeking with the sound so its authentic and perfect. The Noise channel is better but a notch off on some games. i havent uploaded it yet but the slowdown is gone from the noise as well as the horrific sound from that channel. I have more documentation if you need it.  :big yellow: 

NES Doc.pdf
NES Mapper Grid
NES Mapper List
Everything you need to know about the NES
NES Dev
NES Dev Wiki
Zophars Domain NES Documentation
Nintendo Entertainment System Architechture
6502 Instruction Set
6502 Opcodes
NES Technical Emulation FAQs
NES APU Technical Documentation
NES Audio.pdf
My NES Emulator C# Sourecode
YoshiNES VB6 Open Source Emulator
2A03 Technical Reference
Emu Docs.org NES

----------


## DracullSoft

Very large job - well done 
Unfortunately it was very slow on my old xp box Pentium D 3.0 Ghz  (both with Dx and Non)
I tested only with the the super mario rom and with compiled code. It was about 4 fps and sound was breaking up every second or so.
Sound debugged showed check marks in all boxes and my sound card is Dx compatible.

----------


## Jacob Roman

Thanks for the feedback. I think before I upload the update which I was gonna do this weekend, I should inline a few functions and subs to help give it a speed boost. If you disable the sound you might make it a little faster, since the for loop is mixing the sound and probably causing a one sec delay on your comp. On my comp it goes 60 fps when compiled. But, nothing wrong with a little optimization  :big yellow:

----------


## Jacob Roman

Version 0.60 is finally here! See the first post for the update.

----------


## RobDog888

Looks cool and great job JR! I will try this in a few but where do you get the games?

----------


## Jacob Roman

Try coolrom.com but note I only have mappers 0 to 2 supported out of 255

----------


## Jacob Roman

Ok after a number of requests I received, apparently its slow on the slower computers, but 60 fps on mine. So I did a little research on some speed optimization starting with VB6 compiler speed tips. For example, I don't need the overflow checks. So doing things like that will dramatically boost the speed of the emulator. I also need to see how I can boost the speed of the program itself with all the things that are doing but it comes at a cost unfortunately...readability. First thing I'm gonna do is a lot of experimenting with another program and test whats faster such as just having a sub/function there or literally *Call* the sub/function. I also heard \ is faster than both / and * so I'm gonna test it to truely know for sure. Inlining some functions and subs is another way. And it just goes on an on what I need to do. I also got a request to fix the menu exit, so I'm also gonna do that.

----------


## omundodogabriel

Hi, I'm omundodogabriel, creator of YoshiNES. I did YoshiNES alone, using as a basis the code BasicNES. I'm happy to see that there is still someone who cares for emulation in vb6.

Well, I wanted to implement the sound wave using WaveOut in vb6, but I not have much experience working with this sound API.

I have been interested in trying to make your sound code work with WaveOut API, if you authorize. Using Directx with vb6 I did not find very interesting, because it only supports up to DirectX 7 and has no compatibility with older versions of windows.

Take a look at YoshiNES 0.7, where some of the bugs you mentioned have been fixed.

----------


## Jacob Roman

Sure if you want to. Its freely available for modification. And if you really want to, maybe we can work on this project together.  :Smilie:   Btw VB6 also supports DirectX8 and with some minor tweeks even DirectX9. Operating systems XP and up have DirectX already preinstalled with the operating system. So its ok to work with DirectX in VB6. My emulator uses DirectX8. That file I have above are for those who have Windows 7 and Windows 8 since MS has dropped support for vb6.  

Glad to finally chat with the creator of YoshiNES  :big yellow:  We should totally work on this thing. Best to work as a team and share knowledge  :Wink:

----------


## omundodogabriel

Most of the credits go to Don Jarret and David Finch, the authors of bnes, who wrote the code for the CPU. I think it is worth trying to use DirectX 9 in vb.

I agree that we should work together on this project, just can't help with APU emulation. I'll stop the development of YoshiNES to work on this project.

I'm currently working on the support Mapper 5, which is one of the most complex of the NES in my opinion. Only Castlevania 3 is working at the moment, and only menu. : (

I have a code that generates the Nes pallete and looks very similar to the original. I think it might be useful.

I'll send you my email via pm.

----------


## Jacob Roman

Just one problem. They based their cpu off of the 6502c processor, not the 6502. Plus the execution cycle times differed from the 6502. So many thanks to the 2 links up there I found on the 6502 instruction set, so as a result I created a better 6502 module. I also found a couple opcodes needed more code or slightly changed after examining numerous opensource emulators as well as some other documentation on how to execute each instruction.

My APU is currently in its beta stages, and whats really slowing it down is the For Loop on the sound buffer where the sound is mixed. Most languages can handle this such as C# and C++. But making it fast in vb6 is a real challenge. I may have to split up the buffers more so, so the for loop isnt stressing the main loop. Inlining some functions is another way, but it comes at an unfortunate cost, which is readability. Funny thing is, I get a blazing 320 fps average with the sound on my computer when I shut off the Lock_FPS, which locks the framerate to whatever frames per second you desire. And thats with software rendering. So on my computer the sounds fine. However I'm gonna continue to optimize it. Well....it could be because I already optimized the hell out of it but didn't upload it yet. 

[EDIT] For now I'm gonna stick with DirectX8 since it coincides with vb6 by default, and not too many people don't know how to get vb6 to work with DX9. I don't wanna risk running into problems and end up reverting back to DirectX8. That would suck!

Also, since you messaged me about mapper 5, here are a couple of files to get you on the go, with C# source code you might be able to convert to vb6, as well as this link to all the mappers with docs to each:

Mapper Grid

----------


## omundodogabriel

After searching for the problem that was causing flicker when scrolling, I managed to fix using jsnes code.
It was actually very simple, I just replaced this code on write6502 function:
PPUAddress2 = (PPUAddress2 And &HFFE0&) Or (Value And &HF8) \ 8
- with this -
PPUAddress2 = Value \ 8 And &H1F
And flickers are gone. However, when trying to use the code on your emulator, it not worked  :Frown: 

I am attaching the YoshiNES code with the bug fixed. I hope you can adapt to your emulator.
YoshiNES scroll_fix.zip

You also need to take a look at your 6502 code. vb returned an overflow error in SP on function Push8 after a while playing battletoads.

----------


## Jacob Roman

Ok I'll look into it right away.

[EDIT] Guess what. I put it in my updated version of my NES emulator (the one I didn't upload yet) and it works o.O. Also for some reason the sound was a little funky on your YoshiNES v0.8. I think it has a lot to do with register $4015 where theres suppose to be a call to Sound_Channel_Write_Status_Register. I had some comments why I created this too:



```
    'http://wiki.nesdev.com/w/index.php/APU
    '   Writing a zero to any of the channel enable bits will silence that channel and "immediately" set its length counter to 0.
    
    'Note: Not having length counter = 0 when channel is disabled immediately afterwards, or placing length counter = 0 somewhere else in another sub produces
    '      horrific results.
    'Examples: In Super Mario Bros.
    '          - going into a pipe will cause the sound to loop
    '          - finishing a level and the score being tallied with your alloted time, the sound keeps looping even after it stopped
    '          - worse of all, the dark levels such as level 2, almost all the sounds are sweeping waaaaay too hard producing ear piercing results!
    
    'So be sure to keep LengthCounter = 0 here in this sub. Its what the NES does immediately when the channels enabled flag is false anyways.
```

I'll have to examine your code some more but Im just guessing thats why. Either that or you forgot something from my emulator related to sound.

----------


## Jacob Roman

I was right. You are missing a write to $4015, so add this:

Case &H4015&: Sound_Channel_Write_Status_Register Value

I'm looking into my Push8, but it seems ok. Did it crash in a particular opcode? And also even though we fixed Super Mario Bros, Castlevania 1 has minor scrolling problems with the score board.

----------


## omundodogabriel

"or you forgot something from my emulator related to sound." - most likely because I have not tidied up the code (you may have noticed that is very messy for now).

good that the code worked  :Smilie:  I still have to fix the timing problems on my emulator

[EDIT] Thanks, will fix the sound right now! 
I'll take look on castlevania and see what I can do.

----------


## Jacob Roman

For the heck of it, I'm gonna upload v0.65. Was gonna add DMC but I'll save that for the next update.

----------


## Niya

Watching you guys converse is quite intriguing since I have no idea what yall are talking about. lol I'm jealous  :Mad:

----------


## omundodogabriel

I found out why it had not worked when I tried to fix the scrolling, the function Write_PPU_Register is not used, instead the ppu code is on the WriteMemory8_Inline function.

The sound is better now, and the emulator a little faster. I'm waiting dmc to hear the characters voices  :Wink:

----------


## Jacob Roman

> Watching you guys converse is quite intriguing since I have no idea what yall are talking about. lol I'm jealous


Would you like to learn?  :big yellow:

----------


## Niya

> Would you like to learn?


If only I had the time, I would. I'm fascinated with things like that but unfortunately, at the moment I have to invest the time into boring yet marketable stuff. Hopefully in the future, when I have a solid base to make income, I can spend my coding time doing things that don't pay but are nonetheless, immensely enjoyable. God knows, I have so many pet projects that I'd like to finish and so many new things I'd like to learn.

----------


## Jacob Roman

There are known problems with my emulator, and this is what I know so far that either I or omundodogabriel need to fix:
 The noise channels 93 step mode (I believe) isnt playng sound, which is why in Super Mario Bros you don't hear bricks breaking and only hear half the percussion. However in Double Dragon, its perfect, because it remains in 32767 mode the entire time. But if you remove the .Length_Counter > 0 from the if statement in the Noise_Channel_Render_Sample function, run Super Mario Bros, ignor the constant noise for a min, grab a mushroom, and break a block, you will finally hear the brick breaking noise that was missing. So I may have to create a look up table to XOR tap like this C++ NES emulator I have did. The rectangle channels sounds semi perfect, but going into pipes in Super Mario Bros doesnt sound authentic enough. Those channels might need a minor tweak. DMC channel is in the works for voice samples. Games such as Castlevania still has scrolling issues in the scroll board as you move. Might need to darken one of the turquoise blues in the palette to match up with my actual NES. This color you mainly see in World 1-2 of Super Mario Bros.

----------


## omundodogabriel

I'm working to fix problems in PPU. I fixed some problems based on virtuanes source code and loopy docs, and fixed games like yo noid and arch rivals. Castlevania, however, still flickering  :Frown:

----------


## Jacob Roman

Sweet! Keep it up. In the mean time I'm gonna keep perfecting the sound.

----------


## Jacob Roman

I found the source code to LoopyNES, so hopefully this link will help: http://home.comcast.net/~olimar/NES/loopynes.zip

Its written entirely in assembly but I can help kinda translate it to VB.

----------


## omundodogabriel

today i was fixing the CPU problems, and found that the tick table of both our emulators is wrong.

I'll try to fix it tomorrow. Regarding the PPU, castlevania still flickering. Maybe is a timing issue?

correct tick table:


```
static const uint32_t ticktable[256] = {
/*        |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  8  |  9  |  A  |  B  |  C  |  D  |  E  |  F  |     */
/* 0 */      7,    6,    2,    8,    3,    3,    5,    5,    3,    2,    2,    2,    4,    4,    6,    6,  /* 0 */
/* 1 */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7,  /* 1 */
/* 2 */      6,    6,    2,    8,    3,    3,    5,    5,    4,    2,    2,    2,    4,    4,    6,    6,  /* 2 */
/* 3 */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7,  /* 3 */
/* 4 */      6,    6,    2,    8,    3,    3,    5,    5,    3,    2,    2,    2,    3,    4,    6,    6,  /* 4 */
/* 5 */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7,  /* 5 */
/* 6 */      6,    6,    2,    8,    3,    3,    5,    5,    4,    2,    2,    2,    5,    4,    6,    6,  /* 6 */
/* 7 */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7,  /* 7 */
/* 8 */      2,    6,    2,    6,    3,    3,    3,    3,    2,    2,    2,    2,    4,    4,    4,    4,  /* 8 */
/* 9 */      2,    6,    2,    6,    4,    4,    4,    4,    2,    5,    2,    5,    5,    5,    5,    5,  /* 9 */
/* A */      2,    6,    2,    6,    3,    3,    3,    3,    2,    2,    2,    2,    4,    4,    4,    4,  /* A */
/* B */      2,    5,    2,    5,    4,    4,    4,    4,    2,    4,    2,    4,    4,    4,    4,    4,  /* B */
/* C */      2,    6,    2,    8,    3,    3,    5,    5,    2,    2,    2,    2,    4,    4,    6,    6,  /* C */
/* D */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7,  /* D */
/* E */      2,    6,    2,    8,    3,    3,    5,    5,    2,    2,    2,    2,    4,    4,    6,    6,  /* E */
/* F */      2,    5,    2,    8,    4,    4,    6,    6,    2,    4,    2,    7,    4,    4,    7,    7   /* F */
};
```

----------


## Jacob Roman

Hmmm that is interesting, but where exactly did you get this information from? If another emulator written in C++ had different ticks than the documentation, it could possibly be wrong. But if it executes better than expected, then there could be a chance the documentation was wrong just like people were wrong on the NTSC palette. 

Speaking of palettes, I've been lately tweaking with the values to match more with my NES's colors. Not quite done yet but this is what I have so far where I commented. Believe it or not, this took 2 hours to nail down after tons of tweaks:


vb Code:
Public Sub Create_Real_NES_Pallete_NTSC()    'This is based on the pallete from [url]http://forums.nesdev.com/viewtopic.php?f=21&t=8121[/url]        'In my opinion this is closer to the NES than the other NTSC pallete        Dim Current_Color As Long        'Row 1    Pallete(0) = NES_RGB(104, 104, 104)    Pallete(1) = NES_RGB(0, 42, 136)    Pallete(2) = NES_RGB(20, 18, 167)    Pallete(3) = NES_RGB(59, 0, 164)    Pallete(4) = NES_RGB(92, 0, 126)    Pallete(5) = NES_RGB(110, 0, 64)    Pallete(6) = NES_RGB(108, 6, 0)    Pallete(7) = NES_RGB(86, 29, 0) 'One of the coin block animations in Super Mario Bros    Pallete(8) = NES_RGB(51, 53, 0)    Pallete(9) = NES_RGB(11, 72, 0)    Pallete(10) = NES_RGB(0, 82, 0)    Pallete(11) = NES_RGB(0, 79, 8)    Pallete(12) = NES_RGB(0, 64, 77)    Pallete(13) = NES_RGB(0, 0, 0)    Pallete(14) = NES_RGB(0, 0, 0)    Pallete(15) = NES_RGB(0, 0, 0)        'Row 2    Pallete(16) = NES_RGB(173, 173, 173)    Pallete(17) = NES_RGB(21, 95, 217)    Pallete(18) = NES_RGB(66, 64, 255)    Pallete(19) = NES_RGB(117, 39, 254)    Pallete(20) = NES_RGB(160, 26, 204)    Pallete(21) = NES_RGB(183, 30, 123)    Pallete(22) = NES_RGB(151, 19, 2) 'NES_RGB(181, 49, 32) 'Dark Red: Marios suspenders in Super Mario Bros    Pallete(23) = NES_RGB(113, 68, 0) 'NES_RGB(153, 78, 0) 'Brown: Ground Bricks and regular bricks of outdoor worlds in Super Mario Bros    Pallete(24) = NES_RGB(107, 109, 0)    Pallete(25) = NES_RGB(56, 135, 0)    Pallete(26) = NES_RGB(0, 117, 0) 'NES_RGB(12, 147, 0) 'Dark Green: Hills, turtle shells, pipe, top of flag pole in Super Mario Bros    Pallete(27) = NES_RGB(0, 143, 50)    Pallete(28) = NES_RGB(0, 104, 101) 'NES_RGB(0, 124, 141) 'Dark Turquoise: Ground and ceiling bricks in dark worlds such as 1-2 of Super Mario Bros    Pallete(29) = NES_RGB(0, 0, 0)    Pallete(30) = NES_RGB(0, 0, 0)    Pallete(31) = NES_RGB(0, 0, 0)        'Row 3    Pallete(32) = NES_RGB(255, 254, 255)    Pallete(33) = NES_RGB(100, 176, 255)    Pallete(34) = NES_RGB(156, 174, 255) 'NES_RGB(146, 144, 255) 'Sky Blue: Sky of outdoor worlds in Super Mario Bros    Pallete(35) = NES_RGB(198, 118, 255)    Pallete(36) = NES_RGB(243, 106, 255)    Pallete(37) = NES_RGB(254, 110, 204)    Pallete(38) = NES_RGB(254, 129, 112)    Pallete(39) = NES_RGB(234, 158, 34)    Pallete(40) = NES_RGB(188, 190, 0)    Pallete(41) = NES_RGB(180, 196, 0) 'NES_RGB(136, 216, 0) 'Green: Pipes in Super Mario Bros    Pallete(42) = NES_RGB(92, 228, 48)    Pallete(43) = NES_RGB(69, 224, 130)    Pallete(44) = NES_RGB(72, 205, 222)    Pallete(45) = NES_RGB(79, 79, 79)    Pallete(46) = NES_RGB(0, 0, 0)    Pallete(47) = NES_RGB(0, 0, 0)        'Row 4    Pallete(48) = NES_RGB(255, 254, 255)    Pallete(49) = NES_RGB(192, 223, 255)    Pallete(50) = NES_RGB(211, 210, 255)    Pallete(51) = NES_RGB(232, 200, 255)    Pallete(52) = NES_RGB(251, 194, 255)    Pallete(53) = NES_RGB(254, 196, 234)    Pallete(54) = NES_RGB(254, 204, 197)    Pallete(55) = NES_RGB(247, 216, 165)    Pallete(56) = NES_RGB(228, 229, 148)    Pallete(57) = NES_RGB(207, 239, 150)    Pallete(58) = NES_RGB(189, 244, 171)    Pallete(59) = NES_RGB(179, 243, 204)    Pallete(60) = NES_RGB(181, 235, 242)    Pallete(61) = NES_RGB(184, 184, 184)    Pallete(62) = NES_RGB(0, 0, 0)    Pallete(63) = NES_RGB(0, 0, 0)        For Current_Color = 0 To 63        Pallete(Current_Color + 64) = Pallete(Current_Color)        Pallete(Current_Color + 128) = Pallete(Current_Color)        Pallete(Current_Color + 192) = Pallete(Current_Color)    Next Current_ColorEnd Sub

And although you should never trust the camera for color values since itll never be the same, the colors I did tweak at least matched. The Sky, the brown bricks, the turquoise bricks, the pipes 2 colors, etc. However I didnt tweak Marios shirt yet. Needs darken a tad to match the NES. But I did match his red suspenders at least so far:

*Real NES*


*Emulated NES*


I also wouldnt mind trying to simulate that border on the left and right hand side of the screen, rather than just stretch out whats in between. I will need to research it in the docs.

----------


## omundodogabriel

I added mid-frame palette chaging, as seen in the picture above (rstrdemo.nes from virtuanes). Had to rewrite portions of the blitscreen code.

Although I already have fixed several problems related to PPU, there are still problems of timing. I took tick table f fakenes, which also corresponds with the virtuanes.

How are you going to emulate on the sound emulation? DMC already working?

----------


## Jacob Roman

Still working on it, but its not quite ready yet. I'm still trying to fix noise, correcting the color palette to match the NES as exact as possible, and some minor optimizations. At the same time I'm also working on my Nintoaster project, which is a fully functional Nintendo inside a toaster (which works great so far). But I'll try to finish it up and have it for ya in the next update.

Also you may wanna put that new palette in that I tweaked in my previous post. The matching colors make it look pretty sharp.

[EDIT] Ok just for the heck of it, I'm gonna link another source, which has links to multiple sources showing the tick counts for the Opcodes and what you should do is compare it with your chart. I believe to match them you go horizontal, then vertical with the Opcode number. Here are the links":

http://wiki.nesdev.com/w/index.php/6502_instructions
http://www.obelisk.demon.co.uk/6502/reference.html

----------


## Jacob Roman

Ok. Another thing I would like to see in my emulator (as well as yours) that I quite frankly am not seeing in other emulators. if you take a look at post #29, I displayed my real NES image of Super Mario Bros and the emulated version from my emulator at the exact spot. If you notice, the real NES has a border on the left and right side of the screen. This holds true in just about every other NES game I pop into my nintendo. Also if you notice, the scoreboard is a lot closer to the top of the screen than the emulated version of the NES. As I was reading everynes.txt, I think I may have found the answer:




> PPU Dimensions & Timings
> ------------------------
> 
> NTSC/PAL Timings
>   Item              NTSC             PAL
>   Video Clock       21.47727MHz      26.601712MHz
>   CPU Clock         1.7897725MHz     1.7734474MHz
>   Clock Divider     CPU=Video/12     CPU=Video/15
>   Cycles/Scanline   113.66; 1364/12  106.53; 1598/15
> ...


I believe we coded the emulator to be at a resolution of 256x240 rather than 240x224 for NTSC. So for the beginning of the scanline, well need to have the first 8 pixels of the scanline be the color of the background before drawing the actual tiles, as well as have the last 8 pixels of the scanline be the color of the background. The 8 on top and 8 on the bottom as described in the quote I believe are skipped. So I did a little mini test just to screw around with just the top and bottom:



```
    If Scanline >= 8 And Scanline <= 231 Then '240x224
        Render_Sprites Scanline, False
        Render_Background Scanline
        Render_Sprites Scanline, True
    End If
```

I ran Super Mario Bros, and I think I just simulated the issue with Castlevania rather than have it draw to match the NES (sucks to be me  :Ehh: ). So perhaps thats what we need to do. Get our code to coincide with the 240x224 resolution.

----------


## omundodogabriel

in fact, I had done it yesterday  :Smilie:  I had to lower the resolution, because some games show "garbage" after the scanline 232 (yo noid for example). The only thing I did was change the Top property of the picturebox to -8 and decreases the resolution of the form to 224, hiding the extra scanlines.

One thing that is worrying me is that the tests that I did detect the emulator to PAL, not NTSC. I think it has something to do with the timing, because it detects the system as PAL or NTSC through ticks.

As for your sound emulation, in some games the square channels still need some tweaking.

----------


## Jacob Roman

Yea I know. Go into a pipe in Super Mario Bros and youll see what I mean. I'm still trying to fix the sound with all the channels. Theres gotta be something I'm missing. But I'm pretty close at least.

I've been a little busy with work, since they got me working extra days, otherwise I would have responded sooner. I found out why it was cut off from the top and bottom. Its because I'm using an HDTV. If I were to use an old school tube TV, it would not be cut off. I found out the hardway after seeing footage on YouTube from old tvs. But there is possibility to add an option to set the Nintendo Emulator to HDTV mode o.O. I don't wanna just make the picturebox -8 though. That would be cheating and not work well fullscreen. I prefer to do it programmably. I did the bottom part at least over in Render_Scanline() by making If Scanline >= 232 Then Exit Sub, rather than 240.  

I'm not quite finished adjusting the color palette but I made more tweaks, even with the colors I did tweak so it looks even more so like the actual NES. Its a pain trying to match it precisely. But heres what I have so far:



```
Public Sub Create_Real_NES_Pallete_NTSC()
    'This is based on the pallete from http://forums.nesdev.com/viewtopic.php?f=21&t=8121
    
    'In my opinion this is closer to the NES than the other NTSC pallete
    
    Dim Current_Color As Long
    
    'Row 1
    Pallete(0) = NES_RGB(104, 104, 104)
    Pallete(1) = NES_RGB(0, 42, 136)
    Pallete(2) = NES_RGB(20, 18, 167)
    Pallete(3) = NES_RGB(59, 0, 164)
    Pallete(4) = NES_RGB(92, 0, 126)
    Pallete(5) = NES_RGB(110, 0, 64)
    Pallete(6) = NES_RGB(108, 6, 0)
    Pallete(7) = NES_RGB(86, 29, 0) 'One of the coin block animations in Super Mario Bros
    Pallete(8) = NES_RGB(51, 53, 0)
    Pallete(9) = NES_RGB(11, 72, 0)
    Pallete(10) = NES_RGB(0, 82, 0)
    Pallete(11) = NES_RGB(0, 79, 8)
    Pallete(12) = NES_RGB(0, 64, 77)
    Pallete(13) = NES_RGB(0, 0, 0)
    Pallete(14) = NES_RGB(0, 0, 0)
    Pallete(15) = NES_RGB(0, 0, 0)
    
    'Row 2
    Pallete(16) = NES_RGB(173, 173, 173)
    Pallete(17) = NES_RGB(21, 95, 217)
    Pallete(18) = NES_RGB(66, 64, 255)
    Pallete(19) = NES_RGB(117, 39, 254)
    Pallete(20) = NES_RGB(160, 26, 204)
    Pallete(21) = NES_RGB(183, 30, 123)
    Pallete(22) = NES_RGB(141, 49, 12) 'NES_RGB(181, 49, 32) 'Dark Red: Marios suspenders in Super Mario Bros, Marios hair, mustache, and boots as fire mario.
    Pallete(23) = NES_RGB(113, 63, 0) 'NES_RGB(153, 78, 0) 'Brown: Ground Bricks and regular bricks of outdoor worlds in Super Mario Bros
    Pallete(24) = NES_RGB(100, 99, 46) 'NES_RGB(107, 109, 0) 'Greenish Yellow 'Marios Shirt
    Pallete(25) = NES_RGB(56, 135, 0)
    Pallete(26) = NES_RGB(0, 110, 0) 'NES_RGB(12, 147, 0) 'Dark Green: Hills, turtle shells, pipe, top of flag pole in Super Mario Bros
    Pallete(27) = NES_RGB(0, 143, 50)
    Pallete(28) = NES_RGB(0, 104, 101) 'NES_RGB(0, 124, 141) 'Dark Turquoise: Ground and ceiling bricks in dark worlds such as 1-2 of Super Mario Bros
    Pallete(29) = NES_RGB(0, 0, 0)
    Pallete(30) = NES_RGB(0, 0, 0)
    Pallete(31) = NES_RGB(0, 0, 0)
    
    'Row 3
    Pallete(32) = NES_RGB(255, 254, 255)
    Pallete(33) = NES_RGB(100, 176, 255)
    Pallete(34) = NES_RGB(146, 154, 255) 'NES_RGB(146, 144, 255) 'Sky Blue: Sky of outdoor worlds in Super Mario Bros
    Pallete(35) = NES_RGB(198, 118, 255)
    Pallete(36) = NES_RGB(243, 106, 255)
    Pallete(37) = NES_RGB(254, 110, 204)
    Pallete(38) = NES_RGB(254, 129, 112)
    Pallete(39) = NES_RGB(225, 184, 114) 'NES_RGB(234, 158, 34) 'Peach/Light Yello: Marios skin, Bright color coins, bright color ? blocks in Super Mario Bros.
    Pallete(40) = NES_RGB(188, 190, 0)
    Pallete(41) = NES_RGB(175, 196, 0) 'NES_RGB(136, 216, 0) 'Green: Pipes in Super Mario Bros
    Pallete(42) = NES_RGB(92, 228, 48)
    Pallete(43) = NES_RGB(69, 224, 130)
    Pallete(44) = NES_RGB(72, 205, 222)
    Pallete(45) = NES_RGB(79, 79, 79)
    Pallete(46) = NES_RGB(0, 0, 0)
    Pallete(47) = NES_RGB(0, 0, 0)
    
    'Row 4
    Pallete(48) = NES_RGB(255, 254, 255) 'White: Super Mario Bros Text
    Pallete(49) = NES_RGB(192, 223, 255)
    Pallete(50) = NES_RGB(211, 210, 255)
    Pallete(51) = NES_RGB(232, 200, 255)
    Pallete(52) = NES_RGB(251, 194, 255)
    Pallete(53) = NES_RGB(254, 196, 234)
    Pallete(54) = NES_RGB(254, 204, 197) 'Pinkish White: Super Mario Logo, White in bricks
    Pallete(55) = NES_RGB(247, 236, 225) 'NES_RGB(247, 216, 165) 'Pinkish White 2: Marios Shirt with Fireflower in Super Mario Bros
    Pallete(56) = NES_RGB(228, 229, 148)
    Pallete(57) = NES_RGB(207, 239, 150)
    Pallete(58) = NES_RGB(189, 244, 171)
    Pallete(59) = NES_RGB(179, 243, 204)
    Pallete(60) = NES_RGB(181, 235, 242)
    Pallete(61) = NES_RGB(184, 184, 184)
    Pallete(62) = NES_RGB(0, 0, 0)
    Pallete(63) = NES_RGB(0, 0, 0)
    
    For Current_Color = 0 To 63
        Pallete(Current_Color + 64) = Pallete(Current_Color)
        Pallete(Current_Color + 128) = Pallete(Current_Color)
        Pallete(Current_Color + 192) = Pallete(Current_Color)
    Next Current_Color
End Sub
```

----------


## omundodogabriel

These days I ported the YoshiNES to vb.net. The main problems I had, is that the rendering is very slow zoom, the speed drops by almost half when I put 2x zoom. This is the code I am using to render:


```
    
Public Sub Blit(ByVal Buffer() As Integer, ByVal W As Integer, ByVal H As Integer, Optional ByVal MyZoom As Integer = 1, Optional ByVal Interpolation As Integer = 5)
        Dim bm1 As New Bitmap(W, H, Imaging.PixelFormat.Format32bppRgb)
        Dim bm2 As New Bitmap(W * MyZoom, H * MyZoom, Imaging.PixelFormat.Format32bppRgb)
        Dim GR As Graphics = Graphics.FromImage(bm2)
        GR.InterpolationMode = Interpolation
        Dim BitmapData1 As Imaging.BitmapData
        BitmapData1 = bm1.LockBits(New Rectangle(0, 0, W, H), Imaging.ImageLockMode.WriteOnly, Imaging.PixelFormat.Format32bppRgb)
        Dim Scan0 As IntPtr = BitmapData1.Scan0
        Runtime.InteropServices.Marshal.Copy(Buffer, 0, Scan0, W * H)
        bm1.UnlockBits(BitmapData1)
        GR.DrawImage(bm1, 0, 0, bm2.Width, bm2.Height)
        Form1.NesScreen.Image = bm2
    End Sub
```

Another problem was that I could not in any way make the DirectX work in vb.net (my version is Visual Basic Express 2010). I installed the DirectX SDK, and even then DirectX not appear in the Add Reference dialog  :Frown:  .  My top priority is to make your sound emulation engine work on vb.net

The code is very similar to the original, and any improvements I make in my emu can be easily implemented in yours. I sent you an email with the code if you want to take a look.

----------


## Niya

A popular graphics framework in use for .Net is called XNA which is a wrapper around DirectX if I'm not mistaken. There are a few XNA guys around here like _dday9_ and _Shaggy Hiker_. Maybe you should look up their stuff or ask them about using XNA in VB.Net.

----------


## Jacob Roman

Nah I'm gonna stick with DirectX. Theres no point of using another graphics library.

And this is how you put DirectX9 in VB.Net:



```
-------------------------------
VB.Net 2010
-------------------------------
Setting up Project:
- Start a new project and create a Windows Forms Application.

Setting up for DirectX9:
- Go up in the menu to Project > Add Reference... 
- Next goto .NET tab. 
- Scroll down to Microsoft.DirectX and click it. 
- Hold control and also add Microsoft.DirectX.Direct3D. You are welcome to adding more DirectX references if you choose. 
- Click Ok.
            
Note: If any of the DirectX stuff isn't located in your .NET tab, you may need to manually add it using your Browse tab under (your harddrive letter):\Windows\Microsoft.NET\DirectX For Managed Code\1.0.2902.0 and add your necessary .dll files such as Microsoft.DirectX.dll and Microsoft.DirectX.Direct3D.dll, etc. For any other new projects afterwards, if it's still not there, look under the Recent Tab.

Project must be in X86 for DirectX9 apps to run. And thankfully it's x86 by default. However the .Net Framework is 4.0 and needs changed to 3.5. Here's how to set it up:
- Go towards the right of the screen where it says Solution Explorer.
- Right click your project name and goto Properties.
- On the left side, select Compile.
- Click on the button Advanced Compile Options... A new window should pop up.
- On the bottom where it says Target Framework, select .NET Framework 3.5
- Click Ok.
- You are now ready to code with DirectX


--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
```

I'll take a look at your code, but if I were you, I would stick with the C++ written API's we were using in vb6 rather than the slow built in VB.Net functions from the .NET library.

----------


## Jacob Roman

I checked out your vb.net code and noticed you didn't use Option Strict On. The program executes slower when you dont convert things programmably. If the program itself tries to, its gotta add extra assembly code to do so. Also your timer is not good. Its better to use a Do Loop locked at 60 frames per second such as here:


vb.net Code:
Option Explicit OnOption Strict On Public Class Form1     Private Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Integer    Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Integer     Private Ticks_Per_Second As Long    Private Start_Time As Long     Private Milliseconds As Integer    Private Get_Frames_Per_Second As Integer    Private Frame_Count As Integer     Private Running As Boolean     Private Function Hi_Res_Timer_Initialize() As Boolean        If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then            Hi_Res_Timer_Initialize = False        Else            QueryPerformanceCounter(Start_Time)            Hi_Res_Timer_Initialize = True        End If    End Function     Private Function Get_Elapsed_Time() As Single        Dim Last_Time As Long        Dim Current_Time As Long         QueryPerformanceCounter(Current_Time)        Get_Elapsed_Time = Convert.ToSingle((Current_Time - Last_Time) / Ticks_Per_Second)        QueryPerformanceCounter(Last_Time)    End Function     Private Function Get_Elapsed_Time_Per_Frame() As Single        Static Last_Time As Long        Static Current_Time As Long         QueryPerformanceCounter(Current_Time)        Get_Elapsed_Time_Per_Frame = Convert.ToSingle((Current_Time - Last_Time) / Ticks_Per_Second)        QueryPerformanceCounter(Last_Time)    End Function     Private Sub Lock_Framerate(ByVal Target_FPS As Long)        Static Last_Time As Long        Dim Current_Time As Long        Dim FPS As Single         Do            QueryPerformanceCounter(Current_Time)            FPS = Convert.ToSingle(Ticks_Per_Second / (Current_Time - Last_Time))        Loop While (FPS > Target_FPS)         QueryPerformanceCounter(Last_Time)    End Sub     Private Function Get_FPS() As String        Frame_Count = Frame_Count + 1         If Get_Elapsed_Time() - Milliseconds >= 1 Then            Get_Frames_Per_Second = Frame_Count            Frame_Count = 0            Milliseconds = Convert.ToInt32(Get_Elapsed_Time)        End If         Get_FPS = "Frames Per Second: " & Get_Frames_Per_Second    End Function     Private Sub Game_Loop()        Do While Running = True            'Game Code Here            Lock_Framerate(60)            Me.Text = Get_FPS()            Application.DoEvents()        Loop    End Sub     Private Sub Main()        With Me            .Show()            .BackColor = Color.FromArgb(255, 0, 0, 0)            .DoubleBuffered = True        End With         Hi_Res_Timer_Initialize()        Running = True        Game_Loop()    End Sub     Private Sub Shutdown()        Running = False        Application.Exit()    End Sub     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load        Main()    End Sub     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing        Shutdown()    End SubEnd Class

I'm at the moment adding this sub from vb6 to vb.net, so try and impliement this. It may not be done, I did the conversion to give you an idea:


vb.net Code:
Public Sub Blit(Buffer() As Integer, Pic As PictureBox, ByVal Width As Integer, ByVal Height As Integer)    If Width = 0 Or Height = 0 Then Exit Sub    Dim BI As BITMAPINFO    With BI.bmiHeader        .biWidth = Width        .biHeight = -Height        .biSize = 40        .biBitCount = 32        .biPlanes = 1    End With     StretchDIBits Pic.hDC, 0, 0, Pic.Width, Pic.Height, 0, 0, Width, Height, Buffer(0), BI, 0, SRCCOPYEnd Sub

----------


## omundodogabriel

I managed to add DirectX to vb.net, and ported all sound emulation code to use with the new DirectSound. However, in runtime, vb show the error NullReferenceException. What I am doing wrong?

Edit: Already discovered the problem, I forgot to call the function DirectSound_Initialize  :EEK!: 
Now is giving a ArgumentException error on Sound_Process_Through_Mixer function ....  :Mad: 

Edit 2: FIXED! It's working perfectly now! NES vb.net emulator now with sound! The source with working sound engine is attached! OMG, i can ever hear bricks breaking now!


```
Option Explicit On
Imports Microsoft.DirectX
Imports Microsoft.DirectX.DirectSound
Module DSound
    'Public DX As DirectX9

    'Public DirectSound_Enum As Enum
    Private Sound_Device As New Device
    Public Sound_Buffer As SecondaryBuffer
    Private Sound_Buffer_Description As New DirectSound.BufferDescription()
    Public Sound_Buffer_Wave_Format As New WaveFormat()

    Public Const MAX_VOLUME As Long = 100
    Public Buffer_Length As Long, Half_Buffer_Length As Long
    Public Buffer_Size As Long
    Public Sound_Data() As Byte
    Public Sub DirectSound_Initialize()

        'DX = New DirectSound
        'DirectSound_Enum = DX.GetDSEnum
        'DirectSound = DX.DirectSoundCreate(DirectSound_Enum.GetGuid(1))

        With Sound_Buffer_Wave_Format
            .FormatTag = WaveFormatTag.Pcm
            .Channels = 1 '1 = Mono   2 = Stereo. The NES is Mono
            .BitsPerSample = 16
            .SamplesPerSecond = 44100 '22050
            .BlockAlign = (.BitsPerSample * .Channels) / 8
            .AverageBytesPerSecond = ((.BitsPerSample / 8) * .Channels) * .SamplesPerSecond

            Buffer_Size = .AverageBytesPerSecond '* 5
            ReDim Sound_Data(Buffer_Size)

            Half_Buffer_Length = .AverageBytesPerSecond / 2 '/ 15
            Half_Buffer_Length = Half_Buffer_Length + (Half_Buffer_Length Mod .BlockAlign)
        End With

        Buffer_Length = Half_Buffer_Length * 2

        Sound_Device.SetCooperativeLevel(Form1.Handle, CooperativeLevel.Normal)

        With Sound_Buffer_Description
            .Format = Sound_Buffer_Wave_Format
            .BufferBytes = Buffer_Length
            'DSBCAPS_STICKYFOCUS - means it will keep playing even if our application does not have focus
            .Flags = BufferDescriptionFlags.ControlPositionNotify Or _
                      BufferDescriptionFlags.StickyFocus Or _
                      BufferDescriptionFlags.ControlFrequency Or _
                      BufferDescriptionFlags.ControlPan Or _
                      BufferDescriptionFlags.ControlVolume
        End With

        Sound_Buffer = New SecondaryBuffer(Sound_Buffer_Description, Sound_Device)
        'DirectSound.CreateSoundBuffer(Sound_Buffer_Description)
        Sound_Channel_Clear_Buffer()
        Set_Sound_Volume(Sound_Buffer, 100)
        Play_Sound_Loop(Sound_Buffer)
        'Sound_Buffer.Play(0, DirectSound.BufferPlayFlags.Looping)
    End Sub
    Public Sub Play_Sound(ByVal Sound_Buffer As SecondaryBuffer)
        Sound_Buffer.SetCurrentPosition(0)
        Sound_Buffer.Play(0, BufferPlayFlags.Default)
    End Sub
    Public Sub Play_Sound_Once(ByVal Sound_Buffer As SecondaryBuffer)
        Sound_Buffer.Play(0, BufferPlayFlags.Default)
    End Sub
    Public Sub Play_Sound_Loop(ByVal Sound_Buffer As SecondaryBuffer)
        Sound_Buffer.Play(0, BufferPlayFlags.Looping)
    End Sub
    Public Sub Pause_Sound(ByVal Sound_Buffer As SecondaryBuffer)
        Sound_Buffer.Stop()
    End Sub
    Public Sub Set_Sound_Volume(ByVal Buffer As SecondaryBuffer, ByVal Volume As Long)
        If Volume >= MAX_VOLUME Then Volume = MAX_VOLUME
        If Volume <= 0 Then Volume = 0
        Buffer.Volume = ((Volume / MAX_VOLUME) * 10000) + -10000
    End Sub
```

Here is the code with sound
Nes.net_dsound_working.zip

----------


## Niya

I have a question Jacob....Why do you use QueryPerformanceCounter  ? What's its function ? MSDN says returns a count of a high resolution counter. What does that mean in layman's terms ?

----------


## Jacob Roman

> I have a question Jacob....Why do you use QueryPerformanceCounter  ? What's its function ? MSDN says returns a count of a high resolution counter. What does that mean in layman's terms ?


Because its a high resolution timer. Practically the highest resolution timer out there. And can be used for real time related things such as game physics, locking framerates, getting FPS, timing things, anything to do with time, etc. You could alternatively use the timeGetTime API. But its not as a high resolution. But a good alternative if you feel QueryPerformanceCounter is overkill. Its a matter of preference.

----------


## Niya

Ah, I think I get it. I suppose for something like an emulator, that kind of precision is necessary. I made simple game-like engines in the past without it so I guess its not that big a deal in such a scenario.

----------


## Jacob Roman

> I managed to add DirectX to vb.net, and ported all sound emulation code to use with the new DirectSound. However, in runtime, vb show the error NullReferenceException. What I am doing wrong?
> 
> Edit: Already discovered the problem, I forgot to call the function DirectSound_Initialize 
> Now is giving a ArgumentException error on Sound_Process_Through_Mixer function .... 
> 
> Edit 2: FIXED! It's working perfectly now! NES vb.net emulator now with sound! The source with working sound engine is attached! OMG, i can ever hear bricks breaking now!
> 
> 
> ```
> ...


I oughta check this out. The bricks actually making the breaking sound? No way!

[EDIT] Yea no bricks breaking on my end. Its just a thump which I believe comes from the triangle or rectangle channel. The brick breaking noise is suppose to sound like the bricks are crumbling. You get that satisfying feeling with the thump combined with the crackling noise, knowing you broke the bricks.

Also you forgot to shut off the sound when you close out of it. It persists after you exit the program. I get on average 55 fps on my computer at least. I'll try to work with the sound more so. I'm browsing through virtuanes's source code on the apu to get ideas. It probably has something to do with the IRQ implementation over in register $4017 which I did not put in. But thats just a wild guess. Wont know for sure till then.

----------


## omundodogabriel

Already solved the speed problem. The code "Play_Sound_Loop (Sound_Buffer)" on 6502.vb play the sound buffer, but the buffer is already being played trough the Sound_Process_Through_Mixer function. I deleted that line of code, and speed is back to 200 fps  :Smilie: 

As for the breaking bricks sound, I was pretty sure I heard the first time, now also do not hear anymore ...

Edit: In fact, I can only hear the breaking blocks in a rom hack of Super Mario Bros  :Confused:  . I don't know why, since the only difference is some graphic changes. I am attaching the rom hack.
Acid Bros (SMB1 Hack).zip

----------


## omundodogabriel

The mapper MMC5 is already working, at least for Castlevania 3. Still has some problems regarding the name tables, but I believe that it shouldn't be difficult to solve.

The mappers MMC5 is one of the most complex to emulate.

----------


## Jacob Roman

> Already solved the speed problem. The code "Play_Sound_Loop (Sound_Buffer)" on 6502.vb play the sound buffer, but the buffer is already being played trough the Sound_Process_Through_Mixer function. I deleted that line of code, and speed is back to 200 fps 
> 
> As for the breaking bricks sound, I was pretty sure I heard the first time, now also do not hear anymore ...
> 
> Edit: In fact, I can only hear the breaking blocks in a rom hack of Super Mario Bros  . I don't know why, since the only difference is some graphic changes. I am attaching the rom hack.
> Acid Bros (SMB1 Hack).zip


That is very strange. I hear bricks breaking on the vb.net version, but not the vb6 version. I'm gonna have to take a look at your code to see what you have done differently.

----------


## omundodogabriel

Actually, I just did the conversion of your code to directx 9, I have not changed anything but the buffer size. The block breaking noise on Mario hack works on both vb.net and vb6 versions here, but not on the original game... It's really is very weird.

Already fixed all the problems related to Castlevania 3, was just the IRQ that was not working. Now Castlevania 3 is perfect. I will test other MMC5 games.

Edit: Castlevania 3 still have some Mirroring problems...

----------


## omundodogabriel

I'm putting the progress I've made so far in the code if Jacob wants to improve and fix the current problems. I'll take a break for now, I have other projects I want to work, but soon I will work on it again.  :Wink: 

*Main changes:*
- Added Mappers 1, 2, 3, 4, 5
- Improved Menus, need a english translation
- Added controls
- Fixed some PPU issues
- Some settings

*ToDo:*
- Faster Blit function (maybe with DirectX?), FullScreen is too slow
- Mapeable Keyboard keys and USB Joystick support
- Fix some sprite priority issues (on foreground or background), Simpsons the space ship is behind the stars and the moon!
- Fix some Noise channel problems and add DMC channel
- Add translations support

Source Here:
NES.net_rev2_src.zip

I'm wanting to make a snes emulator for vb, after fix the issues with this emulator of course. Jacob, you will help me?  :Big Grin:

----------


## kivisoft@

Pretty nice job! just played the mario! brought back memories!

----------


## Jacob Roman

Thanks. It was a royal pain to put together and took a lot of research. Was pretty cool for both of us emulator developers to work on it.  :big yellow:

----------


## kivisoft@

Sega genesis is your next step! I'm sure you can handle it!

Although I don't think something like that is even possible in VB6. even if it is, it's going to be a pain in (You know where!!) but maybe .Net can handle it.

----------


## Niya

If it were me, I would export all the heavy lifting to C++ libraries. You really cannot touch C++ for creating super fast algorithms. Some of the best emulators make use of assembly. ZSNES, which is considered to be one of the greatest SNES emulators ever made was written in pure assembly. If you're emulating hardware like that used for an advanced system like the Sega Genesis you really want speed. Neither VB6 nor VB.Net can natively provide such astonishing speed. Then again, we are in 2013 so the sheer speed of processors today may render that point moot.

----------


## Jacob Roman

> Sega genesis is your next step! I'm sure you can handle it!
> 
> Although I don't think something like that is even possible in VB6. even if it is, it's going to be a pain in (You know where!!) but maybe .Net can handle it.


Ugh dont get me started on .Net. Well end up turning this thread into another VS war and I'm pretty sure Niyas in agreement we don't want that again.  omundodogabriel has already ported it to VB.Net only he found it to be extremely slow compared to VB6. You can find out yourself has he has it available for download in one of the posts in this thread. If you read up eventually youll find it. Gotta hit the sack again because Im never this up early. I just woke up from a sound sleep in the middle of the crack of dawn and I'm not a morning person!

I was thinking about making a Genesis version. Its already been done in Gameboy in VB6 only the comments are in Japanese. Hell I even got documentation on Playstation as well.

----------


## Niya

> Ugh dont get me started on .Net. Well end up turning this thread into another VS war and I'm pretty sure Niyas in agreement we don't want that again.


Well this kind of thing is your domain. I'm not gonna argue you on something I know little about. I've never written an emulator or even anything close so I'd be more than willing to defer to you on this. If VB6 is better than VB.Net for this then I'm not gonna even try and debate that. You'd know better than I do.

----------


## kivisoft@

I agree the whole argument on Which one is better (VB6 or VB.NET) is just stupid. Every language has it's capabilities and it's limitations, I always laughed at those who say "C++" is good for anything, I have no C++ skills but that is just crap. which is why knowing multiple languages is useful, you can pick the one that is right for the job. And about VB6, as I Always said "It gets the job done FAST" and that's it (maybe I should put that in my sig!). There is currently two versions of this Emu (VB6 and .NET) now ask yourself which one took more time? definitely VB.NET but that doesn't necessarily means that VB6 is better.

----------


## Nightwalker83

> Its already been done in Gameboy in VB6 only the comments are in Japanese.


Well, it shouldn't be too hard to translate it into English! You wouldn't even need the Japanese comments. I am sure a master such as yourself can tell what is happening just by looking at the code?

----------


## Jacob Roman

I honestly dont know how I'm gonna simulate Blast Processing if I do the Genesis. Genesis does what Nintendont  :big yellow:

----------


## Niya

> I honestly dont know how I'm gonna simulate Blast Processing if I do the Genesis. Genesis does what Nintendont


Whoa...I had to look up that term. Seems there is some controversy behind it because it was overhyped so as to become an effective marketing gimmick. But technically, it seems simple enough. Something about using DMA to do bit block transfers, not that I really know anything about that.

----------


## Jacob Roman



----------


## Niya

lol....aggressive marketing.

----------


## Jacob Roman

If I do make a Sega Genesis Emulator I am definitely adding this sub:


vb Code:
Public Sub Blast_Processing     'Do Blast Processing here!!!End Sub

----------


## Niya

Might be more like this:-

vbnet Code:
Public Class BlastProcessor     Public Sub Blast(ByVal src As IntPtr, ByVal dest As IntPtr, ByVal cb As Integer)        'Blast processing code!!!!    End Sub End Class

----------


## Jacob Roman

I found lots of goodies on programming an emulator for the Sega Genesis:

http://www.zophar.net/documents/genesis.html
http://emu-docs.org/?page=Genesis
http://www.genny4ever.net/index.php?page=docs

----------


## Niya

> I found lots of goodies on programming an emulator for the Sega Genesis:
> 
> http://www.zophar.net/documents/genesis.html
> http://emu-docs.org/?page=Genesis
> http://www.genny4ever.net/index.php?page=docs


Do you think you're up to the challenge ?....I wish I had massive amounts of time to spend on non-profitable ventures. I would really love to spend my days learning about these things in depth.

----------


## kivisoft@

> Do you think you're up to the challenge ?....I wish I had massive amounts of time to spend on non-profitable ventures. I would really love to spend my days learning about these things in depth.


Really?! sounds like a true pain! it's like reading a note in chines!

----------


## Jacob Roman

The NES emulator uses the 6502 CPU with 56 opcodes and 13 address modes. Any start in designing any emulator starts with the CPU. So if I do the Sega Genesis I would have to simulate the 68000 CPU. Its gonna be tough but very possible.

----------


## Niya

I've always found it quite cute that processors and emulate other processors. There is a beautiful symmetry about that.

----------


## omundodogabriel

A sega genesis emulator? It would be amazing to play the Sega classics like Sonic 3 on an emulator made ​​in vb6! It would be the first emulator of a 16-bit system in vb. The CPU will be very hard to do, but after this, emulate the apu and ppu should be easy! If you want I am willing to help in this project.  :Big Grin: 

As for the Gameboy emulator, there is a very good Gameboy Color emulator for vb6 in english with sound called BasicBoy, and code is avaible!, it's worth a look:
http://www.zophar.net/gb/basicboy.html

If anyone is interested, here is the latest version of Nes.net. I probably will not touch it again.
NES.net_rev3.zip

-Gabriel.

----------


## Jacob Roman

Yeah sure lets do it and make history. Blast Processing on VB6 =D

----------


## omundodogabriel

> Yeah sure lets do it and make history. Blast Processing on VB6 =D


Well, I tried to find documents about sega genesis emulation (68k CPU and VPU), and found very little. The best I got so far was reading the Rom Header  :Stick Out Tongue: . You've managed to find good simple emulators and good documents that we can rely?

----------


## Jacob Roman

I created a thread on it in the games and graphics section. All the info you need will be there and lots more to come  :Wink:

----------

