Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!jarthur!nntp-server.caltech.edu!nntp-server.caltech.edu!hemphill From: hemphill@over.world (Scott Hemphill) Newsgroups: comp.sys.apple2 Subject: Re: 65C02 ADC in Decimal Mode Message-ID: Date: 19 Feb 91 04:52:00 GMT References: Sender: news@nntp-server.caltech.edu Organization: California Institute of Technology Lines: 57 In-Reply-To: lee@chsun1.uchicago.edu's message of 19 Feb 91 00:34:54 GMT Nntp-Posting-Host: over.cs.caltech.edu >>>>> 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