6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 6:36 am

All times are UTC




Post new topic Reply to topic  [ 32 posts ]  Go to page 1, 2, 3  Next
Author Message
 Post subject: Questions
PostPosted: Tue Feb 14, 2006 2:46 pm 
Offline

Joined: Tue Feb 14, 2006 2:36 pm
Posts: 11
Hello Everyone. Some of you may already know me as WedNESday from the nesdev forums. I have some 6502 questions that are better asked here than there. This is for my 6502 emulator;

1. What are the Power Up values of the registers/memory?

2. Is the Interrupt Disable flag set on a RESET/NMI?

3. In decimal the N, V and Z flags are not set on ADC/SBC. But are they cleared?

4. What are the differences between 6502 and 6502A (or other numbers/letters)?

5. Are all 6502 models the same no matter whom the manufacturer? (as my 6502 emulator is for the Acorn Electron, C64 and NES)

6. When a KIL/JAM/HLT instruction occurs can the CPU recover with an interrupt? If so, should the return address be greater by 1? Before an interrupt occurs, should I just increase the Clock Cycle counter by 1 until one does occur?


Top
 Profile  
Reply with quote  
 Post subject: Re: Questions
PostPosted: Tue Feb 14, 2006 6:14 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Alucard wrote:
1. What are the Power Up values of the registers/memory?


NMOS version is undefined. CMOS version, I believe, zeros out all the registers, except for S, which is set to $0100. I could be wrong though; I don't have the 65C02 manual in front of me at the moment.

Quote:
Is the Interrupt Disable flag set on a RESET/NMI?


Yes.

Quote:
In decimal the N, V and Z flags are not set on ADC/SBC. But are they cleared?


Undefined.

Quote:
What are the differences between 6502 and 6502A (or other numbers/letters)?


Speed. 6502 was rated at 1MHz, 6502A was rated at 2MHz. This was a common practice back in the 70s, but was abandoned during the mid-80s as the CPU clock speed race (especially in the Intel camp) took off. It became impractical to use alphabetic suffices for speed grades.

Quote:
Are all 6502 models the same no matter whom the manufacturer? (as my 6502 emulator is for the Acorn Electron, C64 and NES)


No. The Commodore 64 used a 6510 which has an internal I/O port that the 6502 doesn't (hence, locations $00 and $01 were not normal RAM locations). Additionally, the 6510 has undocumented opcodes that are not compatible with the WDC 65C02 (used in the Apple IIc and future products). The NES lacks decimal-mode all-together. Etc.

It's best to consult the specific platform's documentation for details.

I should note that Commodore's CPUs were considered the benchmark/canon implementations of the various CPUs, because Commodore Semiconductor Group bought out MOS Technology (the manufacturers and incubator of the 6502 architecture itself). The current authority on the 6502/65816 architecture now that Commodore is no more is Western Design Center, where Bill Mensche (CEO, and co-inventor of the 6502) is working to continue the product line (and quite successfully too!).

Quote:
When a KIL/JAM/HLT instruction occurs can the CPU recover with an interrupt?


No, because the internal state machine of the CPU itself is what's jammed. Only a hard reset can bring the CPU back to life.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Feb 14, 2006 8:42 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
> > 1. What are the Power Up values of the registers/memory?
>
> NMOS version is undefined. CMOS version, I believe, zeros out
> all the registers, except for S, which is set to $0100. I could
> be wrong though; I don't have the 65C02 manual in front of
> me at the moment.

I've never seen anything in any of the data sheets about initial values of A, X, Y, and most of the flags, or even S. Both NMOS and CMOS set the interrupt-disable flag and load PC with the reset vector. The CMOS versions also clear the decimal flag.


> 2. Is the Interrupt Disable flag set on a RESET/NMI?

Yes, and IRQ as well.


> 3. In decimal the N, V and Z flags are not set on ADC/SBC. But
> are they cleared?

They will be affected by ADC & SBC, but invalid. Is that your understanding, kc5tja? (but undefined at reset.) With the CMOS versions, Z will be correct. V and N follow the logic rules for them, but probably will not be relevant. In signed decimal arithmetic, I would take N=1 (negative numbers to mean 50-99), but N just reflects the high bit status, which means decimal 80-99.


