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/z80.h

Committer:
gertk
Date:
2011-06-29
Revision:
0:806c2f2a7d47

File content as of revision 0:806c2f2a7d47:

/* z81/xz81, Linux console and X ZX81/ZX80 emulators.
 * Copyright (C) 1994 Ian Collier. z81 changes (C) 1995-2001 Russell Marks.
 *
 * 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.
 */

// I have made all Z80 registers global and volatile
volatile bool iff1, iff2;
unsigned char im;
volatile unsigned char a, f, b, c, d, e, h, l;
volatile unsigned char r, a1, f1, b1, c1, d1, e1, h1, l1, i;
volatile unsigned short pc;
volatile unsigned short ix, iy, sp;

// some flags
volatile   bool intpend=0;
volatile   unsigned char new_ixoriy=0;
volatile   unsigned char ixoriy=0;


#define Z80_quit  1
#define Z80_NMI   2
#define Z80_reset 3
#define Z80_load  4
#define Z80_save  5
#define Z80_log   6

#define parity(a) (partable[a])
unsigned char partable[256]={
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
      4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4
   };


#define fetch(x) (rdmem(x))
#define fetch2(x) ((fetch((x)+1)<<8)|fetch(x))

// store 8 bit value y at 16 bit location x
#define store(x,y) (wrmem(x,(y)))

#define store2b(x,hi,lo) do {wrmem(x,lo);wrmem(x+1,hi);}while(0)

#define store2(x,y) store2b(x,(y)>>8,(y)&255)

#define bc ((b<<8)|c)
#define de ((d<<8)|e)
#define hl ((h<<8)|l)

#define instr(opcode,cycles) case opcode: {
#define HLinstr(opcode) \
                             case opcode: {unsigned short addr; \
                                if(ixoriy==0)addr=hl; \
                                else    addr=(ixoriy==1?ix:iy)+ \
                                        (signed char)fetch(pc),\
                                   pc++
#define endinstr             }; break

#define cy (f&1)

#define xh (ixoriy==0?h:ixoriy==1?(ix>>8):(iy>>8))
#define xl (ixoriy==0?l:ixoriy==1?(ix&0xff):(iy&0xff))

#define setxh(x) (ixoriy==0?(h=(x)):ixoriy==1?(ix=(ix&0xff)|((x)<<8)):\
                  (iy=(iy&0xff)|((x)<<8)))
#define setxl(x) (ixoriy==0?(l=(x)):ixoriy==1?(ix=(ix&0xff00)|(x)):\
                  (iy=(iy&0xff00)|(x)))

#define inc(var) /* 8-bit increment */ ( var++,\
                                         f=(f&1)|(var&0xa8)|\
                                           ((!(var&15))<<4)|((!var)<<6)|\
                                           ((var==128)<<2)\
                                       )
#define dec(var) /* 8-bit decrement */ ( f=(f&1)|((!(var&15))<<4)|2,\
                                         --var,\
                                         f|=(var&0xa8)|((var==127)<<2)|\
                                            ((!var)<<6)\
                                       )
#define swap(x,y) {unsigned char t=x; x=y; y=t;}
#define addhl(hi,lo) /* 16-bit add */ if(!ixoriy){\
                      unsigned short t;\
                      l=t=l+(lo);\
                      f=(f&0xc4)|(((t>>=8)+(h&0x0f)+((hi)&0x0f)>15)<<4);\
                      h=t+=h+(hi);\
                      f|=(h&0x28)|(t>>8);\
                   }\
                   else do{unsigned long t=(ixoriy==1?ix:iy);\
                      f=(f&0xc4)|(((t&0xfff)+((hi<<8)|lo)>0xfff)<<4);\
                      t+=(hi<<8)|lo;\
                      if(ixoriy==1)ix=t; else iy=t;\
                      f|=((t>>8)&0x28)|(t>>16);\
                   } while(0)

#define adda(x,c) /* 8-bit add */ do{unsigned short y;\
                      unsigned char z=(x);\
                      y=a+z+(c);\
                      f=(y&0xa8)|(y>>8)|(((a&0x0f)+(z&0x0f)+(c)>15)<<4)|\
                        (((~a^z)&0x80&(y^a))>>5);\
                        a=y; \
                      f|=(!a)<<6;\
                   } while(0)
#define suba(x,c) /* 8-bit subtract */ do{unsigned short y;\
                      unsigned char z=(x);\
                      y=(a-z-(c))&0x1ff;\
                      f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f)+(c))<<4)|\
                        (((a^z)&0x80&(y^a))>>5)|2;\
                        a=y; \
                      f|=(!a)<<6;\
                   } while(0)
#define cpa(x) /* 8-bit compare */ do{unsigned short y;\
                      unsigned char z=(x);\
                      y=(a-z)&0x1ff;\
                      f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f))<<4)|\
                        (((a^z)&0x80&(y^a))>>5)|2|((!y)<<6);\
                   } while(0)
#define anda(x) /* logical and */ do{\
                      a&=(x);\
                      f=(a&0xa8)|((!a)<<6)|0x10|parity(a);\
                   } while(0)
#define xora(x) /* logical xor */ do{\
                      a^=(x);\
                      f=(a&0xa8)|((!a)<<6)|parity(a);\
                   } while(0)
#define ora(x) /* logical or */ do{\
                      a|=(x);\
                      f=(a&0xa8)|((!a)<<6)|parity(a);\
                   } while(0)

#define jr /* execute relative jump */ do{int j=(signed char)fetch(pc);\
                      pc+=j+1;\
                   } while(0)
#define jp /* execute jump */ (pc=fetch2(pc))
#define call /* execute call */ do{\
                      push2(pc+2);\
                      jp;\
                   } while(0)
#define ret /* execute return */ do{\
                      pop2(pc);\
                   } while(0)
#define pop2(var) /* pop 16-bit register */ (var=fetch2(sp),sp+=2)
#define pop1(v1,v2) /* pop register pair */ (v2=fetch(sp),\
                                             v1=fetch(sp+1),sp+=2)
#define push2(val) /* push 16-bit register */ do{sp-=2;store2(sp,(val));}\
                                              while(0)
#define push1(v1,v2) /* push register pair */ do{sp-=2;\
                                                 store2b(sp,v1,v2);\
                                              }while(0)