libz80 with compilation problems (uses up to much ram)

Committer:
gertk
Date:
Sat Mar 12 22:39:10 2011 +0000
Revision:
1:78a39c3a30f6
Parent:
0:b612024f5aee

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
gertk 0:b612024f5aee 1 /* =========================================================
gertk 0:b612024f5aee 2 * libz80 - Z80 emulation library
gertk 0:b612024f5aee 3 * =========================================================
gertk 0:b612024f5aee 4 *
gertk 0:b612024f5aee 5 * (C) Gabriel Gambetta (ggambett@adinet.com.uy) 2000 - 2002
gertk 0:b612024f5aee 6 *
gertk 0:b612024f5aee 7 * Version 1.99
gertk 1:78a39c3a30f6 8 * modified for mbed 2011 Gert van der Knokke
gertk 0:b612024f5aee 9 * ---------------------------------------------------------
gertk 0:b612024f5aee 10 *
gertk 0:b612024f5aee 11 * This program is free software; you can redistribute it and/or modify
gertk 0:b612024f5aee 12 * it under the terms of the GNU General Public License as published by
gertk 0:b612024f5aee 13 * the Free Software Foundation; either version 2 of the License, or
gertk 0:b612024f5aee 14 * (at your option) any later version.
gertk 0:b612024f5aee 15 *
gertk 0:b612024f5aee 16 * This program is distributed in the hope that it will be useful,
gertk 0:b612024f5aee 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
gertk 0:b612024f5aee 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
gertk 0:b612024f5aee 19 * GNU General Public License for more details.
gertk 0:b612024f5aee 20 *
gertk 0:b612024f5aee 21 * You should have received a copy of the GNU General Public License
gertk 0:b612024f5aee 22 * along with this program; if not, write to the Free Software
gertk 0:b612024f5aee 23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
gertk 0:b612024f5aee 24 */
gertk 0:b612024f5aee 25
gertk 0:b612024f5aee 26 #include "z80.h"
gertk 0:b612024f5aee 27 #include "string.h"
gertk 0:b612024f5aee 28
gertk 0:b612024f5aee 29
gertk 0:b612024f5aee 30 #define BR (ctx->R1.br)
gertk 0:b612024f5aee 31 #define WR (ctx->R1.wr)
gertk 0:b612024f5aee 32
gertk 0:b612024f5aee 33 #define SETFLAG(F) setFlag(ctx, F)
gertk 0:b612024f5aee 34 #define RESFLAG(F) resFlag(ctx, F)
gertk 0:b612024f5aee 35 #define GETFLAG(F) getFlag(ctx, F)
gertk 0:b612024f5aee 36
gertk 0:b612024f5aee 37 #define VALFLAG(F,V) valFlag(ctx, F, V)
gertk 0:b612024f5aee 38
gertk 0:b612024f5aee 39
gertk 0:b612024f5aee 40 /* ---------------------------------------------------------
gertk 0:b612024f5aee 41 * Flag tricks
gertk 0:b612024f5aee 42 * ---------------------------------------------------------
gertk 0:b612024f5aee 43 *
gertk 0:b612024f5aee 44 * To avoid repeating entries in the spec files, many operations that look similar are treated as special cases
gertk 0:b612024f5aee 45 * of a more general operation.
gertk 0:b612024f5aee 46 *
gertk 0:b612024f5aee 47 * For example, ADD and ADC are similar in syntax and operation - the difference is that ADC takes the carry flag
gertk 0:b612024f5aee 48 * into account.
gertk 0:b612024f5aee 49 *
gertk 0:b612024f5aee 50 * So we define a general operation doArithmetic(...) which accepts a boolean parameter specifying wheter to do
gertk 0:b612024f5aee 51 * a Carry-operation or not. Then, when we parse, we can say
gertk 0:b612024f5aee 52 *
gertk 0:b612024f5aee 53 * (ADD|ADC) ....
gertk 0:b612024f5aee 54 * doArithmetic(FLAG_FOR_%1)
gertk 0:b612024f5aee 55 *
gertk 0:b612024f5aee 56 * and everything works fine.
gertk 0:b612024f5aee 57 *
gertk 0:b612024f5aee 58 */
gertk 0:b612024f5aee 59
gertk 0:b612024f5aee 60 /* Flags for doIncDec() */
gertk 0:b612024f5aee 61 static const int ID_INC = 0;
gertk 0:b612024f5aee 62 static const int ID_DEC = 1;
gertk 0:b612024f5aee 63
gertk 0:b612024f5aee 64 /* Flags for enable / disable interrupts */
gertk 0:b612024f5aee 65 static const int IE_DI = 0;
gertk 0:b612024f5aee 66 static const int IE_EI = 1;
gertk 0:b612024f5aee 67
gertk 0:b612024f5aee 68 /* Flags for doSetRes() */
gertk 0:b612024f5aee 69 static const int SR_RES = 0;
gertk 0:b612024f5aee 70 static const int SR_SET = 1;
gertk 0:b612024f5aee 71
gertk 0:b612024f5aee 72 /* Flags for logical / arithmetic operations */
gertk 0:b612024f5aee 73 static const int IA_L = 0;
gertk 0:b612024f5aee 74 static const int IA_A = 1;
gertk 0:b612024f5aee 75
gertk 0:b612024f5aee 76 /* Flags for doArithmetic() - F1 = withCarry, F2 = isSub */
gertk 0:b612024f5aee 77 static const int F1_ADC = 1;
gertk 0:b612024f5aee 78 static const int F1_SBC = 1;
gertk 0:b612024f5aee 79 static const int F1_ADD = 0;
gertk 0:b612024f5aee 80 static const int F1_SUB = 0;
gertk 0:b612024f5aee 81
gertk 0:b612024f5aee 82 static const int F2_ADC = 0;
gertk 0:b612024f5aee 83 static const int F2_SBC = 1;
gertk 0:b612024f5aee 84 static const int F2_ADD = 0;
gertk 0:b612024f5aee 85 static const int F2_SUB = 1;
gertk 0:b612024f5aee 86
gertk 0:b612024f5aee 87
gertk 0:b612024f5aee 88 /* ---------------------------------------------------------
gertk 0:b612024f5aee 89 * The opcode implementations
gertk 0:b612024f5aee 90 * ---------------------------------------------------------
gertk 0:b612024f5aee 91 */
gertk 0:b612024f5aee 92 #include "opcodes_decl.h"
gertk 0:b612024f5aee 93
gertk 0:b612024f5aee 94 typedef enum
gertk 0:b612024f5aee 95 {
gertk 0:b612024f5aee 96 OP_NONE,
gertk 0:b612024f5aee 97 OP_BYTE,
gertk 0:b612024f5aee 98 OP_OFFSET,
gertk 0:b612024f5aee 99 OP_WORD
gertk 0:b612024f5aee 100 } Z80OperandType;
gertk 0:b612024f5aee 101
gertk 0:b612024f5aee 102 typedef void (*Z80OpcodeFunc) (Z80Context* ctx);
gertk 0:b612024f5aee 103
gertk 0:b612024f5aee 104 struct Z80OpcodeEntry
gertk 0:b612024f5aee 105 {
gertk 0:b612024f5aee 106 Z80OpcodeFunc func;
gertk 0:b612024f5aee 107
gertk 0:b612024f5aee 108 int operand_type;
gertk 0:b612024f5aee 109 char* format;
gertk 0:b612024f5aee 110
gertk 0:b612024f5aee 111 struct Z80OpcodeTable* table;
gertk 0:b612024f5aee 112 };
gertk 0:b612024f5aee 113
gertk 0:b612024f5aee 114
gertk 0:b612024f5aee 115 struct Z80OpcodeTable
gertk 0:b612024f5aee 116 {
gertk 0:b612024f5aee 117 int opcode_offset;
gertk 0:b612024f5aee 118 struct Z80OpcodeEntry entries[256];
gertk 0:b612024f5aee 119 };
gertk 0:b612024f5aee 120
gertk 0:b612024f5aee 121
gertk 0:b612024f5aee 122 #include "opcodes_table.h"
gertk 0:b612024f5aee 123
gertk 0:b612024f5aee 124
gertk 0:b612024f5aee 125 /* ---------------------------------------------------------
gertk 0:b612024f5aee 126 * Data operations
gertk 0:b612024f5aee 127 * ---------------------------------------------------------
gertk 0:b612024f5aee 128 */
gertk 0:b612024f5aee 129 static void write8 (Z80Context* ctx, ushort addr, byte val)
gertk 0:b612024f5aee 130 {
gertk 0:b612024f5aee 131 ctx->memWrite(ctx->memParam, addr, val);
gertk 0:b612024f5aee 132 }
gertk 0:b612024f5aee 133
gertk 0:b612024f5aee 134
gertk 0:b612024f5aee 135 static void write16 (Z80Context* ctx, ushort addr, ushort val)
gertk 0:b612024f5aee 136 {
gertk 0:b612024f5aee 137 ctx->memWrite(ctx->memParam, addr, (byte)(val & 0xFF));
gertk 0:b612024f5aee 138 val >>= 8;
gertk 0:b612024f5aee 139 addr++;
gertk 0:b612024f5aee 140 ctx->memWrite(ctx->memParam, addr, (byte)(val & 0xFF));
gertk 0:b612024f5aee 141 }
gertk 0:b612024f5aee 142
gertk 0:b612024f5aee 143
gertk 0:b612024f5aee 144 static byte read8 (Z80Context* ctx, ushort addr)
gertk 0:b612024f5aee 145 {
gertk 0:b612024f5aee 146 return ctx->memRead(ctx->memParam, addr);
gertk 0:b612024f5aee 147 }
gertk 0:b612024f5aee 148
gertk 0:b612024f5aee 149
gertk 0:b612024f5aee 150 static ushort read16 (Z80Context* ctx, ushort addr)
gertk 0:b612024f5aee 151 {
gertk 0:b612024f5aee 152 return (ctx->memRead(ctx->memParam, addr) | (ctx->memRead(ctx->memParam, ++addr) << 8));
gertk 0:b612024f5aee 153 }
gertk 0:b612024f5aee 154
gertk 0:b612024f5aee 155
gertk 0:b612024f5aee 156 static byte ioRead (Z80Context* ctx, ushort addr)
gertk 0:b612024f5aee 157 {
gertk 0:b612024f5aee 158 return ctx->ioRead(ctx->ioParam, addr);
gertk 0:b612024f5aee 159 }
gertk 0:b612024f5aee 160
gertk 0:b612024f5aee 161
gertk 0:b612024f5aee 162 static void ioWrite (Z80Context* ctx, ushort addr, byte val)
gertk 0:b612024f5aee 163 {
gertk 0:b612024f5aee 164 ctx->ioWrite(ctx->ioParam, addr, val);
gertk 0:b612024f5aee 165 }
gertk 0:b612024f5aee 166
gertk 0:b612024f5aee 167
gertk 0:b612024f5aee 168 /* ---------------------------------------------------------
gertk 0:b612024f5aee 169 * Flag operations
gertk 0:b612024f5aee 170 * ---------------------------------------------------------
gertk 0:b612024f5aee 171 */
gertk 0:b612024f5aee 172
gertk 0:b612024f5aee 173 /** Sets a flag */
gertk 1:78a39c3a30f6 174 //static void setFlag(Z80Context* ctx, Z80Flags flag)
gertk 1:78a39c3a30f6 175 static void setFlag(Z80Context* ctx, int flag)
gertk 0:b612024f5aee 176 {
gertk 0:b612024f5aee 177 BR.F |= flag;
gertk 0:b612024f5aee 178 }
gertk 0:b612024f5aee 179
gertk 0:b612024f5aee 180 /** Resets a flag */
gertk 1:78a39c3a30f6 181 // static void resFlag(Z80Context* ctx, Z80Flags flag)
gertk 1:78a39c3a30f6 182 static void resFlag(Z80Context* ctx, int flag)
gertk 0:b612024f5aee 183 {
gertk 0:b612024f5aee 184 BR.F &= ~flag;
gertk 0:b612024f5aee 185 }
gertk 0:b612024f5aee 186
gertk 0:b612024f5aee 187 /** Puts a value in a flag */
gertk 1:78a39c3a30f6 188 //static void valFlag(Z80Context* ctx, Z80Flags flag, int val)
gertk 1:78a39c3a30f6 189 static void valFlag(Z80Context* ctx, int flag, int val)
gertk 0:b612024f5aee 190 {
gertk 0:b612024f5aee 191 if (val)
gertk 0:b612024f5aee 192 SETFLAG(flag);
gertk 0:b612024f5aee 193 else
gertk 0:b612024f5aee 194 RESFLAG(flag);
gertk 0:b612024f5aee 195 }
gertk 0:b612024f5aee 196
gertk 0:b612024f5aee 197 /** Returns a flag */
gertk 1:78a39c3a30f6 198 // static int getFlag(Z80Context* ctx, Z80Flags flag)
gertk 1:78a39c3a30f6 199 static int getFlag(Z80Context* ctx, int flag)
gertk 0:b612024f5aee 200 {
gertk 0:b612024f5aee 201 return (BR.F & flag) != 0;
gertk 0:b612024f5aee 202 }
gertk 0:b612024f5aee 203
gertk 0:b612024f5aee 204
gertk 0:b612024f5aee 205 /* ---------------------------------------------------------
gertk 0:b612024f5aee 206 * Flag adjustments
gertk 0:b612024f5aee 207 * ---------------------------------------------------------
gertk 0:b612024f5aee 208 */
gertk 0:b612024f5aee 209
gertk 0:b612024f5aee 210 static int parityBit[256] = {
gertk 0:b612024f5aee 211 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 212 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 213 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 214 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 215 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 216 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 217 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 218 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 219 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 220 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 221 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 222 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 223 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 224 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 225 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 226 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
gertk 0:b612024f5aee 227
gertk 0:b612024f5aee 228
gertk 0:b612024f5aee 229 static void adjustFlags (Z80Context* ctx, byte val)
gertk 0:b612024f5aee 230 {
gertk 0:b612024f5aee 231 VALFLAG(F_5, (val & F_5) != 0);
gertk 0:b612024f5aee 232 VALFLAG(F_3, (val & F_3) != 0);
gertk 0:b612024f5aee 233 }
gertk 0:b612024f5aee 234
gertk 0:b612024f5aee 235
gertk 0:b612024f5aee 236 static void adjustFlagSZP (Z80Context* ctx, byte val)
gertk 0:b612024f5aee 237 {
gertk 0:b612024f5aee 238 VALFLAG(F_S, (val & 0x80) != 0);
gertk 0:b612024f5aee 239 VALFLAG(F_Z, (val == 0));
gertk 0:b612024f5aee 240 VALFLAG(F_PV, parityBit[val]);
gertk 0:b612024f5aee 241 }
gertk 0:b612024f5aee 242
gertk 0:b612024f5aee 243
gertk 0:b612024f5aee 244 // Adjust flags after AND, OR, XOR
gertk 0:b612024f5aee 245 static void adjustLogicFlag (Z80Context* ctx, int flagH)
gertk 0:b612024f5aee 246 {
gertk 0:b612024f5aee 247 VALFLAG(F_S, (BR.A & 0x80) != 0);
gertk 0:b612024f5aee 248 VALFLAG(F_Z, (BR.A == 0));
gertk 0:b612024f5aee 249 VALFLAG(F_H, flagH);
gertk 0:b612024f5aee 250 VALFLAG(F_N, 0);
gertk 0:b612024f5aee 251 VALFLAG(F_C, 0);
gertk 0:b612024f5aee 252 VALFLAG(F_PV, parityBit[BR.A]);
gertk 0:b612024f5aee 253
gertk 0:b612024f5aee 254 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 255 }
gertk 0:b612024f5aee 256
gertk 0:b612024f5aee 257
gertk 0:b612024f5aee 258 /* ---------------------------------------------------------
gertk 0:b612024f5aee 259 * Condition checks
gertk 0:b612024f5aee 260 * ---------------------------------------------------------
gertk 0:b612024f5aee 261 */
gertk 0:b612024f5aee 262
gertk 0:b612024f5aee 263 typedef enum
gertk 0:b612024f5aee 264 {
gertk 0:b612024f5aee 265 C_,
gertk 0:b612024f5aee 266 C_Z,
gertk 0:b612024f5aee 267 C_NZ,
gertk 0:b612024f5aee 268 C_C,
gertk 0:b612024f5aee 269 C_NC,
gertk 0:b612024f5aee 270 C_M,
gertk 0:b612024f5aee 271 C_P,
gertk 0:b612024f5aee 272 C_PE,
gertk 0:b612024f5aee 273 C_PO
gertk 0:b612024f5aee 274 } Z80Condition;
gertk 0:b612024f5aee 275
gertk 0:b612024f5aee 276 static int condition(Z80Context* ctx, Z80Condition cond)
gertk 0:b612024f5aee 277 {
gertk 0:b612024f5aee 278 if (cond == C_)
gertk 0:b612024f5aee 279 return GETFLAG(F_);
gertk 0:b612024f5aee 280
gertk 0:b612024f5aee 281 if (cond == C_Z)
gertk 0:b612024f5aee 282 return !GETFLAG(F_Z);
gertk 0:b612024f5aee 283
gertk 0:b612024f5aee 284 if (cond == C_NZ)
gertk 0:b612024f5aee 285 return GETFLAG(F_Z);
gertk 0:b612024f5aee 286
gertk 0:b612024f5aee 287 if (cond == C_C)
gertk 0:b612024f5aee 288 return GETFLAG(F_C);
gertk 0:b612024f5aee 289
gertk 0:b612024f5aee 290 if (cond == C_NC)
gertk 0:b612024f5aee 291 return !GETFLAG(F_C);
gertk 0:b612024f5aee 292
gertk 0:b612024f5aee 293 if (cond == C_M)
gertk 0:b612024f5aee 294 return GETFLAG(F_S);
gertk 0:b612024f5aee 295
gertk 0:b612024f5aee 296 if (cond == C_P)
gertk 0:b612024f5aee 297 return !(GETFLAG(F_S) | GETFLAG(F_Z));
gertk 0:b612024f5aee 298 if (cond == C_PE)
gertk 0:b612024f5aee 299 return !GETFLAG(F_PV);
gertk 0:b612024f5aee 300
gertk 0:b612024f5aee 301 /* if (cond == C_PO)*/
gertk 0:b612024f5aee 302 return GETFLAG(F_PV);
gertk 0:b612024f5aee 303 }
gertk 0:b612024f5aee 304
gertk 0:b612024f5aee 305
gertk 0:b612024f5aee 306 /* ---------------------------------------------------------
gertk 0:b612024f5aee 307 * Generic operations
gertk 0:b612024f5aee 308 * ---------------------------------------------------------
gertk 0:b612024f5aee 309 */
gertk 0:b612024f5aee 310
gertk 0:b612024f5aee 311
gertk 0:b612024f5aee 312 static int doComplement(byte v)
gertk 0:b612024f5aee 313 {
gertk 0:b612024f5aee 314 if ((v & 0x80) == 0)
gertk 0:b612024f5aee 315 return v;
gertk 0:b612024f5aee 316
gertk 0:b612024f5aee 317 v = ~v;
gertk 0:b612024f5aee 318 v &= 0x7F;
gertk 0:b612024f5aee 319 v++;
gertk 0:b612024f5aee 320
gertk 0:b612024f5aee 321 return -v;
gertk 0:b612024f5aee 322 }
gertk 0:b612024f5aee 323
gertk 0:b612024f5aee 324
gertk 0:b612024f5aee 325 /** Do an arithmetic operation (ADD, SUB, ADC, SBC y CP) */
gertk 0:b612024f5aee 326 static byte doArithmetic (Z80Context* ctx, byte value, int withCarry, int isSub)
gertk 0:b612024f5aee 327 {
gertk 0:b612024f5aee 328 ushort res; /* To detect carry */
gertk 0:b612024f5aee 329
gertk 0:b612024f5aee 330 if (isSub)
gertk 0:b612024f5aee 331 {
gertk 0:b612024f5aee 332 SETFLAG(F_N);
gertk 0:b612024f5aee 333 VALFLAG(F_H, (((BR.A & 0x0F) - (value & 0x0F)) & 0x10) != 0);
gertk 0:b612024f5aee 334 res = BR.A - value;
gertk 0:b612024f5aee 335 if (withCarry && GETFLAG(F_C))
gertk 0:b612024f5aee 336 res--;
gertk 0:b612024f5aee 337 }
gertk 0:b612024f5aee 338 else
gertk 0:b612024f5aee 339 {
gertk 0:b612024f5aee 340 RESFLAG(F_N);
gertk 0:b612024f5aee 341 VALFLAG(F_H, (((BR.A & 0x0F) + (value & 0x0F)) & 0x10) != 0);
gertk 0:b612024f5aee 342 res = BR.A + value;
gertk 0:b612024f5aee 343 if (withCarry && GETFLAG(F_C))
gertk 0:b612024f5aee 344 res++;
gertk 0:b612024f5aee 345 }
gertk 0:b612024f5aee 346 VALFLAG(F_S, ((res & 0x80) != 0));
gertk 0:b612024f5aee 347 VALFLAG(F_C, ((res & 0x100) != 0));
gertk 0:b612024f5aee 348 VALFLAG(F_Z, (res == 0));
gertk 0:b612024f5aee 349 VALFLAG(F_PV, (((BR.A & 0x80) == (value & 0x80)) && ((BR.A & 0x80) != (res & 0x80))) != 0);
gertk 0:b612024f5aee 350
gertk 0:b612024f5aee 351 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 352
gertk 0:b612024f5aee 353 return (byte)(res & 0xFF);
gertk 0:b612024f5aee 354 }
gertk 0:b612024f5aee 355
gertk 0:b612024f5aee 356
gertk 0:b612024f5aee 357 static void doAND (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 358 {
gertk 0:b612024f5aee 359 BR.A &= value;
gertk 0:b612024f5aee 360 adjustLogicFlag(ctx, 1);
gertk 0:b612024f5aee 361 }
gertk 0:b612024f5aee 362
gertk 0:b612024f5aee 363
gertk 0:b612024f5aee 364 static void doOR (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 365 {
gertk 0:b612024f5aee 366 BR.A |= value;
gertk 0:b612024f5aee 367 adjustLogicFlag(ctx, 0);
gertk 0:b612024f5aee 368 }
gertk 0:b612024f5aee 369
gertk 0:b612024f5aee 370
gertk 0:b612024f5aee 371 static void doXOR (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 372 {
gertk 0:b612024f5aee 373 BR.A ^= value;
gertk 0:b612024f5aee 374 adjustLogicFlag(ctx, 0);
gertk 0:b612024f5aee 375 }
gertk 0:b612024f5aee 376
gertk 0:b612024f5aee 377
gertk 0:b612024f5aee 378 static void doBIT (Z80Context* ctx, int b, byte val)
gertk 0:b612024f5aee 379 {
gertk 0:b612024f5aee 380 if (val & (1 << b))
gertk 1:78a39c3a30f6 381 RESFLAG(F_Z | F_PV);
gertk 0:b612024f5aee 382 else
gertk 0:b612024f5aee 383 SETFLAG(F_Z | F_PV);
gertk 0:b612024f5aee 384
gertk 0:b612024f5aee 385 SETFLAG(F_H);
gertk 0:b612024f5aee 386 RESFLAG(F_N);
gertk 0:b612024f5aee 387
gertk 0:b612024f5aee 388 RESFLAG(F_S);
gertk 0:b612024f5aee 389 if ((b == 7) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 390 SETFLAG(F_S);
gertk 0:b612024f5aee 391
gertk 0:b612024f5aee 392 RESFLAG(F_5);
gertk 0:b612024f5aee 393 if ((b == 5) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 394 SETFLAG(F_5);
gertk 0:b612024f5aee 395
gertk 0:b612024f5aee 396 RESFLAG(F_3);
gertk 0:b612024f5aee 397 if ((b == 3) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 398 SETFLAG(F_3);
gertk 0:b612024f5aee 399 }
gertk 0:b612024f5aee 400
gertk 0:b612024f5aee 401
gertk 0:b612024f5aee 402 byte doSetRes (Z80Context* ctx, int bit, int pos, byte val)
gertk 0:b612024f5aee 403 {
gertk 0:b612024f5aee 404 if (bit)
gertk 0:b612024f5aee 405 val |= (1 << pos);
gertk 0:b612024f5aee 406 else
gertk 0:b612024f5aee 407 val &= ~(1 << pos);
gertk 0:b612024f5aee 408 return val;
gertk 0:b612024f5aee 409 }
gertk 0:b612024f5aee 410
gertk 0:b612024f5aee 411
gertk 0:b612024f5aee 412
gertk 0:b612024f5aee 413 static byte doIncDec (Z80Context* ctx, byte val, int isDec)
gertk 0:b612024f5aee 414 {
gertk 0:b612024f5aee 415 if (isDec)
gertk 0:b612024f5aee 416 {
gertk 0:b612024f5aee 417 VALFLAG(F_PV, (val & 0x80) && !((val - 1) & 0x80));
gertk 0:b612024f5aee 418 val--;
gertk 0:b612024f5aee 419 VALFLAG(F_H, !(val & 0x0F));
gertk 0:b612024f5aee 420 }
gertk 0:b612024f5aee 421 else
gertk 0:b612024f5aee 422 {
gertk 0:b612024f5aee 423 VALFLAG(F_PV, !(val & 0x80) && ((val + 1) & 0x80));
gertk 0:b612024f5aee 424 val++;
gertk 0:b612024f5aee 425 VALFLAG(F_H, !(val & 0x0F));
gertk 0:b612024f5aee 426 }
gertk 0:b612024f5aee 427
gertk 0:b612024f5aee 428 VALFLAG(F_S, ((val & 0x80) != 0));
gertk 0:b612024f5aee 429 VALFLAG(F_Z, (val == 0));
gertk 0:b612024f5aee 430 VALFLAG(F_N, isDec);
gertk 0:b612024f5aee 431
gertk 0:b612024f5aee 432 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 433
gertk 0:b612024f5aee 434 return val;
gertk 0:b612024f5aee 435 }
gertk 0:b612024f5aee 436
gertk 0:b612024f5aee 437
gertk 0:b612024f5aee 438 static byte doRLC (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 439 {
gertk 0:b612024f5aee 440 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 441 val <<= 1;
gertk 0:b612024f5aee 442 val |= (byte)GETFLAG(F_C);
gertk 0:b612024f5aee 443
gertk 0:b612024f5aee 444 adjustFlags(ctx, val);
gertk 0:b612024f5aee 445 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 446
gertk 0:b612024f5aee 447 if (adjFlags)
gertk 0:b612024f5aee 448 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 449
gertk 0:b612024f5aee 450 return val;
gertk 0:b612024f5aee 451 }
gertk 0:b612024f5aee 452
gertk 0:b612024f5aee 453
gertk 0:b612024f5aee 454 static byte doRL (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 455 {
gertk 0:b612024f5aee 456 int CY = GETFLAG(F_C);
gertk 0:b612024f5aee 457 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 458 val <<= 1;
gertk 0:b612024f5aee 459 val |= (byte)CY;
gertk 0:b612024f5aee 460
gertk 0:b612024f5aee 461 adjustFlags(ctx, val);
gertk 0:b612024f5aee 462 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 463
gertk 0:b612024f5aee 464 if (adjFlags)
gertk 0:b612024f5aee 465 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 466
gertk 0:b612024f5aee 467 return val;
gertk 0:b612024f5aee 468 }
gertk 0:b612024f5aee 469
gertk 0:b612024f5aee 470
gertk 0:b612024f5aee 471 static byte doRRC (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 472 {
gertk 0:b612024f5aee 473 VALFLAG(F_C, (val & 0x01) != 0);
gertk 0:b612024f5aee 474 val >>= 1;
gertk 0:b612024f5aee 475 val |= ((byte)GETFLAG(F_C) << 7);
gertk 0:b612024f5aee 476
gertk 0:b612024f5aee 477 adjustFlags(ctx, val);
gertk 0:b612024f5aee 478 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 479
gertk 0:b612024f5aee 480 if (adjFlags)
gertk 0:b612024f5aee 481 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 482
gertk 0:b612024f5aee 483 return val;
gertk 0:b612024f5aee 484 }
gertk 0:b612024f5aee 485
gertk 0:b612024f5aee 486
gertk 0:b612024f5aee 487 static byte doRR (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 488 {
gertk 0:b612024f5aee 489 int CY = GETFLAG(F_C);
gertk 0:b612024f5aee 490 VALFLAG(F_C, (val & 0x01));
gertk 0:b612024f5aee 491 val >>= 1;
gertk 0:b612024f5aee 492 val |= (CY << 7);
gertk 0:b612024f5aee 493
gertk 0:b612024f5aee 494 adjustFlags(ctx, val);
gertk 0:b612024f5aee 495 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 496
gertk 0:b612024f5aee 497 if (adjFlags)
gertk 0:b612024f5aee 498 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 499
gertk 0:b612024f5aee 500 return val;
gertk 0:b612024f5aee 501 }
gertk 0:b612024f5aee 502
gertk 0:b612024f5aee 503
gertk 0:b612024f5aee 504 static byte doSL (Z80Context* ctx, byte val, int isArith)
gertk 0:b612024f5aee 505 {
gertk 0:b612024f5aee 506 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 507 val <<= 1;
gertk 0:b612024f5aee 508
gertk 0:b612024f5aee 509 if (!isArith)
gertk 0:b612024f5aee 510 val |= 1;
gertk 0:b612024f5aee 511
gertk 0:b612024f5aee 512 adjustFlags(ctx, val);
gertk 0:b612024f5aee 513 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 514 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 515
gertk 0:b612024f5aee 516 return val;
gertk 0:b612024f5aee 517 }
gertk 0:b612024f5aee 518
gertk 0:b612024f5aee 519
gertk 0:b612024f5aee 520 static byte doSR (Z80Context* ctx, byte val, int isArith)
gertk 0:b612024f5aee 521 {
gertk 0:b612024f5aee 522 int b = ((val & 0x80) != 0);
gertk 0:b612024f5aee 523
gertk 0:b612024f5aee 524 VALFLAG(F_C, (val & 0x01) != 0);
gertk 0:b612024f5aee 525 val >>= 1;
gertk 0:b612024f5aee 526
gertk 0:b612024f5aee 527 if (isArith)
gertk 0:b612024f5aee 528 val |= (byte)b;
gertk 0:b612024f5aee 529
gertk 0:b612024f5aee 530 adjustFlags(ctx, val);
gertk 0:b612024f5aee 531 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 532 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 533
gertk 0:b612024f5aee 534 return val;
gertk 0:b612024f5aee 535 }
gertk 0:b612024f5aee 536
gertk 0:b612024f5aee 537
gertk 0:b612024f5aee 538 static void doPush (Z80Context* ctx, ushort val)
gertk 0:b612024f5aee 539 {
gertk 0:b612024f5aee 540 WR.SP--;
gertk 0:b612024f5aee 541 write16(ctx, WR.SP, val);
gertk 0:b612024f5aee 542 WR.SP--;
gertk 0:b612024f5aee 543 }
gertk 0:b612024f5aee 544
gertk 0:b612024f5aee 545
gertk 0:b612024f5aee 546 static ushort doPop (Z80Context* ctx)
gertk 0:b612024f5aee 547 {
gertk 0:b612024f5aee 548 ushort val;
gertk 0:b612024f5aee 549
gertk 0:b612024f5aee 550 WR.SP++;
gertk 0:b612024f5aee 551 val = read16(ctx, WR.SP);
gertk 0:b612024f5aee 552 WR.SP++;
gertk 0:b612024f5aee 553
gertk 0:b612024f5aee 554 return val;
gertk 0:b612024f5aee 555 }
gertk 0:b612024f5aee 556
gertk 0:b612024f5aee 557
gertk 0:b612024f5aee 558 /* The DAA opcode
gertk 0:b612024f5aee 559 * According to the value in A and the flags set, add a value to A
gertk 0:b612024f5aee 560 *
gertk 0:b612024f5aee 561 * Flags set Byte (0..9)(0..9)
gertk 0:b612024f5aee 562 * --------------------------------------------
gertk 0:b612024f5aee 563 * (None) + &00
gertk 0:b612024f5aee 564 * Carry:+ &60
gertk 0:b612024f5aee 565 * Subtract:+ &00
gertk 0:b612024f5aee 566 * Subtract+Carry:+ &A0
gertk 0:b612024f5aee 567 * Half-carry:+ &06
gertk 0:b612024f5aee 568 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 569 * Half-carry+Subtract:+ &FA
gertk 0:b612024f5aee 570 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 571 *
gertk 0:b612024f5aee 572 * Flags set Byte (0..9)(A..F)
gertk 0:b612024f5aee 573 * --------------------------------------------
gertk 0:b612024f5aee 574 * (None) + &06
gertk 0:b612024f5aee 575 * Carry:+ &66
gertk 0:b612024f5aee 576 * Subtract:+ &00
gertk 0:b612024f5aee 577 * Subtract+Carry:+ &a0
gertk 0:b612024f5aee 578 * Half-carry:+ &06
gertk 0:b612024f5aee 579 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 580 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 581 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 582 *
gertk 0:b612024f5aee 583 * Flags set Byte (A..F)(0..9)
gertk 0:b612024f5aee 584 * --------------------------------------------
gertk 0:b612024f5aee 585 * (None) + &60
gertk 0:b612024f5aee 586 * Carry:+ &60
gertk 0:b612024f5aee 587 * Subtract:+ &00
gertk 0:b612024f5aee 588 * Subtract+Carry:+ &A0
gertk 0:b612024f5aee 589 * Half-carry:+ &66
gertk 0:b612024f5aee 590 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 591 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 592 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 593 *
gertk 0:b612024f5aee 594 * Flags set Byte (A..F)(A..F)
gertk 0:b612024f5aee 595 * --------------------------------------------
gertk 0:b612024f5aee 596 * (None) + &66
gertk 0:b612024f5aee 597 * Carry:+ &66
gertk 0:b612024f5aee 598 * Subtract:+ &00
gertk 0:b612024f5aee 599 * Subtract+Carry:+ &a0
gertk 0:b612024f5aee 600 * Half-carry:+ &66
gertk 0:b612024f5aee 601 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 602 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 603 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 604 */
gertk 0:b612024f5aee 605
gertk 0:b612024f5aee 606 static int DAA_BYTETYPE[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };
gertk 0:b612024f5aee 607
gertk 0:b612024f5aee 608 static byte DAA_ADJUSTMENT[4][8] = {
gertk 0:b612024f5aee 609 { 0x00, 0x60, 0x00, 0xA0, 0x06, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 610 { 0x06, 0x66, 0x00, 0xA0, 0x06, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 611 { 0x60, 0x60, 0x00, 0xA0, 0x66, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 612 { 0x66, 0x66, 0x00, 0xA0, 0x66, 0x66, 0xFA, 0x9A } };
gertk 0:b612024f5aee 613
gertk 0:b612024f5aee 614 static void doDAA (Z80Context* ctx)
gertk 0:b612024f5aee 615 {
gertk 0:b612024f5aee 616 /* (0..9)(0..9) = 0 */
gertk 0:b612024f5aee 617 /* (0..9)(A..F) = 1 */
gertk 0:b612024f5aee 618 /* (A..F)(0..9) = 2 */
gertk 0:b612024f5aee 619 /* (A..F)(A..F) = 3 */
gertk 0:b612024f5aee 620 int byteType = DAA_BYTETYPE[BR.A] | ((DAA_BYTETYPE[BR.A >> 4]) << 1);
gertk 0:b612024f5aee 621
gertk 0:b612024f5aee 622 int flagMask = 0;
gertk 0:b612024f5aee 623 if (GETFLAG(F_C))
gertk 0:b612024f5aee 624 flagMask |= 1;
gertk 0:b612024f5aee 625 if (GETFLAG(F_S))
gertk 0:b612024f5aee 626 flagMask |= 2;
gertk 0:b612024f5aee 627 if (GETFLAG(F_H))
gertk 0:b612024f5aee 628 flagMask |= 4;
gertk 0:b612024f5aee 629
gertk 0:b612024f5aee 630 BR.A += DAA_ADJUSTMENT[byteType][flagMask];
gertk 0:b612024f5aee 631
gertk 0:b612024f5aee 632 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 633 }
gertk 0:b612024f5aee 634
gertk 1:78a39c3a30f6 635 #include "opcodes_impl.h"
gertk 0:b612024f5aee 636
gertk 0:b612024f5aee 637
gertk 0:b612024f5aee 638 /* ---------------------------------------------------------
gertk 0:b612024f5aee 639 * The top-level functions
gertk 0:b612024f5aee 640 * ---------------------------------------------------------
gertk 0:b612024f5aee 641 */
gertk 0:b612024f5aee 642 void Z80Execute (Z80Context* ctx)
gertk 0:b612024f5aee 643 {
gertk 0:b612024f5aee 644 struct Z80OpcodeTable* current = &opcodes_main;
gertk 0:b612024f5aee 645 struct Z80OpcodeEntry* entries = current->entries;
gertk 0:b612024f5aee 646 Z80OpcodeFunc func;
gertk 0:b612024f5aee 647
gertk 0:b612024f5aee 648 byte opcode;
gertk 0:b612024f5aee 649 int offset = 0;
gertk 0:b612024f5aee 650 do
gertk 0:b612024f5aee 651 {
gertk 0:b612024f5aee 652 opcode = read8(ctx, ctx->PC + offset);
gertk 0:b612024f5aee 653
gertk 0:b612024f5aee 654 ctx->PC++;
gertk 0:b612024f5aee 655 func = entries[opcode].func;
gertk 0:b612024f5aee 656 if (func != NULL)
gertk 0:b612024f5aee 657 {
gertk 0:b612024f5aee 658 ctx->PC -= offset;
gertk 0:b612024f5aee 659 func(ctx);
gertk 0:b612024f5aee 660 ctx->PC += offset;
gertk 0:b612024f5aee 661 break;
gertk 0:b612024f5aee 662 }
gertk 0:b612024f5aee 663 else if (entries[opcode].table != NULL)
gertk 0:b612024f5aee 664 {
gertk 0:b612024f5aee 665 current = entries[opcode].table;
gertk 0:b612024f5aee 666 entries = current->entries;
gertk 0:b612024f5aee 667 offset = current->opcode_offset;
gertk 0:b612024f5aee 668 }
gertk 0:b612024f5aee 669
gertk 0:b612024f5aee 670 else
gertk 0:b612024f5aee 671 {
gertk 0:b612024f5aee 672 /* NOP */
gertk 0:b612024f5aee 673 break;
gertk 0:b612024f5aee 674 }
gertk 0:b612024f5aee 675 } while(1);
gertk 0:b612024f5aee 676 }
gertk 0:b612024f5aee 677
gertk 0:b612024f5aee 678
gertk 0:b612024f5aee 679 void Z80Debug (Z80Context* ctx, char* dump, char* decode)
gertk 0:b612024f5aee 680 {
gertk 0:b612024f5aee 681 char tmp[20];
gertk 0:b612024f5aee 682 struct Z80OpcodeTable* current = &opcodes_main;
gertk 0:b612024f5aee 683 struct Z80OpcodeEntry* entries = current->entries;
gertk 0:b612024f5aee 684 char* fmt;
gertk 0:b612024f5aee 685 byte opcode;
gertk 0:b612024f5aee 686 ushort parm;
gertk 0:b612024f5aee 687 int offset = 0;
gertk 0:b612024f5aee 688 int PC = ctx->PC;
gertk 0:b612024f5aee 689 int size = 0;
gertk 0:b612024f5aee 690
gertk 0:b612024f5aee 691 if (dump)
gertk 0:b612024f5aee 692 dump[0] = 0;
gertk 0:b612024f5aee 693
gertk 0:b612024f5aee 694 if (decode)
gertk 0:b612024f5aee 695 decode[0] = 0;
gertk 0:b612024f5aee 696
gertk 0:b612024f5aee 697 do
gertk 0:b612024f5aee 698 {
gertk 0:b612024f5aee 699 opcode = read8(ctx, PC + offset);
gertk 0:b612024f5aee 700 size++;
gertk 0:b612024f5aee 701
gertk 0:b612024f5aee 702 PC++;
gertk 0:b612024f5aee 703 ctx->R++;
gertk 0:b612024f5aee 704 fmt = entries[opcode].format;
gertk 0:b612024f5aee 705 if (fmt != NULL)
gertk 0:b612024f5aee 706 {
gertk 0:b612024f5aee 707 PC -= offset;
gertk 0:b612024f5aee 708 parm = read16(ctx, PC);
gertk 0:b612024f5aee 709
gertk 0:b612024f5aee 710 if (entries[opcode].operand_type == OP_NONE)
gertk 0:b612024f5aee 711 size++;
gertk 0:b612024f5aee 712 else
gertk 0:b612024f5aee 713 size += 2;
gertk 0:b612024f5aee 714 if (entries[opcode].operand_type != OP_WORD)
gertk 0:b612024f5aee 715 {
gertk 0:b612024f5aee 716 parm &= 0xFF;
gertk 0:b612024f5aee 717 size--;
gertk 0:b612024f5aee 718 }
gertk 0:b612024f5aee 719
gertk 0:b612024f5aee 720 if (decode)
gertk 0:b612024f5aee 721 sprintf(decode, fmt, parm);
gertk 0:b612024f5aee 722
gertk 0:b612024f5aee 723 PC += offset;
gertk 0:b612024f5aee 724 break;
gertk 0:b612024f5aee 725 }
gertk 0:b612024f5aee 726 else if (entries[opcode].table != NULL)
gertk 0:b612024f5aee 727 {
gertk 0:b612024f5aee 728 current = entries[opcode].table;
gertk 0:b612024f5aee 729 entries = current->entries;
gertk 0:b612024f5aee 730 offset = current->opcode_offset;
gertk 0:b612024f5aee 731 }
gertk 0:b612024f5aee 732
gertk 0:b612024f5aee 733 else
gertk 0:b612024f5aee 734 {
gertk 0:b612024f5aee 735 if (decode != NULL)
gertk 0:b612024f5aee 736 strcpy(decode, "NOP (ignored)");
gertk 0:b612024f5aee 737 break;
gertk 0:b612024f5aee 738 }
gertk 0:b612024f5aee 739 } while(1);
gertk 0:b612024f5aee 740
gertk 0:b612024f5aee 741 if (dump)
gertk 0:b612024f5aee 742 {
gertk 0:b612024f5aee 743 for (offset = 0; offset < size; offset++)
gertk 0:b612024f5aee 744 {
gertk 0:b612024f5aee 745 sprintf(tmp, "%02X", read8(ctx, ctx->PC + offset));
gertk 0:b612024f5aee 746 strcat(dump, tmp);
gertk 0:b612024f5aee 747 }
gertk 0:b612024f5aee 748 }
gertk 0:b612024f5aee 749 }
gertk 0:b612024f5aee 750
gertk 0:b612024f5aee 751
gertk 0:b612024f5aee 752 void Z80RESET (Z80Context* ctx)
gertk 0:b612024f5aee 753 {
gertk 0:b612024f5aee 754 ctx->PC = 0x0000;
gertk 0:b612024f5aee 755 BR.F = 0;
gertk 0:b612024f5aee 756 ctx->IM = 0;
gertk 0:b612024f5aee 757 ctx->IFF1 = ctx->IFF2 = 0;
gertk 0:b612024f5aee 758 }
gertk 0:b612024f5aee 759
gertk 0:b612024f5aee 760
gertk 0:b612024f5aee 761 void Z80INT (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 762 {
gertk 0:b612024f5aee 763 if (!ctx->IFF1)
gertk 0:b612024f5aee 764 return;
gertk 0:b612024f5aee 765
gertk 0:b612024f5aee 766 if (ctx->IM == 0)
gertk 0:b612024f5aee 767 {
gertk 0:b612024f5aee 768 /* FIXME What to do? */
gertk 0:b612024f5aee 769 /* opcode = Val;
gertk 0:b612024f5aee 770 execute();*/
gertk 0:b612024f5aee 771 }
gertk 0:b612024f5aee 772 else if (ctx->IM == 1)
gertk 0:b612024f5aee 773 {
gertk 0:b612024f5aee 774 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 775 ctx->PC = 0x0038;
gertk 0:b612024f5aee 776 }
gertk 0:b612024f5aee 777 else if (ctx->IM == 2)
gertk 0:b612024f5aee 778 {
gertk 0:b612024f5aee 779 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 780 ctx->PC = (ctx->I << 8) | value;
gertk 0:b612024f5aee 781 }
gertk 0:b612024f5aee 782 }
gertk 0:b612024f5aee 783
gertk 0:b612024f5aee 784
gertk 0:b612024f5aee 785 void Z80NMI (Z80Context* ctx)
gertk 0:b612024f5aee 786 {
gertk 0:b612024f5aee 787 ctx->IFF1 = 0;
gertk 0:b612024f5aee 788 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 789 ctx->PC = 0x0066;
gertk 0:b612024f5aee 790 }