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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers z80.h Source File

z80.h

00001 /* z81/xz81, Linux console and X ZX81/ZX80 emulators.
00002  * Copyright (C) 1994 Ian Collier. z81 changes (C) 1995-2001 Russell Marks.
00003  *
00004  * This program is free software; you can redistribute it and/or modify
00005  * it under the terms of the GNU General Public License as published by
00006  * the Free Software Foundation; either version 2 of the License, or
00007  * (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00017  */
00018 
00019 // I have made all Z80 registers global and volatile
00020 volatile bool iff1, iff2;
00021 unsigned char im;
00022 volatile unsigned char a, f, b, c, d, e, h, l;
00023 volatile unsigned char r, a1, f1, b1, c1, d1, e1, h1, l1, i;
00024 volatile unsigned short pc;
00025 volatile unsigned short ix, iy, sp;
00026 
00027 // some flags
00028 volatile   bool intpend=0;
00029 volatile   unsigned char new_ixoriy=0;
00030 volatile   unsigned char ixoriy=0;
00031 
00032 
00033 #define Z80_quit  1
00034 #define Z80_NMI   2
00035 #define Z80_reset 3
00036 #define Z80_load  4
00037 #define Z80_save  5
00038 #define Z80_log   6
00039 
00040 #define parity(a) (partable[a])
00041 unsigned char partable[256]={
00042       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00043       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00044       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00045       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00046       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00047       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00048       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00049       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00050       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00051       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00052       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00053       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00054       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4,
00055       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00056       0, 4, 4, 0, 4, 0, 0, 4, 4, 0, 0, 4, 0, 4, 4, 0,
00057       4, 0, 0, 4, 0, 4, 4, 0, 0, 4, 4, 0, 4, 0, 0, 4
00058    };
00059 
00060 
00061 #define fetch(x) (rdmem(x))
00062 #define fetch2(x) ((fetch((x)+1)<<8)|fetch(x))
00063 
00064 // store 8 bit value y at 16 bit location x
00065 #define store(x,y) (wrmem(x,(y)))
00066 
00067 #define store2b(x,hi,lo) do {wrmem(x,lo);wrmem(x+1,hi);}while(0)
00068 
00069 #define store2(x,y) store2b(x,(y)>>8,(y)&255)
00070 
00071 #define bc ((b<<8)|c)
00072 #define de ((d<<8)|e)
00073 #define hl ((h<<8)|l)
00074 
00075 #define instr(opcode,cycles) case opcode: {
00076 #define HLinstr(opcode) \
00077                              case opcode: {unsigned short addr; \
00078                                 if(ixoriy==0)addr=hl; \
00079                                 else    addr=(ixoriy==1?ix:iy)+ \
00080                                         (signed char)fetch(pc),\
00081                                    pc++
00082 #define endinstr             }; break
00083 
00084 #define cy (f&1)
00085 
00086 #define xh (ixoriy==0?h:ixoriy==1?(ix>>8):(iy>>8))
00087 #define xl (ixoriy==0?l:ixoriy==1?(ix&0xff):(iy&0xff))
00088 
00089 #define setxh(x) (ixoriy==0?(h=(x)):ixoriy==1?(ix=(ix&0xff)|((x)<<8)):\
00090                   (iy=(iy&0xff)|((x)<<8)))
00091 #define setxl(x) (ixoriy==0?(l=(x)):ixoriy==1?(ix=(ix&0xff00)|(x)):\
00092                   (iy=(iy&0xff00)|(x)))
00093 
00094 #define inc(var) /* 8-bit increment */ ( var++,\
00095                                          f=(f&1)|(var&0xa8)|\
00096                                            ((!(var&15))<<4)|((!var)<<6)|\
00097                                            ((var==128)<<2)\
00098                                        )
00099 #define dec(var) /* 8-bit decrement */ ( f=(f&1)|((!(var&15))<<4)|2,\
00100                                          --var,\
00101                                          f|=(var&0xa8)|((var==127)<<2)|\
00102                                             ((!var)<<6)\
00103                                        )
00104 #define swap(x,y) {unsigned char t=x; x=y; y=t;}
00105 #define addhl(hi,lo) /* 16-bit add */ if(!ixoriy){\
00106                       unsigned short t;\
00107                       l=t=l+(lo);\
00108                       f=(f&0xc4)|(((t>>=8)+(h&0x0f)+((hi)&0x0f)>15)<<4);\
00109                       h=t+=h+(hi);\
00110                       f|=(h&0x28)|(t>>8);\
00111                    }\
00112                    else do{unsigned long t=(ixoriy==1?ix:iy);\
00113                       f=(f&0xc4)|(((t&0xfff)+((hi<<8)|lo)>0xfff)<<4);\
00114                       t+=(hi<<8)|lo;\
00115                       if(ixoriy==1)ix=t; else iy=t;\
00116                       f|=((t>>8)&0x28)|(t>>16);\
00117                    } while(0)
00118 
00119 #define adda(x,c) /* 8-bit add */ do{unsigned short y;\
00120                       unsigned char z=(x);\
00121                       y=a+z+(c);\
00122                       f=(y&0xa8)|(y>>8)|(((a&0x0f)+(z&0x0f)+(c)>15)<<4)|\
00123                         (((~a^z)&0x80&(y^a))>>5);\
00124                         a=y; \
00125                       f|=(!a)<<6;\
00126                    } while(0)
00127 #define suba(x,c) /* 8-bit subtract */ do{unsigned short y;\
00128                       unsigned char z=(x);\
00129                       y=(a-z-(c))&0x1ff;\
00130                       f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f)+(c))<<4)|\
00131                         (((a^z)&0x80&(y^a))>>5)|2;\
00132                         a=y; \
00133                       f|=(!a)<<6;\
00134                    } while(0)
00135 #define cpa(x) /* 8-bit compare */ do{unsigned short y;\
00136                       unsigned char z=(x);\
00137                       y=(a-z)&0x1ff;\
00138                       f=(y&0xa8)|(y>>8)|(((a&0x0f)<(z&0x0f))<<4)|\
00139                         (((a^z)&0x80&(y^a))>>5)|2|((!y)<<6);\
00140                    } while(0)
00141 #define anda(x) /* logical and */ do{\
00142                       a&=(x);\
00143                       f=(a&0xa8)|((!a)<<6)|0x10|parity(a);\
00144                    } while(0)
00145 #define xora(x) /* logical xor */ do{\
00146                       a^=(x);\
00147                       f=(a&0xa8)|((!a)<<6)|parity(a);\
00148                    } while(0)
00149 #define ora(x) /* logical or */ do{\
00150                       a|=(x);\
00151                       f=(a&0xa8)|((!a)<<6)|parity(a);\
00152                    } while(0)
00153 
00154 #define jr /* execute relative jump */ do{int j=(signed char)fetch(pc);\
00155                       pc+=j+1;\
00156                    } while(0)
00157 #define jp /* execute jump */ (pc=fetch2(pc))
00158 #define call /* execute call */ do{\
00159                       push2(pc+2);\
00160                       jp;\
00161                    } while(0)
00162 #define ret /* execute return */ do{\
00163                       pop2(pc);\
00164                    } while(0)
00165 #define pop2(var) /* pop 16-bit register */ (var=fetch2(sp),sp+=2)
00166 #define pop1(v1,v2) /* pop register pair */ (v2=fetch(sp),\
00167                                              v1=fetch(sp+1),sp+=2)
00168 #define push2(val) /* push 16-bit register */ do{sp-=2;store2(sp,(val));}\
00169                                               while(0)
00170 #define push1(v1,v2) /* push register pair */ do{sp-=2;\
00171                                                  store2b(sp,v1,v2);\
00172                                               }while(0)
00173