Z80 DAA (Emulation MSX Fora)MSX Resource Center MSX Info Update - Finnish MSX madness at its best           
            
English Nederlands Español Português Russian         
 Nieuws
   Voorpagina
  Nieuws archief
  Nieuws onderwerpen

 Informatie
   MSX Fora
  Artikelen
  Recensies
  Beursverslagen
  Fotoreportages
  Beurzen en meetings
  Enquêtes
  Links
  Zoek

 Software
   Downloads
  Webshop

 MRC
   Wie we zijn
  Kom bij ons team
  Doneren
  Policies
  Contact met het MRC
  Link naar Ons
  Statistieken

 Zoek
 
  

  

 Login
 

Gebruikersnaam

Wachtwoord




Ben je nog niet lid? Klik hier en word MSX vriend!


 Statistieken
 

Er zijn 130 gasten en 4 MSX vrienden online

Je bent een anonieme bezoeker.
 

MSX Fora


MSX Fora

Emulation - Z80 DAA

Schrijver

Z80 DAA

hap
msx addict
Berichten: 463
Geplaatst: 12 Februari 2007, 14:36   
I'm currently creating a Z80 CPU emulator, using several technical documents, including this: http://wikiti.denglend.net/index.php?title=Z80_Instruction_Set

I noticed blueMSX and openMSX fill a big 4KB lookuptable with an unnecessarily complex calculation, like this (from openMSX):
for (int x = 0; x < 0x800; ++x) {
	bool nf = x & 0x400;
	bool hf = x & 0x200;
	bool cf = x & 0x100;
	byte a = x & 0xFF;
	byte hi = a / 16;
	byte lo = a & 15;
	byte diff;
	if (cf) {
		diff = ((lo <= 9) && !hf) ? 0x60 : 0x66;
	} else {
		if (lo >= 10) {
			diff = (hi <= 8) ? 0x06 : 0x66;
		} else {
			if (hi >= 10) {
				diff = hf ? 0x66 : 0x60;
			} else {
				diff = hf ? 0x06 : 0x00;
			}
		}
	}
	byte res_a = nf ? a - diff : a + diff;
	byte res_f = ZSPXYTable[res_a] | (nf ? N_FLAG : 0);
	if (cf || ((lo <= 9) ? (hi >= 10) : (hi >= 9))) {
		res_f |= C_FLAG;
	}
	if (nf ? (hf && (lo <= 5)) : (lo >= 10)) {
		res_f |= H_FLAG;
	}
	DAATable[x] = (res_a << 8) + res_f;
}


and then handle DAA like this:
template <class T> void CPUCore<T>::daa()
{
	int i = R.getA();
	if (R.getF() & C_FLAG) i |= 0x100;
	if (R.getF() & H_FLAG) i |= 0x200;
	if (R.getF() & N_FLAG) i |= 0x400;
	R.AF = DAATable[i];
}



a direct translation from the link above gives exactly the same result, without the need of a DAA table:
u8 r=A;
if NF {
	if (HF||(A&0xf)>9) r-=6;
	if (CF||A>0x99) r-=0x60;
}
else {
	if (HF||(A&0xf)>9) r+=6;
	if (CF||A>0x99) r+=0x60;
}
F=(F&3)|lut_flags[r]|(A>0x99)|((A^r)&0x10);
A=r;


I don't know which one's faster, but if you're going to stick with the DAA table, at least get rid of that big, hard-to-understand calculation
Kwik
msx lover
Berichten: 105
Geplaatst: 12 Februari 2007, 15:09   
I've seen very different implementations on DAA, but none as short as this one. Have you verified it with ZEXALL? Are X-flag and Y flag ("undocumented" ) supported?
hap
msx addict
Berichten: 463
Geplaatst: 12 Februari 2007, 15:25   
I've verified it by comparing all possible results with that 4KB table, and verified blueMSX DAA opcode by comparing it with my MSX2 (small program: push value, pop af, daa, push af, pop value and write to ram). The X/Y flags are handled by that 256byte lut_flags, which is basically the same as openMSX ZSPXYTable.

My Z80 emulator is far from complete, so it'd be nice if someone double checked this shorter implementation in their own ZEXALL compliant Z80 emulation core.
Kwik
msx lover
Berichten: 105
Geplaatst: 12 Februari 2007, 15:34   
If the code is correct then it's very cool. I spend several hours on DAA and came up with this (which is a lot bigger):
        reg1 = reg_a;
        if (reg_f & NFLAG) {
            reg2 = reg_f & (CFLAG|NFLAG|HFLAG);
            if ((reg_f&CFLAG)||(reg_a>0x99)) reg1 -= 0x160;
            if ((reg_f&HFLAG)||((reg_a&0x0F)>9)) {
                if ((reg_a&0x0F)>5) reg2 &= ~HFLAG;
                reg1 = (reg1&0xFF00)|((reg1-6)&0xFF);
            }
        } else {
            reg2 = (reg_f&CFLAG) | (((reg_a&0x0F)>9)?HFLAG:0);
            if ((reg2|reg_f)&HFLAG) reg1 += 6;
            if ((reg_f&CFLAG) || ((reg1&0x1F0)>0x90)) reg1 += 0x60;
        }
        reg_a = reg1&255;
	reg_f = flagSZP[reg_a] | reg2 | ((reg1>>8)&CFLAG);


It does pass ZEXALL by the way.
FluBBa
msx friend
Berichten: 3
Geplaatst: 22 Mei 2007, 23:16   
Speaking of which, does anyone know where to find ZEXALL for the MSX?
Kwik
msx lover
Berichten: 105
Geplaatst: 23 Mei 2007, 09:39   
FluBBa
msx friend
Berichten: 3
Geplaatst: 23 Mei 2007, 12:37   
So which one should I download for the MSX? The YAZE, CPM or Spectrum?
NYYRIKKI
msx master
Berichten: 1500
Geplaatst: 23 Mei 2007, 14:27   
CPM

MSX-DOS is CP/M compatible.

FluBBa
msx friend
Berichten: 3
Geplaatst: 23 Mei 2007, 21:40   
Oh, wow. Thanks a lot.
I guess I have some more coding to do then
 
 







(c) 1994 - 2008 Stichting MSX Resource Center. MSX is een trademark van MSX Licensing Corporation.