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.
z80/edops.h@0:806c2f2a7d47, 2011-06-29 (annotated)
- Committer:
- gertk
- Date:
- Wed Jun 29 14:25:56 2011 +0000
- Revision:
- 0:806c2f2a7d47
preliminary version
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
gertk | 0:806c2f2a7d47 | 1 | /* Emulations of the ED 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 input(var) { var=in(c);\ |
gertk | 0:806c2f2a7d47 | 20 | f=(f&1)|(var&0xa8)|((!var)<<6)|parity(var);\ |
gertk | 0:806c2f2a7d47 | 21 | } |
gertk | 0:806c2f2a7d47 | 22 | #define sbchl(x) { unsigned short z=(x);\ |
gertk | 0:806c2f2a7d47 | 23 | unsigned long t=(hl-z-cy)&0x1ffff;\ |
gertk | 0:806c2f2a7d47 | 24 | f=((t>>8)&0xa8)|(t>>16)|2|\ |
gertk | 0:806c2f2a7d47 | 25 | (((hl&0xfff)<(z&0xfff)+cy)<<4)|\ |
gertk | 0:806c2f2a7d47 | 26 | (((hl^z)&(hl^t)&0x8000)>>13)|\ |
gertk | 0:806c2f2a7d47 | 27 | ((!(t&0xffff))<<6)|2;\ |
gertk | 0:806c2f2a7d47 | 28 | l=t;\ |
gertk | 0:806c2f2a7d47 | 29 | h=t>>8;\ |
gertk | 0:806c2f2a7d47 | 30 | } |
gertk | 0:806c2f2a7d47 | 31 | |
gertk | 0:806c2f2a7d47 | 32 | #define adchl(x) { unsigned short z=(x);\ |
gertk | 0:806c2f2a7d47 | 33 | unsigned long t=hl+z+cy;\ |
gertk | 0:806c2f2a7d47 | 34 | f=((t>>8)&0xa8)|(t>>16)|\ |
gertk | 0:806c2f2a7d47 | 35 | (((hl&0xfff)+(z&0xfff)+cy>0xfff)<<4)|\ |
gertk | 0:806c2f2a7d47 | 36 | (((~hl^z)&(hl^t)&0x8000)>>13)|\ |
gertk | 0:806c2f2a7d47 | 37 | ((!(t&0xffff))<<6)|2;\ |
gertk | 0:806c2f2a7d47 | 38 | l=t;\ |
gertk | 0:806c2f2a7d47 | 39 | h=t>>8;\ |
gertk | 0:806c2f2a7d47 | 40 | } |
gertk | 0:806c2f2a7d47 | 41 | |
gertk | 0:806c2f2a7d47 | 42 | #define neg (a=-a,\ |
gertk | 0:806c2f2a7d47 | 43 | f=(a&0xa8)|((!a)<<6)|(((a&15)>0)<<4)|((a==128)<<2)|2|(a>0)) |
gertk | 0:806c2f2a7d47 | 44 | |
gertk | 0:806c2f2a7d47 | 45 | { |
gertk | 0:806c2f2a7d47 | 46 | unsigned char op=fetch(pc); |
gertk | 0:806c2f2a7d47 | 47 | pc++; |
gertk | 0:806c2f2a7d47 | 48 | |
gertk | 0:806c2f2a7d47 | 49 | // IN B,(C) |
gertk | 0:806c2f2a7d47 | 50 | switch(op){ |
gertk | 0:806c2f2a7d47 | 51 | instr(0x40,8); |
gertk | 0:806c2f2a7d47 | 52 | input(b); |
gertk | 0:806c2f2a7d47 | 53 | endinstr; |
gertk | 0:806c2f2a7d47 | 54 | |
gertk | 0:806c2f2a7d47 | 55 | // OUT (C),B |
gertk | 0:806c2f2a7d47 | 56 | instr(0x41,8); |
gertk | 0:806c2f2a7d47 | 57 | out(c,b); |
gertk | 0:806c2f2a7d47 | 58 | endinstr; |
gertk | 0:806c2f2a7d47 | 59 | |
gertk | 0:806c2f2a7d47 | 60 | // SBC HL,BC |
gertk | 0:806c2f2a7d47 | 61 | instr(0x42,11); |
gertk | 0:806c2f2a7d47 | 62 | sbchl(bc); |
gertk | 0:806c2f2a7d47 | 63 | endinstr; |
gertk | 0:806c2f2a7d47 | 64 | |
gertk | 0:806c2f2a7d47 | 65 | // LD (nn),BC |
gertk | 0:806c2f2a7d47 | 66 | instr(0x43,16); |
gertk | 0:806c2f2a7d47 | 67 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 68 | pc+=2; |
gertk | 0:806c2f2a7d47 | 69 | store2b(addr,b,c); |
gertk | 0:806c2f2a7d47 | 70 | } |
gertk | 0:806c2f2a7d47 | 71 | endinstr; |
gertk | 0:806c2f2a7d47 | 72 | |
gertk | 0:806c2f2a7d47 | 73 | // NEG |
gertk | 0:806c2f2a7d47 | 74 | instr(0x44,4); |
gertk | 0:806c2f2a7d47 | 75 | neg; |
gertk | 0:806c2f2a7d47 | 76 | endinstr; |
gertk | 0:806c2f2a7d47 | 77 | |
gertk | 0:806c2f2a7d47 | 78 | // RETN |
gertk | 0:806c2f2a7d47 | 79 | instr(0x45,4); |
gertk | 0:806c2f2a7d47 | 80 | iff1=iff2; |
gertk | 0:806c2f2a7d47 | 81 | ret; |
gertk | 0:806c2f2a7d47 | 82 | endinstr; |
gertk | 0:806c2f2a7d47 | 83 | |
gertk | 0:806c2f2a7d47 | 84 | // IM 0 |
gertk | 0:806c2f2a7d47 | 85 | instr(0x46,4); |
gertk | 0:806c2f2a7d47 | 86 | im=0; |
gertk | 0:806c2f2a7d47 | 87 | endinstr; |
gertk | 0:806c2f2a7d47 | 88 | |
gertk | 0:806c2f2a7d47 | 89 | // LD I,A |
gertk | 0:806c2f2a7d47 | 90 | instr(0x47,5); |
gertk | 0:806c2f2a7d47 | 91 | i=a; |
gertk | 0:806c2f2a7d47 | 92 | endinstr; |
gertk | 0:806c2f2a7d47 | 93 | |
gertk | 0:806c2f2a7d47 | 94 | // IN C,(C) |
gertk | 0:806c2f2a7d47 | 95 | instr(0x48,8); |
gertk | 0:806c2f2a7d47 | 96 | input(c); |
gertk | 0:806c2f2a7d47 | 97 | endinstr; |
gertk | 0:806c2f2a7d47 | 98 | |
gertk | 0:806c2f2a7d47 | 99 | // OUT (C),C |
gertk | 0:806c2f2a7d47 | 100 | instr(0x49,8); |
gertk | 0:806c2f2a7d47 | 101 | out(c,c); |
gertk | 0:806c2f2a7d47 | 102 | endinstr; |
gertk | 0:806c2f2a7d47 | 103 | |
gertk | 0:806c2f2a7d47 | 104 | // ADC HL,BC |
gertk | 0:806c2f2a7d47 | 105 | instr(0x4a,11); |
gertk | 0:806c2f2a7d47 | 106 | adchl(bc); |
gertk | 0:806c2f2a7d47 | 107 | endinstr; |
gertk | 0:806c2f2a7d47 | 108 | |
gertk | 0:806c2f2a7d47 | 109 | // LD BC,(nn) |
gertk | 0:806c2f2a7d47 | 110 | instr(0x4b,16); |
gertk | 0:806c2f2a7d47 | 111 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 112 | pc+=2; |
gertk | 0:806c2f2a7d47 | 113 | c=fetch(addr); |
gertk | 0:806c2f2a7d47 | 114 | b=fetch(addr+1); |
gertk | 0:806c2f2a7d47 | 115 | } |
gertk | 0:806c2f2a7d47 | 116 | endinstr; |
gertk | 0:806c2f2a7d47 | 117 | |
gertk | 0:806c2f2a7d47 | 118 | // ? |
gertk | 0:806c2f2a7d47 | 119 | instr(0x4c,4); |
gertk | 0:806c2f2a7d47 | 120 | neg; |
gertk | 0:806c2f2a7d47 | 121 | endinstr; |
gertk | 0:806c2f2a7d47 | 122 | |
gertk | 0:806c2f2a7d47 | 123 | // RETI |
gertk | 0:806c2f2a7d47 | 124 | instr(0x4d,4); |
gertk | 0:806c2f2a7d47 | 125 | ret; |
gertk | 0:806c2f2a7d47 | 126 | endinstr; |
gertk | 0:806c2f2a7d47 | 127 | |
gertk | 0:806c2f2a7d47 | 128 | // ? |
gertk | 0:806c2f2a7d47 | 129 | instr(0x4e,4); |
gertk | 0:806c2f2a7d47 | 130 | im=1; |
gertk | 0:806c2f2a7d47 | 131 | endinstr; |
gertk | 0:806c2f2a7d47 | 132 | |
gertk | 0:806c2f2a7d47 | 133 | // ? |
gertk | 0:806c2f2a7d47 | 134 | instr(0x4f,5); |
gertk | 0:806c2f2a7d47 | 135 | r=a; |
gertk | 0:806c2f2a7d47 | 136 | endinstr; |
gertk | 0:806c2f2a7d47 | 137 | |
gertk | 0:806c2f2a7d47 | 138 | // IN D,(C) |
gertk | 0:806c2f2a7d47 | 139 | instr(0x50,8); |
gertk | 0:806c2f2a7d47 | 140 | input(d); |
gertk | 0:806c2f2a7d47 | 141 | endinstr; |
gertk | 0:806c2f2a7d47 | 142 | |
gertk | 0:806c2f2a7d47 | 143 | // OUT (C),D |
gertk | 0:806c2f2a7d47 | 144 | instr(0x51,8); |
gertk | 0:806c2f2a7d47 | 145 | out(c,d); |
gertk | 0:806c2f2a7d47 | 146 | endinstr; |
gertk | 0:806c2f2a7d47 | 147 | |
gertk | 0:806c2f2a7d47 | 148 | // SBC HL,DE |
gertk | 0:806c2f2a7d47 | 149 | instr(0x52,11); |
gertk | 0:806c2f2a7d47 | 150 | sbchl(de); |
gertk | 0:806c2f2a7d47 | 151 | endinstr; |
gertk | 0:806c2f2a7d47 | 152 | |
gertk | 0:806c2f2a7d47 | 153 | // LD (nn),DE |
gertk | 0:806c2f2a7d47 | 154 | instr(0x53,16); |
gertk | 0:806c2f2a7d47 | 155 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 156 | pc+=2; |
gertk | 0:806c2f2a7d47 | 157 | store2b(addr,d,e); |
gertk | 0:806c2f2a7d47 | 158 | } |
gertk | 0:806c2f2a7d47 | 159 | endinstr; |
gertk | 0:806c2f2a7d47 | 160 | |
gertk | 0:806c2f2a7d47 | 161 | // ? |
gertk | 0:806c2f2a7d47 | 162 | instr(0x54,4); |
gertk | 0:806c2f2a7d47 | 163 | neg; |
gertk | 0:806c2f2a7d47 | 164 | endinstr; |
gertk | 0:806c2f2a7d47 | 165 | |
gertk | 0:806c2f2a7d47 | 166 | // my opcode for replacing the MOS routines |
gertk | 0:806c2f2a7d47 | 167 | instr(0x55,4); |
gertk | 0:806c2f2a7d47 | 168 | // printf("@ %04x Illegal opcode ED55 (MOS) \n\r",pc); |
gertk | 0:806c2f2a7d47 | 169 | do_mos(); // |
gertk | 0:806c2f2a7d47 | 170 | ret; |
gertk | 0:806c2f2a7d47 | 171 | endinstr; |
gertk | 0:806c2f2a7d47 | 172 | |
gertk | 0:806c2f2a7d47 | 173 | // IM 1 |
gertk | 0:806c2f2a7d47 | 174 | instr(0x56,4); |
gertk | 0:806c2f2a7d47 | 175 | im=1; |
gertk | 0:806c2f2a7d47 | 176 | endinstr; |
gertk | 0:806c2f2a7d47 | 177 | |
gertk | 0:806c2f2a7d47 | 178 | // LD A,I |
gertk | 0:806c2f2a7d47 | 179 | instr(0x57,5); |
gertk | 0:806c2f2a7d47 | 180 | a=i; |
gertk | 0:806c2f2a7d47 | 181 | f=(f&1)|(a&0xa8)|((!a)<<6)|(iff2<<2); |
gertk | 0:806c2f2a7d47 | 182 | endinstr; |
gertk | 0:806c2f2a7d47 | 183 | |
gertk | 0:806c2f2a7d47 | 184 | // IN E,(C) |
gertk | 0:806c2f2a7d47 | 185 | instr(0x58,8); |
gertk | 0:806c2f2a7d47 | 186 | input(e); |
gertk | 0:806c2f2a7d47 | 187 | endinstr; |
gertk | 0:806c2f2a7d47 | 188 | |
gertk | 0:806c2f2a7d47 | 189 | // OUT (C),E |
gertk | 0:806c2f2a7d47 | 190 | instr(0x59,8); |
gertk | 0:806c2f2a7d47 | 191 | out(c,e); |
gertk | 0:806c2f2a7d47 | 192 | endinstr; |
gertk | 0:806c2f2a7d47 | 193 | |
gertk | 0:806c2f2a7d47 | 194 | // ADC HL,DE |
gertk | 0:806c2f2a7d47 | 195 | instr(0x5a,11); |
gertk | 0:806c2f2a7d47 | 196 | adchl(de); |
gertk | 0:806c2f2a7d47 | 197 | endinstr; |
gertk | 0:806c2f2a7d47 | 198 | |
gertk | 0:806c2f2a7d47 | 199 | // LD DE,(nn) |
gertk | 0:806c2f2a7d47 | 200 | instr(0x5b,16); |
gertk | 0:806c2f2a7d47 | 201 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 202 | pc+=2; |
gertk | 0:806c2f2a7d47 | 203 | e=fetch(addr); |
gertk | 0:806c2f2a7d47 | 204 | d=fetch(addr+1); |
gertk | 0:806c2f2a7d47 | 205 | } |
gertk | 0:806c2f2a7d47 | 206 | endinstr; |
gertk | 0:806c2f2a7d47 | 207 | |
gertk | 0:806c2f2a7d47 | 208 | // ? |
gertk | 0:806c2f2a7d47 | 209 | instr(0x5c,4); |
gertk | 0:806c2f2a7d47 | 210 | neg; |
gertk | 0:806c2f2a7d47 | 211 | endinstr; |
gertk | 0:806c2f2a7d47 | 212 | |
gertk | 0:806c2f2a7d47 | 213 | // ? |
gertk | 0:806c2f2a7d47 | 214 | instr(0x5d,4); |
gertk | 0:806c2f2a7d47 | 215 | ret; |
gertk | 0:806c2f2a7d47 | 216 | endinstr; |
gertk | 0:806c2f2a7d47 | 217 | |
gertk | 0:806c2f2a7d47 | 218 | // IM 2 |
gertk | 0:806c2f2a7d47 | 219 | instr(0x5e,4); |
gertk | 0:806c2f2a7d47 | 220 | im=2; |
gertk | 0:806c2f2a7d47 | 221 | endinstr; |
gertk | 0:806c2f2a7d47 | 222 | |
gertk | 0:806c2f2a7d47 | 223 | // LDA A,R (unecessary on static memory) |
gertk | 0:806c2f2a7d47 | 224 | instr(0x5f,5); |
gertk | 0:806c2f2a7d47 | 225 | a=r; |
gertk | 0:806c2f2a7d47 | 226 | f=(f&1)|(a&0xa8)|((!a)<<6)|(iff2<<2); |
gertk | 0:806c2f2a7d47 | 227 | endinstr; |
gertk | 0:806c2f2a7d47 | 228 | |
gertk | 0:806c2f2a7d47 | 229 | // IN H,(C) |
gertk | 0:806c2f2a7d47 | 230 | instr(0x60,8); |
gertk | 0:806c2f2a7d47 | 231 | input(h); |
gertk | 0:806c2f2a7d47 | 232 | endinstr; |
gertk | 0:806c2f2a7d47 | 233 | |
gertk | 0:806c2f2a7d47 | 234 | // OUT (C),H |
gertk | 0:806c2f2a7d47 | 235 | instr(0x61,8); |
gertk | 0:806c2f2a7d47 | 236 | out(c,h); |
gertk | 0:806c2f2a7d47 | 237 | endinstr; |
gertk | 0:806c2f2a7d47 | 238 | |
gertk | 0:806c2f2a7d47 | 239 | // SBC HL,HL |
gertk | 0:806c2f2a7d47 | 240 | instr(0x62,11); |
gertk | 0:806c2f2a7d47 | 241 | sbchl(hl); |
gertk | 0:806c2f2a7d47 | 242 | endinstr; |
gertk | 0:806c2f2a7d47 | 243 | |
gertk | 0:806c2f2a7d47 | 244 | // ? |
gertk | 0:806c2f2a7d47 | 245 | instr(0x63,16); |
gertk | 0:806c2f2a7d47 | 246 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 247 | pc+=2; |
gertk | 0:806c2f2a7d47 | 248 | store2b(addr,h,l); |
gertk | 0:806c2f2a7d47 | 249 | } |
gertk | 0:806c2f2a7d47 | 250 | endinstr; |
gertk | 0:806c2f2a7d47 | 251 | |
gertk | 0:806c2f2a7d47 | 252 | // ? |
gertk | 0:806c2f2a7d47 | 253 | instr(0x64,4); |
gertk | 0:806c2f2a7d47 | 254 | neg; |
gertk | 0:806c2f2a7d47 | 255 | endinstr; |
gertk | 0:806c2f2a7d47 | 256 | |
gertk | 0:806c2f2a7d47 | 257 | // ? illegal instruction ED65 |
gertk | 0:806c2f2a7d47 | 258 | instr(0x65,4); |
gertk | 0:806c2f2a7d47 | 259 | ret; |
gertk | 0:806c2f2a7d47 | 260 | endinstr; |
gertk | 0:806c2f2a7d47 | 261 | |
gertk | 0:806c2f2a7d47 | 262 | // ? |
gertk | 0:806c2f2a7d47 | 263 | instr(0x66,4); |
gertk | 0:806c2f2a7d47 | 264 | ret; |
gertk | 0:806c2f2a7d47 | 265 | // was im=0; |
gertk | 0:806c2f2a7d47 | 266 | endinstr; |
gertk | 0:806c2f2a7d47 | 267 | |
gertk | 0:806c2f2a7d47 | 268 | // RRD |
gertk | 0:806c2f2a7d47 | 269 | instr(0x67,14); |
gertk | 0:806c2f2a7d47 | 270 | {unsigned char t=fetch(hl); |
gertk | 0:806c2f2a7d47 | 271 | unsigned char u=(a<<4)|(t>>4); |
gertk | 0:806c2f2a7d47 | 272 | a=(a&0xf0)|(t&0x0f); |
gertk | 0:806c2f2a7d47 | 273 | store(hl,u); |
gertk | 0:806c2f2a7d47 | 274 | f=(f&1)|(a&0xa8)|((!a)<<6)|parity(a); |
gertk | 0:806c2f2a7d47 | 275 | } |
gertk | 0:806c2f2a7d47 | 276 | endinstr; |
gertk | 0:806c2f2a7d47 | 277 | |
gertk | 0:806c2f2a7d47 | 278 | // IN L,(C) |
gertk | 0:806c2f2a7d47 | 279 | instr(0x68,8); |
gertk | 0:806c2f2a7d47 | 280 | input(l); |
gertk | 0:806c2f2a7d47 | 281 | endinstr; |
gertk | 0:806c2f2a7d47 | 282 | |
gertk | 0:806c2f2a7d47 | 283 | // OUT (C),L |
gertk | 0:806c2f2a7d47 | 284 | instr(0x69,8); |
gertk | 0:806c2f2a7d47 | 285 | out(c,l); |
gertk | 0:806c2f2a7d47 | 286 | endinstr; |
gertk | 0:806c2f2a7d47 | 287 | |
gertk | 0:806c2f2a7d47 | 288 | // ADC HL,HL |
gertk | 0:806c2f2a7d47 | 289 | instr(0x6a,11); |
gertk | 0:806c2f2a7d47 | 290 | adchl(hl); |
gertk | 0:806c2f2a7d47 | 291 | endinstr; |
gertk | 0:806c2f2a7d47 | 292 | |
gertk | 0:806c2f2a7d47 | 293 | // ? |
gertk | 0:806c2f2a7d47 | 294 | instr(0x6b,16); |
gertk | 0:806c2f2a7d47 | 295 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 296 | pc+=2; |
gertk | 0:806c2f2a7d47 | 297 | l=fetch(addr); |
gertk | 0:806c2f2a7d47 | 298 | h=fetch(addr+1); |
gertk | 0:806c2f2a7d47 | 299 | } |
gertk | 0:806c2f2a7d47 | 300 | endinstr; |
gertk | 0:806c2f2a7d47 | 301 | |
gertk | 0:806c2f2a7d47 | 302 | // ? |
gertk | 0:806c2f2a7d47 | 303 | instr(0x6c,4); |
gertk | 0:806c2f2a7d47 | 304 | neg; |
gertk | 0:806c2f2a7d47 | 305 | endinstr; |
gertk | 0:806c2f2a7d47 | 306 | |
gertk | 0:806c2f2a7d47 | 307 | // ? |
gertk | 0:806c2f2a7d47 | 308 | instr(0x6d,4); |
gertk | 0:806c2f2a7d47 | 309 | ret; |
gertk | 0:806c2f2a7d47 | 310 | endinstr; |
gertk | 0:806c2f2a7d47 | 311 | |
gertk | 0:806c2f2a7d47 | 312 | // ? |
gertk | 0:806c2f2a7d47 | 313 | instr(0x6e,4); |
gertk | 0:806c2f2a7d47 | 314 | // im=1; |
gertk | 0:806c2f2a7d47 | 315 | ret; |
gertk | 0:806c2f2a7d47 | 316 | endinstr; |
gertk | 0:806c2f2a7d47 | 317 | |
gertk | 0:806c2f2a7d47 | 318 | // RLD |
gertk | 0:806c2f2a7d47 | 319 | instr(0x6f,5); |
gertk | 0:806c2f2a7d47 | 320 | {unsigned char t=fetch(hl); |
gertk | 0:806c2f2a7d47 | 321 | unsigned char u=(a&0x0f)|(t<<4); |
gertk | 0:806c2f2a7d47 | 322 | a=(a&0xf0)|(t>>4); |
gertk | 0:806c2f2a7d47 | 323 | store(hl,u); |
gertk | 0:806c2f2a7d47 | 324 | f=(f&1)|(a&0xa8)|((!a)<<6)|parity(a); |
gertk | 0:806c2f2a7d47 | 325 | } |
gertk | 0:806c2f2a7d47 | 326 | endinstr; |
gertk | 0:806c2f2a7d47 | 327 | |
gertk | 0:806c2f2a7d47 | 328 | // ? |
gertk | 0:806c2f2a7d47 | 329 | instr(0x70,8); |
gertk | 0:806c2f2a7d47 | 330 | {unsigned char x;input(x);} |
gertk | 0:806c2f2a7d47 | 331 | endinstr; |
gertk | 0:806c2f2a7d47 | 332 | |
gertk | 0:806c2f2a7d47 | 333 | // ? |
gertk | 0:806c2f2a7d47 | 334 | instr(0x71,8); |
gertk | 0:806c2f2a7d47 | 335 | out(c,0); |
gertk | 0:806c2f2a7d47 | 336 | endinstr; |
gertk | 0:806c2f2a7d47 | 337 | |
gertk | 0:806c2f2a7d47 | 338 | // SBC HL,SP |
gertk | 0:806c2f2a7d47 | 339 | instr(0x72,11); |
gertk | 0:806c2f2a7d47 | 340 | sbchl(sp); |
gertk | 0:806c2f2a7d47 | 341 | endinstr; |
gertk | 0:806c2f2a7d47 | 342 | |
gertk | 0:806c2f2a7d47 | 343 | // LD (nn),SP |
gertk | 0:806c2f2a7d47 | 344 | instr(0x73,16); |
gertk | 0:806c2f2a7d47 | 345 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 346 | pc+=2; |
gertk | 0:806c2f2a7d47 | 347 | store2(addr,sp); |
gertk | 0:806c2f2a7d47 | 348 | } |
gertk | 0:806c2f2a7d47 | 349 | endinstr; |
gertk | 0:806c2f2a7d47 | 350 | |
gertk | 0:806c2f2a7d47 | 351 | // ? |
gertk | 0:806c2f2a7d47 | 352 | instr(0x74,4); |
gertk | 0:806c2f2a7d47 | 353 | neg; |
gertk | 0:806c2f2a7d47 | 354 | endinstr; |
gertk | 0:806c2f2a7d47 | 355 | |
gertk | 0:806c2f2a7d47 | 356 | // ? |
gertk | 0:806c2f2a7d47 | 357 | instr(0x75,4); |
gertk | 0:806c2f2a7d47 | 358 | ret; |
gertk | 0:806c2f2a7d47 | 359 | endinstr; |
gertk | 0:806c2f2a7d47 | 360 | |
gertk | 0:806c2f2a7d47 | 361 | // ? |
gertk | 0:806c2f2a7d47 | 362 | instr(0x76,4); |
gertk | 0:806c2f2a7d47 | 363 | im=2; |
gertk | 0:806c2f2a7d47 | 364 | endinstr; |
gertk | 0:806c2f2a7d47 | 365 | |
gertk | 0:806c2f2a7d47 | 366 | // IN A,(C) |
gertk | 0:806c2f2a7d47 | 367 | instr(0x78,8); |
gertk | 0:806c2f2a7d47 | 368 | input(a); |
gertk | 0:806c2f2a7d47 | 369 | endinstr; |
gertk | 0:806c2f2a7d47 | 370 | |
gertk | 0:806c2f2a7d47 | 371 | // OUT (C),A |
gertk | 0:806c2f2a7d47 | 372 | instr(0x79,8); |
gertk | 0:806c2f2a7d47 | 373 | out(c,a); |
gertk | 0:806c2f2a7d47 | 374 | endinstr; |
gertk | 0:806c2f2a7d47 | 375 | |
gertk | 0:806c2f2a7d47 | 376 | // ADC HL,SP |
gertk | 0:806c2f2a7d47 | 377 | instr(0x7a,11); |
gertk | 0:806c2f2a7d47 | 378 | adchl(sp); |
gertk | 0:806c2f2a7d47 | 379 | endinstr; |
gertk | 0:806c2f2a7d47 | 380 | |
gertk | 0:806c2f2a7d47 | 381 | // LD SP,(nn) |
gertk | 0:806c2f2a7d47 | 382 | instr(0x7b,16); |
gertk | 0:806c2f2a7d47 | 383 | {unsigned short addr=fetch2(pc); |
gertk | 0:806c2f2a7d47 | 384 | pc+=2; |
gertk | 0:806c2f2a7d47 | 385 | sp=fetch2(addr); |
gertk | 0:806c2f2a7d47 | 386 | } |
gertk | 0:806c2f2a7d47 | 387 | endinstr; |
gertk | 0:806c2f2a7d47 | 388 | |
gertk | 0:806c2f2a7d47 | 389 | // ? |
gertk | 0:806c2f2a7d47 | 390 | instr(0x7c,4); |
gertk | 0:806c2f2a7d47 | 391 | neg; |
gertk | 0:806c2f2a7d47 | 392 | endinstr; |
gertk | 0:806c2f2a7d47 | 393 | |
gertk | 0:806c2f2a7d47 | 394 | // ? |
gertk | 0:806c2f2a7d47 | 395 | instr(0x7d,4); |
gertk | 0:806c2f2a7d47 | 396 | ret; |
gertk | 0:806c2f2a7d47 | 397 | endinstr; |
gertk | 0:806c2f2a7d47 | 398 | |
gertk | 0:806c2f2a7d47 | 399 | // ? |
gertk | 0:806c2f2a7d47 | 400 | instr(0x7e,4); |
gertk | 0:806c2f2a7d47 | 401 | im=3; |
gertk | 0:806c2f2a7d47 | 402 | endinstr; |
gertk | 0:806c2f2a7d47 | 403 | |
gertk | 0:806c2f2a7d47 | 404 | // LDI |
gertk | 0:806c2f2a7d47 | 405 | instr(0xa0,12); |
gertk | 0:806c2f2a7d47 | 406 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 407 | store(de,x); |
gertk | 0:806c2f2a7d47 | 408 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 409 | if(!++e)d++; |
gertk | 0:806c2f2a7d47 | 410 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 411 | f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 412 | } |
gertk | 0:806c2f2a7d47 | 413 | endinstr; |
gertk | 0:806c2f2a7d47 | 414 | |
gertk | 0:806c2f2a7d47 | 415 | // CPI |
gertk | 0:806c2f2a7d47 | 416 | instr(0xa1,12); |
gertk | 0:806c2f2a7d47 | 417 | {unsigned char carry=cy; |
gertk | 0:806c2f2a7d47 | 418 | cpa(fetch(hl)); |
gertk | 0:806c2f2a7d47 | 419 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 420 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 421 | f=(f&0xfa)|carry|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 422 | } |
gertk | 0:806c2f2a7d47 | 423 | endinstr; |
gertk | 0:806c2f2a7d47 | 424 | |
gertk | 0:806c2f2a7d47 | 425 | // INI |
gertk | 0:806c2f2a7d47 | 426 | instr(0xa2,12); |
gertk | 0:806c2f2a7d47 | 427 | {unsigned char t=in(c); |
gertk | 0:806c2f2a7d47 | 428 | store(hl,t); |
gertk | 0:806c2f2a7d47 | 429 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 430 | b--; |
gertk | 0:806c2f2a7d47 | 431 | f=(b&0xa8)|((!b)<<6)|2|((parity(b)^c)&4); |
gertk | 0:806c2f2a7d47 | 432 | } |
gertk | 0:806c2f2a7d47 | 433 | endinstr; |
gertk | 0:806c2f2a7d47 | 434 | |
gertk | 0:806c2f2a7d47 | 435 | // OUTI |
gertk | 0:806c2f2a7d47 | 436 | instr(0xa3,12); /* I can't determine the correct flags outcome for the |
gertk | 0:806c2f2a7d47 | 437 | block OUT instructions. Spec says that the carry |
gertk | 0:806c2f2a7d47 | 438 | flag is left unchanged and N is set to 1, but that |
gertk | 0:806c2f2a7d47 | 439 | doesn't seem to be the case... */ |
gertk | 0:806c2f2a7d47 | 440 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 441 | // printf("OUTI %02x %02x\n\r",c,x); |
gertk | 0:806c2f2a7d47 | 442 | out(c,x); |
gertk | 0:806c2f2a7d47 | 443 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 444 | b--; |
gertk | 0:806c2f2a7d47 | 445 | f=(f&1)|0x12|(b&0xa8)|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 446 | // f=(f & 0xBF)|2|((b==0)<<6); |
gertk | 0:806c2f2a7d47 | 447 | |
gertk | 0:806c2f2a7d47 | 448 | } |
gertk | 0:806c2f2a7d47 | 449 | endinstr; |
gertk | 0:806c2f2a7d47 | 450 | |
gertk | 0:806c2f2a7d47 | 451 | // LDD |
gertk | 0:806c2f2a7d47 | 452 | instr(0xa8,12); |
gertk | 0:806c2f2a7d47 | 453 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 454 | store(de,x); |
gertk | 0:806c2f2a7d47 | 455 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 456 | if(!e--)d--; |
gertk | 0:806c2f2a7d47 | 457 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 458 | f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 459 | } |
gertk | 0:806c2f2a7d47 | 460 | endinstr; |
gertk | 0:806c2f2a7d47 | 461 | |
gertk | 0:806c2f2a7d47 | 462 | // CPD |
gertk | 0:806c2f2a7d47 | 463 | instr(0xa9,12); |
gertk | 0:806c2f2a7d47 | 464 | {unsigned char carry=cy; |
gertk | 0:806c2f2a7d47 | 465 | cpa(fetch(hl)); |
gertk | 0:806c2f2a7d47 | 466 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 467 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 468 | f=(f&0xfa)|carry|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 469 | } |
gertk | 0:806c2f2a7d47 | 470 | endinstr; |
gertk | 0:806c2f2a7d47 | 471 | |
gertk | 0:806c2f2a7d47 | 472 | // IND |
gertk | 0:806c2f2a7d47 | 473 | instr(0xaa,12); |
gertk | 0:806c2f2a7d47 | 474 | {unsigned char t=in(c); |
gertk | 0:806c2f2a7d47 | 475 | store(hl,t); |
gertk | 0:806c2f2a7d47 | 476 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 477 | b--; |
gertk | 0:806c2f2a7d47 | 478 | // f=(f & 0xBF)|2|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 479 | |
gertk | 0:806c2f2a7d47 | 480 | f=(b&0xa8)|((b>0)<<6)|2|((parity(b)^c^4)&4); |
gertk | 0:806c2f2a7d47 | 481 | } |
gertk | 0:806c2f2a7d47 | 482 | endinstr; |
gertk | 0:806c2f2a7d47 | 483 | |
gertk | 0:806c2f2a7d47 | 484 | // OUTD |
gertk | 0:806c2f2a7d47 | 485 | instr(0xab,12); |
gertk | 0:806c2f2a7d47 | 486 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 487 | out(c,x); |
gertk | 0:806c2f2a7d47 | 488 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 489 | b--; |
gertk | 0:806c2f2a7d47 | 490 | f=(f&1)|0x12|(b&0xa8)|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 491 | } |
gertk | 0:806c2f2a7d47 | 492 | endinstr; |
gertk | 0:806c2f2a7d47 | 493 | |
gertk | 0:806c2f2a7d47 | 494 | /* Note: the Z80 implements "*R" as "*" followed by JR -2. No reason |
gertk | 0:806c2f2a7d47 | 495 | to change this... */ |
gertk | 0:806c2f2a7d47 | 496 | |
gertk | 0:806c2f2a7d47 | 497 | // LDIR |
gertk | 0:806c2f2a7d47 | 498 | instr(0xb0,12); |
gertk | 0:806c2f2a7d47 | 499 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 500 | store(de,x); |
gertk | 0:806c2f2a7d47 | 501 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 502 | if(!++e)d++; |
gertk | 0:806c2f2a7d47 | 503 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 504 | f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 505 | if(b|c)pc-=2; |
gertk | 0:806c2f2a7d47 | 506 | } |
gertk | 0:806c2f2a7d47 | 507 | endinstr; |
gertk | 0:806c2f2a7d47 | 508 | |
gertk | 0:806c2f2a7d47 | 509 | // CPIR |
gertk | 0:806c2f2a7d47 | 510 | instr(0xb1,12); |
gertk | 0:806c2f2a7d47 | 511 | {unsigned char carry=cy; |
gertk | 0:806c2f2a7d47 | 512 | cpa(fetch(hl)); |
gertk | 0:806c2f2a7d47 | 513 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 514 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 515 | f=(f&0xfa)|carry|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 516 | if((f&0x44)==4)pc-=2; |
gertk | 0:806c2f2a7d47 | 517 | } |
gertk | 0:806c2f2a7d47 | 518 | endinstr; |
gertk | 0:806c2f2a7d47 | 519 | |
gertk | 0:806c2f2a7d47 | 520 | // INIR |
gertk | 0:806c2f2a7d47 | 521 | instr(0xb2,12); |
gertk | 0:806c2f2a7d47 | 522 | {unsigned char t=in(c); |
gertk | 0:806c2f2a7d47 | 523 | store(hl,t); |
gertk | 0:806c2f2a7d47 | 524 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 525 | b--; |
gertk | 0:806c2f2a7d47 | 526 | f=(b&0xa8)|((!b)<<6)|2|((parity(b)^c)&4); |
gertk | 0:806c2f2a7d47 | 527 | // f=(f & 0xBF)|2|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 528 | if(b)pc-=2; |
gertk | 0:806c2f2a7d47 | 529 | } |
gertk | 0:806c2f2a7d47 | 530 | endinstr; |
gertk | 0:806c2f2a7d47 | 531 | |
gertk | 0:806c2f2a7d47 | 532 | // OTIR |
gertk | 0:806c2f2a7d47 | 533 | instr(0xb3,12); |
gertk | 0:806c2f2a7d47 | 534 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 535 | out(c,x); |
gertk | 0:806c2f2a7d47 | 536 | if(!++l)h++; |
gertk | 0:806c2f2a7d47 | 537 | b--; |
gertk | 0:806c2f2a7d47 | 538 | f=(f&1)|0x12|(b&0xa8)|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 539 | if(b)pc-=2; |
gertk | 0:806c2f2a7d47 | 540 | } |
gertk | 0:806c2f2a7d47 | 541 | endinstr; |
gertk | 0:806c2f2a7d47 | 542 | |
gertk | 0:806c2f2a7d47 | 543 | // LDDR |
gertk | 0:806c2f2a7d47 | 544 | instr(0xb8,12); |
gertk | 0:806c2f2a7d47 | 545 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 546 | store(de,x); |
gertk | 0:806c2f2a7d47 | 547 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 548 | if(!e--)d--; |
gertk | 0:806c2f2a7d47 | 549 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 550 | f=(f&0xc1)|(x&0x28)|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 551 | if(b|c)pc-=2; |
gertk | 0:806c2f2a7d47 | 552 | } |
gertk | 0:806c2f2a7d47 | 553 | endinstr; |
gertk | 0:806c2f2a7d47 | 554 | |
gertk | 0:806c2f2a7d47 | 555 | // CPDR |
gertk | 0:806c2f2a7d47 | 556 | instr(0xb9,12); |
gertk | 0:806c2f2a7d47 | 557 | {unsigned char carry=cy; |
gertk | 0:806c2f2a7d47 | 558 | cpa(fetch(hl)); |
gertk | 0:806c2f2a7d47 | 559 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 560 | if(!c--)b--; |
gertk | 0:806c2f2a7d47 | 561 | f=(f&0xfa)|carry|(((b|c)>0)<<2); |
gertk | 0:806c2f2a7d47 | 562 | if((f&0x44)==4)pc-=2; |
gertk | 0:806c2f2a7d47 | 563 | } |
gertk | 0:806c2f2a7d47 | 564 | endinstr; |
gertk | 0:806c2f2a7d47 | 565 | |
gertk | 0:806c2f2a7d47 | 566 | // INDR |
gertk | 0:806c2f2a7d47 | 567 | instr(0xba,12); |
gertk | 0:806c2f2a7d47 | 568 | {unsigned char t=in(c); |
gertk | 0:806c2f2a7d47 | 569 | store(hl,t); |
gertk | 0:806c2f2a7d47 | 570 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 571 | b--; |
gertk | 0:806c2f2a7d47 | 572 | f=(b&0xa8)|((!b)<<6)|2|((parity(b)^c^4)&4); |
gertk | 0:806c2f2a7d47 | 573 | // f=(f & 0xBF)|2|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 574 | |
gertk | 0:806c2f2a7d47 | 575 | if(b)pc-=2; |
gertk | 0:806c2f2a7d47 | 576 | } |
gertk | 0:806c2f2a7d47 | 577 | endinstr; |
gertk | 0:806c2f2a7d47 | 578 | |
gertk | 0:806c2f2a7d47 | 579 | // OTDR |
gertk | 0:806c2f2a7d47 | 580 | instr(0xbb,12); |
gertk | 0:806c2f2a7d47 | 581 | {unsigned char x=fetch(hl); |
gertk | 0:806c2f2a7d47 | 582 | out(c,x); |
gertk | 0:806c2f2a7d47 | 583 | if(!l--)h--; |
gertk | 0:806c2f2a7d47 | 584 | b--; |
gertk | 0:806c2f2a7d47 | 585 | f=(f&1)|0x12|(b&0xa8)|((!b)<<6); |
gertk | 0:806c2f2a7d47 | 586 | if(b)pc-=2; |
gertk | 0:806c2f2a7d47 | 587 | } |
gertk | 0:806c2f2a7d47 | 588 | endinstr; |
gertk | 0:806c2f2a7d47 | 589 | |
gertk | 0:806c2f2a7d47 | 590 | }} |