2181 lines
50 KiB
C
2181 lines
50 KiB
C
#include<inttypes.h>
|
|
#include<stdio.h>
|
|
#include<stdlib.h>
|
|
#include"cpu.h"
|
|
#include"ppu.h"
|
|
|
|
/* static char log_buffer[10*128]={0}; */
|
|
/* static size_t log_buffer_line=0; */
|
|
static char log_buffer[128*10]={0};
|
|
|
|
/* #define qprintf(...) do{\ */
|
|
/* if(!quiet){\ */
|
|
/* if(log_buffer_line<10)\ */
|
|
/* sprintf(log_buffer+(log_buffer_line++),__VA_ARGS__);\ */
|
|
/* }}while(0) */
|
|
|
|
//#define qprintf(...) do{size_t __i=0;if(!quiet){__i=sprintf(log_buffer,"%#x:",(cpu)->pc);sprintf(log_buffer+__i,__VA_ARGS__);}}while(0)
|
|
// This causes memory problems, why?
|
|
//#define qprintf(...) do{if(!quiet){int __i=sprintf(log_buffer,"%#x:",(cpu)->pc);sprintf((log_buffer+__i),__VA_ARGS__);}}while(0)
|
|
#define qprintf(...) do{if(!quiet)sprintf(log_buffer,__VA_ARGS__);}while(0)
|
|
|
|
char*cpu_log(void)
|
|
{
|
|
return log_buffer;
|
|
}
|
|
|
|
void cpu_fetch8(Cpu*cpu,uint8_t*rom,uint8_t*u8)
|
|
{
|
|
*u8=rom[cpu->pc++];
|
|
}
|
|
|
|
void cpu_fetch16(Cpu*cpu,uint8_t*rom,uint16_t*u16)
|
|
{
|
|
*u16=rom[cpu->pc]|rom[cpu->pc+1]<<8;
|
|
cpu->pc+=2;
|
|
}
|
|
|
|
// cpu_write_ram Allow access to read/write to ram
|
|
// through a filter for interrupts
|
|
void cpu_write_ram(struct Ppu*ppu,uint16_t addr,uint8_t val,uint8_t*ram)
|
|
{
|
|
if(addr>0x7fff)//don't write into ROM
|
|
ram[addr]=val;
|
|
if(addr==0xff46)//DMA Transfer
|
|
{
|
|
//for(uint16_t i=0;i<-0x9f;i++)
|
|
for(uint16_t i=0;i<0x9f;i++)
|
|
for(uint16_t j=0xfe00;j<=0xfe9f;j++)
|
|
ram[j]=ram[val*0x100|i];//copy from DMA reg src to FExx
|
|
}
|
|
if(addr==0xff00)//JOYP INT
|
|
{
|
|
ppu_updatejoypad(ppu,ram);//this is distinct from interrupts (?)
|
|
// cpu->sp-=2;
|
|
// // cpu_write_ram(cpu->sp,(uint16_t)cpu->pc&0x00ff,cpu,ram);
|
|
// // cpu_write_ram(cpu->sp+1,(uint16_t)cpu->pc>>8,cpu,ram);
|
|
// ram[(uint16_t)cpu->pc&0x00ff]=cpu->sp;
|
|
// ram[(uint16_t)cpu->pc>>8]=cpu->sp+1;
|
|
|
|
}
|
|
//return ram+*(uint8_t*)&addr;
|
|
return;
|
|
}
|
|
|
|
void cpu_romhexdump(uint8_t *rom)
|
|
{
|
|
for(uint16_t i=0;i<0xffff;i++)printf("%.2x ",rom[i]);
|
|
}
|
|
|
|
// Normal instructions
|
|
void cpu_decexec(Cpu*cpu,struct Ppu*ppu,uint8_t*rom,uint8_t*op,uint8_t*ram,bool quiet)
|
|
{
|
|
uint16_t tmp;
|
|
uint8_t tmp8;
|
|
switch(*op)
|
|
{
|
|
case 0x01://ld bc,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->b=tmp>>8;
|
|
cpu->c=tmp&0x00ff;
|
|
qprintf("ld bc,%.4xh",cpu->b<<8|cpu->c);
|
|
break;
|
|
case 0x02://ld (bc),a
|
|
// *_ram(cpu->b<<8|cpu->c,ram)=cpu->a;
|
|
// ram[cpu->b<<8|cpu->c]=cpu->a;
|
|
cpu_write_ram(ppu,cpu->b<<8|cpu->c,cpu->a,ram);
|
|
qprintf("ld (bc),a ;(%.4xh)=%.2xh",cpu->b<<8|cpu->c,cpu->a);
|
|
break;
|
|
case 0x03://inc bc
|
|
tmp=((uint16_t)cpu->b<<8|cpu->c)+1; //lsh lower pri than add
|
|
cpu->b=tmp>>8;
|
|
cpu->c=tmp&0x00ff;
|
|
qprintf("inc bc ;%.4xh",cpu->b<<8|cpu->c);
|
|
break;
|
|
case 0x04://inc b
|
|
//flags:
|
|
cpu->f&=~F_N;//N 0
|
|
if((cpu->b&0xf)==0xf)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
cpu->b++;
|
|
if(cpu->b==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
qprintf("inc b");
|
|
break;
|
|
case 0x05://dec b
|
|
if(cpu->b&0x10&&!(cpu->b&0x08))cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
cpu->b--;
|
|
if(cpu->b==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec b");
|
|
break;
|
|
case 0x06://ld b,m8
|
|
cpu_fetch8(cpu,rom,&cpu->b);
|
|
qprintf("ld b,%.2xh",cpu->b);
|
|
break;
|
|
case 0x07://rlca
|
|
if(cpu->a&0x80)cpu->f|=F_C;else cpu->f&=~F_C;//C
|
|
cpu->f&=F_C;//N 0,Z 0,H 0
|
|
tmp8=cpu->a;
|
|
if(cpu->f&F_C)asm("stc");
|
|
else asm("clc");
|
|
asm("rclb %0":"=m"(tmp8));
|
|
cpu->a=tmp8;
|
|
qprintf("rlca ;%.2x",tmp8);
|
|
break;
|
|
case 0x08://ld (m16),sp
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
// ram[tmp]=cpu->sp;
|
|
cpu_write_ram(ppu,tmp,cpu->sp,ram);
|
|
qprintf("ld (%.4xh),sp",tmp);
|
|
break;
|
|
case 0x09://add hl,bc
|
|
tmp=cpu->h<<8|cpu->l;
|
|
tmp+=cpu->b<<8|cpu->c;
|
|
cpu->b=tmp>>8;
|
|
cpu->c=(uint8_t)tmp;//trunc
|
|
qprintf("add hl,bc");
|
|
if(tmp<(cpu->b<<8|cpu->c))cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
cpu->f&=~F_N;//N
|
|
//H
|
|
// if(cpu->f==0)cpu->f|=F_Z;else cpu->f&=~F_Z;//Z -
|
|
break;
|
|
case 0x0a: //ld a,(bc)
|
|
cpu->a=ram[cpu->b<<8|cpu->c];
|
|
qprintf("ld a,(bc)");
|
|
break;
|
|
case 0x0b: //dec bc
|
|
tmp=((uint16_t)cpu->b<<8|cpu->c)-1;
|
|
cpu->b=tmp>>8;
|
|
cpu->c=(uint8_t)tmp;
|
|
qprintf("dec bc");
|
|
break;
|
|
case 0x0c: //inc c
|
|
cpu->c++;
|
|
if(cpu->c==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
if((cpu->c&0xf)==0xf)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
qprintf("inc c");
|
|
break;
|
|
case 0x0d: //dec c
|
|
if(cpu->c&0x10&&!(cpu->c&0x08))cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
cpu->c--;
|
|
if(cpu->c==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec c ;%.2xh",cpu->c);
|
|
break;
|
|
case 0x0e: //ld c,m8
|
|
cpu_fetch8(cpu,rom,&cpu->c);
|
|
qprintf("ld c,%.2xh",cpu->c);
|
|
break;
|
|
case 0x0f: //rrca
|
|
if(cpu->a&0x01)cpu->f|=F_C;else cpu->f&=~F_C;//C
|
|
cpu->f&=F_C;//N 0,Z 0,H 0
|
|
tmp8=cpu->a;
|
|
tmp8=ror(tmp8,1);
|
|
//asm("rorb %0":"=m"(tmp8));
|
|
cpu->a=tmp8;
|
|
qprintf("rrca ;%.2xh",tmp8);
|
|
break;
|
|
case 0x10://stop 0x00
|
|
cpu_fetch8(cpu,rom,(uint8_t*)(uint8_t*)&tmp);//second byte of opcode
|
|
qprintf("stop %.2xh ;10h 00h",tmp);
|
|
break;
|
|
case 0x11://ld de,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->d=tmp>>8;
|
|
cpu->e=tmp&0x00ff;
|
|
qprintf("ld de,%.4xh",tmp);
|
|
break;
|
|
case 0x12://ld (de),a
|
|
// ram[cpu->d<<8|cpu->e]=cpu->a;
|
|
cpu_write_ram(ppu,cpu->d<<8|cpu->e,cpu->a,ram);
|
|
qprintf("ld (de),a");
|
|
break;
|
|
case 0x13://inc de
|
|
tmp=((uint16_t)cpu->d<<8|cpu->e)+1;
|
|
cpu->d=tmp>>8;
|
|
cpu->e=tmp&0x00ff;
|
|
qprintf("inc de");
|
|
break;
|
|
case 0x14://inc d
|
|
cpu->d++;
|
|
if(cpu->d==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
if((cpu->d&0xf)==0xf)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
qprintf("inc d");
|
|
break;
|
|
case 0x15://dec d
|
|
if(cpu->d&0x10&&!(cpu->d&0x08))cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
cpu->d--;
|
|
if(cpu->d==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec d");
|
|
break;
|
|
case 0x16://ld d,m8
|
|
cpu_fetch8(cpu,rom,&cpu->d);
|
|
qprintf("ld d,%.2xh",cpu->d);
|
|
break;
|
|
case 0x17://rla
|
|
if(cpu->a&0x80)cpu->f|=F_C;else cpu->f&=~F_C;//C
|
|
cpu->f&=F_C;//N 0,Z 0,H 0
|
|
tmp8=cpu->a;
|
|
asm("rolb %0":"=m"(tmp8));
|
|
cpu->a=tmp8;
|
|
qprintf("rla");
|
|
break;
|
|
case 0x18://jr m8 (signed)
|
|
cpu_fetch8(cpu,rom,(uint8_t*)(uint8_t*)&tmp);
|
|
cpu->pc+=(int8_t)tmp;//cast to signed int8, C will sign extend
|
|
qprintf("jr %.2xh ;%.2xh",(uint8_t)tmp,cpu->pc);
|
|
break;
|
|
case 0x19://add hl,de
|
|
tmp=cpu->h<<8|cpu->l;
|
|
tmp+=cpu->d<<8|cpu->e;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;//trunc
|
|
qprintf("add hl,de");
|
|
if(tmp<(cpu->d<<8|cpu->e))cpu->f|=F_C;else cpu->f&=~F_C;//C
|
|
cpu->f&=~F_N;//N
|
|
//H
|
|
// if(cpu->f==0)cpu->f|=F_Z;else cpu->f&=~F_Z;//Z -
|
|
break;
|
|
case 0x1a: //ld a,(de)
|
|
cpu->a=ram[cpu->d<<8|cpu->e];
|
|
qprintf("ld a,(de)");
|
|
break;
|
|
case 0x1b: //dec de
|
|
tmp=((uint16_t)cpu->d<<8|cpu->e)-1;
|
|
cpu->d=tmp>>8;
|
|
cpu->e=(uint8_t)tmp;
|
|
qprintf("dec de");
|
|
break;
|
|
case 0x1c: //inc e
|
|
cpu->e++;
|
|
if(cpu->e==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
if((cpu->e&0xf)==0xf)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
qprintf("inc e");
|
|
break;
|
|
case 0x1d: //dec e
|
|
if(cpu->e&0x10&&!(cpu->e&0x08))cpu->f|=F_H;
|
|
else cpu->f&=~F_H;//borrow H
|
|
cpu->e--;
|
|
if(cpu->e==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec c");
|
|
break;
|
|
case 0x1e: //ld e,m8
|
|
cpu_fetch8(cpu,rom,&cpu->e);
|
|
qprintf("ld e,%.2xh",cpu->e);
|
|
break;
|
|
case 0x1f: //rra //TODO: fix behavior of rotate
|
|
{
|
|
//create new call stack
|
|
uint8_t cf=cpu->f&F_C;
|
|
if(cpu->a&0x01)cpu->f|=F_C;else cpu->f&=~F_C;//C
|
|
cpu->f&=F_C;//Z 0,H 0,N 0
|
|
tmp=cpu->a;
|
|
tmp8=cpu->f&F_C;
|
|
|
|
if(cf)asm(" stc ");
|
|
else asm(" clc");
|
|
asm("rcrb %0":"=m"(tmp));
|
|
|
|
|
|
cpu->a=(uint8_t)tmp;
|
|
qprintf("rra ; %.2xh",(uint8_t)tmp);
|
|
break;
|
|
}
|
|
case 0x20://jr nz m8 (signed)
|
|
cpu_fetch8(cpu,rom,(uint8_t*)(uint8_t*)&tmp);
|
|
if(!(cpu->f&F_Z))
|
|
cpu->pc+=(int8_t)tmp;//m8 is signed!
|
|
qprintf("jr nz %.2xh%s",(uint8_t)tmp,(!(cpu->f&F_Z))?(""):(" ;skipped"));
|
|
break;
|
|
case 0x21://ld hl,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->h=tmp>>8;
|
|
cpu->l=tmp&0x00ff;
|
|
qprintf("ld hl,%.4xh",tmp);
|
|
break;
|
|
case 0x22://ld (hli),a
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->a;
|
|
cpu_write_ram(ppu,tmp,cpu->a,ram);
|
|
tmp++;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=tmp&0x00ff;
|
|
qprintf("ld (hli),a ;%.4x",tmp);
|
|
break;
|
|
case 0x23://inc hl
|
|
tmp=((uint16_t)cpu->h<<8|cpu->l)+1;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;//trunc
|
|
qprintf("inc hl");
|
|
break;
|
|
case 0x24: //inc h
|
|
cpu->h++;
|
|
qprintf("inc h");
|
|
if(cpu->h==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
if((cpu->h&0xf)==0xf)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
break;
|
|
case 0x25: //dec h
|
|
if(cpu->h&0x10&&!(cpu->h&0x08))cpu->f|=F_H;
|
|
else cpu->f&=~F_H;//borrow H
|
|
cpu->h--;
|
|
if(cpu->h==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec h");
|
|
break;
|
|
case 0x26://ld h,m8
|
|
cpu_fetch8(cpu,rom,&cpu->h);
|
|
qprintf("ld h,%.2xh",cpu->h);
|
|
break;
|
|
case 0x27://daa ;decimal adjust a (BCD)
|
|
qprintf("daa");
|
|
if(cpu->a==0)cpu->f|=F_Z;//Z
|
|
cpu->f&=~F_H;//H
|
|
//N -
|
|
//C
|
|
break;
|
|
case 0x28://jr z m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)(uint8_t*)&tmp);
|
|
if(cpu->f&F_Z)cpu->pc+=(int8_t)tmp;
|
|
qprintf("jr z %.2xh ;%.2xh%s",(uint8_t)tmp,cpu->pc,(cpu->f&F_Z)?(""):(" ;skipped"));
|
|
break;
|
|
case 0x29://add hl,hl
|
|
tmp=cpu->h<<8|cpu->l;
|
|
tmp+=tmp;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;
|
|
qprintf("add hl,hl ;%.4xh",tmp);
|
|
cpu->f&=~F_N;//N
|
|
//C
|
|
//H
|
|
break;
|
|
case 0x2a: //ld a,(hli) ld a,(hl) ; inc hl
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
cpu->a=ram[tmp];
|
|
tmp++;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=tmp&0x00ff;
|
|
qprintf("ld a,(hli) ;(%.4xh)",tmp);
|
|
break;
|
|
case 0x2b: //dec hl
|
|
tmp=((uint16_t)cpu->h<<8|cpu->l)-1;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;
|
|
qprintf("dec hl");
|
|
break;
|
|
case 0x2c: //inc l
|
|
cpu->l++;
|
|
if(cpu->l==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
qprintf("inc l");
|
|
break;
|
|
case 0x2d: //dec l
|
|
if(cpu->l&0x10&&!(cpu->l&0x08))cpu->f|=F_H;
|
|
else cpu->f&=~F_H;//H
|
|
cpu->l--;
|
|
if(cpu->l==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("dec l");
|
|
break;
|
|
case 0x2e: //ld l,m8
|
|
cpu_fetch8(cpu,rom,&cpu->l);
|
|
qprintf("ld l,%.2xh",cpu->l);
|
|
break;
|
|
case 0x2f: //cpl ;cpl a
|
|
cpu->a=~cpu->a;
|
|
cpu->f|=F_H;
|
|
cpu->f|=F_N;
|
|
qprintf("cpl ;cpl a");
|
|
break;
|
|
case 0x30://jr nc m8 (signed)
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
if(!(cpu->f&F_C))
|
|
cpu->pc+=(int8_t)tmp;//m8 is signed!
|
|
qprintf("jr nc %.2xh%s",(uint8_t)tmp,(!(cpu->f&F_C))?(""):(" ;skipped"));
|
|
break;
|
|
case 0x31://ld sp,m16
|
|
cpu_fetch16(cpu,rom,&cpu->sp);
|
|
qprintf("ld sp,%.4xh",cpu->sp);
|
|
break;
|
|
case 0x32://ld (hld),a ld (hl),a ; dec hl
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->a;
|
|
cpu_write_ram(ppu,tmp,cpu->a,ram);
|
|
tmp--;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=tmp&0x00ff;
|
|
qprintf("ld (hld),a ;(%.4xh)",tmp);
|
|
break;
|
|
case 0x33://inc sp
|
|
cpu->sp++;
|
|
qprintf("inc sp");
|
|
break;
|
|
case 0x34://inc (hl)
|
|
tmp=cpu->h|cpu->l<<8;
|
|
// ram[tmp]++;
|
|
cpu_write_ram(ppu,tmp,ram[tmp]+1,ram);
|
|
qprintf("inc (hl) ;%.4xh",ram[tmp]);
|
|
break;
|
|
case 0x35://dec (hl)
|
|
tmp=cpu->h|cpu->l<<8;
|
|
// ram[tmp]--;
|
|
cpu_write_ram(ppu,tmp,ram[tmp]-1,ram);
|
|
qprintf("dec (hl) ;%.4xh",ram[tmp]);
|
|
break;
|
|
case 0x36://ld (hl),m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
// ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
cpu_write_ram(ppu,cpu->h<<8|cpu->l,(uint8_t)tmp,ram);
|
|
qprintf("ld (hl),%.2xh",(uint8_t)tmp);
|
|
break;
|
|
case 0x37://scf
|
|
cpu->f&=F_C|F_Z;//reset F_H,F_N
|
|
cpu->f|=F_C;//set F_C
|
|
qprintf("scf ;%.2xh",cpu->f);
|
|
break;
|
|
case 0x38://jr c,m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
if(cpu->f&F_C)
|
|
cpu->pc+=(int8_t)tmp;//m8 is signed!
|
|
qprintf("jr c %.2xh%s",(uint8_t)tmp,(!(cpu->f&F_C))?(""):(" ;skipped"));
|
|
break;
|
|
case 0x39://add hl,sp
|
|
tmp=cpu->h<<8|cpu->l;
|
|
tmp+=cpu->sp;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;//trunc
|
|
qprintf("add hl,sp");
|
|
break;
|
|
case 0x3a: //ld a,(hld) ld a,(hl) ; dec hl
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
cpu->a=ram[tmp];
|
|
tmp--;
|
|
cpu->h=tmp>>8;
|
|
cpu->l=tmp|0x00ff;
|
|
qprintf("ld a,(hld) ;(%.4xh)",tmp);
|
|
break;
|
|
case 0x3b: //dec sp
|
|
cpu->sp--;
|
|
qprintf("dec sp");
|
|
break;
|
|
case 0x3c: //inc a
|
|
cpu->a++;
|
|
if(cpu->a==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
qprintf("inc a");
|
|
break;
|
|
case 0x3d: //dec a
|
|
cpu->a--;
|
|
if(!cpu->a)cpu->f|=F_Z;
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;
|
|
//F_H
|
|
qprintf("dec a");
|
|
break;
|
|
case 0x3e: //ld a,m8
|
|
cpu_fetch8(cpu,rom,&cpu->a);
|
|
qprintf("ld a,%.2xh",cpu->a);
|
|
break;
|
|
case 0x3f: //ccf ;complement F_C flag
|
|
//flags
|
|
cpu->f=(cpu->f&F_C)?cpu->f&~F_C:cpu->f|F_C;//cpl C
|
|
//Z -
|
|
cpu->f&=~(F_N|F_H);//N 0,H 0
|
|
qprintf("ccf ;%.2x",cpu->f&F_C);
|
|
break;
|
|
case 0x40://ld b,b
|
|
qprintf("ld b,b");
|
|
break;
|
|
case 0x41://ld b,c
|
|
cpu->b=cpu->c;
|
|
qprintf("ld b,c");
|
|
break;
|
|
case 0x42://ld b,d
|
|
cpu->b=cpu->d;
|
|
qprintf("ld b,d");
|
|
break;
|
|
case 0x43://ld b,e
|
|
cpu->b=cpu->e;
|
|
qprintf("ld b,e");
|
|
break;
|
|
case 0x44://ld b,h
|
|
cpu->b=cpu->h;
|
|
qprintf("ld b,h");
|
|
break;
|
|
case 0x45://ld b,l
|
|
cpu->b=cpu->l;
|
|
qprintf("ld b,l");
|
|
break;
|
|
case 0x46://ld b,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->b=ram[tmp];
|
|
qprintf("ld b,(hl)");
|
|
break;
|
|
case 0x47://ld b,a
|
|
cpu->b=cpu->a;
|
|
qprintf("ld b,a");
|
|
break;
|
|
case 0x48://ld c,b
|
|
cpu->c=cpu->b;
|
|
qprintf("ld c,b");
|
|
break;
|
|
case 0x49://ld c,c
|
|
qprintf("ld c,c");
|
|
break;
|
|
case 0x4a: //ld c,d
|
|
cpu->c=cpu->d;
|
|
qprintf("ld c,d");
|
|
break;
|
|
case 0x4b: //ld c,e
|
|
cpu->c=cpu->e;
|
|
qprintf("ld c,e");
|
|
break;
|
|
case 0x4c: //ld c,h
|
|
cpu->c=cpu->h;
|
|
qprintf("ld c,h");
|
|
break;
|
|
case 0x4d: //ld c,l
|
|
cpu->c=cpu->l;
|
|
qprintf("ld c,l");
|
|
break;
|
|
case 0x4e: //ld c,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->c=ram[tmp];
|
|
qprintf("ld c,(hl)");
|
|
break;
|
|
case 0x4f: //ld c,a
|
|
cpu->c=cpu->a;
|
|
qprintf("ld c,a");
|
|
break;
|
|
case 0x50: //ld d,b
|
|
cpu->d=cpu->b;
|
|
qprintf("ld d,b");
|
|
break;
|
|
case 0x51: //ld d,c
|
|
cpu->d=cpu->c;
|
|
qprintf("ld d,c");
|
|
break;
|
|
case 0x52: //ld d,d
|
|
qprintf("ld d,d");
|
|
break;
|
|
case 0x53: //ld d,e
|
|
cpu->d=cpu->e;
|
|
qprintf("ld d,e");
|
|
break;
|
|
case 0x54: //ld d,h
|
|
cpu->d=cpu->h;
|
|
qprintf("ld d,h");
|
|
break;
|
|
case 0x55: //ld d,l
|
|
cpu->d=cpu->l;
|
|
qprintf("ld d,l");
|
|
break;
|
|
case 0x56: //ld d,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->d=ram[tmp];
|
|
qprintf("ld d,(hl)");
|
|
break;
|
|
case 0x57: //ld d,a
|
|
cpu->d=cpu->a;
|
|
qprintf("ld d,a");
|
|
break;
|
|
case 0x58: //ld e,b
|
|
cpu->e=cpu->b;
|
|
qprintf("ld e,b");
|
|
break;
|
|
case 0x59: //ld e,c
|
|
cpu->e=cpu->c;
|
|
qprintf("ld e,c");
|
|
break;
|
|
case 0x5a: //ld e,d
|
|
cpu->e=cpu->d;
|
|
qprintf("ld e,d");
|
|
break;
|
|
case 0x5b: //ld e,e
|
|
qprintf("ld e,e");
|
|
break;
|
|
case 0x5c: //ld e,h
|
|
cpu->e=cpu->h;
|
|
qprintf("ld e,h");
|
|
break;
|
|
case 0x5d: //ld e,l
|
|
cpu->e=cpu->l;
|
|
qprintf("ld e,l");
|
|
break;
|
|
case 0x5e: //ld e,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->e=ram[tmp];
|
|
qprintf("ld e,(hl)");
|
|
break;
|
|
case 0x5f: //ld e,a
|
|
cpu->e=cpu->a;
|
|
qprintf("ld e,a");
|
|
break;
|
|
case 0x60: //ld h,b
|
|
cpu->h=cpu->b;
|
|
qprintf("ld h,b");
|
|
break;
|
|
case 0x61: //ld h,c
|
|
cpu->h=cpu->c;
|
|
qprintf("ld h,c");
|
|
break;
|
|
case 0x62: //ld h,d
|
|
cpu->h=cpu->d;
|
|
qprintf("ld h,d");
|
|
break;
|
|
case 0x63: //ld h,e
|
|
cpu->h=cpu->e;
|
|
qprintf("ld h,e");
|
|
break;
|
|
case 0x64: //ld h,h
|
|
qprintf("ld h,h");
|
|
break;
|
|
case 0x65: //ld h,l
|
|
cpu->h=cpu->l;
|
|
qprintf("ld h,l");
|
|
break;
|
|
case 0x66: //ld h,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->h=ram[tmp];
|
|
qprintf("ld h,(hl)");
|
|
break;
|
|
case 0x67: //ld h,a
|
|
cpu->h=cpu->a;
|
|
qprintf("ld h,a");
|
|
break;
|
|
case 0x68: //ld l,b
|
|
cpu->l=cpu->b;
|
|
qprintf("ld l,b");
|
|
break;
|
|
case 0x69: //ld l,c
|
|
cpu->l=cpu->c;
|
|
qprintf("ld l,c");
|
|
break;
|
|
case 0x6a: //ld l,d
|
|
cpu->l=cpu->d;
|
|
qprintf("ld l,d");
|
|
break;
|
|
case 0x6b: //ld l,e
|
|
cpu->l=cpu->e;
|
|
qprintf("ld l,e");
|
|
break;
|
|
case 0x6c: //ld l,h
|
|
cpu->l=cpu->h;
|
|
qprintf("ld l,h");
|
|
break;
|
|
case 0x6d: //ld l,l
|
|
qprintf("ld l,l");
|
|
break;
|
|
case 0x6e: //ld l,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->l=ram[tmp];
|
|
qprintf("ld l,(hl)");
|
|
break;
|
|
case 0x6f: //ld l,a
|
|
cpu->l=cpu->a;
|
|
qprintf("ld l,a");
|
|
break;
|
|
case 0x70: //ld (hl),b
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->b;
|
|
cpu_write_ram(ppu,tmp,cpu->b,ram);
|
|
qprintf("ld (hl),b ;ld (%.4xh),%.2xh",tmp,cpu->b);
|
|
break;
|
|
case 0x71: //ld (hl),c
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->c;
|
|
cpu_write_ram(ppu,tmp,cpu->c,ram);
|
|
qprintf("ld (hl),c");
|
|
break;
|
|
case 0x72: //ld (hl),d
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->d;
|
|
cpu_write_ram(ppu,tmp,cpu->d,ram);
|
|
qprintf("ld (hl),d");
|
|
break;
|
|
case 0x73: //ld (hl),e
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->e;
|
|
cpu_write_ram(ppu,tmp,cpu->e,ram);
|
|
qprintf("ld (hl),e");
|
|
break;
|
|
case 0x74: //ld (hl),h
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->h;
|
|
cpu_write_ram(ppu,tmp,cpu->h,ram);
|
|
qprintf("ld (hl),h");
|
|
break;
|
|
case 0x75: //ld (hl),l
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->l;
|
|
cpu_write_ram(ppu,tmp,cpu->l,ram);
|
|
qprintf("ld (hl),l");
|
|
break;
|
|
case 0x76: //halt
|
|
//if(cpu->ime)
|
|
cpu->pc--;//stay put
|
|
qprintf("halt%s",ram[0xffff]?"":"");
|
|
break;
|
|
case 0x77: //ld (hl),a
|
|
tmp=cpu->h<<8|cpu->l;
|
|
// ram[tmp]=cpu->a;
|
|
cpu_write_ram(ppu,tmp,cpu->a,ram);
|
|
qprintf("ld (hl),a ;ld (%.4xh),%.2xh",tmp,cpu->a);
|
|
break;
|
|
case 0x78: //ld a,b
|
|
cpu->a=cpu->b;
|
|
qprintf("ld a,b");
|
|
break;
|
|
case 0x79: //ld a,c
|
|
cpu->a=cpu->c;
|
|
qprintf("ld a,c");
|
|
break;
|
|
case 0x7a: //ld a,d
|
|
cpu->a=cpu->d;
|
|
qprintf("ld a,d");
|
|
break;
|
|
case 0x7b: //ld a,e
|
|
cpu->a=cpu->e;
|
|
qprintf("ld a,e");
|
|
break;
|
|
case 0x7c: //ld a,h
|
|
cpu->a=cpu->h;
|
|
qprintf("ld a,h");
|
|
break;
|
|
case 0x7d: //ld a,l
|
|
cpu->a=cpu->l;
|
|
qprintf("ld a,l");
|
|
break;
|
|
case 0x7e: //ld a,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->a=ram[tmp];
|
|
qprintf("ld a,(hl)");
|
|
break;
|
|
case 0x7f: //ld a,a
|
|
qprintf("ld a,a");
|
|
break;
|
|
case 0x80://add b
|
|
cpu->a+=cpu->b;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->b)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add b");
|
|
break;
|
|
case 0x81://add c
|
|
cpu->a+=cpu->c;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->c)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add c");
|
|
break;
|
|
case 0x82://add d
|
|
cpu->a+=cpu->d;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->d)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add d");
|
|
break;
|
|
case 0x83://add e
|
|
cpu->a+=cpu->e;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->e)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add e");
|
|
break;
|
|
case 0x84://add h
|
|
cpu->a+=cpu->h;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->h)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add h");
|
|
break;
|
|
case 0x85://add l
|
|
cpu->a+=cpu->l;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->l)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add l ;%x",cpu->f&F_C);
|
|
break;
|
|
case 0x86://add (hl)
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
cpu->a+=ram[tmp];
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->h)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add (hl) ;%.4xh",tmp);
|
|
break;
|
|
case 0x87://add a
|
|
tmp=cpu->a;
|
|
cpu->a+=cpu->a;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(tmp<cpu->a)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add a");
|
|
break;
|
|
case 0x88://adc b
|
|
cpu->a+=cpu->b+(cpu->f&F_C)!=0;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->b)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc b");
|
|
break;
|
|
case 0x89://adc c
|
|
cpu->a+=cpu->c+(cpu->f&F_C)!=0;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->c)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc c");
|
|
break;
|
|
case 0x8a: //adc d
|
|
cpu->a+=cpu->d+(cpu->f&F_C)!=0;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->d)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc d");
|
|
break;
|
|
case 0x8b: //adc e
|
|
cpu->a+=cpu->e+(cpu->f&F_C)!=0;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->e)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc e");
|
|
break;
|
|
case 0x8c: //adc h
|
|
cpu->a+=cpu->h+(cpu->f&F_C)!=0;
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<cpu->h)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc h ;%x",cpu->f&F_C);
|
|
break;
|
|
case 0x8d: //adc a,l
|
|
cpu->a+=cpu->l+!!(cpu->f&F_C);
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
//F_C
|
|
qprintf("adc a,l");
|
|
break;
|
|
case 0x8e: //adc a,(hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->a+=ram[tmp]+!!(cpu->f&F_C);
|
|
if(cpu->a==0)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
//F_H
|
|
//F_C
|
|
qprintf("adc a,(hl) ;%.4xh",tmp);
|
|
break;
|
|
case 0x8f: //adc a,a
|
|
cpu->a+=cpu->a+!!(cpu->f&F_C);
|
|
if(cpu->a==0)cpu->f|=F_Z;
|
|
cpu->f&=~F_N;
|
|
if(!cpu->a)cpu->f|=F_Z;
|
|
//F_H
|
|
//F_C
|
|
qprintf("adc a,a");
|
|
break;
|
|
case 0x90://sub b
|
|
if(cpu->a<cpu->b)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->b;
|
|
if(!(cpu->a))cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub b");
|
|
break;
|
|
case 0x91://sub c
|
|
if(cpu->a<cpu->c)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->c;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub c");
|
|
break;
|
|
case 0x92://sub d
|
|
if(cpu->a<cpu->d)cpu->f&=~F_C;//C //SUB CARRY IS REVERSED
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->d;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub d");
|
|
break;
|
|
case 0x93://sub e
|
|
if(cpu->a<cpu->e)cpu->f&=~F_C;//C //SUB CARRY IS REVERSED
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->e;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub e");
|
|
break;
|
|
case 0x94://sub h
|
|
if(cpu->a<cpu->h)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->h;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub h");
|
|
break;
|
|
case 0x95://sub l
|
|
if(cpu->a<cpu->l)cpu->f&=~F_C;//C //SUB CARRY IS REVERSED
|
|
else cpu->f|=F_C;
|
|
cpu->a-=cpu->l;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub l ;CF:%x a:%.2x",(cpu->f&F_C),cpu->a);
|
|
break;
|
|
case 0x96://sub (hl)
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
if(cpu->a<tmp)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->a-=ram[tmp];
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub (hl)");
|
|
break;
|
|
case 0x97://sub a
|
|
cpu->a-=cpu->a;
|
|
cpu->f&=~F_C;//C
|
|
cpu->f|=F_Z;//Z
|
|
cpu->f|=F_N;//N
|
|
qprintf("sub a");
|
|
break;
|
|
case 0x98://sbc b
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->b+!(cpu->f&F_C);
|
|
if(tmp<cpu->b)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;//N
|
|
qprintf("sbc b");
|
|
break;
|
|
case 0x99://sbc c
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->c+!(cpu->f&F_C);
|
|
if(tmp<cpu->c)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc c");
|
|
break;
|
|
case 0x9a: //sbc d
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->d+!(cpu->f&F_C);
|
|
if(tmp<cpu->d)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc d");
|
|
break;
|
|
case 0x9b: //sbc e
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->e+!(cpu->f&F_C);
|
|
if(tmp<cpu->e)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc e");
|
|
break;
|
|
case 0x9c: //sbc h
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->h+!(cpu->f&F_C);
|
|
if(tmp<cpu->h)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc h ;C:%x",(cpu->f&F_C));
|
|
break;
|
|
case 0x9d: //sbc l
|
|
tmp=cpu->a;
|
|
cpu->a-=cpu->l+!(cpu->f&F_C);
|
|
if(tmp<cpu->l)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc l ;C:%u",(!!cpu->f)&F_C);
|
|
break;
|
|
case 0x9e: //sbc (hl)
|
|
tmp=(uint16_t)cpu->h<<8|cpu->l;
|
|
tmp8=cpu->a;
|
|
cpu->a-=ram[tmp]+!(cpu->f&F_C);
|
|
if(tmp8<ram[tmp])cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//zero flag
|
|
cpu->f|=F_N;
|
|
qprintf("sbc (hl)");
|
|
break;
|
|
case 0x9f: //sbc a
|
|
cpu->a-=cpu->a+!(cpu->f&F_C);
|
|
cpu->f|=F_C;//C
|
|
cpu->f|=F_Z;//Z
|
|
cpu->f|=F_N;//N
|
|
qprintf("sbc (hl)");
|
|
break;
|
|
case 0xa0://and b
|
|
cpu->a&=cpu->b;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and b");
|
|
break;
|
|
case 0xa1://and c
|
|
cpu->a&=cpu->c;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and c");
|
|
break;
|
|
case 0xa2://and d
|
|
cpu->a&=cpu->d;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and d");
|
|
break;
|
|
case 0xa3://and e
|
|
cpu->a&=cpu->e;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and e");
|
|
break;
|
|
case 0xa4://and h
|
|
cpu->a&=cpu->h;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and h");
|
|
break;
|
|
case 0xa5://and l
|
|
cpu->a&=cpu->l;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and l");
|
|
break;
|
|
case 0xa6://and (hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->a&=ram[tmp];
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and (hl)");
|
|
break;
|
|
case 0xa7://and a
|
|
// cpu->a&=cpu->a;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("and a");
|
|
break;
|
|
case 0xa8://xor b
|
|
cpu->a^=cpu->b;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor b");
|
|
break;
|
|
case 0xa9://xor c
|
|
cpu->a^=cpu->c;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor c");
|
|
break;
|
|
case 0xaa: //xor d
|
|
cpu->a^=cpu->d;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor d");
|
|
break;
|
|
case 0xab: //xor e
|
|
cpu->a^=cpu->e;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor e");
|
|
break;
|
|
case 0xac: //xor h
|
|
cpu->a^=cpu->h;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor h");
|
|
break;
|
|
case 0xad: //xor l
|
|
cpu->a^=cpu->l;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor l");
|
|
break;
|
|
case 0xae: //xor (hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->a^=ram[tmp];
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor (hl)");
|
|
break;
|
|
case 0xaf: //xor a
|
|
cpu->a=0;//xor X,X is always zero
|
|
cpu->f|=F_Z;//Z
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor a");
|
|
break;
|
|
case 0xb0://or b
|
|
cpu->a|=cpu->b;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or b");
|
|
break;
|
|
case 0xb1://or c
|
|
cpu->a|=cpu->c;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or c");
|
|
break;
|
|
case 0xb2://or d
|
|
cpu->a|=cpu->d;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or d");
|
|
break;
|
|
case 0xb3://or e
|
|
cpu->a|=cpu->e;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or e");
|
|
break;
|
|
case 0xb4://or h
|
|
cpu->a|=cpu->h;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or h");
|
|
break;
|
|
case 0xb5://or l
|
|
cpu->a|=cpu->l;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or l");
|
|
break;
|
|
case 0xb6://or (hl)
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->a|=ram[tmp];
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or (hl)");
|
|
break;
|
|
case 0xb7://or a
|
|
// cpu->a|=cpu->a;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or a");
|
|
break;
|
|
case 0xb8://cp b
|
|
tmp=cpu->a-cpu->b;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->b)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp b");
|
|
break;
|
|
case 0xb9://cp c
|
|
tmp=cpu->a-cpu->c;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->c)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp c");
|
|
break;
|
|
case 0xba: //cp d
|
|
tmp=cpu->a-cpu->d;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->d)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp d");
|
|
break;
|
|
case 0xbb: //cp e
|
|
tmp=cpu->a-cpu->e;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->e)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp e");
|
|
break;
|
|
case 0xbc: //cp h
|
|
tmp=cpu->a-cpu->h;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->h)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp h");
|
|
break;
|
|
case 0xbd: //cp l
|
|
tmp=cpu->a-cpu->l;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<cpu->l)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp l");
|
|
break;
|
|
case 0xbe: //cp (hl)
|
|
tmp=ram[cpu->h<<8|cpu->l];
|
|
tmp8=cpu->a-tmp;
|
|
if(!tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
if(cpu->a<tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;//C
|
|
qprintf("cp (hl)");
|
|
break;
|
|
case 0xbf: //cp a
|
|
cpu->f|=F_Z;//Z
|
|
cpu->f|=F_N;//N
|
|
//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("cp a");
|
|
break;
|
|
case 0xc0://ret nz
|
|
//pop ret val from stack!
|
|
if(!(cpu->f&F_Z))
|
|
{
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
}
|
|
qprintf("ret nz%s",cpu->f&F_Z?" ;skipped":"");
|
|
break;
|
|
case 0xc1://pop bc
|
|
cpu->c=ram[cpu->sp];//little-endian
|
|
cpu->b=ram[cpu->sp+1];
|
|
cpu->sp+=2;
|
|
qprintf("pop bc ;%.4xh",cpu->b<<8|cpu->c);
|
|
break;
|
|
case 0xc2://jp nz,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(!(cpu->f&F_Z))cpu->pc=tmp;
|
|
qprintf("jp nz,%.4xh%s",tmp,!cpu->a?" ;skipped":"");
|
|
break;
|
|
case 0xc3://jp m16
|
|
cpu_fetch16(cpu,rom,&cpu->pc);
|
|
cpu->pc-=2;//fetch incr's pc
|
|
qprintf("jp %.4xh",cpu->pc);
|
|
break;
|
|
case 0xc4://call nz,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(!(cpu->f&F_Z))
|
|
{
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp] =(uint8_t)cpu->pc;//push pc
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,(uint8_t)cpu->pc,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=tmp;
|
|
}
|
|
qprintf("call nz,%.4xh%s",tmp,!cpu->a?" ;skipped":"");
|
|
break;
|
|
case 0xc5://push bc
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp]=cpu->c;//little-endian
|
|
// ram[cpu->sp+1]=cpu->b;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->c,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->b,ram);
|
|
qprintf("push bc ;%.4xh",cpu->b<<8|cpu->c);
|
|
break;
|
|
case 0xc6://add a,m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
if((cpu->a&0x0f)+((tmp&0x0f)&0x10))cpu->f|=F_H;//F_H
|
|
else cpu->f&=~F_H;
|
|
cpu->a+=tmp;
|
|
if(cpu->a==0)cpu->f|=F_Z;//Z
|
|
cpu->f&=~F_N;//N
|
|
if(cpu->a<tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("add a,%.2xh",tmp);
|
|
break;
|
|
case 0xc7: //rst 00h (call 0000h + 00h)
|
|
// cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0000;
|
|
qprintf("rst 00h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xc8: //ret z //ret addr stays on stack if skipped!
|
|
if(cpu->f&F_Z)
|
|
{
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
}
|
|
qprintf("ret z%s",cpu->f&F_Z?"":" ;skipped");
|
|
break;
|
|
case 0xc9://ret
|
|
//pop ret val from stack!
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
qprintf("ret");
|
|
break;
|
|
case 0xca: //jp z,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(cpu->f&F_Z)cpu->pc=tmp;
|
|
qprintf("jp z%s",cpu->f&F_Z?"":" ;skipped");
|
|
break;
|
|
case 0xcb: //PREFIX CB
|
|
//IX CBPREF IX CBPREF IX CBPR EF IXCBPR EFIX CBPR
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
qprintf("0x%.2x: ",tmp8);
|
|
cpu_decexecCB((uint8_t*)cpu,(uint8_t*)&tmp8,ram,quiet);
|
|
break;
|
|
case 0xcc: //call z,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(cpu->f&F_Z)
|
|
{
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp] =(uint8_t)cpu->pc;//push pc
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,(uint8_t)cpu->pc,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=tmp;
|
|
}
|
|
qprintf("call z,%.4xh%s",tmp,!cpu->a?"":" ;skipped");
|
|
break;
|
|
case 0xcd: //call m16
|
|
//push ret addr to stack!
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=(uint16_t)cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=(uint16_t)cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,(uint16_t)cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,(uint16_t)cpu->pc>>8,ram);
|
|
cpu->pc=tmp;
|
|
qprintf("call %.4xh ;ret to %.4xh",cpu->pc,ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xce: //adc a,m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
|
|
cpu->a+=tmp8+!!(cpu->f&F_C);
|
|
cpu->f&=~F_N;//N
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
//F_H
|
|
if(cpu->a<tmp8)cpu->f|=F_C;//F_C
|
|
else cpu->f&=~F_C;
|
|
qprintf("adc a,%.2x",tmp8);
|
|
break;
|
|
case 0xcf: //rst 08h (call 0000h + 00h)
|
|
//MessageBoxA(NULL,"RST08","-",MB_OK);
|
|
// cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0008;
|
|
qprintf("rst 08h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xd0: //ret nc
|
|
if(!(cpu->f&F_C))
|
|
{
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
}
|
|
qprintf("ret nc%s",cpu->f&F_C?" ;skipped":"");
|
|
break;
|
|
case 0xd1: //pop de
|
|
cpu->e=ram[cpu->sp];//little-endian
|
|
cpu->d=ram[cpu->sp+1];
|
|
cpu->sp+=2;
|
|
qprintf("pop de ;%.4xh",cpu->d<<8|cpu->e);
|
|
break;
|
|
case 0xd2: //jp nc,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(!(cpu->f&F_C))cpu->pc=tmp;
|
|
qprintf("jp nc,%.4xh%s",tmp,!cpu->a?" ;skipped":"");
|
|
break;
|
|
case 0xd4://call nc,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(!(cpu->f&F_C))
|
|
{
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp] =(uint8_t)cpu->pc;//push pc
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,(uint8_t)cpu->pc,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=tmp;
|
|
}
|
|
qprintf("call nc,%.4xh%s",tmp,cpu->f&F_C?" ;skipped":"");
|
|
break;
|
|
case 0xd5://push de
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp]=cpu->e;//little-endian
|
|
// ram[cpu->sp+1]=cpu->d;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->e,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->d,ram);
|
|
qprintf("push de ;%.4xh",cpu->d<<8|cpu->e);
|
|
break;
|
|
case 0xd6://sub m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
if(((cpu->a&0x0f)+(uint8_t)(tmp&0x0f))&0x10)cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
cpu->a-=(uint8_t)tmp;//2's complement add/sub aren't signed
|
|
if(!(cpu->a))cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
if(cpu->a<(uint8_t)tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("sub %.2xh",(uint8_t)tmp);
|
|
break;
|
|
case 0xd7://rst 10h (call 0000h + 10h)
|
|
// cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0010;
|
|
qprintf("rst 10h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xd8: //ret c
|
|
if(cpu->f&F_C)
|
|
{
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
}
|
|
qprintf("ret c%s",cpu->f&F_C?"":" ;skipped");
|
|
break;
|
|
case 0xd9: //reti
|
|
//pop ret val from stack!
|
|
cpu->pc=ram[cpu->sp]|ram[cpu->sp+1]<<8;
|
|
cpu->sp+=2;
|
|
// ram[0xffff]=0x1f;//enable all interrupts
|
|
cpu_write_ram(ppu,0xffff,0x1f,ram);
|
|
qprintf("reti");
|
|
break;
|
|
case 0xda: //jp c,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(cpu->f&F_C)cpu->pc=tmp;
|
|
qprintf("jp c%s",cpu->f&F_C?"":" ;skipped");
|
|
break;
|
|
case 0xdc: //call c,m16
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
if(cpu->f&F_C)
|
|
{
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp] =(uint8_t)cpu->pc;//push pc
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,(uint8_t)cpu->pc,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=tmp;
|
|
}
|
|
qprintf("call c,%.4xh%s",tmp,!cpu->a?"":" ;skipped");
|
|
break;
|
|
case 0xde: //sbc a,m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
tmp=cpu->a;
|
|
cpu->a-=tmp8+!(cpu->f&F_C);
|
|
if(tmp<tmp8)cpu->f&=~F_C;//C
|
|
else cpu->f|=F_C;
|
|
cpu->f|=F_Z;//Z
|
|
cpu->f|=F_N;//N
|
|
qprintf("sbc %.2x ;C:%x",tmp8,(cpu->f&F_C));
|
|
break;
|
|
case 0xdf: //rst 18h (call 0000h + 00h)
|
|
// cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0018;
|
|
qprintf("rst 18h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xe0://ldh (m8),a ---> ld (ff00 + m8),a
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
// ram[0xff00|tmp]=cpu->a;
|
|
cpu_write_ram(ppu,0xff00|tmp,cpu->a,ram);
|
|
qprintf("ldh (%.2xh),a ;ld (ff00h+%.2xh),a",tmp,tmp);
|
|
break;
|
|
case 0xe1://pop hl
|
|
cpu->l=ram[cpu->sp];
|
|
cpu->h=ram[cpu->sp+1];
|
|
cpu->sp+=2;
|
|
qprintf("pop hl ;%.4xh",cpu->h|cpu->l<<8);
|
|
break;
|
|
case 0xe2://ld (c),a
|
|
// cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
// ram[0xff00|(uint16_t)cpu->c]=cpu->a;
|
|
cpu_write_ram(ppu,0xff00|(uint16_t)cpu->c,cpu->a,ram);
|
|
qprintf("ld (c),a");
|
|
break;
|
|
case 0xe5://push hl
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp]=cpu->h;
|
|
// ram[cpu->sp+1]=cpu->l;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->h,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->l,ram);
|
|
qprintf("push hl ;%.4xh",cpu->h|cpu->l<<8);
|
|
break;
|
|
case 0xe6://and c ;and a,c
|
|
cpu->a&=cpu->c;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
cpu->f&=~F_N;//N
|
|
qprintf("and c");
|
|
break;
|
|
case 0xe7://rst 20h (call 0000h + 20h)
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0020;
|
|
qprintf("rst 20h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xe8: //add sp,m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
// tmp=cpu->sp;
|
|
cpu->sp+=tmp8;
|
|
cpu->f&=~F_Z;//Z
|
|
cpu->f&=~F_N;//N
|
|
if(cpu->sp<tmp8)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
if( ((cpu->sp&0x0f00)>>8) + ((tmp8&0x0f) & 0x10) )cpu->f|=F_H;
|
|
else cpu->f&=~F_H;
|
|
qprintf("add sp,%.2xh",tmp8);
|
|
break;
|
|
case 0xe9: //jp (hl)
|
|
cpu->pc=cpu->h<<8|cpu->l;
|
|
qprintf("jp (hl) ;%.4x",cpu->h<<8|cpu->l);
|
|
break;
|
|
case 0xea: //ld (m16),a
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
// ram[tmp]=cpu->a;
|
|
cpu_write_ram(ppu,tmp,cpu->a,ram);
|
|
qprintf("ld (%.4xh),a",tmp);
|
|
break;
|
|
case 0xee: //xor m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
cpu->a^=tmp8;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("xor %.2xh",tmp8);
|
|
break;
|
|
case 0xef: //rst 28h (call 0000h + 00h)
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0028;
|
|
qprintf("rst 28h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xf0://ldh a,(m8) ---> ld a,(ff00 + m8)
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
cpu->a=ram[0xff00|tmp];
|
|
qprintf("ldh a,(%.2xh) ;ld a,(ff00h+%.2xh)",tmp,tmp);
|
|
break;
|
|
case 0xf1://pop af
|
|
cpu->f=ram[cpu->sp];//little-endian
|
|
cpu->a=ram[cpu->sp+1];
|
|
cpu->sp+=2;
|
|
qprintf("pop bc ;%.4xh",cpu->a<<8|cpu->f);
|
|
break;
|
|
case 0xf2://ld a,(c)
|
|
cpu->a=ram[0xff00|(uint16_t)cpu->c];
|
|
qprintf("ld a,(c)");
|
|
break;
|
|
case 0xf3://di
|
|
//cpu_write_ram(ppu,0xffff,0x00,ram);
|
|
cpu->ime=0;
|
|
qprintf("di");
|
|
break;
|
|
case 0xf5://push af
|
|
cpu->sp-=2;
|
|
// ram[cpu->sp]=cpu->a;
|
|
// ram[cpu->sp+1]=cpu->f;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->a,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->f,ram);
|
|
qprintf("push af ;%.4xh",cpu->a|cpu->f<<8);
|
|
break;
|
|
case 0xf6://or m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
cpu->a|=tmp8;
|
|
if(!cpu->a)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
cpu->f&=~F_C;//C
|
|
qprintf("or %.2xh",tmp8);
|
|
break;
|
|
case 0xf7://rst 30h (call 0000h + 30h)
|
|
cpu->sp-=2;//alloc
|
|
// ram[cpu->sp]=cpu->pc&0x00ff;
|
|
// ram[cpu->sp+1]=cpu->pc>>8;
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0030;
|
|
qprintf("rst 30h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0xf8://ld hl,sp+m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp8);
|
|
tmp=cpu->sp+(int8_t)tmp8;//tmp8 needs to be sign-extended
|
|
cpu->h=tmp>>8;
|
|
cpu->l=(uint8_t)tmp;//trunc
|
|
cpu->f&=~F_Z;//Z
|
|
cpu->f&=~F_N;//N
|
|
if(tmp<tmp8)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
if((cpu->sp&0xff)+(tmp8&0xff))cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
qprintf("ld hl,sp%+ih",(int8_t)tmp8);
|
|
break;
|
|
case 0xf9: //ld sp,hl
|
|
tmp=cpu->h<<8|cpu->l;
|
|
cpu->sp=tmp;
|
|
qprintf("ld sp,hl ;%.4xh",tmp);
|
|
break;
|
|
case 0xfa: //ld a,(m16)
|
|
cpu_fetch16(cpu,rom,(uint16_t*)&tmp);
|
|
cpu->a=ram[tmp];
|
|
qprintf("ld a,(%.2xh)",tmp);
|
|
break;
|
|
case 0xfb: //ei
|
|
//cpu_write_ram(ppu,0xffff,0x1f,ram);
|
|
cpu->ime=1;
|
|
qprintf("ei");
|
|
break;
|
|
case 0xfe: //cp m8
|
|
cpu_fetch8(cpu,rom,(uint8_t*)&tmp);
|
|
//flags:
|
|
if(cpu->a-tmp==0)cpu->f|=F_Z;else cpu->f&=~F_Z;//Z
|
|
cpu->f|=F_N;//N
|
|
if((cpu->a&0x0f)-(tmp&0xf))cpu->f|=F_H;//H
|
|
else cpu->f&=~F_H;
|
|
if(cpu->a<tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
qprintf("cp %.2xh",tmp);
|
|
break;
|
|
case 0xff: //rst 38h (call 0000h + 38h)
|
|
//MessageBoxA(NULL,"RST38","-",MB_OK);
|
|
cpu->sp-=2;//alloc
|
|
cpu_write_ram(ppu,cpu->sp,cpu->pc&0x00ff,ram);
|
|
cpu_write_ram(ppu,cpu->sp+1,cpu->pc>>8,ram);
|
|
cpu->pc=0x0038;
|
|
qprintf("rst 38h ;ret to %.4xh",ram[cpu->sp]|ram[cpu->sp+1]<<8);
|
|
break;
|
|
case 0x00: //nop
|
|
case 0xd3: //nop
|
|
case 0xdb: //nop
|
|
case 0xdd: //nop
|
|
case 0xe3: //nop
|
|
case 0xe4: //nop
|
|
case 0xeb: //nop
|
|
case 0xec: //nop
|
|
case 0xed: //nop
|
|
case 0xf4: //nop
|
|
case 0xfc: //nop
|
|
case 0xfd: //nop
|
|
default:
|
|
qprintf("nop");
|
|
break;
|
|
}
|
|
}
|
|
|
|
// CB Prefix instructions
|
|
void cpu_decexecCB(uint8_t*cpua,uint8_t*op,uint8_t*ram,bool quiet)
|
|
{
|
|
static const uint8_t cbreg[]={2,3,4,5,6,7,0xff,0}; //(op&0xf)%8
|
|
static const char*cbrnm[]={"b","c","d","e","h","l","(hl)","a"};
|
|
uint16_t tmp;
|
|
uint8_t tmp8;
|
|
Cpu*cpu=(Cpu*)cpua;
|
|
|
|
//08h - 0fh RRC
|
|
if(*op>=0x08 && *op<=0x0f)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)
|
|
{
|
|
if(ram[cpu->h<<8|cpu->l]&0x1)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=ram[cpu->h<<8|cpu->l];
|
|
|
|
if(cpu->f&F_C)asm(" stc");
|
|
else asm(" clc");
|
|
asm("mov %0,%%ax":"=m"(tmp));
|
|
asm("rcr %al");
|
|
asm("mov %%ax,%0":"=m"(tmp));
|
|
|
|
ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
}
|
|
else
|
|
{
|
|
if(cpua[cbreg[tmp8]]&0x1)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=cpua[cbreg[tmp8]];
|
|
|
|
if(cpu->f&F_C)asm(" stc");
|
|
else asm(" clc");
|
|
asm("mov %0,%%ax":"=m"(tmp));
|
|
asm("rcr %al");
|
|
asm("mov %%ax,%0":"=m"(tmp));
|
|
|
|
cpua[cbreg[tmp8]]=(uint8_t)tmp;
|
|
}
|
|
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!(uint8_t)tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("rrc %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
/*NOTE: For some reason, RRC/RLC doesn't use CF, but RR/RL does*/
|
|
//00h - 07h RLC
|
|
//if((*op>=0x00) && (*op<=0x07))
|
|
if(*op<=0x07)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)
|
|
{
|
|
if(ram[cpu->h<<8|cpu->l]&0x80)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=ram[cpu->h<<8|cpu->l];
|
|
|
|
if(cpu->f&F_C)asm(" stc");
|
|
else asm("clc");
|
|
asm("mov %0,%%ax":"=m"(tmp));
|
|
asm("rcl %al");
|
|
asm("mov %%ax,%0":"=m"(tmp));
|
|
|
|
ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
}
|
|
else
|
|
{
|
|
if(cpua[cbreg[tmp8]]&0x80)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=cpua[cbreg[tmp8]];
|
|
|
|
if(cpu->f&F_C)asm(" stc");
|
|
else asm(" clc");
|
|
asm("mov %0,%%ax":"=m"(tmp));
|
|
asm("rcl %al");
|
|
asm("mov %%ax,%0":"=m"(tmp));
|
|
|
|
cpua[cbreg[tmp8]]=(uint8_t)tmp;
|
|
}
|
|
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!(uint8_t)tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("rlc %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//18h - 1fh RR
|
|
if(*op>=0x18 && *op<=0x1f)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)
|
|
{
|
|
uint8_t cf=cpu->f&F_C;
|
|
if(ram[cpu->h<<8|cpu->l]&0x1)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=ram[cpu->h<<8|cpu->l];
|
|
|
|
|
|
if(cf)asm("stc");
|
|
else asm("clc");
|
|
asm("mov %0,%%ax":"=m"(tmp));
|
|
asm("rcr %al");
|
|
asm("mov %%ax,%0":"=m"(tmp));
|
|
|
|
ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
}
|
|
else
|
|
{
|
|
uint8_t cf=cpu->f&F_C;
|
|
if(cpua[cbreg[tmp8]]&0x1)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=cpua[cbreg[tmp8]];
|
|
|
|
if(cf)asm(" stc");
|
|
else asm(" clc");
|
|
asm("mov %0,%%al":"=m"(tmp));
|
|
asm("rcr %al");
|
|
asm("mov %%al,%0":"=m"(tmp));
|
|
|
|
cpua[cbreg[tmp8]]=(uint8_t)tmp;
|
|
}
|
|
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!(uint8_t)tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("rr %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//10h - 17h RL
|
|
if(*op>=0x10 && *op<=0x17)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)
|
|
{
|
|
uint8_t cf=cpu->f&F_C;
|
|
if(ram[cpu->h<<8|cpu->l]&0x80)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=ram[cpu->h<<8|cpu->l];
|
|
|
|
|
|
if(cf)asm(" stc");
|
|
else asm(" clc");
|
|
asm("mov %0,%%al":"=m"(tmp));
|
|
asm("rcl %al");
|
|
asm("mov %%al,%0":"=m"(tmp));
|
|
|
|
ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
}
|
|
else
|
|
{
|
|
uint8_t cf=cpu->f&F_C;
|
|
if(cpua[cbreg[tmp8]]&0x80)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
|
|
tmp=cpua[cbreg[tmp8]];
|
|
|
|
|
|
if(cf)asm("stc");
|
|
else asm("clc");
|
|
asm("mov %0,%%al":"=m"(tmp));
|
|
asm("rcl %al");
|
|
asm("mov %%al,%0":"=m"(tmp));
|
|
|
|
cpua[cbreg[tmp8]]=(uint8_t)tmp;
|
|
}
|
|
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!(uint8_t)tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("rl %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//28h - 2fh SRA
|
|
if(*op>=0x28 && *op<=0x2f)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
if(tmp8==6)
|
|
{
|
|
//NOTE: We are depending on arithmetic shift here,
|
|
// sra is a 'signed' operation
|
|
tmp=ram[cpu->h<<8|cpu->l]&0x1;
|
|
tmp8=ram[cpu->h<<8|cpu->l]>>=1;
|
|
}
|
|
else
|
|
{
|
|
tmp=cpua[cbreg[tmp8]]&0x1;
|
|
tmp8=cpua[cbreg[tmp8]]>>=1;
|
|
}
|
|
|
|
if(tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!tmp8)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("sra %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//20h - 27h SLA
|
|
if(*op>=0x20 && *op<=0x27)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
if(tmp8==6)
|
|
{
|
|
tmp=ram[cpu->h<<8|cpu->l]&0x80;
|
|
tmp8=ram[cpu->h<<8|cpu->l]<<=1;
|
|
}
|
|
else
|
|
{
|
|
tmp=cpua[cbreg[tmp8]]&0x80;
|
|
tmp8=cpua[cbreg[tmp8]]<<=1;
|
|
|
|
}
|
|
|
|
if(tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!tmp8)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("sla %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//30h - 3fh SRL
|
|
if(*op>=0x38 && *op<=0x3f)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
if(tmp8==6)
|
|
{
|
|
//NOTE: We are depending on logical shift here,
|
|
// srl is an 'unsigned' operation
|
|
tmp=ram[cpu->h<<8|cpu->l]&0x1;
|
|
tmp8=ram[cpu->h<<8|cpu->l]>>=1;
|
|
}
|
|
else
|
|
{
|
|
tmp=cpua[cbreg[tmp8]]&0x1;
|
|
tmp8=cpua[cbreg[tmp8]]>>=1;
|
|
|
|
}
|
|
|
|
if(tmp)cpu->f|=F_C;//C
|
|
else cpu->f&=~F_C;
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!tmp8)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("srl %s",cbrnm[(*op&0xf)%8]);
|
|
}
|
|
|
|
//30h - 37h SWAP
|
|
if(*op>=0x30 && *op<=0x37)
|
|
{
|
|
tmp8=(*op&0xf)%8;
|
|
if(tmp8==6)tmp=ram[cpu->h<<8|cpu->l];
|
|
else tmp=cpua[cbreg[tmp8]];//reg
|
|
|
|
asm("mov %0,%%al":"=m"(tmp));
|
|
tmp=ror(tmp,4);
|
|
//asm("rorb %0,%%al");
|
|
asm("mov %%al,%0":"=m"(tmp));
|
|
|
|
if(tmp8==6)ram[cpu->h<<8|cpu->l]=(uint8_t)tmp;
|
|
else cpua[cbreg[tmp8]]=(uint8_t)tmp;//reg
|
|
|
|
cpu->f&=~F_C;//C
|
|
cpu->f&=~F_N;//N
|
|
cpu->f&=~F_H;//H
|
|
if(!(uint8_t)tmp)cpu->f|=F_Z;//Z
|
|
else cpu->f&=~F_Z;
|
|
|
|
qprintf("swap %s ; %.2xh",cbrnm[(*op&0xf)%8],(uint8_t)tmp);
|
|
}
|
|
|
|
//40h - 7fh BIT
|
|
if(*op>=0x40 && *op<=0x80)
|
|
{
|
|
tmp=((*op&0xf0)>>4)%4*2+((*op&0x0f)>=8);//bit
|
|
tmp8=(*op&0xf)%8;
|
|
if(tmp8==6)tmp8=ram[cpu->h<<8|cpu->l];
|
|
else tmp8=cpua[cbreg[tmp8]];//reg
|
|
if(tmp8&0x1<<tmp)cpu->f&=~F_Z;//Z
|
|
else cpu->f|=F_Z;
|
|
cpu->f|=F_H;//H
|
|
cpu->f&=~F_N;//N
|
|
qprintf("bit %u,%s ;%x (%x)",tmp,cbrnm[(*op&0xf)%8],cpu->f&F_Z,tmp8&0x1<<tmp);
|
|
return;
|
|
}
|
|
|
|
//80h - bfh RES
|
|
if(*op>=0x80 && *op<=0xbf)
|
|
{
|
|
tmp=((*op&0xf0)>>4)%4*2+((*op&0x0f)>=8);//bit
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)ram[cpu->h<<8|cpu->l]&=~(1<<tmp);
|
|
else cpua[cbreg[tmp8]]&=~(1<<tmp);//reg
|
|
|
|
qprintf("res %u,%s",tmp,cbrnm[(*op&0xf)%8]);
|
|
return;
|
|
}
|
|
|
|
//c0h - ffh SET
|
|
//if(*op>=0xc0 && *op<=0xff)
|
|
if(*op>=0xc0)
|
|
{
|
|
tmp=((*op&0xf0)>>4)%4*2+((*op&0x0f)>=8);//bit
|
|
tmp8=(*op&0xf)%8;
|
|
|
|
if(tmp8==6)ram[cpu->h<<8|cpu->l]|=(1<<tmp);
|
|
else cpua[cbreg[tmp8]]|=(1<<tmp);//reg
|
|
|
|
qprintf("set %u,%s",tmp,cbrnm[(*op&0xf)%8]);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void cpu_log_clear(void)
|
|
{
|
|
log_buffer[0]='\0';
|
|
}
|
|
|
|
#undef qprintf
|