64doc has a good description of exactly what the NMOS 6502s do in BCD mode:

https://github.com/ahefner/tenes/blob/m ... /64doc.txtThe CMOS parts work differently for BCD, but a lot of sources are a bit vague about the details, so I thought I'd paste the following from my (new, upcoming...) BBC emulator. Hopefully it should be obvious what's going on and easy to modify for use elsewhere.

I've checked this against results from my Master 128, and it passes the Klaus Dormann CMOS tests, so it ought to be correct! (Results from my cheese wedge 2nd processor and ReCo6502Mini were the same.)

Code: Select all

`static void ADC_CMOS(M6502 *s) {`

if(s->p.bits.d) {

unsigned tmp=(s->a&0xfu)+(s->data&0xfu)+s->p.bits.c;

if(tmp>9) {

tmp+=6;

}

if(tmp<=0xf) {

tmp=(tmp&0xf)+(s->a&0xf0)+(s->data&0xf0);

} else {

tmp=(tmp&0xf)+(s->a&0xf0)+(s->data&0xf0)+0x10;

}

s->p.bits.v=((s->a^tmp)&(~s->a^s->data)&0x80)!=0;

s->p.bits.c=0;

if((tmp&0x1f0)>0x90) {

tmp+=0x60;

s->p.bits.c=1;

}

s->a=(uint8_t)tmp;

SetNZ(s,s->a);

} else {

M6502Word result;

result.w=s->a+s->data+s->p.bits.c;

SetNZ(s,result.b.l);

s->p.bits.c=result.b.h>0;

s->p.bits.v=(~(s->a^s->data)&(s->a^result.b.l)&0x80)!=0;

s->a=result.b.l;

}

}

static void SBC(M6502 *s) {

M6502Word result;

result.w=s->a+(uint8_t)~s->data+s->p.bits.c;

if(s->p.bits.d) {

unsigned tmp=(s->a&0xfu)-(s->data&0xfu)-(!s->p.bits.c);

if(tmp&0x10) {

tmp=((tmp-6u)&0xfu)|((s->a&0xf0u)-(s->data&0xf0u)-0x10u);

} else {

tmp=(tmp&0xfu)|((s->a&0xf0u)-(s->data&0xf0u));

}

if(tmp&0x100) {

tmp-=0x60;

}

SetNZ(s,result.b.l);

s->p.bits.c=result.b.h>0;

s->p.bits.v=(((s->a^result.b.l)&0x80)&&((s->a^s->data)&0x80))!=0;

s->a=(uint8_t)tmp;

} else {

SetNZ(s,result.b.l);

s->p.bits.c=result.b.h>0;

s->p.bits.v=((s->a^s->data)&(s->a^result.b.l)&0x80)!=0;

s->a=result.b.l;

}

}

I've got a strong feeling that I ended up copying this from somewhere, but I can't remember where

- my recollection being that I started with the 64doc code and the results from my Master, and that it was mostly obvious what was going on, but there were still a few cases that I couldn't seem to figure out on my own.

I also note (when I checked just now) that it's a bit uglier than the code in jsbeeb, or

Hoglet's post, etc., so maybe I need to think about copying from them instead