News: 11 March 2016 - Forum Rules, Mobile Version
Current Moderators - DarkSol, KingMike, MathOnNapkins, Azkadellia

Recent Posts

Pages: [1] 2 3 4 5 6 ... 10
I agree that reform is usually better than revolution.

The French could have had a more stable transition, had Honoré Mirabeau lived longer. The British Empire, which was aristocratic, managed to expand "democracy" over a gradual period of time. The French are much given to upheaval, though.

India breaking from the British Empire was somewhat inevitable (the whole trend of decolonisation). Muslims are not really part of Indian (Vedic) culture, though; they only got there through the Mughal invasion. On a side note, I think that the British leadership should have had more vision and kept the culturally Western parts of the Empire together.

Russia is somewhat different, in that their culture demands a tsar-like figure of some kind or another; still, that could have been handled better.

I'm surprised you didn't mention Germany. Overthrowing the Kaiser led to the disastrous Weimar Republic.
General Discussion / Re: General Chatter
« Last post by RandomHeretic on Today at 03:52:19 am »
After that comment I suppose next you'll be suggesting a Presidential run?

My anonymous sources tell me that you'll be running against Mark Zuckerberg. Confucius says git gud ;)
Personal Projects / Re: Castlevania - Cadence Of Agony Linear Reboot
« Last post by Sephirous on Today at 03:39:19 am »

Photobucket is telling me I've shared too many photos and they want money now.

This sucks. It has been fine all along. I'll have to delete some of the photos and remove them from my forum posts to avoid clutter.

I'll do it in the morning.  :banghead:
General Discussion / Re: Games banned from Turkey
« Last post by SunGodPortal on Today at 02:39:51 am »
Maybe they are thinking it is Political Action Committee-Man.
Finally an excuse to invade Canada?

Yes. We will be confiscating all of their "Canadian bacon", which we all know is just ham. They're not fooling anyone.
not gonna lie, i read that as babadook
:D and what does Babadook mean?!

Well done! The translation is of really nice quality. Great job translating all those early Famicom games, although I do believe that the most interesting stuff is still ahead of you. :)

Thanks! :) I know that some of the early games haven't been done because they don't excite people's interests as much, but nevertheless I think it's a good goal to aim for. I learnt a lot from Gomoku Narabe Renju, and I learnt significantly more from this. It'll help me going forward. Now I need to decide what comes next! :)
Well done! The translation is of really nice quality. Great job translating all those early Famicom games, although I do believe that the most interesting stuff is still ahead of you. :)
This project looks great so far! Keep up the good work! Do you guys plan to add a VWF?
Been awhile since an update. Unfortunately I haven't been able to work on this in any meaningful way in about a month. Just some minor code cleaning. Before that though, I did implement a plugin system sufficient enough for external file loaders. The Managed Extensibility Framework (MEF) really worked wonders and I recommend it to anybody thinking about implementing a plugin system for .NET. I made a TIM loader/searcher as a proof of concept.

I'm currently stuck on a design decision regarding how tiled and linear graphics should interact with palettes from a UI and XML standpoint. In particular, tiled graphics are currently 1:1 with palettes but linear graphics (such as TIMs) can have several palettes. I'll resume work once I have an elegant (or at least clean) solution and free time.
Programming / Re: ELI5: Nerdy Nights Week 3
« Last post by Disch on Today at 01:26:52 am »
Klarth's reply is good, and I don't mean to step on his toes here, but I felt I could elaborate on a few things a bit:


I wouldn't worry about these until you get a very basic "hello world" program running and understanding how that works.

NMIs and IRQs are "interrupts".  As Klarth mentioned, these are external signals that are used to "cut into" or "interrupt" the running program to let you know that a certain event has happened.

NMIs and IRQs are mostly the same, but with some minor differences:

- The 'I' processor flag (see CLI/SEI instructions) will prevent IRQs from occurring, but will not stop NMIs.
- IRQs go the the IRQ vector ($FFFE) when they happen, whereas NMIs go to the NMI vector ($FFFA)
- On the NES, NMIs are used exclusively for notifying you when VBlank happens, whereas IRQs have various mapper-specific uses (though virtually all of them are raster related, like letting you know when a specific scanline is starting)

