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.

Dependencies:   mbed

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;