> 5. Are all 6502 models the same no matter who the
> manufacturer? (as my 6502 emulator is for the Acorn Electron,
> C64 and NES)

If you specifically want to make an emulator (although I suspect you mean a simulator, which is all software, unlike the emulator) for just the NMOS ones, that's one thing. But do be aware that the CMOS 6502 not only takes a lot less power, but has the bugs and quirks fixed and has more instructions and addressing modes. Also:
    RDY is bidirectional now, pulled low internally by the WAIt instruction
    RDY can be used to stop write instructions too
    there's an onboard oscillator which you can use with a crystal or RC
    an outboard clock source can be a simple, single-phase square wave
    clock can be stopped indefinitely
    Unused input pins like NMI have internal pull-ups so you don't need the external resistor or connection
    RST is a schmitt-trigger input
    RST can be held low indefinitely, unlike the NMOS which should not be held low more than 50ms.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Feb 14, 2006 9:30 pm 
Offline

Joined: Tue Feb 14, 2006 2:36 pm
Posts: 11
Thanks for the replies. Just to clarify one thing though. You all say that the N, V and Z flags are undefined in decimal ADC/SBC. Currently, I clear the three flags whenever a ADC/SBC opcodes is encountered. If decimal mode is set then they are not affected. Is this right? Or do the flags equal something random?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Feb 14, 2006 9:51 pm 
Offline

Joined: Sat Jan 04, 2003 10:03 pm
Posts: 1706
Alucard wrote:
Thanks for the replies. Just to clarify one thing though. You all say that the N, V and Z flags are undefined in decimal ADC/SBC. Currently, I clear the three flags whenever a ADC/SBC opcodes is encountered. If decimal mode is set then they are not affected. Is this right? Or do the flags equal something random?


Well, the three flags are probably set as if the ALU were working in binary mode. That is, if the most significant digit is 8 or 9, then N flag is set, else clear. It's not that they're just random, but rather, they don't mean anything useful in decimal mode, since overflow on a BCD number is different from overflow on a binary number. And there are two methods of representing negative BCD numbers: 10s compliment and an explicit flag. ADC/SBC appears to be able to handle both.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Tue Feb 14, 2006 10:46 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Regarding V: I think you'll be interested in the discussion we had at http://www.6502.org/forum/viewtopic.php?t=254 (which is two pages so far). Do read through completely though, because some of the things initially posted seemed to be erroneous and we got that figured out as the discussion progressed.

There is a V flag tutorial at http://www.6502.org/tutorials/vflag.html .


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Feb 15, 2006 6:30 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
Alucard wrote:
If decimal mode is set then they are not affected. Is this right?


The N, V, and Z flags are always affected in decimal mode. The accumulator always contains the correct BCD arithmetic result, but the flags do not always reflect the accumulator contents. For example, after a SBC of 1 - 1 = 0, the Z flag will be one, but after an ADC of 99 + 1 = 0, the Z flag will be zero in decimal mode.

I've got a write up about decimal mode that I haven't gotten around to finishing. It includes a program intended for writing and checking simulators. It's a 6502 assembly program that uses binary arithmetic to replicate the N, V, and Z flag results that would occur in decimal mode then checks this with the actual flag results in decimal mode. Thus, you can check your simulator to make sure it replicates decimal arithmetic behavior completely. You can also copy the program logic into the simulator itself to calculate the N, V, Z, results in decimal mode. It's not documented well at the moment, but there's nothing intentionally tricky. I can send you the source code if you'd like. The code I posted in the thread Garth mentioned gives the flavor of how it works.

Since the N, V, and Z flag results in decimal mode fall under the category of undocumented behavior, to me, it is fair game if a simulator does NOT replicate this or any other undocumented behavior. However, there are a few programs that do make use of specific instances of undocumented behavior. For example, one method for distiniguishing a (NMOS) 6502 from a 65C02 is to use an ADC of 99 + 1 in decimal mode and look at the Z flag result (which will be zero on a 6502 and one on a 65C02).

kc5tja wrote:
Well, the three flags are probably set as if the ALU were working in binary mode.


