It is currently Fri Dec 15, 2017 8:30 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri May 12, 2017 9:32 am 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
The first instructions in the rom for Donkey Kong are the following:

SEI
CLD
LDA 10
STA $2000
LDX ff
TXS
LDA $2002
AND 80, imm
BEQ f9, imm

Since BEQ branches if the zero flag is set, and $2002 is 0 initially, LDA sets the zero flag when it executes. BEQ then branches 7 bytes back to the LDA command, and it loops forever like this. Am I doing something wrong, or is the CPU waiting for some signal from the PPU here? (I know that $2000-$2007 are PPU registers, and since $2002 is being read, the CPU could be waiting for something?)


Top
 Profile  
 
PostPosted: Fri May 12, 2017 9:37 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10165
Location: Rio de Janeiro - Brazil
PolarBITS wrote:
is the CPU waiting for some signal from the PPU here?

Yes, it's waiting for the PPU to signal that vblank has started.

Since you're apparently coding an NES emulator, it might be a good idea to familiarize yourself with the basic architecture of the system, otherwise you'll run into all sorts of little surprises like this.

Quote:
(I know that $2000-$2007 are PPU registers, and since $2002 is being read, the CPU could be waiting for something?)

When in doubt, look at the PPU's documentation to see what bits of which register are being used/watched, and you should get a better idea of what the code is trying to do.


Top
 Profile  
 
PostPosted: Fri May 12, 2017 6:44 pm 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
I'm looking at the PPU documentation and I'm a bit confused. STA writes 0x10 (16 in decimal and 00010000 in binary) to address $2000. The byte that controls vblank is the first one, byte 7, yet it seems to be set to 0. What am I missing?


Top
 Profile  
 
PostPosted: Fri May 12, 2017 6:50 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10165
Location: Rio de Janeiro - Brazil
PolarBITS wrote:
The byte

You mean bit. Anyway, that bit controls whether the PPU generates an NMI every time vblank starts, not whether vblanks happen. Even if NMIs are turned off, vblanks will still happen, and their occurrence will be signaled in bit 7 of register $2002.


Top
 Profile  
 
PostPosted: Fri May 12, 2017 6:54 pm 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
Right. Nothing seems to be writing anything to bit 7 of $2002 though.


Top
 Profile  
 
PostPosted: Fri May 12, 2017 6:56 pm 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
Hold on nevermind it's usually set at powerup. I'm dumb lol


Top
 Profile  
 
PostPosted: Fri May 12, 2017 7:14 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10165
Location: Rio de Janeiro - Brazil
$2002 is a read-only register. Games read it to get information about what the PPU is doing, they aren't supposed to write to $2002.


Top
 Profile  
 
PostPosted: Fri May 12, 2017 8:16 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10165
Location: Rio de Janeiro - Brazil
One thing that's important to note it's that memory-mapped registers are NOT memory. They are "ports" that allow the CPU to communicate with other parts of the hardware, such as the PPU and the APU. The CPU writes to these ports to send messages, but the written values are not stored in actual memory locations that can be read back. The CPU can also read from certain registers to receive messages from other parts of the system, and this is different from a memory read, because what you get is a dynamic value supplied by the hardware being pooled, not a static byte that was previously stored in a memory location.


Top
 Profile  
 
PostPosted: Sat May 13, 2017 9:15 am 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
After the BEQ I have the following instructions:

LDY 07, imm
STY 01, zp
LDY 00, imm
STY 00, zp
LDA 00, imm
STA 00, indY
DEY
BNE fb, imm
DEC 01, zp
BPL f7, imm

This still results in an infinite loop for me. If I'm getting it right, the following happens:

7 is stored in Y
Y is stored in $0001 (value of $0001 is now 7)
0 is stored in Y
Y is stored in $0000 (value of $0000 is now 0)
0 is stored in A
A is stored in the value at $0000 plus Y (therefore A is stored in $0000, same effect as above)
Y is decremented (Y is now -1 and the Negative flag is set)
The program branches back to (STA 00), because the negative flag is set.

This causes another infinite loop. What's the problem here?


Top
 Profile  
 
PostPosted: Sat May 13, 2017 10:39 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5898
Location: Canada
PolarBITS wrote:
Y is decremented (Y is now -1 and the Negative flag is set)
The program branches back to (STA 00), because the negative flag is set.

This causes another infinite loop. What's the problem here?

BNE does not branch on negative, BNE branches on not-zero. It is the opposite of BEQ. (BNE = branch not equal, BEQ = branch equal. Would have been nicer if they were named BZC and BZS maybe?)

BMI branches on negative (branch minus), and BPL branches on positive (branch plus). (Again, BNS and BNC would have been clearer, IMO.)

DEY will eventally set the zero flag when Y reaches zero. (On the first test it will be $FF = -1, on the 256th test it will be back down to 0.)

DEC $01 will eventually set the negative flag when ($01) rolls over to $FF.


Top
 Profile  
 
PostPosted: Sat May 13, 2017 10:51 am 
Offline

Joined: Tue Aug 12, 2014 11:25 pm
Posts: 9
Location: Sonora, Mexico
Quote:
A is stored in the value at $0000 plus Y (therefore A is stored in $0000, same effect as above)

wrong. Instruction "sta ($00), y" is post indexed indirect, That mean register A is stored in
address "at where" is pointing address $0000 plus y, not address $00 plus y.

address $0000 = 00
address $0001 = 07
register y = 0
sta ($00),y = $0700 + y = $0700

for what I can see this code fill with 0's entirely the main RAM.


Top
 Profile  
 
PostPosted: Sat May 13, 2017 11:02 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5898
Location: Canada
Ah, yeah I figured it was a "clear RAM" loop (PolarBITS seems to be working through a startup sequence), but I had neglected to notice that this loop overwrites its own counters, i.e. $01 is expected to be overwritten with 0 at some point. Interesting that this loop will leave with ($01)=$FF after that last DEC, and it has to write the $00XX page last.

If "indY" meant "indexed Y" it would overwrite $01 right away and the BPL would trigger on the first test, but yeah obviously it is "indirect Y".


Top
 Profile  
 
PostPosted: Sat May 13, 2017 12:37 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10165
Location: Rio de Janeiro - Brazil
This non standard notation threw me off too, I also assumed that was "indexed Y".


Top
 Profile  
 
PostPosted: Sat May 13, 2017 12:38 pm 
Offline

Joined: Mon May 01, 2017 4:11 pm
Posts: 21
rainwarrior wrote:
(On the first test it will be $FF = -1, on the 256th test it will be back down to 0.)
[/quote]

So you're saying that all numbers in RAM are unsigned bytes? I completely forgot about that lol.


Top
 Profile  
 
PostPosted: Sat May 13, 2017 12:44 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 19348
Location: NE Indiana, USA (NTSC)
Everything on a 6502 is unsigned, with the exception of the V flag in ADC, CMP, and SBC. N just means bit 7.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: zxbdragon and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group