56 #define END }while(0);break;
57 #define OPCODE(n) END case n: BEGIN
63 #define FLAG_CARRY 0x80
64 #define FLAG_ZERO 0x40
65 #define FLAG_SIGN 0x20
69 #define F_CARRY_BOOL (!!(z8k1.flags & FLAG_CARRY))
70 #define F_ZERO_BOOL (!!(z8k1.flags & FLAG_ZERO))
71 #define F_SIGN_BOOL (!!(z8k1.flags & FLAG_SIGN))
72 #define F_PV_BOOL (!!(z8k1.flags & FLAG_PV))
73 #define F_DA_BOOL (!!(z8k1.flags & FLAG_DA))
74 #define F_HC_BOOL (!!(z8k1.flags & FLAG_HC))
88 #define FCW_ALL_MASK (FCW_SEG|FCW_SYS|FCW_EPA|FCW_VIE|FCW_NVIE)
92 #define IS_SEGMENTED_MODE (z8k1.fcw & FCW_SEG)
93 #define IS_SYSTEM_MODE (z8k1.fcw & FCW_SYS)
94 #define IS_USER_MODE (!(IS_SYSTEM_MODE))
96 static int do_disasm = 1;
100 #define DISASM(fmt,...) do { if (XEMU_UNLIKELY(do_disasm)) DEBUGPRINT("%02X:%04X %04X " fmt NL, z8k1.codeseg, pc_orig, opc, __VA_ARGS__); } while(0)
102 #define DISASM(fmt,...)
107 #define NOT_EMULATED_OPCODE() FATAL("ERROR: Opcode not emulated: $%04X at $%02X:%04X", opc, z8k1.codeseg, pc_orig)
108 #define NOT_EMULATED_OPCODE_VARIANT() FATAL("ERROR: Opcode VARIANT not emulated: $%04X at $%02X:%04X", opc, z8k1.codeseg, pc_orig)
109 #define RESERVED_OPCODE() FATAL("ERROR: Reserved opcode: $%04X at $%02X:%04X\n", opc, z8k1.codeseg, pc_orig);
142 static const char *__reg8names__[16] = {
143 "RH0",
"RH1",
"RH2",
"RH3",
"RH4",
"RH5",
"RH6",
"RH7",
144 "RL0",
"RL1",
"RL2",
"RL3",
"RL4",
"RL5",
"RL6",
"RL7"
146 #define reg8names(n) __reg8names__[(n) & 0xF]
147 static const char *__reg16names__[16] = {
148 "R0",
"R1",
"R2",
"R3",
"R4",
"R5",
"R6",
"R7",
149 "R8",
"R9",
"R10",
"R11",
"R12",
"R13",
"R14",
"R15"
151 #define reg16names(n) __reg16names__[(n) & 0xF]
152 static const char *__reg32names__[16] = {
153 "RR0",
"RR0?",
"RR2",
"RR2?",
"RR4",
"RR4?",
"RR6",
"RR6?",
154 "RR8",
"RR8?",
"RR10",
"RR10?",
"RR12",
"RR12?",
"RR14",
"RR14?"
156 #define reg32names(n) __reg32names__[(n) & 0xF]
157 static const char *__reg64names__[16] = {
158 "RQ0",
"RQ0?",
"RQ0??",
"RQ0???",
"RQ4",
"RQ4?",
"RQ4??",
"RQ4???",
159 "RQ8",
"RQ8?",
"RQ8??",
"RQ8???",
"RQ12",
"RQ12?",
"RQ12??",
"RQ12???"
161 #define reg64names(n) __reg64names__[(n) & 0xF]
162 static const char *__ccnames__[16] = {
163 "F",
"LT",
"LE",
"ULE",
"PE",
"MI",
"Z",
"C",
164 "T",
"GE",
"GT",
"UGT",
"PO",
"PL",
"NZ",
"NC"
166 #define ccnames(n) __ccnames__[(n) & 0xF]
171 static Uint16 READCODE (
void )
175 FATAL(
"READCODE() at odd address $%04X", z8k1.pc);
185 static int check_cc (
int cc )
221 FATAL(
"Cannot happen");
227 #define F_ZERO_BY8(v) (((v) & 0xFF) ? 0 : FLAG_ZERO)
228 #define F_SIGN_BY8(v) (((v) & 0x80) ? FLAG_SIGN : 0)
229 #define F_CARRY_BY8(v) (((v) & 0x100) ? FLAG_CARRY : 0)
230 #define F_OVERFLOW_BY8(ad1,ad2,res) (((((ad1) & 0x80) == ((ad2) & 0x80)) && (((ad1) & 0x80) != ((res) & 0x80))) ? FLAG_PV : 0)
232 #define F_ZERO_BY16(v) (((v) & 0xFFFF) ? 0 : FLAG_ZERO)
233 #define F_SIGN_BY16(v) (((v) & 0x8000) ? FLAG_SIGN : 0)
234 #define F_CARRY_BY16(v) (((v) & 0x10000) ? FLAG_CARRY : 0)
235 #define F_OVERFLOW_BY16(ad1,ad2,res) (((((ad1) & 0x8000) == ((ad2) & 0x8000)) && (((ad1) & 0x8000) != ((res) & 0x8000))) ? FLAG_PV : 0)
237 #define F_PARITY_BY8(v) yay
238 #define F_PARITY_BY16(v) yay
240 #define F_HALFCARRY_BY8(ad1,ad2,res) ((((ad1) ^ (ad2) ^ (res)) & 16) ? FLAG_HC : 0)
251 #define REG8INDEX(index) ((((index)&7)<<1)|(((index)&8)>>3))
256 #define NIB3(n) (((n) >> 12) & 0xF)
257 #define NIB2(n) (((n) >> 8) & 0xF)
258 #define NIB1(n) (((n) >> 4) & 0xF)
259 #define NIB0(n) ((n) & 0xF)
261 #define OPCNIB3 NIB3(opc)
262 #define OPCNIB2 NIB2(opc)
263 #define OPCNIB1 NIB1(opc)
264 #define OPCNIB0 NIB0(opc)
269 return (
index & 8) ? (z8k1.regs[
index & 7] & 0xFF) : (z8k1.regs[
index & 7] >> 8);
277 z8k1.regs[
index & 7] = (z8k1.regs[
index & 7] & 0x00FF) | (
data << 8);
282 return z8k1.regs[
index & 0xF];
320 #define IMMEDBYTEFROMWORD(index,n) (((n)>>(((index)&8)?0:8))&0xFF)
326 z8k1.regs[
index & 7] = (z8k1.regs[
index & 7] & 0xFF00) | (
data & 0x00FF);
328 z8k1.regs[
index & 7] = (z8k1.regs[
index & 7] & 0x00FF) | (
data & 0xFF00);
335 z8k1.RegisterFile[
index + 1] =
data & 0xFF;
345 static inline void SetReg8FromCodeRead16 (
int index )
352 static inline void SetReg16FromCodeRead (
int index )
360 static inline void SetReg32FromCodeRead (
int index )
372 static inline Uint8 IncReg8 (
int index,
int incval )
375 SetReg8(
index, temp);
380 static inline Uint16 IncReg16 (
int index,
int incval )
382 z8k1.regs[
index & 0xF] += incval;
383 return z8k1.regs[
index & 0xF];
387 static char disasm_get_address_code[5+5+1];
388 static char disasm_get_address[5+3+1+1];
392 static void get_address (
void )
396 int seg = READCODE();
397 z8k1.use_seg = (
seg >> 8) & 0x7F;
399 z8k1.use_ofs = READCODE();
401 sprintf(disasm_get_address_code,
"%04X %04X",
seg, z8k1.use_ofs);
402 sprintf(disasm_get_address,
"$%02X:$%04X", z8k1.use_seg, z8k1.use_ofs);
404 z8k1.get_address_mode = 1;
406 z8k1.use_ofs =
seg & 0xFF;
408 sprintf(disasm_get_address_code,
"%04X",
seg);
409 sprintf(disasm_get_address,
"$%02X:$%02X", z8k1.use_seg, z8k1.use_ofs);
411 z8k1.get_address_mode = 2;
416 z8k1.use_ofs = READCODE();
418 sprintf(disasm_get_address_code,
"%04X", z8k1.use_ofs);
419 sprintf(disasm_get_address,
"$%04X", z8k1.use_ofs);
421 z8k1.get_address_mode = 0;
428 static Uint16 fetch_address ()
433 cycles_extra_fetch = 3;
436 Uint16 ret = READCODE_HI() << 8;
437 return ret | READCODE_LO();
440 return READCODE_LO();
444 Uint16 ret = READCODE_HI() << 8;
445 return ret | READCODE_LO();
452 static void set_fcw_byte (
Uint8 newfcw )
460 DEBUGPRINT(
"Z8000: FCW: CPU mode change: normal -> system" NL);
462 z8k1.stackptrusr = GetReg16(15);
463 z8k1.stacksegusr = (GetReg16(14) >> 8) & 0x7F;
465 SetReg16(15, z8k1.stackptrsys);
466 SetReg16(14, z8k1.stacksegsys << 8);
468 DEBUGPRINT(
"Z8000: FCW: CPU mode change: system -> normal" NL);
470 z8k1.stackptrsys = GetReg16(15);
471 z8k1.stacksegsys = (GetReg16(14) >> 8) & 0x7F;
473 SetReg16(15, z8k1.stackptrusr);
474 SetReg16(14, z8k1.stacksegusr << 8);
480 if (newfcw != z8k1.fcw)
481 DEBUGPRINT(
"Z8000: FCW: %02X -> %02X" NL, z8k1.fcw, newfcw);
489 memset(z8k1.regs, 0,
sizeof z8k1.regs);
498 z8k1.stacksegusr = 0;
499 z8k1.stackptrusr = 0;
500 z8k1.stacksegsys = 0;
501 z8k1.stackptrsys = 0;
504 set_fcw_byte(
data >> 8);
509 z8k1.flags =
data & 0xFC;
511 z8k1.codeseg = (
data >> 8) & 0x7F;
513 printf(
"Z8000: reset -> FCW=$%02X%02X SEG=$%02X PC=$%04X\n" NL, z8k1.fcw, z8k1.flags, z8k1.codeseg, z8k1.pc);
524 int pc_orig = z8k1.pc;
993 Uint32 val = READCODE() << 16;
1221 z8k1.codeseg = z8k1.use_seg;
1222 z8k1.pc = z8k1.use_ofs;
1224 static const int jp_cycles[] = { 7, 8, 10 };
1225 cycles += jp_cycles[z8k1.get_address_mode];
1624 if (z8k1.regs[
OPCNIB1] & 0x80)
1634 z8k1.regs[
OPCNIB1 & 0xE] = (z8k1.regs[
OPCNIB1 | 1] & 0x8000) ? 0xFFFF : 0x0000;
1641 z8k1.regs[
OPCNIB1 & 0xC] = z8k1.regs[(
OPCNIB1 & 0xC) | 1] = (z8k1.regs[(
OPCNIB1 & 0xC) | 2] & 0x8000) ? 0xFFFF : 0x0000;
1713 Uint16 disp = READCODE();
1714 Uint16 val = z8k1.pc + (Sint16)disp;
1859 switch ((opc >> 1) & 7) {
1862 Uint16 port = READCODE();
2001 set_fcw_byte(temp >> 8);
2002 z8k1.flags = temp & 0xFC;
2089 int vals = GetReg8(opc2 >> 4), vald = GetReg8(opc2 & 0xF);
2095 (((vals & 0x80) == (vald & 0x80)) && ((temp & 0x80) != (vals & 0x80))) ?
FLAG_PV : 0;
2096 SetReg8(opc & 0xF, temp & 0xFF);
2105 if ((opc2 & 0xF0)) {
2109 Uint8 datah = READCODE();
2110 Uint8 datal = READCODE();
2111 Uint8 data = (opc2 & 8) ? datal : datah;
2112 DISASM(
"%02X:%04X %02X%02X%02X%02X\tLDB*\t%s,#%02X",
2114 opc, opc2, datah, datal,
2119 SetReg8(opc2 & 0xF,
data);
2136 case 0xC0:
case 0xC1:
case 0xC2:
case 0xC3:
case 0xC4:
case 0xC5:
case 0xC6:
case 0xC7:
2137 case 0xC8:
case 0xC9:
case 0xCA:
case 0xCB:
case 0xCC:
case 0xCD:
case 0xCE:
case 0xCF:
2147 case 0xD0:
case 0xD1:
case 0xD2:
case 0xD3:
case 0xD4:
case 0xD5:
case 0xD6:
case 0xD7:
2148 case 0xD8:
case 0xD9:
case 0xDA:
case 0xDB:
case 0xDC:
case 0xDD:
case 0xDE:
case 0xDF:
2150 Uint16 pc_new = ((opc & 0x800) ? (
2151 (opc & 0xFFF) - 0x1000
2155 DISASM(
"|%s\t$%04X",
"CALR", pc_new);
2165 case 0xE0:
case 0xE1:
case 0xE2:
case 0xE3:
case 0xE4:
case 0xE5:
case 0xE6:
case 0xE7:
2166 case 0xE8:
case 0xE9:
case 0xEA:
case 0xEB:
case 0xEC:
case 0xED:
case 0xEE:
case 0xEF:
2168 Uint16 pc_new = z8k1.pc + (2 * (int)(Sint8)(opc & 0xFF));
2180 case 0xF0:
case 0xF1:
case 0xF2:
case 0xF3:
case 0xF4:
case 0xF5:
case 0xF6:
case 0xF7:
2181 case 0xF8:
case 0xF9:
case 0xFA:
case 0xFB:
case 0xFC:
case 0xFD:
case 0xFE:
case 0xFF:
2183 Uint16 pc_new = z8k1.pc - ((opc & 0x7F) << 1);
2198 printf(
"Unknown opcode $%02X\n", opc);
2202 }
while (cycles < cycles_limit);