BBC Basic in Z80 emulation on the mbed, USB serial terminal output only. LOAD and SAVE work on the local file system but there is no error signalling.
z80/z80ops.h
- Committer:
- gertk
- Date:
- 2011-06-29
- Revision:
- 0:806c2f2a7d47
File content as of revision 0:806c2f2a7d47:
/* Emulations of the Z80 CPU instruction set - part of xz80. * Copyright (C) 1994 Ian Collier. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* nop */ case 0: break; // ld BC,nn instr(0x01,10); c=fetch(pc),pc++; b=fetch(pc),pc++; endinstr; // ld (BC),A instr(0x02,7); store(bc,a); endinstr; // inc BC instr(0x03,6); if (!++c)b++; endinstr; // inc B instr(0x04,4); inc(b); endinstr; // dec B instr(0x05,4); dec(b); endinstr; // ld B,n instr(0x06,7); b=fetch(pc),pc++; endinstr; // rlca instr(0x07,4); a=(a<<1)|(a>>7); f=(f&0xc4)|(a&0x29); endinstr; // ex AF,AF' instr(0x08,4); swap(a,a1); swap(f,f1); endinstr; // add HL,BC instr(0x09,11); addhl(b,c); endinstr; // ld A,(BC) instr(0x0a,7); a=fetch(bc); endinstr; // dec BC instr(0x0b,6); if (!c--)b--; endinstr; // inc C instr(0x0c,4); inc(c); endinstr; // dec C instr(0x0d,4); dec(c); endinstr; // ld C,n instr(0x0e,4); c=fetch(pc),pc++; endinstr; // rrca instr(0x0f,4); f=(f&0xc4)|(a&1); a=(a>>1)|(a<<7); f|=a&0x28; endinstr; // djnz instr(0x10,8); if (!--b)pc++; else jr; endinstr; // ld DE,nn instr(0x11,10); e=fetch(pc),pc++; d=fetch(pc),pc++; endinstr; // ld (DE),A instr(0x12,7); store(de,a); endinstr; // inc DE instr(0x13,6); if (!++e)d++; endinstr; // inc D instr(0x14,4); inc(d); endinstr; // dec D instr(0x15,4); dec(d); endinstr; // ld D,n instr(0x16,7); d=fetch(pc),pc++; endinstr; // rla instr(0x17,4); { int t=a>>7; a=(a<<1)|(f&1); f=(f&0xc4)|(a&0x28)|t; } endinstr; // JR instr(0x18,7); jr; endinstr; // add HL,DE instr(0x19,11); addhl(d,e); endinstr; // ld A,(DE) instr(0x1a,7); a=fetch(de); endinstr; // dec DE instr(0x1b,6); if (!e--)d--; endinstr; // inc E instr(0x1c,4); inc(e); endinstr; // dec E instr(0x1d,4); dec(e); endinstr; // ld E,n instr(0x1e,4); e=fetch(pc),pc++; endinstr; // rra instr(0x1f,4); { int t=a&1; a=(a>>1)|(f<<7); f=(f&0xc4)|(a&0x28)|t; } endinstr; // jr NZ instr(0x20,7); if (f&0x40)pc++; else jr; endinstr; // ld HL,nn instr(0x21,10); if (!ixoriy) { l=fetch(pc),pc++; h=fetch(pc),pc++; } else { if (ixoriy==1) ix=fetch2(pc); else iy=fetch2(pc); pc+=2; } endinstr; // ld (nn),HL instr(0x22,16); { unsigned short addr=fetch2(pc); pc+=2; if (!ixoriy) store2b(addr,h,l); else if (ixoriy==1)store2(addr,ix); else store2(addr,iy); } endinstr; // inc HL instr(0x23,6); if (!ixoriy) { if (!++l)h++; } else if (ixoriy==1)ix++; else iy++; endinstr; // inc H instr(0x24,4); if (ixoriy==0)inc(h); else { unsigned char t; t=(ixoriy==1?ix:iy)>>8; inc(t); if (ixoriy==1)ix=(ix&0xff)|(t<<8); else iy=(iy&0xff)|(t<<8); } endinstr; // dec H instr(0x25,4); if (ixoriy==0)dec(h); else { unsigned char t; t=(ixoriy==1?ix:iy)>>8; dec(t); if (ixoriy==1)ix=(ix&0xff)|(t<<8); else iy=(iy&0xff)|(t<<8); } endinstr; // ld H,n instr(0x26,7); setxh(fetch(pc)); pc++; endinstr; // daa instr(0x27,4); { unsigned char incr=0, carry=cy; if ((f&0x10) || (a&0x0f)>9) incr=6; if ((f&1) || (a>>4)>9) incr|=0x60; if (f&2) suba(incr,0); else { if (a>0x90 && (a&15)>9)incr|=0x60; adda(incr,0); } f=((f|carry)&0xfb)|parity(a); } endinstr; // jr Z instr(0x28,7); if (f&0x40)jr; else pc++; endinstr; // add HL,HL instr(0x29,11); if (!ixoriy)addhl(h,l); else if (ixoriy==1)addhl((ix>>8),(ix&0xff)); else addhl((iy>>8),(iy&0xff)); endinstr; // ld HL,(nn) instr(0x2a,16); { unsigned short addr=fetch2(pc); pc+=2; if (!ixoriy) { l=fetch(addr); h=fetch(addr+1); } else if (ixoriy==1)ix=fetch2(addr); else iy=fetch2(addr); } endinstr; // dec HL instr(0x2b,6); if (!ixoriy) { if (!l--)h--; } else if (ixoriy==1)ix--; else iy--; endinstr; // inc L instr(0x2c,4); if (!ixoriy)inc(l); else { unsigned char t; t=(ixoriy==1?ix:iy); inc(t); if (ixoriy==1)ix=(ix&0xff00)|t; else iy=(iy&0xff00)|t; } endinstr; // dec L instr(0x2d,4); if (!ixoriy)dec(l); else { unsigned char t; t=(ixoriy==1?ix:iy); dec(t); if (ixoriy==1)ix=(ix&0xff00)|t; else iy=(iy&0xff00)|t; } endinstr; // ld L,n instr(0x2e,4); setxl(fetch(pc)); pc++; endinstr; // cpl instr(0x2f,4); a=~a; f=(f&0xc5)|(a&0x28)|0x12; endinstr; // jr NC instr(0x30,7); if (f&1)pc++; else jr; endinstr; // ld SP,nn instr(0x31,10); sp=fetch2(pc); pc+=2; endinstr; // ld (nn),A instr(0x32,13); { unsigned short addr=fetch2(pc); pc+=2; store(addr,a); } endinstr; // inc SP instr(0x33,6); sp++; endinstr; // inc (HL) HLinstr(0x34); { unsigned char t=fetch(addr); inc(t); store(addr,t); } endinstr; // dec (HL) HLinstr(0x35); { unsigned char t=fetch(addr); dec(t); store(addr,t); } endinstr; // ld (HL),n HLinstr(0x36); store(addr,fetch(pc)); pc++; endinstr; // scf instr(0x37,4); f=(f&0xc4)|1|(a&0x28); endinstr; // jr C instr(0x38,7); if (f&1)jr; else pc++; endinstr; // add HL,SP instr(0x39,11); addhl((sp>>8),(sp&0xff)); endinstr; // ld A,(nn) instr(0x3a,13); { unsigned short addr=fetch2(pc); pc+=2; a=fetch(addr); } endinstr; // dec SP instr(0x3b,6); sp--; endinstr; // inc A instr(0x3c,4); inc(a); endinstr; // dec A instr(0x3d,4); dec(a); endinstr; // ld A,n instr(0x3e,4); a=fetch(pc),pc++; endinstr; // ccf instr(0x3f,4); f=(f&0xc4)|(cy^1)|(cy<<4)|(a&0x28); endinstr; // ld B,B instr(0x40,4); /* ld b,b */ endinstr; instr(0x41,4); b=c; endinstr; instr(0x42,4); b=d; endinstr; instr(0x43,4); b=e; endinstr; instr(0x44,4); b=xh; endinstr; instr(0x45,4); b=xl; endinstr; HLinstr(0x46); b=fetch(addr); endinstr; instr(0x47,4); b=a; endinstr; instr(0x48,4); c=b; endinstr; instr(0x49,4); /* ld c,c */ endinstr; instr(0x4a,4); c=d; endinstr; instr(0x4b,4); c=e; endinstr; instr(0x4c,4); c=xh; endinstr; instr(0x4d,4); c=xl; endinstr; HLinstr(0x4e); c=fetch(addr); endinstr; instr(0x4f,4); c=a; endinstr; instr(0x50,4); d=b; endinstr; instr(0x51,4); d=c; endinstr; instr(0x52,4); /* ld d,d */ endinstr; instr(0x53,4); d=e; endinstr; instr(0x54,4); d=xh; endinstr; instr(0x55,4); d=xl; endinstr; HLinstr(0x56); d=fetch(addr); endinstr; instr(0x57,4); d=a; endinstr; instr(0x58,4); e=b; endinstr; instr(0x59,4); e=c; endinstr; instr(0x5a,4); e=d; endinstr; instr(0x5b,4); /* ld e,e */ endinstr; instr(0x5c,4); e=xh; endinstr; instr(0x5d,4); e=xl; endinstr; HLinstr(0x5e); e=fetch(addr); endinstr; instr(0x5f,4); e=a; endinstr; instr(0x60,4); setxh(b); endinstr; instr(0x61,4); setxh(c); endinstr; instr(0x62,4); setxh(d); endinstr; instr(0x63,4); setxh(e); endinstr; instr(0x64,4); /* ld h,h */ endinstr; instr(0x65,4); setxh(xl); endinstr; HLinstr(0x66); h=fetch(addr); endinstr; instr(0x67,4); setxh(a); endinstr; instr(0x68,4); setxl(b); endinstr; instr(0x69,4); setxl(c); endinstr; instr(0x6a,4); setxl(d); endinstr; instr(0x6b,4); setxl(e); endinstr; instr(0x6c,4); setxl(xh); endinstr; instr(0x6d,4); /* ld l,l */ endinstr; HLinstr(0x6e); l=fetch(addr); endinstr; instr(0x6f,4); setxl(a); endinstr; HLinstr(0x70); store(addr,b); endinstr; HLinstr(0x71); store(addr,c); endinstr; HLinstr(0x72); store(addr,d); endinstr; HLinstr(0x73); store(addr,e); endinstr; HLinstr(0x74); store(addr,h); endinstr; HLinstr(0x75); store(addr,l); endinstr; // HALT instr(0x76,4); pc--; /* keep nopping until int */ endinstr; HLinstr(0x77); store(addr,a); endinstr; instr(0x78,4); a=b; endinstr; instr(0x79,4); a=c; endinstr; instr(0x7a,4); a=d; endinstr; instr(0x7b,4); a=e; endinstr; instr(0x7c,4); a=xh; endinstr; instr(0x7d,4); a=xl; endinstr; HLinstr(0x7e); a=fetch(addr); endinstr; instr(0x7f,4); /* ld a,a */ endinstr; instr(0x80,4); adda(b,0); endinstr; instr(0x81,4); adda(c,0); endinstr; instr(0x82,4); adda(d,0); endinstr; instr(0x83,4); adda(e,0); endinstr; instr(0x84,4); adda(xh,0); endinstr; instr(0x85,4); adda(xl,0); endinstr; HLinstr(0x86); adda(fetch(addr),0); endinstr; instr(0x87,4); adda(a,0); endinstr; instr(0x88,4); adda(b,cy); endinstr; instr(0x89,4); adda(c,cy); endinstr; instr(0x8a,4); adda(d,cy); endinstr; instr(0x8b,4); adda(e,cy); endinstr; instr(0x8c,4); adda(xh,cy); endinstr; instr(0x8d,4); adda(xl,cy); endinstr; HLinstr(0x8e); adda(fetch(addr),cy); endinstr; instr(0x8f,4); adda(a,cy); endinstr; instr(0x90,4); suba(b,0); endinstr; instr(0x91,4); suba(c,0); endinstr; instr(0x92,4); suba(d,0); endinstr; instr(0x93,4); suba(e,0); endinstr; instr(0x94,4); suba(xh,0); endinstr; instr(0x95,4); suba(xl,0); endinstr; HLinstr(0x96); suba(fetch(addr),0); endinstr; instr(0x97,4); suba(a,0); endinstr; instr(0x98,4); suba(b,cy); endinstr; instr(0x99,4); suba(c,cy); endinstr; instr(0x9a,4); suba(d,cy); endinstr; instr(0x9b,4); suba(e,cy); endinstr; instr(0x9c,4); suba(xh,cy); endinstr; instr(0x9d,4); suba(xl,cy); endinstr; HLinstr(0x9e); suba(fetch(addr),cy); endinstr; instr(0x9f,4); suba(a,cy); endinstr; instr(0xa0,4); anda(b); endinstr; instr(0xa1,4); anda(c); endinstr; instr(0xa2,4); anda(d); endinstr; instr(0xa3,4); anda(e); endinstr; instr(0xa4,4); anda(xh); endinstr; instr(0xa5,4); anda(xl); endinstr; HLinstr(0xa6); anda(fetch(addr)); endinstr; instr(0xa7,4); anda(a); endinstr; instr(0xa8,4); xora(b); endinstr; instr(0xa9,4); xora(c); endinstr; instr(0xaa,4); xora(d); endinstr; instr(0xab,4); xora(e); endinstr; instr(0xac,4); xora(xh); endinstr; instr(0xad,4); xora(xl); endinstr; HLinstr(0xae); xora(fetch(addr)); endinstr; instr(0xaf,4); xora(a); endinstr; instr(0xb0,4); ora(b); endinstr; instr(0xb1,4); ora(c); endinstr; instr(0xb2,4); ora(d); endinstr; instr(0xb3,4); ora(e); endinstr; instr(0xb4,4); ora(xh); endinstr; instr(0xb5,4); ora(xl); endinstr; HLinstr(0xb6); ora(fetch(addr)); endinstr; instr(0xb7,4); ora(a); endinstr; instr(0xb8,4); cpa(b); endinstr; instr(0xb9,4); cpa(c); endinstr; instr(0xba,4); cpa(d); endinstr; instr(0xbb,4); cpa(e); endinstr; instr(0xbc,4); cpa(xh); endinstr; instr(0xbd,4); cpa(xl); endinstr; HLinstr(0xbe); cpa(fetch(addr)); endinstr; instr(0xbf,4); cpa(a); endinstr; instr(0xc0,5); if (!(f&0x40))ret; endinstr; instr(0xc1,10); pop1(b,c); endinstr; instr(0xc2,10); if (!(f&0x40))jp; else pc+=2; endinstr; instr(0xc3,10); jp; endinstr; instr(0xc4,10); if (!(f&0x40))call; else pc+=2; endinstr; instr(0xc5,11); push1(b,c); endinstr; instr(0xc6,7); adda(fetch(pc),0); pc++; endinstr; instr(0xc7,11); push2(pc); pc=0; endinstr; instr(0xc8,5); if (f&0x40)ret; endinstr; instr(0xc9,4); ret; endinstr; instr(0xca,10); if (f&0x40)jp; else pc+=2; endinstr; instr(0xcb,4); #include "cbops.h" endinstr; instr(0xcc,10); if (f&0x40)call; else pc+=2; endinstr; instr(0xcd,10); call; endinstr; instr(0xce,7); adda(fetch(pc),cy); pc++; endinstr; instr(0xcf,11); push2(pc); pc=8; endinstr; instr(0xd0,5); if (!cy)ret; endinstr; instr(0xd1,10); pop1(d,e); endinstr; instr(0xd2,10); if (!cy)jp; else pc+=2; endinstr; // OUT instr(0xd3,11); out(fetch(pc),a); pc++; endinstr; instr(0xd4,10); if (!cy)call; else pc+=2; endinstr; instr(0xd5,11); push1(d,e); endinstr; instr(0xd6,7); suba(fetch(pc),0); pc++; endinstr; instr(0xd7,11); push2(pc); pc=16; endinstr; instr(0xd8,5); if (cy)ret; endinstr; instr(0xd9,4); swap(b,b1); swap(c,c1); swap(d,d1); swap(e,e1); swap(h,h1); swap(l,l1); endinstr; instr(0xda,10); if (cy)jp; else pc+=2; endinstr; // IN instr(0xdb,11); { a=in(fetch(pc)); pc++; } endinstr; instr(0xdc,10); if (cy)call; else pc+=2; endinstr; instr(0xdd,4); new_ixoriy=1; endinstr; instr(0xde,7); suba(fetch(pc),cy); pc++; endinstr; // RST 18 instr(0xdf,11); push2(pc); pc=0x0018; endinstr; instr(0xe0,5); if (!(f&4))ret; endinstr; instr(0xe1,10); if (!ixoriy)pop1(h,l); else if (ixoriy==1)pop2(ix); else pop2(iy); endinstr; instr(0xe2,10); if (!(f&4))jp; else pc+=2; endinstr; instr(0xe3,19); if (!ixoriy) { unsigned short t=fetch2(sp); store2b(sp,h,l); l=t; h=t>>8; } else if (ixoriy==1) { unsigned short t=fetch2(sp); store2(sp,ix); ix=t; } else { unsigned short t=fetch2(sp); store2(sp,iy); iy=t; } endinstr; instr(0xe4,10); if (!(f&4))call; else pc+=2; endinstr; instr(0xe5,11); if (!ixoriy)push1(h,l); else if (ixoriy==1)push2(ix); else push2(iy); endinstr; instr(0xe6,7); anda(fetch(pc)); pc++; endinstr; instr(0xe7,11); push2(pc); pc=32; endinstr; instr(0xe8,5); if (f&4)ret; endinstr; instr(0xe9,4); pc=!ixoriy?hl:ixoriy==1?ix:iy; endinstr; instr(0xea,10); if (f&4)jp; else pc+=2; endinstr; instr(0xeb,4); swap(h,d); swap(e,l); endinstr; instr(0xec,10); if (f&4)call; else pc+=2; endinstr; instr(0xed,4); #include"edops.h" endinstr; instr(0xee,7); xora(fetch(pc)); pc++; endinstr; instr(0xef,11); push2(pc); pc=40; endinstr; instr(0xf0,5); if (!(f&0x80))ret; endinstr; instr(0xf1,10); pop1(a,f); endinstr; instr(0xf2,10); if (!(f&0x80))jp; else pc+=2; endinstr; instr(0xf3,4); iff1=iff2=0; // __disable_irq(); endinstr; instr(0xf4,10); if (!(f&0x80))call; else pc+=2; endinstr; instr(0xf5,11); push1(a,f); endinstr; instr(0xf6,7); ora(fetch(pc)); pc++; endinstr; // rst 30 instr(0xf7,11); push2(pc); pc=0x30; // printf("RST30\n\r"); endinstr; instr(0xf8,5); if (f&0x80)ret; endinstr; instr(0xf9,6); sp=!ixoriy?hl:ixoriy==1?ix:iy; endinstr; instr(0xfa,10); if (f&0x80)jp; else pc+=2; endinstr; instr(0xfb,4); iff1=iff2=1; endinstr; instr(0xfc,10); if (f&0x80)call; else pc+=2; endinstr; instr(0xfd,4); new_ixoriy=2; endinstr; instr(0xfe,7); cpa(fetch(pc)); pc++; endinstr; instr(0xff,11); push2(pc); pc=56; endinstr;