lee@chsun1.uchicago.edu (Dwight A Lee) (02/19/91)
I'm writing a function in C which needs to behave exactly like a 65C02 ADC (add with carry). Unfortunately, I am unable to find out just how the N (negative) and V (overflow) processor flags are set when the processor is in decimal mode. Either direct information or pointers to information sources would be appreciated. I seem to recall reading in Litchy & Eyes (_Programming the 65816_) that N and V were not used in decimal-mode ADC on the 6502, but that this was corrected in the 65C02 and later 65 processors. On a related note, how would negative decimal numbers be represented? Is there a standard way? If 99, for example, was used as a -1, wouldn't this limit one-byte representations to a single digit (for posible multiple-byte calculations) or to a lopsided range (if the high bit is used as in binary mode)? Thanks for any information. Email or post. Net summary will be provided if more than two "me too" requests are received. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Dwight A Lee / lee@chsun1.uchicago.edu / T904107@niucs.BITNET / tCS/BB / Font I speak only for myself. / "I am not the only dust my mother raised" - TMBG
hemphill@over.world (Scott Hemphill) (02/19/91)
>>>>> On 19 Feb 91 00:34:54 GMT, lee@chsun1.uchicago.edu (Dwight A Lee) said: > I'm writing a function in C which needs to behave exactly like a 65C02 > ADC (add with carry). Unfortunately, I am unable to find out just how > the N (negative) and V (overflow) processor flags are set when the > processor is in decimal mode. Here is some C code that is straight out of a simulator I have written for the 65c02. I have verified that it gives the correct answers for all possible operands. (Even when adding invalid bcd in decimal mode!) Variables: A the accumulator (an unsigned char) b the other operand (an unsigned char) C the carry flag (0 or 1) D the decimal mode flag (0 or 1) V the overflow flag (0 or 1) w (an unsigned int temporary) NZ the N and Z flags are derived from this unsigned int A word of explation about "NZ": one optimization my simulator makes is to avoid computing the N and Z bits unnecessarily. I do this by storing an intermediate value in NZ. If I need to compute "N" or "Z" later, I can do so. "N" is equivalent to (NZ >= 0x80) and "Z" is equivalent to ((Z & 0xff) == 0). Anyway, here's the code: #define ADC() \ do { \ if ((A^b) & 0x80) V = 0; else V = 1; \ if (D) { \ w = (A & 0xf) + (b & 0xf) + C; \ if (w >= 10) w = 0x10 | ((w+6)&0xf); \ w += (A & 0xf0) + (b & 0xf0); \ if (w >= 160) { \ C = 1; \ if (V && w >= 0x180) V = 0; \ w += 0x60; \ } else { \ C = 0; \ if (V && w < 0x80) V = 0; \ } \ } else { \ w = A + b + C; \ if (w >= 0x100) { \ C = 1; \ if (V && w >= 0x180) V = 0; \ } else { \ C = 0; \ if (V && w < 0x80) V = 0; \ } \ } \ A = w; \ NZ = A; \ } while (0) -- Scott Hemphill hemphill@csvax.cs.caltech.edu ...!ames!elroy!cit-vax!hemphill