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.
Diff: z80/z80ops.h
- Revision:
- 0:806c2f2a7d47
diff -r 000000000000 -r 806c2f2a7d47 z80/z80ops.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/z80/z80ops.h Wed Jun 29 14:25:56 2011 +0000 @@ -0,0 +1,1218 @@ +/* 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; +