libz80 with compilation problems (uses up to much ram)

Committer:
gertk
Date:
Thu Mar 10 20:32:59 2011 +0000
Revision:
0:b612024f5aee
Child:
1:78a39c3a30f6
not yet functional !

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 0:b612024f5aee 8 *
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 0:b612024f5aee 174 static void setFlag(Z80Context* ctx, Z80Flags flag)
gertk 0:b612024f5aee 175 {
gertk 0:b612024f5aee 176 BR.F |= flag;
gertk 0:b612024f5aee 177 }
gertk 0:b612024f5aee 178
gertk 0:b612024f5aee 179 /** Resets a flag */
gertk 0:b612024f5aee 180 static void resFlag(Z80Context* ctx, Z80Flags flag)
gertk 0:b612024f5aee 181 {
gertk 0:b612024f5aee 182 BR.F &= ~flag;
gertk 0:b612024f5aee 183 }
gertk 0:b612024f5aee 184
gertk 0:b612024f5aee 185 /** Puts a value in a flag */
gertk 0:b612024f5aee 186 static void valFlag(Z80Context* ctx, Z80Flags flag, int val)
gertk 0:b612024f5aee 187 {
gertk 0:b612024f5aee 188 if (val)
gertk 0:b612024f5aee 189 SETFLAG(flag);
gertk 0:b612024f5aee 190 else
gertk 0:b612024f5aee 191 RESFLAG(flag);
gertk 0:b612024f5aee 192 }
gertk 0:b612024f5aee 193
gertk 0:b612024f5aee 194 /** Returns a flag */
gertk 0:b612024f5aee 195 static int getFlag(Z80Context* ctx, Z80Flags flag)
gertk 0:b612024f5aee 196 {
gertk 0:b612024f5aee 197 return (BR.F & flag) != 0;
gertk 0:b612024f5aee 198 }
gertk 0:b612024f5aee 199
gertk 0:b612024f5aee 200
gertk 0:b612024f5aee 201 /* ---------------------------------------------------------
gertk 0:b612024f5aee 202 * Flag adjustments
gertk 0:b612024f5aee 203 * ---------------------------------------------------------
gertk 0:b612024f5aee 204 */
gertk 0:b612024f5aee 205
gertk 0:b612024f5aee 206 static int parityBit[256] = {
gertk 0:b612024f5aee 207 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 208 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 209 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 210 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 211 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 212 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 213 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 214 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
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 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0,
gertk 0:b612024f5aee 220 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 221 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1,
gertk 0:b612024f5aee 222 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
gertk 0:b612024f5aee 223
gertk 0:b612024f5aee 224
gertk 0:b612024f5aee 225 static void adjustFlags (Z80Context* ctx, byte val)
gertk 0:b612024f5aee 226 {
gertk 0:b612024f5aee 227 VALFLAG(F_5, (val & F_5) != 0);
gertk 0:b612024f5aee 228 VALFLAG(F_3, (val & F_3) != 0);
gertk 0:b612024f5aee 229 }
gertk 0:b612024f5aee 230
gertk 0:b612024f5aee 231
gertk 0:b612024f5aee 232 static void adjustFlagSZP (Z80Context* ctx, byte val)
gertk 0:b612024f5aee 233 {
gertk 0:b612024f5aee 234 VALFLAG(F_S, (val & 0x80) != 0);
gertk 0:b612024f5aee 235 VALFLAG(F_Z, (val == 0));
gertk 0:b612024f5aee 236 VALFLAG(F_PV, parityBit[val]);
gertk 0:b612024f5aee 237 }
gertk 0:b612024f5aee 238
gertk 0:b612024f5aee 239
gertk 0:b612024f5aee 240 // Adjust flags after AND, OR, XOR
gertk 0:b612024f5aee 241 static void adjustLogicFlag (Z80Context* ctx, int flagH)
gertk 0:b612024f5aee 242 {
gertk 0:b612024f5aee 243 VALFLAG(F_S, (BR.A & 0x80) != 0);
gertk 0:b612024f5aee 244 VALFLAG(F_Z, (BR.A == 0));
gertk 0:b612024f5aee 245 VALFLAG(F_H, flagH);
gertk 0:b612024f5aee 246 VALFLAG(F_N, 0);
gertk 0:b612024f5aee 247 VALFLAG(F_C, 0);
gertk 0:b612024f5aee 248 VALFLAG(F_PV, parityBit[BR.A]);
gertk 0:b612024f5aee 249
gertk 0:b612024f5aee 250 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 251 }
gertk 0:b612024f5aee 252
gertk 0:b612024f5aee 253
gertk 0:b612024f5aee 254 /* ---------------------------------------------------------
gertk 0:b612024f5aee 255 * Condition checks
gertk 0:b612024f5aee 256 * ---------------------------------------------------------
gertk 0:b612024f5aee 257 */
gertk 0:b612024f5aee 258
gertk 0:b612024f5aee 259 typedef enum
gertk 0:b612024f5aee 260 {
gertk 0:b612024f5aee 261 C_,
gertk 0:b612024f5aee 262 C_Z,
gertk 0:b612024f5aee 263 C_NZ,
gertk 0:b612024f5aee 264 C_C,
gertk 0:b612024f5aee 265 C_NC,
gertk 0:b612024f5aee 266 C_M,
gertk 0:b612024f5aee 267 C_P,
gertk 0:b612024f5aee 268 C_PE,
gertk 0:b612024f5aee 269 C_PO
gertk 0:b612024f5aee 270 } Z80Condition;
gertk 0:b612024f5aee 271
gertk 0:b612024f5aee 272 static int condition(Z80Context* ctx, Z80Condition cond)
gertk 0:b612024f5aee 273 {
gertk 0:b612024f5aee 274 if (cond == C_)
gertk 0:b612024f5aee 275 return GETFLAG(F_);
gertk 0:b612024f5aee 276
gertk 0:b612024f5aee 277 if (cond == C_Z)
gertk 0:b612024f5aee 278 return !GETFLAG(F_Z);
gertk 0:b612024f5aee 279
gertk 0:b612024f5aee 280 if (cond == C_NZ)
gertk 0:b612024f5aee 281 return GETFLAG(F_Z);
gertk 0:b612024f5aee 282
gertk 0:b612024f5aee 283 if (cond == C_C)
gertk 0:b612024f5aee 284 return GETFLAG(F_C);
gertk 0:b612024f5aee 285
gertk 0:b612024f5aee 286 if (cond == C_NC)
gertk 0:b612024f5aee 287 return !GETFLAG(F_C);
gertk 0:b612024f5aee 288
gertk 0:b612024f5aee 289 if (cond == C_M)
gertk 0:b612024f5aee 290 return GETFLAG(F_S);
gertk 0:b612024f5aee 291
gertk 0:b612024f5aee 292 if (cond == C_P)
gertk 0:b612024f5aee 293 return !(GETFLAG(F_S) | GETFLAG(F_Z));
gertk 0:b612024f5aee 294 if (cond == C_PE)
gertk 0:b612024f5aee 295 return !GETFLAG(F_PV);
gertk 0:b612024f5aee 296
gertk 0:b612024f5aee 297 /* if (cond == C_PO)*/
gertk 0:b612024f5aee 298 return GETFLAG(F_PV);
gertk 0:b612024f5aee 299 }
gertk 0:b612024f5aee 300
gertk 0:b612024f5aee 301
gertk 0:b612024f5aee 302 /* ---------------------------------------------------------
gertk 0:b612024f5aee 303 * Generic operations
gertk 0:b612024f5aee 304 * ---------------------------------------------------------
gertk 0:b612024f5aee 305 */
gertk 0:b612024f5aee 306
gertk 0:b612024f5aee 307
gertk 0:b612024f5aee 308 static int doComplement(byte v)
gertk 0:b612024f5aee 309 {
gertk 0:b612024f5aee 310 if ((v & 0x80) == 0)
gertk 0:b612024f5aee 311 return v;
gertk 0:b612024f5aee 312
gertk 0:b612024f5aee 313 v = ~v;
gertk 0:b612024f5aee 314 v &= 0x7F;
gertk 0:b612024f5aee 315 v++;
gertk 0:b612024f5aee 316
gertk 0:b612024f5aee 317 return -v;
gertk 0:b612024f5aee 318 }
gertk 0:b612024f5aee 319
gertk 0:b612024f5aee 320
gertk 0:b612024f5aee 321 /** Do an arithmetic operation (ADD, SUB, ADC, SBC y CP) */
gertk 0:b612024f5aee 322 static byte doArithmetic (Z80Context* ctx, byte value, int withCarry, int isSub)
gertk 0:b612024f5aee 323 {
gertk 0:b612024f5aee 324 ushort res; /* To detect carry */
gertk 0:b612024f5aee 325
gertk 0:b612024f5aee 326 if (isSub)
gertk 0:b612024f5aee 327 {
gertk 0:b612024f5aee 328 SETFLAG(F_N);
gertk 0:b612024f5aee 329 VALFLAG(F_H, (((BR.A & 0x0F) - (value & 0x0F)) & 0x10) != 0);
gertk 0:b612024f5aee 330 res = BR.A - value;
gertk 0:b612024f5aee 331 if (withCarry && GETFLAG(F_C))
gertk 0:b612024f5aee 332 res--;
gertk 0:b612024f5aee 333 }
gertk 0:b612024f5aee 334 else
gertk 0:b612024f5aee 335 {
gertk 0:b612024f5aee 336 RESFLAG(F_N);
gertk 0:b612024f5aee 337 VALFLAG(F_H, (((BR.A & 0x0F) + (value & 0x0F)) & 0x10) != 0);
gertk 0:b612024f5aee 338 res = BR.A + value;
gertk 0:b612024f5aee 339 if (withCarry && GETFLAG(F_C))
gertk 0:b612024f5aee 340 res++;
gertk 0:b612024f5aee 341 }
gertk 0:b612024f5aee 342 VALFLAG(F_S, ((res & 0x80) != 0));
gertk 0:b612024f5aee 343 VALFLAG(F_C, ((res & 0x100) != 0));
gertk 0:b612024f5aee 344 VALFLAG(F_Z, (res == 0));
gertk 0:b612024f5aee 345 VALFLAG(F_PV, (((BR.A & 0x80) == (value & 0x80)) && ((BR.A & 0x80) != (res & 0x80))) != 0);
gertk 0:b612024f5aee 346
gertk 0:b612024f5aee 347 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 348
gertk 0:b612024f5aee 349 return (byte)(res & 0xFF);
gertk 0:b612024f5aee 350 }
gertk 0:b612024f5aee 351
gertk 0:b612024f5aee 352
gertk 0:b612024f5aee 353 static void doAND (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 354 {
gertk 0:b612024f5aee 355 BR.A &= value;
gertk 0:b612024f5aee 356 adjustLogicFlag(ctx, 1);
gertk 0:b612024f5aee 357 }
gertk 0:b612024f5aee 358
gertk 0:b612024f5aee 359
gertk 0:b612024f5aee 360 static void doOR (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 361 {
gertk 0:b612024f5aee 362 BR.A |= value;
gertk 0:b612024f5aee 363 adjustLogicFlag(ctx, 0);
gertk 0:b612024f5aee 364 }
gertk 0:b612024f5aee 365
gertk 0:b612024f5aee 366
gertk 0:b612024f5aee 367 static void doXOR (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 368 {
gertk 0:b612024f5aee 369 BR.A ^= value;
gertk 0:b612024f5aee 370 adjustLogicFlag(ctx, 0);
gertk 0:b612024f5aee 371 }
gertk 0:b612024f5aee 372
gertk 0:b612024f5aee 373
gertk 0:b612024f5aee 374 static void doBIT (Z80Context* ctx, int b, byte val)
gertk 0:b612024f5aee 375 {
gertk 0:b612024f5aee 376 if (val & (1 << b))
gertk 0:b612024f5aee 377 RESFLAG(F_Z | F_PV);
gertk 0:b612024f5aee 378 else
gertk 0:b612024f5aee 379 SETFLAG(F_Z | F_PV);
gertk 0:b612024f5aee 380
gertk 0:b612024f5aee 381 SETFLAG(F_H);
gertk 0:b612024f5aee 382 RESFLAG(F_N);
gertk 0:b612024f5aee 383
gertk 0:b612024f5aee 384 RESFLAG(F_S);
gertk 0:b612024f5aee 385 if ((b == 7) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 386 SETFLAG(F_S);
gertk 0:b612024f5aee 387
gertk 0:b612024f5aee 388 RESFLAG(F_5);
gertk 0:b612024f5aee 389 if ((b == 5) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 390 SETFLAG(F_5);
gertk 0:b612024f5aee 391
gertk 0:b612024f5aee 392 RESFLAG(F_3);
gertk 0:b612024f5aee 393 if ((b == 3) && !GETFLAG(F_Z))
gertk 0:b612024f5aee 394 SETFLAG(F_3);
gertk 0:b612024f5aee 395 }
gertk 0:b612024f5aee 396
gertk 0:b612024f5aee 397
gertk 0:b612024f5aee 398 byte doSetRes (Z80Context* ctx, int bit, int pos, byte val)
gertk 0:b612024f5aee 399 {
gertk 0:b612024f5aee 400 if (bit)
gertk 0:b612024f5aee 401 val |= (1 << pos);
gertk 0:b612024f5aee 402 else
gertk 0:b612024f5aee 403 val &= ~(1 << pos);
gertk 0:b612024f5aee 404 return val;
gertk 0:b612024f5aee 405 }
gertk 0:b612024f5aee 406
gertk 0:b612024f5aee 407
gertk 0:b612024f5aee 408
gertk 0:b612024f5aee 409 static byte doIncDec (Z80Context* ctx, byte val, int isDec)
gertk 0:b612024f5aee 410 {
gertk 0:b612024f5aee 411 if (isDec)
gertk 0:b612024f5aee 412 {
gertk 0:b612024f5aee 413 VALFLAG(F_PV, (val & 0x80) && !((val - 1) & 0x80));
gertk 0:b612024f5aee 414 val--;
gertk 0:b612024f5aee 415 VALFLAG(F_H, !(val & 0x0F));
gertk 0:b612024f5aee 416 }
gertk 0:b612024f5aee 417 else
gertk 0:b612024f5aee 418 {
gertk 0:b612024f5aee 419 VALFLAG(F_PV, !(val & 0x80) && ((val + 1) & 0x80));
gertk 0:b612024f5aee 420 val++;
gertk 0:b612024f5aee 421 VALFLAG(F_H, !(val & 0x0F));
gertk 0:b612024f5aee 422 }
gertk 0:b612024f5aee 423
gertk 0:b612024f5aee 424 VALFLAG(F_S, ((val & 0x80) != 0));
gertk 0:b612024f5aee 425 VALFLAG(F_Z, (val == 0));
gertk 0:b612024f5aee 426 VALFLAG(F_N, isDec);
gertk 0:b612024f5aee 427
gertk 0:b612024f5aee 428 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 429
gertk 0:b612024f5aee 430 return val;
gertk 0:b612024f5aee 431 }
gertk 0:b612024f5aee 432
gertk 0:b612024f5aee 433
gertk 0:b612024f5aee 434 static byte doRLC (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 435 {
gertk 0:b612024f5aee 436 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 437 val <<= 1;
gertk 0:b612024f5aee 438 val |= (byte)GETFLAG(F_C);
gertk 0:b612024f5aee 439
gertk 0:b612024f5aee 440 adjustFlags(ctx, val);
gertk 0:b612024f5aee 441 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 442
gertk 0:b612024f5aee 443 if (adjFlags)
gertk 0:b612024f5aee 444 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 445
gertk 0:b612024f5aee 446 return val;
gertk 0:b612024f5aee 447 }
gertk 0:b612024f5aee 448
gertk 0:b612024f5aee 449
gertk 0:b612024f5aee 450 static byte doRL (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 451 {
gertk 0:b612024f5aee 452 int CY = GETFLAG(F_C);
gertk 0:b612024f5aee 453 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 454 val <<= 1;
gertk 0:b612024f5aee 455 val |= (byte)CY;
gertk 0:b612024f5aee 456
gertk 0:b612024f5aee 457 adjustFlags(ctx, val);
gertk 0:b612024f5aee 458 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 459
gertk 0:b612024f5aee 460 if (adjFlags)
gertk 0:b612024f5aee 461 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 462
gertk 0:b612024f5aee 463 return val;
gertk 0:b612024f5aee 464 }
gertk 0:b612024f5aee 465
gertk 0:b612024f5aee 466
gertk 0:b612024f5aee 467 static byte doRRC (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 468 {
gertk 0:b612024f5aee 469 VALFLAG(F_C, (val & 0x01) != 0);
gertk 0:b612024f5aee 470 val >>= 1;
gertk 0:b612024f5aee 471 val |= ((byte)GETFLAG(F_C) << 7);
gertk 0:b612024f5aee 472
gertk 0:b612024f5aee 473 adjustFlags(ctx, val);
gertk 0:b612024f5aee 474 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 475
gertk 0:b612024f5aee 476 if (adjFlags)
gertk 0:b612024f5aee 477 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 478
gertk 0:b612024f5aee 479 return val;
gertk 0:b612024f5aee 480 }
gertk 0:b612024f5aee 481
gertk 0:b612024f5aee 482
gertk 0:b612024f5aee 483 static byte doRR (Z80Context* ctx, int adjFlags, byte val)
gertk 0:b612024f5aee 484 {
gertk 0:b612024f5aee 485 int CY = GETFLAG(F_C);
gertk 0:b612024f5aee 486 VALFLAG(F_C, (val & 0x01));
gertk 0:b612024f5aee 487 val >>= 1;
gertk 0:b612024f5aee 488 val |= (CY << 7);
gertk 0:b612024f5aee 489
gertk 0:b612024f5aee 490 adjustFlags(ctx, val);
gertk 0:b612024f5aee 491 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 492
gertk 0:b612024f5aee 493 if (adjFlags)
gertk 0:b612024f5aee 494 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 495
gertk 0:b612024f5aee 496 return val;
gertk 0:b612024f5aee 497 }
gertk 0:b612024f5aee 498
gertk 0:b612024f5aee 499
gertk 0:b612024f5aee 500 static byte doSL (Z80Context* ctx, byte val, int isArith)
gertk 0:b612024f5aee 501 {
gertk 0:b612024f5aee 502 VALFLAG(F_C, (val & 0x80) != 0);
gertk 0:b612024f5aee 503 val <<= 1;
gertk 0:b612024f5aee 504
gertk 0:b612024f5aee 505 if (!isArith)
gertk 0:b612024f5aee 506 val |= 1;
gertk 0:b612024f5aee 507
gertk 0:b612024f5aee 508 adjustFlags(ctx, val);
gertk 0:b612024f5aee 509 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 510 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 511
gertk 0:b612024f5aee 512 return val;
gertk 0:b612024f5aee 513 }
gertk 0:b612024f5aee 514
gertk 0:b612024f5aee 515
gertk 0:b612024f5aee 516 static byte doSR (Z80Context* ctx, byte val, int isArith)
gertk 0:b612024f5aee 517 {
gertk 0:b612024f5aee 518 int b = ((val & 0x80) != 0);
gertk 0:b612024f5aee 519
gertk 0:b612024f5aee 520 VALFLAG(F_C, (val & 0x01) != 0);
gertk 0:b612024f5aee 521 val >>= 1;
gertk 0:b612024f5aee 522
gertk 0:b612024f5aee 523 if (isArith)
gertk 0:b612024f5aee 524 val |= (byte)b;
gertk 0:b612024f5aee 525
gertk 0:b612024f5aee 526 adjustFlags(ctx, val);
gertk 0:b612024f5aee 527 RESFLAG(F_H | F_N);
gertk 0:b612024f5aee 528 adjustFlagSZP(ctx, val);
gertk 0:b612024f5aee 529
gertk 0:b612024f5aee 530 return val;
gertk 0:b612024f5aee 531 }
gertk 0:b612024f5aee 532
gertk 0:b612024f5aee 533
gertk 0:b612024f5aee 534 static void doPush (Z80Context* ctx, ushort val)
gertk 0:b612024f5aee 535 {
gertk 0:b612024f5aee 536 WR.SP--;
gertk 0:b612024f5aee 537 write16(ctx, WR.SP, val);
gertk 0:b612024f5aee 538 WR.SP--;
gertk 0:b612024f5aee 539 }
gertk 0:b612024f5aee 540
gertk 0:b612024f5aee 541
gertk 0:b612024f5aee 542 static ushort doPop (Z80Context* ctx)
gertk 0:b612024f5aee 543 {
gertk 0:b612024f5aee 544 ushort val;
gertk 0:b612024f5aee 545
gertk 0:b612024f5aee 546 WR.SP++;
gertk 0:b612024f5aee 547 val = read16(ctx, WR.SP);
gertk 0:b612024f5aee 548 WR.SP++;
gertk 0:b612024f5aee 549
gertk 0:b612024f5aee 550 return val;
gertk 0:b612024f5aee 551 }
gertk 0:b612024f5aee 552
gertk 0:b612024f5aee 553
gertk 0:b612024f5aee 554 /* The DAA opcode
gertk 0:b612024f5aee 555 * According to the value in A and the flags set, add a value to A
gertk 0:b612024f5aee 556 *
gertk 0:b612024f5aee 557 * Flags set Byte (0..9)(0..9)
gertk 0:b612024f5aee 558 * --------------------------------------------
gertk 0:b612024f5aee 559 * (None) + &00
gertk 0:b612024f5aee 560 * Carry:+ &60
gertk 0:b612024f5aee 561 * Subtract:+ &00
gertk 0:b612024f5aee 562 * Subtract+Carry:+ &A0
gertk 0:b612024f5aee 563 * Half-carry:+ &06
gertk 0:b612024f5aee 564 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 565 * Half-carry+Subtract:+ &FA
gertk 0:b612024f5aee 566 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 567 *
gertk 0:b612024f5aee 568 * Flags set Byte (0..9)(A..F)
gertk 0:b612024f5aee 569 * --------------------------------------------
gertk 0:b612024f5aee 570 * (None) + &06
gertk 0:b612024f5aee 571 * Carry:+ &66
gertk 0:b612024f5aee 572 * Subtract:+ &00
gertk 0:b612024f5aee 573 * Subtract+Carry:+ &a0
gertk 0:b612024f5aee 574 * Half-carry:+ &06
gertk 0:b612024f5aee 575 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 576 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 577 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 578 *
gertk 0:b612024f5aee 579 * Flags set Byte (A..F)(0..9)
gertk 0:b612024f5aee 580 * --------------------------------------------
gertk 0:b612024f5aee 581 * (None) + &60
gertk 0:b612024f5aee 582 * Carry:+ &60
gertk 0:b612024f5aee 583 * Subtract:+ &00
gertk 0:b612024f5aee 584 * Subtract+Carry:+ &A0
gertk 0:b612024f5aee 585 * Half-carry:+ &66
gertk 0:b612024f5aee 586 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 587 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 588 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 589 *
gertk 0:b612024f5aee 590 * Flags set Byte (A..F)(A..F)
gertk 0:b612024f5aee 591 * --------------------------------------------
gertk 0:b612024f5aee 592 * (None) + &66
gertk 0:b612024f5aee 593 * Carry:+ &66
gertk 0:b612024f5aee 594 * Subtract:+ &00
gertk 0:b612024f5aee 595 * Subtract+Carry:+ &a0
gertk 0:b612024f5aee 596 * Half-carry:+ &66
gertk 0:b612024f5aee 597 * Half-carry+Carry:+ &66
gertk 0:b612024f5aee 598 * Half-carry+Subtract:+ &fa
gertk 0:b612024f5aee 599 * Half-carry+Subtract+Carry:+ &9A
gertk 0:b612024f5aee 600 */
gertk 0:b612024f5aee 601
gertk 0:b612024f5aee 602 static int DAA_BYTETYPE[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1 };
gertk 0:b612024f5aee 603
gertk 0:b612024f5aee 604 static byte DAA_ADJUSTMENT[4][8] = {
gertk 0:b612024f5aee 605 { 0x00, 0x60, 0x00, 0xA0, 0x06, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 606 { 0x06, 0x66, 0x00, 0xA0, 0x06, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 607 { 0x60, 0x60, 0x00, 0xA0, 0x66, 0x66, 0xFA, 0x9A },
gertk 0:b612024f5aee 608 { 0x66, 0x66, 0x00, 0xA0, 0x66, 0x66, 0xFA, 0x9A } };
gertk 0:b612024f5aee 609
gertk 0:b612024f5aee 610 static void doDAA (Z80Context* ctx)
gertk 0:b612024f5aee 611 {
gertk 0:b612024f5aee 612 /* (0..9)(0..9) = 0 */
gertk 0:b612024f5aee 613 /* (0..9)(A..F) = 1 */
gertk 0:b612024f5aee 614 /* (A..F)(0..9) = 2 */
gertk 0:b612024f5aee 615 /* (A..F)(A..F) = 3 */
gertk 0:b612024f5aee 616 int byteType = DAA_BYTETYPE[BR.A] | ((DAA_BYTETYPE[BR.A >> 4]) << 1);
gertk 0:b612024f5aee 617
gertk 0:b612024f5aee 618 int flagMask = 0;
gertk 0:b612024f5aee 619 if (GETFLAG(F_C))
gertk 0:b612024f5aee 620 flagMask |= 1;
gertk 0:b612024f5aee 621 if (GETFLAG(F_S))
gertk 0:b612024f5aee 622 flagMask |= 2;
gertk 0:b612024f5aee 623 if (GETFLAG(F_H))
gertk 0:b612024f5aee 624 flagMask |= 4;
gertk 0:b612024f5aee 625
gertk 0:b612024f5aee 626 BR.A += DAA_ADJUSTMENT[byteType][flagMask];
gertk 0:b612024f5aee 627
gertk 0:b612024f5aee 628 adjustFlags(ctx, BR.A);
gertk 0:b612024f5aee 629 }
gertk 0:b612024f5aee 630
gertk 0:b612024f5aee 631 #include "opcodes_impl.c"
gertk 0:b612024f5aee 632
gertk 0:b612024f5aee 633
gertk 0:b612024f5aee 634 /* ---------------------------------------------------------
gertk 0:b612024f5aee 635 * The top-level functions
gertk 0:b612024f5aee 636 * ---------------------------------------------------------
gertk 0:b612024f5aee 637 */
gertk 0:b612024f5aee 638 void Z80Execute (Z80Context* ctx)
gertk 0:b612024f5aee 639 {
gertk 0:b612024f5aee 640 struct Z80OpcodeTable* current = &opcodes_main;
gertk 0:b612024f5aee 641 struct Z80OpcodeEntry* entries = current->entries;
gertk 0:b612024f5aee 642 Z80OpcodeFunc func;
gertk 0:b612024f5aee 643
gertk 0:b612024f5aee 644 byte opcode;
gertk 0:b612024f5aee 645 int offset = 0;
gertk 0:b612024f5aee 646 do
gertk 0:b612024f5aee 647 {
gertk 0:b612024f5aee 648 opcode = read8(ctx, ctx->PC + offset);
gertk 0:b612024f5aee 649
gertk 0:b612024f5aee 650 ctx->PC++;
gertk 0:b612024f5aee 651 func = entries[opcode].func;
gertk 0:b612024f5aee 652 if (func != NULL)
gertk 0:b612024f5aee 653 {
gertk 0:b612024f5aee 654 ctx->PC -= offset;
gertk 0:b612024f5aee 655 func(ctx);
gertk 0:b612024f5aee 656 ctx->PC += offset;
gertk 0:b612024f5aee 657 break;
gertk 0:b612024f5aee 658 }
gertk 0:b612024f5aee 659 else if (entries[opcode].table != NULL)
gertk 0:b612024f5aee 660 {
gertk 0:b612024f5aee 661 current = entries[opcode].table;
gertk 0:b612024f5aee 662 entries = current->entries;
gertk 0:b612024f5aee 663 offset = current->opcode_offset;
gertk 0:b612024f5aee 664 }
gertk 0:b612024f5aee 665
gertk 0:b612024f5aee 666 else
gertk 0:b612024f5aee 667 {
gertk 0:b612024f5aee 668 /* NOP */
gertk 0:b612024f5aee 669 break;
gertk 0:b612024f5aee 670 }
gertk 0:b612024f5aee 671 } while(1);
gertk 0:b612024f5aee 672 }
gertk 0:b612024f5aee 673
gertk 0:b612024f5aee 674
gertk 0:b612024f5aee 675 void Z80Debug (Z80Context* ctx, char* dump, char* decode)
gertk 0:b612024f5aee 676 {
gertk 0:b612024f5aee 677 char tmp[20];
gertk 0:b612024f5aee 678 struct Z80OpcodeTable* current = &opcodes_main;
gertk 0:b612024f5aee 679 struct Z80OpcodeEntry* entries = current->entries;
gertk 0:b612024f5aee 680 char* fmt;
gertk 0:b612024f5aee 681 byte opcode;
gertk 0:b612024f5aee 682 ushort parm;
gertk 0:b612024f5aee 683 int offset = 0;
gertk 0:b612024f5aee 684 int PC = ctx->PC;
gertk 0:b612024f5aee 685 int size = 0;
gertk 0:b612024f5aee 686
gertk 0:b612024f5aee 687 if (dump)
gertk 0:b612024f5aee 688 dump[0] = 0;
gertk 0:b612024f5aee 689
gertk 0:b612024f5aee 690 if (decode)
gertk 0:b612024f5aee 691 decode[0] = 0;
gertk 0:b612024f5aee 692
gertk 0:b612024f5aee 693 do
gertk 0:b612024f5aee 694 {
gertk 0:b612024f5aee 695 opcode = read8(ctx, PC + offset);
gertk 0:b612024f5aee 696 size++;
gertk 0:b612024f5aee 697
gertk 0:b612024f5aee 698 PC++;
gertk 0:b612024f5aee 699 ctx->R++;
gertk 0:b612024f5aee 700 fmt = entries[opcode].format;
gertk 0:b612024f5aee 701 if (fmt != NULL)
gertk 0:b612024f5aee 702 {
gertk 0:b612024f5aee 703 PC -= offset;
gertk 0:b612024f5aee 704 parm = read16(ctx, PC);
gertk 0:b612024f5aee 705
gertk 0:b612024f5aee 706 if (entries[opcode].operand_type == OP_NONE)
gertk 0:b612024f5aee 707 size++;
gertk 0:b612024f5aee 708 else
gertk 0:b612024f5aee 709 size += 2;
gertk 0:b612024f5aee 710 if (entries[opcode].operand_type != OP_WORD)
gertk 0:b612024f5aee 711 {
gertk 0:b612024f5aee 712 parm &= 0xFF;
gertk 0:b612024f5aee 713 size--;
gertk 0:b612024f5aee 714 }
gertk 0:b612024f5aee 715
gertk 0:b612024f5aee 716 if (decode)
gertk 0:b612024f5aee 717 sprintf(decode, fmt, parm);
gertk 0:b612024f5aee 718
gertk 0:b612024f5aee 719 PC += offset;
gertk 0:b612024f5aee 720 break;
gertk 0:b612024f5aee 721 }
gertk 0:b612024f5aee 722 else if (entries[opcode].table != NULL)
gertk 0:b612024f5aee 723 {
gertk 0:b612024f5aee 724 current = entries[opcode].table;
gertk 0:b612024f5aee 725 entries = current->entries;
gertk 0:b612024f5aee 726 offset = current->opcode_offset;
gertk 0:b612024f5aee 727 }
gertk 0:b612024f5aee 728
gertk 0:b612024f5aee 729 else
gertk 0:b612024f5aee 730 {
gertk 0:b612024f5aee 731 if (decode != NULL)
gertk 0:b612024f5aee 732 strcpy(decode, "NOP (ignored)");
gertk 0:b612024f5aee 733 break;
gertk 0:b612024f5aee 734 }
gertk 0:b612024f5aee 735 } while(1);
gertk 0:b612024f5aee 736
gertk 0:b612024f5aee 737 if (dump)
gertk 0:b612024f5aee 738 {
gertk 0:b612024f5aee 739 for (offset = 0; offset < size; offset++)
gertk 0:b612024f5aee 740 {
gertk 0:b612024f5aee 741 sprintf(tmp, "%02X", read8(ctx, ctx->PC + offset));
gertk 0:b612024f5aee 742 strcat(dump, tmp);
gertk 0:b612024f5aee 743 }
gertk 0:b612024f5aee 744 }
gertk 0:b612024f5aee 745 }
gertk 0:b612024f5aee 746
gertk 0:b612024f5aee 747
gertk 0:b612024f5aee 748 void Z80RESET (Z80Context* ctx)
gertk 0:b612024f5aee 749 {
gertk 0:b612024f5aee 750 ctx->PC = 0x0000;
gertk 0:b612024f5aee 751 BR.F = 0;
gertk 0:b612024f5aee 752 ctx->IM = 0;
gertk 0:b612024f5aee 753 ctx->IFF1 = ctx->IFF2 = 0;
gertk 0:b612024f5aee 754 }
gertk 0:b612024f5aee 755
gertk 0:b612024f5aee 756
gertk 0:b612024f5aee 757 void Z80INT (Z80Context* ctx, byte value)
gertk 0:b612024f5aee 758 {
gertk 0:b612024f5aee 759 if (!ctx->IFF1)
gertk 0:b612024f5aee 760 return;
gertk 0:b612024f5aee 761
gertk 0:b612024f5aee 762 if (ctx->IM == 0)
gertk 0:b612024f5aee 763 {
gertk 0:b612024f5aee 764 /* FIXME What to do? */
gertk 0:b612024f5aee 765 /* opcode = Val;
gertk 0:b612024f5aee 766 execute();*/
gertk 0:b612024f5aee 767 }
gertk 0:b612024f5aee 768 else if (ctx->IM == 1)
gertk 0:b612024f5aee 769 {
gertk 0:b612024f5aee 770 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 771 ctx->PC = 0x0038;
gertk 0:b612024f5aee 772 }
gertk 0:b612024f5aee 773 else if (ctx->IM == 2)
gertk 0:b612024f5aee 774 {
gertk 0:b612024f5aee 775 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 776 ctx->PC = (ctx->I << 8) | value;
gertk 0:b612024f5aee 777 }
gertk 0:b612024f5aee 778 }
gertk 0:b612024f5aee 779
gertk 0:b612024f5aee 780
gertk 0:b612024f5aee 781 void Z80NMI (Z80Context* ctx)
gertk 0:b612024f5aee 782 {
gertk 0:b612024f5aee 783 ctx->IFF1 = 0;
gertk 0:b612024f5aee 784 doPush(ctx, ctx->PC);
gertk 0:b612024f5aee 785 ctx->PC = 0x0066;
gertk 0:b612024f5aee 786 }