You can think of it this way -- the CPU is always running instructions.  When an interrupt happens, the CPU will stop running code from it's current position, and will jump to a new position (designated by the address in the NMI/IRQ vector).  Once you do an RTI, the interrupt code will stop, and the CPU will jump back to the code it was running before the interrupt happened.

Basically interrupts cause the system to jump to new code when something significant happens.  But to really understand why that's useful, you need to understand the basics of timing.  Which is not a topic I would recommend until you've got the basics of displaying a simple image on screen.


clrmem is clearing memory (RAM).

On the NES, RAM resides between the $0000-07FF address range.  On powerup, this RAM contains unreliable garbage, so it's good practice to clear it (set it all to zero) before using any of it.  clrmem accomplishes this with a basic loop:

Code: [Select]
; It's not mentioned, but for this loop to work properly, X must be 0 at the start
;   It is 0 in the code (due to the INX on line 19) but it's not exactly clear...

  LDA #$00          ; sets A=0
  STA $0000, x      ; writes A (0) to address $0000+X
  STA $0100, x      ; then to $0100+X
  STA $0200, x      ; then to $0200+X
  STA $0400, x      ; etc...
  STA $0500, x
  STA $0600, x
  STA $0700, x
  LDA #$FE
  STA $0300, x      ; then writes $FE to address $0300+X
  INX               ; Increments X
  BNE clrmem        ; Jumps back until X is zero, which won't happen until it wraps from $FF->$00

The loop works like so:  Each time the code runs (each "iteration" of the loop), 'X' will be a new value (one higher than it was before).  So "STA $0000,X" will write to address $0000 the first iteration, but will write to address $0001 the next time (because X=1), then $0002 the time after that (because X=2), and so on.

The last iteration, X will be $FF... which will write to $00FF.  Then, once it hits that INX, since X is only 8-bits wide, it will wrap from $FF to $00, resulting in the Z flag being set, and the BNE to not branch, allowing the code to exit the loop.

The end result is that all addresses in the $0000-07FF range get zero written to them (with the exception of the $0300-03FF page, which gets $FE written to it instead).

If might help to run this code in FCEUX and step through it line by line with the hex editor open so you can see how memory changes with each STA.

Why certain addresses need to be written to

This is a pretty generic question, as you don't specify which addresses you're talking about.

Klarth linked to the memory map, which is a good general outline.  But if you want more details about what certain addresses do, you can look at the nesdev wiki.  In fact, you might want to see if you can find answers to any questions on the nesdev wiki.

PPU (graphics) registers:

APU (sound) registers (I wouldn't worry about this for now -- get graphics working first):


The stack

Klarth did a good job explaining the basics of what the stack is.

Only other thing worth noting is that the NES pushes values to the stack to "remember" where you came from when you do a JSR (or when an interrupt happens).  That way when you RTS/RTI, the CPU will pop values off the stack to know where to jump back to.


BIT is an awkward and not frequently used instruction.  The way it's being used in that code, LDA would do the same thing and would be much, much less confusing for newbies.  My advice is to replace the BIT with an LDA in the code, and don't worry about understanding BIT until you're more comfortable with the system.

BPL is a branch that examines the 'N' status flag.  Most instructions will modify 'N' according to the high bit (bit 7:  "$80") of the resulting value.  For example, with LDA (and BIT) if the high bit of the value you read was set, so too will the N flag be set.  Likewise if the high bit was cleared, so too will the N flag be cleared.

BPL will branch (jump) if the N flag is clear.

Therefore this loop:
Code: [Select]
  LDA $2002     ; (or BIT $2002)
  BPL vblankwait 1

Is effectively polling the $2002 register (aka PPUSTATUS) hundreds of times to examine the high bit (VBlank flag)... and keeps looping until that flag is set, at which point N will be set and the loop will exit.

This is a common way to wait for VBlank during startup -- but don't rely on it at any other time, as the VBlank flag is unreliable.  When you get to the point where VBlank matters -- you'll want to use NMIs.  However, don't worry about that yet -- just get something drawing first.
Pages: [1] 2 3 4 5 6 ... 10