This is true for N, V, and Z with SBC, and Z with ADC. For N and V with ADC, the method given for predicting V in the thread Garth mentioned will also work for predicting Z. Also, appendix B in the V flag tutorial Garth mentioned discusses V in decimal mode, and it goes through a few examples.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Feb 15, 2006 11:37 am 
Offline

Joined: Tue Feb 14, 2006 2:36 pm
Posts: 11
So are they sometimes set correctly, and other times not? When are the N and V flags set when decimal mode is on because it can't be the same as binary mode. I am still confused right now so I will post some of my code. BCDAccumulator and BCDByte make sure that the number is not hexadecimal.

Code:
inline void OpticCode69()
{
   CPU.Byte = CPU.Memory[Immediate];
   CPU.P &= 0x3D;
   if( CPU.P & 0x08 )
   {
      BCDAccumulator();
      BCDByte();
      if( CPU.A + CPU.Byte + (CPU.P & 0x01) > 0x99 )
         CPU.TMP = 1; else CPU.TMP = 0;
      CPU.A += CPU.Byte + (CPU.P & 0x01);
      BCDAccumulator();
      CPU.P &= 0xFE;
      CPU.P += CPU.TMP;
   }
      else
   {
      // Omitted...
   }
   CPU.PC += 2;
   CPU.CC += 2;
}


The N, V and Z flags are never set. Would this be acceptable?


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Feb 15, 2006 8:16 pm 
Offline

Joined: Tue Dec 30, 2003 10:35 am
Posts: 42
If you're writing a software version of a particular variant of the 6502, it should do whatever the actual 6502 would do for ADC/SBC in decimal mode (even if it's odd or seems incorrect), since code you're running could depend on whatver values the actual 6502 would put into the status flags after those operations.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Feb 15, 2006 9:33 pm 
Offline

Joined: Tue Feb 14, 2006 2:36 pm
Posts: 11
Hey blargg it's your best buddy (lol...) from nesdev here WedNESday.

My 6502 emulator is not just for the NES it is for any system so there are no specifics. I still feel that my questions have been unanswered though. I know that N, V and Z are undefined in decimal ADC/SBC, so if we tried...
Code:
SED
LDA #$50
ADC #$50


...ten times would the results be random? e.g. first time around 3/10 the zero flag was set, the second time around 5/10 the zero flag was set etc. etc.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Wed Feb 15, 2006 10:01 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
I don't have any practical way right now to actually try this on an NMOS 6502, but I'm sure the results will not be random. I'm sure the flag results of any given repeated operation will be consistent, but as kc5tja said above, they just won't mean anything useful in decimal mode.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 16, 2006 12:16 am 
Offline

Joined: Tue Dec 30, 2003 10:35 am
Posts: 42
Quote:
My 6502 emulator is not just for the NES it is for any system so there are no specifics.


Each system does have specific behavior (perhaps different than another), so how are you going to manage being unspecific? It seems to me that your 6502 emulator will need compile-time option flags to select between the different behaviors of variants (for example, the lack of decimal mode on NES).

Quote:
I know that N, V and Z are undefined in decimal ADC/SBC


Undefined = not defined; it doesn't mean random. It most likely means "whatever values get put there as a result of the processor design". A programmer can usefully avoid depending on these results, but an accurate simulator should duplicate whatever the actual hardware does in each case. I wouldn't be surprised if different versions of the 6502 had different behaviors for things like undefined flags and opcodes.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 16, 2006 6:15 am 
Offline
User avatar

Joined: Thu Mar 11, 2004 7:42 am
Posts: 362
Read the thread Garth mentioned. To calculate the accumulator result and the carry you use one set of rules. There is a different set of rules for the other flags. With the same inputs you get the same results every time.

In my post about halfway down the first page in the other thread there are two programs given, and a list of seven steps for determining the V flag in decimal mode. Those same seven steps can be used to predict the value of the ADC N flag result in decimal mode -- just subtitute N for V in steps 6 and 7. The other 4 undocumented cases -- the SBC N, V, and Z flag results, and the ADC Z flag result -- are the same as if the two numbers were subtracted (SBC) or added (ADC) in binary mode. In other words, the Z flag after:

Code:
SED
CLC
LDA #$50
ADC #$50


