2 * Zymosis: Z80 CPU emulation engine v0.1.2.1
3 * coded by Ketmar // Invisible Vector (ketmar@ketmar.no-ip.org)
4 * Understanding is not required. Only obedience.
6 * This program is free software. It comes without any warranty, to
7 * the extent permitted by applicable law. You can redistribute it
8 * and/or modify it under the terms of the Do What The Fuck You Want
9 * To Public License, Version 2, as published by Sam Hocevar. See
10 * http://www.wtfpl.net/txt/copying/ for more details.
12 #ifndef ZYMOSIS_UTILS_H
13 #define ZYMOSIS_UTILS_H
18 /******************************************************************************/
19 /* very simple instruction info extractor */
20 /******************************************************************************/
39 ZYM_MEMIO_NONE
= -666,
59 ZYM_PORTIO_NONE
= -666,
61 ZYM_PORTIO_BCM1
= -2 /* (B-1)C, for OUT* */
77 /* there can be DD/FD prefix followed by ED/CB, hence the bitset */
78 /* note that ED totally ignores IX/IY prefix, and CB with IX/IY is a strange beast */
88 /* registers affected by the instruction. not fully tested yet, may be buggy */
89 /* note that EXX and EX AF,AFX doesn't "affect" registers, and have separate flags*/
90 /* NOT IMPLEMENTED YET! */
100 ZYM_REGMOD_F = 1u<<6,
101 ZYM_REGMOD_A = 1u<<7,
102 ZYM_REGMOD_XH = 1u<<8,
103 ZYM_REGMOD_XL = 1u<<9,
104 ZYM_REGMOD_YH = 1u<<10,
105 ZYM_REGMOD_YL = 1u<<11,
106 ZYM_REGMOD_SP = 1u<<12,
108 ZYM_REGMOD_EXX = 1u<<13,
110 ZYM_REGMOD_EXAF = 1u<<14,
111 ZYM_REGMOD_I = 1u<<15,
112 ZYM_REGMOD_R = 1u<<16,
115 ZYM_REGMOD_BC = ZYM_REGMOD_B|ZYM_REGMOD_C,
116 ZYM_REGMOD_DE = ZYM_REGMOD_D|ZYM_REGMOD_E,
117 ZYM_REGMOD_HL = ZYM_REGMOD_H|ZYM_REGMOD_L,
118 ZYM_REGMOD_AF = ZYM_REGMOD_A|ZYM_REGMOD_F,
119 ZYM_REGMOD_IX = ZYM_REGMOD_XH|ZYM_REGMOD_XL,
120 ZYM_REGMOD_IY = ZYM_REGMOD_YH|ZYM_REGMOD_YL,
125 int inslen
; /* instruction length */
126 zym_bool memrwword
; /* !0: reading word (if reading anything at all) */
127 int memread
; /* ZYM_MEMIO_xxx or addr */
128 int memwrite
; /* ZYM_MEMIO_xxx or addr */
129 int jump
; /* Z80_JUMP_xxx or addr */
130 int cond
; /* Z80_COND_xxx */
131 int portread
; /* Z80_PORTIO_xxx or addr; if addr is specified, high byte must be taken from A */
132 int portwrite
; /* Z80_PORTIO_xxx or addr; if addr is specified, high byte must be taken from A */
133 int push
; /* Z80_STK_xxx; CALL/RST will set ZYM_STK_PC */
134 int pop
; /* Z80_STK_xxx; RET will set ZYM_STK_PC */
135 int disp
; /* for (IX+n) / (IY+n), else 0xffff */
136 int trap
; /* slt and other trap opcode or -1 */
137 unsigned prefix
; /* ZYM_PFX_XXX */
138 /* NOT IMPLEMENTED YET! */
139 /*unsigned regread;*/ /* registers read by this instruction */
140 /*unsigned regwrite;*/ /* registers wrote by this instruction */
144 void zym_op_meminfo (zym_cpu_t
*z80
, zym_op_meminfo_t
*nfo
, uint16_t pc
);
147 /******************************************************************************/
148 /* very simple disassembler */
149 /******************************************************************************/
152 ZYM_DIS_FLAGS_DEFAULT
= 0u,
153 // use lower-cased text for mnemonics
154 ZYM_DIS_FLAG_LOCASE_MNEMO
= 1u<<0,
155 // use lower-cased text for arguments
156 ZYM_DIS_FLAG_LOCASE_ARGS
= 1u<<1,
157 // use lower-cased text for hex numbers
158 ZYM_DIS_FLAG_LOCASE_HEX
= 1u<<2,
159 // use decimal numbers instead of hex?
160 ZYM_DIS_FLAG_DECIMAL
= 1u<<3,
161 // if hex, use "0x" instead of "#"?
162 ZYM_DIS_FLAG_HEX_CLIKE
= 1u<<4,
166 int inslen
; // instruction length in bytes (NOT disassembly string length!)
167 char disbuf
[128]; // buffer that holds disassembled text; mnemonic is separated by '\t'
168 const char *mnemo
; // points into disbuf
170 const char *args
[3]; // points into disbuf
172 int tstates
[2]; // tstates for taken/not taken; equal for non-branch commands
173 // disassembler options
174 unsigned flags
; // see above
178 /* size: 1 or 2 -- size in bytes */
179 /* asaddr: !0 if this is for CALL/JP */
181 ZYM_DIS_ATYPE_BYTE
= 0, /* immediate byte value */
182 ZYM_DIS_ATYPE_WORD
= 1, /* immediate word value */
183 ZYM_DIS_ATYPE_PC_ADDR
= 2, /* CALL/JP/JR/DJNZ address */
184 ZYM_DIS_ATYPE_DATA_ADDR
= 3, /* LD (nnn) address */
185 ZYM_DIS_ATYPE_PORT8
= 4,
186 ZYM_DIS_ATYPE_OFFSET
= 5, /* LD (ix+n) address */
189 // for offsets, value is signed 2-complement
190 typedef const char *(*zym_disasm_getlabel_fn
) (uint16_t value
, int type
/*ZYM_DIS_ATYPE_XXX*/);
191 extern zym_disasm_getlabel_fn zym_disasm_getlabel
;
193 extern const char *zym_disasm_mnemo_end
; /* default is NULL ("\t") */
194 extern const char *zym_disasm_num_start
; /* default is NULL */
195 extern const char *zym_disasm_num_end
; /* default is NULL */
197 /* you may skip calling this, and only set `flags` */
198 void zym_disasm_init (zym_disop_t
*nfo
);
200 void zym_disasm_one_ex (zym_disop_t
*nfo
, const uint8_t mem
[8], uint16_t pc
);
201 void zym_disasm_one (zym_cpu_t
*z80
, zym_disop_t
*nfo
, uint16_t pc
);