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

Committer:
gertk
Date:
Wed Jun 29 14:25:56 2011 +0000
Revision:
0:806c2f2a7d47
preliminary version

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gertk 0:806c2f2a7d47 1 /* Emulations of the CB/DD and FD operations of the Z80 instruction set.
gertk 0:806c2f2a7d47 2 * Copyright (C) 1994 Ian Collier.
gertk 0:806c2f2a7d47 3 *
gertk 0:806c2f2a7d47 4 * This program is free software; you can redistribute it and/or modify
gertk 0:806c2f2a7d47 5 * it under the terms of the GNU General Public License as published by
gertk 0:806c2f2a7d47 6 * the Free Software Foundation; either version 2 of the License, or
gertk 0:806c2f2a7d47 7 * (at your option) any later version.
gertk 0:806c2f2a7d47 8 *
gertk 0:806c2f2a7d47 9 * This program is distributed in the hope that it will be useful,
gertk 0:806c2f2a7d47 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
gertk 0:806c2f2a7d47 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
gertk 0:806c2f2a7d47 12 * GNU General Public License for more details.
gertk 0:806c2f2a7d47 13 *
gertk 0:806c2f2a7d47 14 * You should have received a copy of the GNU General Public License
gertk 0:806c2f2a7d47 15 * along with this program; if not, write to the Free Software
gertk 0:806c2f2a7d47 16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
gertk 0:806c2f2a7d47 17 */
gertk 0:806c2f2a7d47 18
gertk 0:806c2f2a7d47 19 #define var_t unsigned char t
gertk 0:806c2f2a7d47 20 #define rlc(x) (x=(x<<1)|(x>>7),rflags(x,x&1))
gertk 0:806c2f2a7d47 21 #define rrc(x) do{var_t=x&1;x=(x>>1)|(t<<7);rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 22 #define rl(x) do{var_t=x>>7;x=(x<<1)|(f&1);rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 23 #define rr(x) do{var_t=x&1;x=(x>>1)|(f<<7);rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 24 #define sla(x) do{var_t=x>>7;x<<=1;rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 25 #define sra(x) do{var_t=x&1;x=((signed char)x)>>1;rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 26 #define sll(x) do{var_t=x>>7;x=(x<<1)|1;rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 27 #define srl(x) do{var_t=x&1;x>>=1;rflags(x,t);}while(0)
gertk 0:806c2f2a7d47 28
gertk 0:806c2f2a7d47 29 #define rflags(x,c) (f=(c)|(x&0xa8)|((!x)<<6)|parity(x))
gertk 0:806c2f2a7d47 30
gertk 0:806c2f2a7d47 31 #define bit(n,x) (f=(f&1)|((x&(1<<n))?0x10:0x54)|(x&0x28))
gertk 0:806c2f2a7d47 32 #define set(n,x) (x|=(1<<n))
gertk 0:806c2f2a7d47 33 #define res(n,x) (x&=~(1<<n))
gertk 0:806c2f2a7d47 34
gertk 0:806c2f2a7d47 35 {
gertk 0:806c2f2a7d47 36 /* reg/val are initialised to stop gcc's (incorrect) warning,
gertk 0:806c2f2a7d47 37 * and static to save initialising them every time.
gertk 0:806c2f2a7d47 38 */
gertk 0:806c2f2a7d47 39 static unsigned char reg=0,val=0;
gertk 0:806c2f2a7d47 40 unsigned short addr;
gertk 0:806c2f2a7d47 41 unsigned char op;
gertk 0:806c2f2a7d47 42 if(ixoriy){
gertk 0:806c2f2a7d47 43 // if IX or IY addressing add the '+d' part
gertk 0:806c2f2a7d47 44 addr=(ixoriy==1?ix:iy)+(signed char)fetch(pc);
gertk 0:806c2f2a7d47 45 pc++;
gertk 0:806c2f2a7d47 46 op=fetch(pc);
gertk 0:806c2f2a7d47 47 reg=op&7;
gertk 0:806c2f2a7d47 48 op=(op&0xf8)|6;
gertk 0:806c2f2a7d47 49 }
gertk 0:806c2f2a7d47 50 else{
gertk 0:806c2f2a7d47 51 op=fetch(pc);
gertk 0:806c2f2a7d47 52 addr=hl;
gertk 0:806c2f2a7d47 53 }
gertk 0:806c2f2a7d47 54 pc++;
gertk 0:806c2f2a7d47 55
gertk 0:806c2f2a7d47 56 if(op<64)switch(op){
gertk 0:806c2f2a7d47 57 case 0: rlc(b); break;
gertk 0:806c2f2a7d47 58 case 1: rlc(c); break;
gertk 0:806c2f2a7d47 59 case 2: rlc(d); break;
gertk 0:806c2f2a7d47 60 case 3: rlc(e); break;
gertk 0:806c2f2a7d47 61 case 4: rlc(h); break;
gertk 0:806c2f2a7d47 62 case 5: rlc(l); break;
gertk 0:806c2f2a7d47 63 case 6: val=fetch(addr);rlc(val);store(addr,val);break;
gertk 0:806c2f2a7d47 64 case 7: rlc(a); break;
gertk 0:806c2f2a7d47 65 case 8: rrc(b); break;
gertk 0:806c2f2a7d47 66 case 9: rrc(c); break;
gertk 0:806c2f2a7d47 67 case 10: rrc(d); break;
gertk 0:806c2f2a7d47 68 case 11: rrc(e); break;
gertk 0:806c2f2a7d47 69 case 12: rrc(h); break;
gertk 0:806c2f2a7d47 70 case 13: rrc(l); break;
gertk 0:806c2f2a7d47 71 case 14: val=fetch(addr);rrc(val);store(addr,val);break;
gertk 0:806c2f2a7d47 72 case 15: rrc(a); break;
gertk 0:806c2f2a7d47 73 case 0x10: rl(b); break;
gertk 0:806c2f2a7d47 74 case 0x11: rl(c); break;
gertk 0:806c2f2a7d47 75 case 0x12: rl(d); break;
gertk 0:806c2f2a7d47 76 case 0x13: rl(e); break;
gertk 0:806c2f2a7d47 77 case 0x14: rl(h); break;
gertk 0:806c2f2a7d47 78 case 0x15: rl(l); break;
gertk 0:806c2f2a7d47 79 case 0x16: val=fetch(addr);rl(val);store(addr,val);break;
gertk 0:806c2f2a7d47 80 case 0x17: rl(a); break;
gertk 0:806c2f2a7d47 81 case 0x18: rr(b); break;
gertk 0:806c2f2a7d47 82 case 0x19: rr(c); break;
gertk 0:806c2f2a7d47 83 case 0x1a: rr(d); break;
gertk 0:806c2f2a7d47 84 case 0x1b: rr(e); break;
gertk 0:806c2f2a7d47 85 case 0x1c: rr(h); break;
gertk 0:806c2f2a7d47 86 case 0x1d: rr(l); break;
gertk 0:806c2f2a7d47 87 case 0x1e: val=fetch(addr);rr(val);store(addr,val);break;
gertk 0:806c2f2a7d47 88 case 0x1f: rr(a); break;
gertk 0:806c2f2a7d47 89 case 0x20: sla(b); break;
gertk 0:806c2f2a7d47 90 case 0x21: sla(c); break;
gertk 0:806c2f2a7d47 91 case 0x22: sla(d); break;
gertk 0:806c2f2a7d47 92 case 0x23: sla(e); break;
gertk 0:806c2f2a7d47 93 case 0x24: sla(h); break;
gertk 0:806c2f2a7d47 94 case 0x25: sla(l); break;
gertk 0:806c2f2a7d47 95 case 0x26: val=fetch(addr);sla(val);store(addr,val);break;
gertk 0:806c2f2a7d47 96 case 0x27: sla(a); break;
gertk 0:806c2f2a7d47 97 case 0x28: sra(b); break;
gertk 0:806c2f2a7d47 98 case 0x29: sra(c); break;
gertk 0:806c2f2a7d47 99 case 0x2a: sra(d); break;
gertk 0:806c2f2a7d47 100 case 0x2b: sra(e); break;
gertk 0:806c2f2a7d47 101 case 0x2c: sra(h); break;
gertk 0:806c2f2a7d47 102 case 0x2d: sra(l); break;
gertk 0:806c2f2a7d47 103 case 0x2e: val=fetch(addr);sra(val);store(addr,val);break;
gertk 0:806c2f2a7d47 104 case 0x2f: sra(a); break;
gertk 0:806c2f2a7d47 105 case 0x30: sll(b); break;
gertk 0:806c2f2a7d47 106 case 0x31: sll(c); break;
gertk 0:806c2f2a7d47 107 case 0x32: sll(d); break;
gertk 0:806c2f2a7d47 108 case 0x33: sll(e); break;
gertk 0:806c2f2a7d47 109 case 0x34: sll(h); break;
gertk 0:806c2f2a7d47 110 case 0x35: sll(l); break;
gertk 0:806c2f2a7d47 111 case 0x36: val=fetch(addr);sll(val);store(addr,val);break;
gertk 0:806c2f2a7d47 112 case 0x37: sll(a); break;
gertk 0:806c2f2a7d47 113 case 0x38: srl(b); break;
gertk 0:806c2f2a7d47 114 case 0x39: srl(c); break;
gertk 0:806c2f2a7d47 115 case 0x3a: srl(d); break;
gertk 0:806c2f2a7d47 116 case 0x3b: srl(e); break;
gertk 0:806c2f2a7d47 117 case 0x3c: srl(h); break;
gertk 0:806c2f2a7d47 118 case 0x3d: srl(l); break;
gertk 0:806c2f2a7d47 119 case 0x3e: val=fetch(addr);srl(val);store(addr,val);break;
gertk 0:806c2f2a7d47 120 case 0x3f: srl(a); break;
gertk 0:806c2f2a7d47 121 }
gertk 0:806c2f2a7d47 122 else{
gertk 0:806c2f2a7d47 123 unsigned char n=(op>>3)&7;
gertk 0:806c2f2a7d47 124 switch(op&0xc7){
gertk 0:806c2f2a7d47 125 case 0x40: bit(n,b); break;
gertk 0:806c2f2a7d47 126 case 0x41: bit(n,c); break;
gertk 0:806c2f2a7d47 127 case 0x42: bit(n,d); break;
gertk 0:806c2f2a7d47 128 case 0x43: bit(n,e); break;
gertk 0:806c2f2a7d47 129 case 0x44: bit(n,h); break;
gertk 0:806c2f2a7d47 130 case 0x45: bit(n,l); break;
gertk 0:806c2f2a7d47 131 case 0x46: val=fetch(addr);bit(n,val);break;
gertk 0:806c2f2a7d47 132 case 0x47: bit(n,a); break;
gertk 0:806c2f2a7d47 133 case 0x80: res(n,b); break;
gertk 0:806c2f2a7d47 134 case 0x81: res(n,c); break;
gertk 0:806c2f2a7d47 135 case 0x82: res(n,d); break;
gertk 0:806c2f2a7d47 136 case 0x83: res(n,e); break;
gertk 0:806c2f2a7d47 137 case 0x84: res(n,h); break;
gertk 0:806c2f2a7d47 138 case 0x85: res(n,l); break;
gertk 0:806c2f2a7d47 139 case 0x86: val=fetch(addr);res(n,val);store(addr,val);break;
gertk 0:806c2f2a7d47 140 case 0x87: res(n,a); break;
gertk 0:806c2f2a7d47 141 case 0xc0: set(n,b); break;
gertk 0:806c2f2a7d47 142 case 0xc1: set(n,c); break;
gertk 0:806c2f2a7d47 143 case 0xc2: set(n,d); break;
gertk 0:806c2f2a7d47 144 case 0xc3: set(n,e); break;
gertk 0:806c2f2a7d47 145 case 0xc4: set(n,h); break;
gertk 0:806c2f2a7d47 146 case 0xc5: set(n,l); break;
gertk 0:806c2f2a7d47 147 case 0xc6: val=fetch(addr);set(n,val);store(addr,val);break;
gertk 0:806c2f2a7d47 148 case 0xc7: set(n,a); break;
gertk 0:806c2f2a7d47 149 }
gertk 0:806c2f2a7d47 150 }
gertk 0:806c2f2a7d47 151 if(ixoriy)switch(reg){
gertk 0:806c2f2a7d47 152 case 0:b=val; break;
gertk 0:806c2f2a7d47 153 case 1:c=val; break;
gertk 0:806c2f2a7d47 154 case 2:d=val; break;
gertk 0:806c2f2a7d47 155 case 3:e=val; break;
gertk 0:806c2f2a7d47 156 case 4:h=val; break;
gertk 0:806c2f2a7d47 157 case 5:l=val; break;
gertk 0:806c2f2a7d47 158 case 7:a=val; break;
gertk 0:806c2f2a7d47 159 }
gertk 0:806c2f2a7d47 160 }
gertk 0:806c2f2a7d47 161
gertk 0:806c2f2a7d47 162 #undef var_t
gertk 0:806c2f2a7d47 163 #undef rlc
gertk 0:806c2f2a7d47 164 #undef rrc
gertk 0:806c2f2a7d47 165 #undef rl
gertk 0:806c2f2a7d47 166 #undef rr
gertk 0:806c2f2a7d47 167 #undef sla
gertk 0:806c2f2a7d47 168 #undef sra
gertk 0:806c2f2a7d47 169 #undef sll
gertk 0:806c2f2a7d47 170 #undef srl
gertk 0:806c2f2a7d47 171 #undef rflags
gertk 0:806c2f2a7d47 172 #undef bit
gertk 0:806c2f2a7d47 173 #undef set
gertk 0:806c2f2a7d47 174 #undef res