is the same as the Z flag after:

Code:
CLD
CLC
LDA #$50
ADC #$50


So, in both cases the Z flag will be zero (i.e. BNE will branch). To summarize:

After ADC:

Accumulator: determined by BCD addition result
C flag: determined by BCD addition result
N flag: see the seven step method in the other thread
V flag: see the seven step method in the other thread
Z flag: same value as when the two numbers are added in binary mode

After SBC:

Accumulator: determined by BCD subtraction result
C flag: determined by BCD subtraction result
N flag: same value as when the two numbers are subtracted in binary mode
V flag: same value as when the two numbers are subtracted in binary mode
Z flag: same value as when the two numbers are subtracted in binary mode

You can use this infomation to synthesize the decimal mode flag results using only binary arithmetic. That is what the two programs mentioned earlier do.

On the 6502, the only documented behavior is the accumulator result and the carry flag when given valid BCD numbers (i.e. both BCD digits are in the range 0-9). So, a simulator can be considered "correct" if these cases give the correct result. However, as blargg mentioned, it can be useful to replicate the undocumented behavior, since there are programs out there that use undocumented decimal mode behavior. Relying on undocumented behavior does not make for a robust program, so when such a program doesn't behave as expected on a simulator, to me, that is a problem with the program, not the simulator. Anyway, here are a couple of examples:

Example #1: distinguishing a 6502 from a 65C02.

Code:
CLC
LDA #$99
ADC #$01
BEQ THIS_IS_A_65C02 ; or it's a 65802 or a 65816
BNE THIS_IS_A_6502


The ADC clears Z flag on a 6502, but sets the Z flag on a 65C02. This is undocumented behavior on a 6502, but it IS documented behavior on a 65C02.

Incidentally, if you always cleared the Z flag in decimal mode, this particular example would still behave correctly.

Example #2: converting a hex digit 0-F to ASCII

A straightforward way to convert $00-$09 to $30-$39 and $0A-$0F to $41-$46 is:

Code:
     CMP #$0A
     BCC SKIP
     ADC #$06 ; this adds 7 since the carry is set
SKIP ADC #$30


A couple of bytes can be saved by resorting to undocumented behavior:

Code:
SED
CMP #$0A
ADC #$30
CLD


In this version, the undocumented behavior relied upon is addition when one of the digits in the range A-F.

I can't recall any other examples off the top of my head. There is very little existing code that would be broken by not replicating undocumented behavior.

If you have additional questions feel free to ask. I've worked out all of the cases for 8-bit and 16-bit (i.e. on the 65816 when the m flag is zero) decimal mode addition and subtraction and have verified every possible combination on the 6502 (Rockwell and Synertek), the 65C02, and the 65816 works as I've described. Now if only I'd stop writing long-winded forum posts and finish the decimal mode write-up... :)


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 16, 2006 6:11 pm 
Offline

Joined: Sun Feb 05, 2006 1:20 am
Posts: 21
Location: The Netherlands
blargg wrote:
Undefined = not defined; it doesn't mean random. It most likely means "whatever values get put there as a result of the processor design".

I think undefined actually means, "whatever values the manufacturer means you to ignore". Even if the flag states were random, it wouldn't make a difference. They'd still be undefined.

There is no such thing as "undefined instructions" either. They only exist in the minds of those who claim having discovered them and should never be relied on.

_________________
I trust my somewhat flawed English is comprehensible to all.


Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: Thu Feb 23, 2006 4:53 pm 
Offline

Joined: Tue Feb 14, 2006 2:36 pm
Posts: 11
Thanks for the responses, I have some more questions;

1. Is the accumulator converted to a BCD number if the Decimal flag is set and it contains a non decimal number?

2. With illegal opcode AAX, do you set the N and Z flags? Half the documents say yes and the other half say no.

3. How is the N flag affected on illegal opcodes that make a shift right 1-bit at the last moment? Do you check for the MSB before the shift? For example;

Code:
A &= Immediate;
A >>= 1; // MSB == 0


4. Are illegal opcodes that contain things like DEC + ADC/SBC affected by the Decimal flag? (i.e. do you check for the flag and then do the same as you would in ADC/SBC)


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 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: