So. I have not been posting, but I have been continuing work and I plan on posting a little bit more about that this week. I hope to post more about what I've learned about the NES through my research, inaccurate though it likely is. However, for the moment just let me say that I am starting to work on the gui. The PPU is coming along and is just about ready to actually do something. I believe most of the registers are more or less working except for the scroll register. I am parsing the character tiles and am starting work on parsing the background tiles, which ought to go easier since it's not too terribly different than the character tiles.
The gui is a little bit fun because it involves working with swing, which I haven't had an awful lot of experience doing. It's also a bit frustrating because it's slow work as I'm having to do a ton of research in order to understand what it is I'm doing.
I received a comment from another guy who is also working on a java based NES emulator that recommended I not start my project based on emulating SMB. This is in many respects a wise bit of advice. SMB is a fairly simple cartridge, but there are simpler ones out there. There are a ton of test cartridges, for example, which test various parts of the system and can help me debug. So, this is what I'm doing currently. I've worked out a lot of bugs in the CPU and in the registers that simply isn't represented in the code in the repository at the moment. I will probably correct that in the next few days to weeks. However, I'm really more interested in getting the PPU at least partially displaying something in the GUI before I update the SVN.
I have begun researching the APU. On first glance it appears a little bit simpler than the PPU. We'll see, though.
I discuss my progress on my project to write an NES emulator in java. This is largely an educational project. I wanted to learn more about how hardware is emulated, how hardware is tied together in these small computers, and I wanted to learn more about assembly. The source code for the project is open source and is being released here: lambnes google code page
Tuesday, December 7, 2010
Sunday, October 24, 2010
I uploaded some code to the svn. It's all of the current source. It compiles, but does not really do very much. The PPU is only partially implemented. I've implemented maybe half of the registers that the CPU and PPU use to interact and there's no attempt yet to implement the graphics.
What I have done is emulated a very small portion of the PPU so that it updates the status register with vblanks occasionally. This allows me to look through the logs and see what the project is doing. I cleared up a couple small bugs that were making the CPU error out and quit. It's still hitting a spot somewhere where it's running into an unemulated opcode and I'm trying to figure out if that's a legitimate code or a spot where my cpu has done something unexpected and has jumped the tracks.
The CPU used by the NES uses a byte of memory for each opcode. This means that there are potentially 256 different opcodes that can exist. However, the CPU only officially use something like 150 of those opcodes. The other 100 or so opcodes do things in the CPU, and it wouldn't surprise me if they were occasionally used in production code, but I have decided to capture these codes instead of implementing them. At least for the moment.
So, my CPU hits one of these illegal codes at a point and I'm trying to figure out if this means I need to implement one of these illegal codes that were legitimately put in the source by the programmer, or if it means that my CPU has done something wrong and is now pulling non-opcode data from memory and treating it like it's an opcode. This involves running the CPU for a while and then going through the logs to see what the CPU is doing. I found a disassembled and heavily commented Super Mario source file on the internet and I compare that to what my CPU is doing. I try to figure out what the code is supposed to be doing and make sure the CPU is doing that. It involves looking at a lot of assembly code. It's really gratifying to see my CPU hit these loops in the source and function properly. It's kind of amazing.
So far as I can see, the code never gets to the point that it's setting up the VRAM. This part is essential before I can start implementing the graphical portion of the application. The character ram that is pulled from the cartridge only contains a portion of the actual character information. I'll probably talk more about that when I actually start implementing that.
One thing I'm seeing is that my CPU is SLOW. It also does a metric shit ton of logging. I'm debugging right now, so I'm not all that concerned about it, but at one point or another I will have to do a significant amount of optimization.
I hope to have these very small, but important issues settled in the next few weeks. Once the code appears to be more or less running appropriately and is setting up all of the memory correctly I'll be able to start working on the graphics output. That ought to be kind of fun, but a little daunting.
What I have done is emulated a very small portion of the PPU so that it updates the status register with vblanks occasionally. This allows me to look through the logs and see what the project is doing. I cleared up a couple small bugs that were making the CPU error out and quit. It's still hitting a spot somewhere where it's running into an unemulated opcode and I'm trying to figure out if that's a legitimate code or a spot where my cpu has done something unexpected and has jumped the tracks.
The CPU used by the NES uses a byte of memory for each opcode. This means that there are potentially 256 different opcodes that can exist. However, the CPU only officially use something like 150 of those opcodes. The other 100 or so opcodes do things in the CPU, and it wouldn't surprise me if they were occasionally used in production code, but I have decided to capture these codes instead of implementing them. At least for the moment.
So, my CPU hits one of these illegal codes at a point and I'm trying to figure out if this means I need to implement one of these illegal codes that were legitimately put in the source by the programmer, or if it means that my CPU has done something wrong and is now pulling non-opcode data from memory and treating it like it's an opcode. This involves running the CPU for a while and then going through the logs to see what the CPU is doing. I found a disassembled and heavily commented Super Mario source file on the internet and I compare that to what my CPU is doing. I try to figure out what the code is supposed to be doing and make sure the CPU is doing that. It involves looking at a lot of assembly code. It's really gratifying to see my CPU hit these loops in the source and function properly. It's kind of amazing.
So far as I can see, the code never gets to the point that it's setting up the VRAM. This part is essential before I can start implementing the graphical portion of the application. The character ram that is pulled from the cartridge only contains a portion of the actual character information. I'll probably talk more about that when I actually start implementing that.
One thing I'm seeing is that my CPU is SLOW. It also does a metric shit ton of logging. I'm debugging right now, so I'm not all that concerned about it, but at one point or another I will have to do a significant amount of optimization.
I hope to have these very small, but important issues settled in the next few weeks. Once the code appears to be more or less running appropriately and is setting up all of the memory correctly I'll be able to start working on the graphics output. That ought to be kind of fun, but a little daunting.
Wednesday, October 20, 2010
I have pretty much completed the cpu portion of the emulator. Emulating the cpu isn't very difficult. Its functionality is well known. It fetches an opcode, processes it, and updates multiple flags. Probably the hardest thing is finding documentation on what each opcode does exactly and how each flag is updated. Not too bad. Some documentation might be a little misleading or a little tough to read -- some of it is written by professional writers, but not much -- there's a lot of it, though, so if you don't understand something there are about 50 other places to look.
Emulating the ppu is a lot harder. Now we're getting into the meat of the system. Again, finding documentation is harder. Also, because the exact functionality of this portion of the system isn't as well understood by me I'm a lot more reliant on documentation. Not to mention the fact that the cpu is used all over the place and is well documented by various people. Not so with the ppu. The ppu is proprietary and any documentation that exists was written by individuals who either experimented on an actual NES or read other documentation elsewhere. None of it is written by professional writers and quite frequently is a work in progress. Kind of like this blog.
So now we're getting to the point that my emulator is actually doing something. Not very much, mind you, but something. It runs for the first 20 or so opcodes then it gets into a position where the opcodes are having it read the ppu state registers to determine whether or not the ppu is in a vblank. Because my ppu is largely unwritten and the registers aren't implemented yet, this doesn't happen and the cpu pretty much just sits there waiting.
The systems all interact via various specific positions in memory. For instance, to set various features on the ppu you can write to addresses 0x2000 and 0x2001. To read what state the ppu is currently in you read from 0x2002. In 0x2002 is a number between 0 and 256 (0x00 and 0xFF). Each bit in that number indicates something about the ppu. For instance, the highest bit -- the bit on the furthest left side of the binary number -- indicates whether or not the ppu is in a vblank period, which is the period in which the television is resetting itself so that it's ready for the next frame. Vblank happens 60 times a second. Interestingly, there are some registers that you should only read from or write to during vblank because reading or writing to or from them when the ppu is drawing the frame affects that frame.
So right now I'm in the process of implementing these registers not to mention the timing mechanism for system so that I can attempt to make the system run at the right speed so that lines are being drawn when they're supposed to be drawn and things run at the expected rate. It's tough work and is quite shittily written at this point. The main loop will probably prove to be pretty buggy. It would clearly have been easier to write a 2d game than to try to emulate the NES. That said, in my opinion this is a far cooler project and one that I'm pretty happy to be involved in. I'm trying to be careful in writing my code, but am also of the opinion that writing dirty code that kind of works helps to understand the problem space and helps you to get to the point that you can clean up the code. It's not an efficient process. It's not agile. But it has its benefits. I feel it works pretty well for hobby projects with a large problem space anyway.
Emulating the ppu is a lot harder. Now we're getting into the meat of the system. Again, finding documentation is harder. Also, because the exact functionality of this portion of the system isn't as well understood by me I'm a lot more reliant on documentation. Not to mention the fact that the cpu is used all over the place and is well documented by various people. Not so with the ppu. The ppu is proprietary and any documentation that exists was written by individuals who either experimented on an actual NES or read other documentation elsewhere. None of it is written by professional writers and quite frequently is a work in progress. Kind of like this blog.
So now we're getting to the point that my emulator is actually doing something. Not very much, mind you, but something. It runs for the first 20 or so opcodes then it gets into a position where the opcodes are having it read the ppu state registers to determine whether or not the ppu is in a vblank. Because my ppu is largely unwritten and the registers aren't implemented yet, this doesn't happen and the cpu pretty much just sits there waiting.
The systems all interact via various specific positions in memory. For instance, to set various features on the ppu you can write to addresses 0x2000 and 0x2001. To read what state the ppu is currently in you read from 0x2002. In 0x2002 is a number between 0 and 256 (0x00 and 0xFF). Each bit in that number indicates something about the ppu. For instance, the highest bit -- the bit on the furthest left side of the binary number -- indicates whether or not the ppu is in a vblank period, which is the period in which the television is resetting itself so that it's ready for the next frame. Vblank happens 60 times a second. Interestingly, there are some registers that you should only read from or write to during vblank because reading or writing to or from them when the ppu is drawing the frame affects that frame.
So right now I'm in the process of implementing these registers not to mention the timing mechanism for system so that I can attempt to make the system run at the right speed so that lines are being drawn when they're supposed to be drawn and things run at the expected rate. It's tough work and is quite shittily written at this point. The main loop will probably prove to be pretty buggy. It would clearly have been easier to write a 2d game than to try to emulate the NES. That said, in my opinion this is a far cooler project and one that I'm pretty happy to be involved in. I'm trying to be careful in writing my code, but am also of the opinion that writing dirty code that kind of works helps to understand the problem space and helps you to get to the point that you can clean up the code. It's not an efficient process. It's not agile. But it has its benefits. I feel it works pretty well for hobby projects with a large problem space anyway.
Saturday, October 9, 2010
So, I have pretty much written the code that emulates what the cpu does. I have not yet begun debugging that code. I have been testing as I've gone along. If there are errors, I suspect that most of them will be centered around parts of the cpu that I didn't understand or misunderstood. I've written the code, but there are significant questions that I have not yet found answers for that could seriously affect how the processor functions. These are the known unknowns. There are probably also unknown unknowns. I've created a small text document called known unknowns that documents some of the things I don't know and will likely upload it the next time I get around to uploading the current code to the google code source repository. As in my professional life, the source repository is a necessary evil and something I am going to be lazy about, I guess.
I have been reading up on the GPU. When I set out to emulate the NES, I was a little surprised to find out that the processor in it had been around since 1975. The cpu was not cutting edge. It was a well known processor that had been used in several other video game systems. The GPU was a lot more cutting edge, I think.
The CPU interacts with all of the other systems of the NES via memory. There are sections of memory that function as input and output for both the graphics processing system and the audio processing system. I am still coming up with the design that my emulator will eventually use to emulate the graphics. I have an idea how the GPU does what it does. I have not yet decided how I want to emulate it. I still need to find out exactly what the inputs and outputs for the GPU look like. Especially the output. I believe I've seen some degree of information concerning some of the input registers, but not an awful lot concerning the output registers.
The other thing to think about is the television. The NES was built specifically to interact with television screens and some of the software uses the physical constraints of the actual television to create effects. For instance, they might interact with the input registers at a particular point in the creation of a particular line on the television screen to create some effect. I don't exactly know what they're doing or what these effects look like yet, but it might be necessary for me to emulate the way a television creates images to one degree or another in order to replicate these effects. If I decide to replicate these effects. My project is mostly just to emulate one or two games in order to learn more about hardware and assembly programming, not to create the most accurate NES emulator available.
I have been reading up on the GPU. When I set out to emulate the NES, I was a little surprised to find out that the processor in it had been around since 1975. The cpu was not cutting edge. It was a well known processor that had been used in several other video game systems. The GPU was a lot more cutting edge, I think.
The CPU interacts with all of the other systems of the NES via memory. There are sections of memory that function as input and output for both the graphics processing system and the audio processing system. I am still coming up with the design that my emulator will eventually use to emulate the graphics. I have an idea how the GPU does what it does. I have not yet decided how I want to emulate it. I still need to find out exactly what the inputs and outputs for the GPU look like. Especially the output. I believe I've seen some degree of information concerning some of the input registers, but not an awful lot concerning the output registers.
The other thing to think about is the television. The NES was built specifically to interact with television screens and some of the software uses the physical constraints of the actual television to create effects. For instance, they might interact with the input registers at a particular point in the creation of a particular line on the television screen to create some effect. I don't exactly know what they're doing or what these effects look like yet, but it might be necessary for me to emulate the way a television creates images to one degree or another in order to replicate these effects. If I decide to replicate these effects. My project is mostly just to emulate one or two games in order to learn more about hardware and assembly programming, not to create the most accurate NES emulator available.
Sunday, September 26, 2010
I've been able to get a lot of work done on the CPU. I'm not an assembly programmer. All of the programming I've ever done has been from a high language level, so it's interesting to see the actual instructions that the CPU offers. I've been able to spend the last few weeks implementing the instruction set. I've tried to be rigorous in testing, but the CPU itself isn't really all that functional. It only makes sense in context and right now I know nothing about that context. I've become pretty familiar with the 6502 instruction set, but know very little about how it's actually programmed. I have no idea how it actually places graphics on the screen or plays sound. I assume it involves placing information at some point in memory since that's pretty much all that the CPU instruction set does. I'm looking forward to implementing the screen and the PPU. That ought to be pretty interesting. Once I've done that I ought to be able to get the CPU to actually do something and will hopefully be able to start debugging. Right now I'm emulating the CPU, but have not started emulating the entire system.
Monday, September 6, 2010
Since I last posted I've done a bit of work. I released the current version of the code as of last week some time via Google Code. This is located here. I'll probably release on there once a week or so. Of course, it doesn't do anything really just yet, so there's very little reason to look at it, but it's there.
So far as the emulator goes, I'm starting to realize how huge of a project this is. I'm working exclusively on the CPU. The main function of the CPU is to do manipulations on values in memory, so getting memory to function properly has been a pretty big project lately. Right now I'm focusing mainly on the program memory, which is held in basically the last half of the total memory that the NES has. I really need to get the front half working.
That said, I've begun a small amount of work on the CPU itself. I've only written one of the 50 or so commands that the 6502 supports. I started with AND. I started alphabetically and skipped ADD because ADD is actually pretty complicated. AND was a much nicer starting point. I need to take a look at the flags. I don't understand all of them very well. The 6502 supports 13 different memory addressing modes. I've implemented something like the first two addressing modes.
The problem I'm having so far is that I need to find some means of writing test cases for the CPU based on the way the CPU really functions. I can write test cases, but these test cases will be based on my understanding of the CPU, which is limited. Testing of the CPU is going to need to be pretty thorough.
I've found a couple of documents pretty useful:
http://nesdev.parodius.com/6502guid.txt
http://nesdev.parodius.com/6502jsm.zip
They both describe the available instructions. 6502guid.txt was really helpful in understanding the memory addressing modes.
So far as the emulator goes, I'm starting to realize how huge of a project this is. I'm working exclusively on the CPU. The main function of the CPU is to do manipulations on values in memory, so getting memory to function properly has been a pretty big project lately. Right now I'm focusing mainly on the program memory, which is held in basically the last half of the total memory that the NES has. I really need to get the front half working.
That said, I've begun a small amount of work on the CPU itself. I've only written one of the 50 or so commands that the 6502 supports. I started with AND. I started alphabetically and skipped ADD because ADD is actually pretty complicated. AND was a much nicer starting point. I need to take a look at the flags. I don't understand all of them very well. The 6502 supports 13 different memory addressing modes. I've implemented something like the first two addressing modes.
The problem I'm having so far is that I need to find some means of writing test cases for the CPU based on the way the CPU really functions. I can write test cases, but these test cases will be based on my understanding of the CPU, which is limited. Testing of the CPU is going to need to be pretty thorough.
I've found a couple of documents pretty useful:
http://nesdev.parodius.com/6502guid.txt
http://nesdev.parodius.com/6502jsm.zip
They both describe the available instructions. 6502guid.txt was really helpful in understanding the memory addressing modes.
Saturday, August 28, 2010
I have done a lot of work on the cartridge portion of the emulator. Now the system is able to take in the raw rom data from a zipped file (still no support for unzipped roms) and parse the data into the header, program instructions, and pattern tiles. No real emulation of the system is occurring, but we are just steps away from that.
Up until now I have been using the working title JNES. This is not satisfactory. I have decided to create a google code repository for the project. This allows me to store the code and create a wiki I can use to create documentation for the system. However, in order to do that I have to come up with a final name for the system. I am toying with a few ideas. LambNes comes to mind.
The next steps for the system involve writing the code that emulates the cpu. I now have the instructions, so now it's time to start doing something with them. This will likely take a long time. I need to find out a lot about the system. For instance, I need to know what flags exist, when these flags are modified, what instructions are supported, etc. Lots and lots of stuff. This will likely involve lots of testing. I will probably have to create one test case for each instruction just about. I think there's on the order of 100 instructions. I will likely be doing more research on the cpu in the next couple of days and will likely be updating with information regarding my progress. I'm kind of excited to be past the file system stuff.
Up until now I have been using the working title JNES. This is not satisfactory. I have decided to create a google code repository for the project. This allows me to store the code and create a wiki I can use to create documentation for the system. However, in order to do that I have to come up with a final name for the system. I am toying with a few ideas. LambNes comes to mind.
The next steps for the system involve writing the code that emulates the cpu. I now have the instructions, so now it's time to start doing something with them. This will likely take a long time. I need to find out a lot about the system. For instance, I need to know what flags exist, when these flags are modified, what instructions are supported, etc. Lots and lots of stuff. This will likely involve lots of testing. I will probably have to create one test case for each instruction just about. I think there's on the order of 100 instructions. I will likely be doing more research on the cpu in the next couple of days and will likely be updating with information regarding my progress. I'm kind of excited to be past the file system stuff.
Monday, August 23, 2010
Read up a little bit on the INES format, but haven't done a whole lot of the implementation of that. I did, however, download a hexeditor so I could look at my test rom to see what was actually in there and downloaded a known good NES emulator to test the rom. I used Nestopia. The rom seems to work well. I played through to about world 2-3. Those damn jumping fish.
I fixed a few small bugs. I initially was using ZipInputStream.read(). This was loading only the first 500 bytes or so for whatever reason even if I set the read size to the entire size of the file. Rather than inspecting why that was I switched over to using ZipEntry to read the file and am now getting an InputStream via ZipFile.getInputStream. Using InputStream.read appears to be loading the entire file. This is a better design and works, so I'm not curious as to why ZipInputStream did not work.
My test rom contains 40976 bytes. This is a little interesting. The NES itself has 32k of program memory and 8k of character memory. This maps directly to the super mario bros rom, which has 32k of program code and 8k of character code. The additional 16 bytes unaccounted for are the ines file header.
Some of the other roms have additional memory built into them which need to be emulated for the emulator to run them, but I don't plan on implementing that feature right now. If I get the NES running with this standard rom I'll consider new features.
Now that I'm reading the entire file I need to work on supporting the INES file format. This means separating out the header from the program code from the character code. Then I can start work on emulating the CPU. I expect this blog will be a bit more interesting once I start writing the actual emulation. Right now I'm still doing the formative work, which isn't all that interesting.
I fixed a few small bugs. I initially was using ZipInputStream.read(). This was loading only the first 500 bytes or so for whatever reason even if I set the read size to the entire size of the file. Rather than inspecting why that was I switched over to using ZipEntry to read the file and am now getting an InputStream via ZipFile.getInputStream. Using InputStream.read appears to be loading the entire file. This is a better design and works, so I'm not curious as to why ZipInputStream did not work.
My test rom contains 40976 bytes. This is a little interesting. The NES itself has 32k of program memory and 8k of character memory. This maps directly to the super mario bros rom, which has 32k of program code and 8k of character code. The additional 16 bytes unaccounted for are the ines file header.
Some of the other roms have additional memory built into them which need to be emulated for the emulator to run them, but I don't plan on implementing that feature right now. If I get the NES running with this standard rom I'll consider new features.
Now that I'm reading the entire file I need to work on supporting the INES file format. This means separating out the header from the program code from the character code. Then I can start work on emulating the CPU. I expect this blog will be a bit more interesting once I start writing the actual emulation. Right now I'm still doing the formative work, which isn't all that interesting.
Sunday, August 22, 2010
So, I'm successfully loading a rom into some sort of data structure. At this point, this is an array of bytes. In the case of my test rom this is an array of 40976 elements. I'm not completely certain this array is the best data structure to store this data. Nor am I at all certain what all of the data in the rom file means. However, I'm starting to figure it out.
I've been talking about roms a lot without really describing what they are. Roms are essentially a file that represents all of the data for a particular program. In the case of the NES, this would be all of the data from the cartridge that is inserted into the NES. Most of this data represents the program code, but also contained in the cartridge and in the rom file are the 8x8 pattern tiles that make up the visual portions of the game. It appears that most NES roms downloadable from the internet are stored in ines format. INES was an early NES emulator. I don't know very much about how it gained dominance in the NES rom market. However, my test rom appears to be in ines format, so this appears to be the format I will be supporting in my emulator. The .nes file I currently search for in the zipped rom is an ines file.
In a way I feel like I am going about this project backwards. I have not done any planning of the architecture for my code. I am not at all certain what it will look like when I'm done. In fact, I don't have the knowledge necessary to do this planning. Instead, I'm gathering this knowledge a I go. I'm concerned that decisions I make regarding the project without full knowledge will cause some portions to be written poorly and will likely need to be rewritten once I have a better understanding of the project.
bibliography:
http://wiki.nesdev.com/w/index.php/INES -- a nice introduction to the ines file format.
http://fms.komkon.org/EMUL8/HOWTO.html -- I am not reading anything too specific regarding nes emulation yet. This is a very high level guide to emulation.
http://www.cecs.csulb.edu/~hill/cecs497/nestreme/howto.html -- this is a pretty general introduction to NES emulation.
I've been talking about roms a lot without really describing what they are. Roms are essentially a file that represents all of the data for a particular program. In the case of the NES, this would be all of the data from the cartridge that is inserted into the NES. Most of this data represents the program code, but also contained in the cartridge and in the rom file are the 8x8 pattern tiles that make up the visual portions of the game. It appears that most NES roms downloadable from the internet are stored in ines format. INES was an early NES emulator. I don't know very much about how it gained dominance in the NES rom market. However, my test rom appears to be in ines format, so this appears to be the format I will be supporting in my emulator. The .nes file I currently search for in the zipped rom is an ines file.
In a way I feel like I am going about this project backwards. I have not done any planning of the architecture for my code. I am not at all certain what it will look like when I'm done. In fact, I don't have the knowledge necessary to do this planning. Instead, I'm gathering this knowledge a I go. I'm concerned that decisions I make regarding the project without full knowledge will cause some portions to be written poorly and will likely need to be rewritten once I have a better understanding of the project.
bibliography:
http://wiki.nesdev.com/w/index.php/INES -- a nice introduction to the ines file format.
http://fms.komkon.org/EMUL8/HOWTO.html -- I am not reading anything too specific regarding nes emulation yet. This is a very high level guide to emulation.
http://www.cecs.csulb.edu/~hill/cecs497/nestreme/howto.html -- this is a pretty general introduction to NES emulation.
Saturday, August 21, 2010
beginnings
I am creating this blog mostly as a means of logging my progress in a personal project of mine. The basic goal of the project is writing an NES emulator in java which I plan to release as open source. This is a fairly ambitious project. While I've been working as a professional developer for approximately 5 years, I don't know very much about emulation. Also, while I know a little bit about assembly programming, I'm hardly an expert. The majority of my programming experience has been with higher level languages. Couple these things with the fact that I don't know very much about NES architecture and it's plain to see that there's going to be a significant learning curve involved with this project.
This project came to my mind about five years ago. I was reading an article on slashdot. I think it was an Ask Slashdot article in which the writer was a new computer science graduate who had recently graduated and was kind of concerned about how much they didn't know about computer science. They mentioned that they had no idea how emulators worked. This resonated a lot with me. I was a new computer science guy myself who had just gotten hired to do java programming for a place in town. I was a little bit overwhelmed with my new position and like the guy in the article was kind of concerned about how much I didn't know about computer science. One of the guys in the article recommended looking at some open source emulators. This struck me as a great idea. I'm a java guy and I found an open source NES emulator written in java. I think it was called nesticle. I took a look at it, but not so much that I really understood it. There's a significant amount of knowledge that I don't have to truly understand the code. I might understand the general concepts behind what it's trying to do, but I don't understand the architecture it's trying to emulate. It became clear to me that if I wanted to understand what was going on I could either study this code or start writing my own emulator. I recently decided to do the latter. This is a bit foolhardy and definitely unnecessary, but it sounds fun to me right now.
I see this blog as a means of recording my progress and of connecting the project with the world. That said, I really doubt that anybody will be interested in my project. There exist NES emulators. As I've mentioned, there even exist java based NES emulators. Also, emulator guys are pretty talkative. There is tons of documentation concerning how to write emulators. Especially, it seems, NES emulators. The NES is historically significant architecture. It has been emulated again and again by anyone and everyone. My project isn't going to do anything new. It's just going to do it again largely as a personal learning project. This blog is going to record the day to day progress on the project. Maybe someone will come along who is also trying to learn more about programming or emulation and might be interested in what I'm doing. Toward that end, one of the things I'm planning on doing is keeping an extensive bibliography of the materials that I read in order to educate myself on the information necessary to get the project off the ground. That will probably be of more use to such a person than this blog and the associated code.
I wrote the very first lines of code for the project today. The portion that I have written now largely just opens up a zipped rom, searches for a .nes file, and reads that file. As I understand it, there are two main functions that an NES emulator has to do. The first is to load the rom, the second is to run the code pulled from the rom. Loading the rom is fairly easy. As it stands right now, the code looks for my test rom (super mario bros.), which is hard coded into the main class. I have not yet bothered to code an interface that will allow the user to pick a rom to load. Nor have I coded in support for roms that are not zipped. My test rom is zipped, so this is what I am sticking with for the time being.
There are several things on the agenda:
1. I have not ran my test rom in a known good emulator. Therefore, whether or not my rom is a good test case is questionable.
2. I want to find a decent and free code repository service so that I can store the code for other people to see it if they want.
3. so far as coding goes, I'm not storing the code that I am reading from the rom into anything yet. I'm actually just writing it to the console. My understanding is that I need to read the rom in a fixed increment. 16 bits maybe? All of the instructions are 16 bits, I think, but I'm not quite certain. Also, I'm not sure how the format of the rom is laid out. I am not certain which portions of the rom are sprites, which are instructions, and which are music. I know absolutely nothing about how the music is encoded. It ought to be pretty interesting to figure that out.
4. This blog is great for the day to day recording of my progress, I'm not sure it will fit the bibliography I want to write. We'll see.
Anyway, thanks for reading.
This project came to my mind about five years ago. I was reading an article on slashdot. I think it was an Ask Slashdot article in which the writer was a new computer science graduate who had recently graduated and was kind of concerned about how much they didn't know about computer science. They mentioned that they had no idea how emulators worked. This resonated a lot with me. I was a new computer science guy myself who had just gotten hired to do java programming for a place in town. I was a little bit overwhelmed with my new position and like the guy in the article was kind of concerned about how much I didn't know about computer science. One of the guys in the article recommended looking at some open source emulators. This struck me as a great idea. I'm a java guy and I found an open source NES emulator written in java. I think it was called nesticle. I took a look at it, but not so much that I really understood it. There's a significant amount of knowledge that I don't have to truly understand the code. I might understand the general concepts behind what it's trying to do, but I don't understand the architecture it's trying to emulate. It became clear to me that if I wanted to understand what was going on I could either study this code or start writing my own emulator. I recently decided to do the latter. This is a bit foolhardy and definitely unnecessary, but it sounds fun to me right now.
I see this blog as a means of recording my progress and of connecting the project with the world. That said, I really doubt that anybody will be interested in my project. There exist NES emulators. As I've mentioned, there even exist java based NES emulators. Also, emulator guys are pretty talkative. There is tons of documentation concerning how to write emulators. Especially, it seems, NES emulators. The NES is historically significant architecture. It has been emulated again and again by anyone and everyone. My project isn't going to do anything new. It's just going to do it again largely as a personal learning project. This blog is going to record the day to day progress on the project. Maybe someone will come along who is also trying to learn more about programming or emulation and might be interested in what I'm doing. Toward that end, one of the things I'm planning on doing is keeping an extensive bibliography of the materials that I read in order to educate myself on the information necessary to get the project off the ground. That will probably be of more use to such a person than this blog and the associated code.
I wrote the very first lines of code for the project today. The portion that I have written now largely just opens up a zipped rom, searches for a .nes file, and reads that file. As I understand it, there are two main functions that an NES emulator has to do. The first is to load the rom, the second is to run the code pulled from the rom. Loading the rom is fairly easy. As it stands right now, the code looks for my test rom (super mario bros.), which is hard coded into the main class. I have not yet bothered to code an interface that will allow the user to pick a rom to load. Nor have I coded in support for roms that are not zipped. My test rom is zipped, so this is what I am sticking with for the time being.
There are several things on the agenda:
1. I have not ran my test rom in a known good emulator. Therefore, whether or not my rom is a good test case is questionable.
2. I want to find a decent and free code repository service so that I can store the code for other people to see it if they want.
3. so far as coding goes, I'm not storing the code that I am reading from the rom into anything yet. I'm actually just writing it to the console. My understanding is that I need to read the rom in a fixed increment. 16 bits maybe? All of the instructions are 16 bits, I think, but I'm not quite certain. Also, I'm not sure how the format of the rom is laid out. I am not certain which portions of the rom are sprites, which are instructions, and which are music. I know absolutely nothing about how the music is encoded. It ought to be pretty interesting to figure that out.
4. This blog is great for the day to day recording of my progress, I'm not sure it will fit the bibliography I want to write. We'll see.
Anyway, thanks for reading.
Subscribe to:
Posts (Atom)