Xemu [doxygen]  hyppo 0a42be3a057156924bc1b626a687bd6e27349c45 @ Sat 19 Mar 02:15:11 CET 2022
z80ex_dasm.c
Go to the documentation of this file.
1 /*
2  * Z80Ex, ZILoG Z80 CPU emulator.
3  *
4  * by Pigmaker57 aka boo_boo [pigmaker57@kahoh57.info]
5  *
6  * contains some code from the FUSE project (http://fuse-emulator.sourceforge.net)
7  * Released under GNU GPL v2
8  *
9  */
10 
11 #include <stdlib.h>
12 #include <string.h>
13 #ifndef __USE_ISOC99
14 #define __USE_ISOC99
15 #endif
16 #include <stdio.h>
17 #include <stdarg.h>
18 
19 #define __Z80EX_SELF_INCLUDE
20 #include "xemu/z80ex/z80ex_dasm.h"
21 
22 #ifdef _MSC_VER
23 #define snprintf _snprintf
24 #endif
25 
26 typedef struct {
27  const char *mnemonic;
28  int t_states;
29  int t_states2;
31 
33 
34 static const char *formats[] = {
35  "$%02X", /*bytes, # was deleted*/
36  "$%04X", /*words, # was deleted*/
37  "%d" /*WORDS_DEC, BYTES_DEC*/
38 };
39 
40 #define STMP_SIZE 100
41 
42 int z80ex_dasm(char *output, int output_size, unsigned flags, int *t_states, int *t_states2,
44 {
45  Z80EX_BYTE opc=0, next=0, disp_u=0;
46  Z80EX_SIGNED_BYTE disp;
47  int have_disp=0;
48  int out_len=0;
49  int bytes=0;
50  const char *bytes_format=formats[0];
51  const char *words_format=formats[1];
52  const z80ex_opc_dasm *dasm = NULL;
53  static char stmp[STMP_SIZE];
54 
55  if(flags & WORDS_DEC) words_format = formats[2];
56  if(flags & BYTES_DEC) bytes_format = formats[2];
57 
58  *output='\0';
59  *t_states=0;
60  *t_states2=0;
61 
62  opc = readbyte_cb(addr++);
63  bytes++;
64 
65  switch(opc)
66  {
67  case 0xDD:
68  case 0xFD:
69  next = readbyte_cb(addr++);
70  if((next | 0x20) == 0xFD || next == 0xED)
71  {
72  strncpy(output,"NOP*",output_size-1);
73  *t_states=4;
74  dasm=NULL;
75  }
76  else if(next == 0xCB)
77  {
78  disp_u = readbyte_cb(addr++);
79  next = readbyte_cb(addr++);
80  bytes+=3;
81 
82  dasm = (opc==0xDD)? &dasm_ddcb[next]: &dasm_fdcb[next];
83  have_disp=1;
84  }
85  else
86  {
87  bytes++;
88  dasm = (opc==0xDD)? &dasm_dd[next]: &dasm_fd[next];
89  if(dasm->mnemonic == NULL) /*mirrored instructions*/
90  {
91  dasm = &dasm_base[next];
92  *t_states=4;
93  *t_states2=4;
94  }
95  }
96  break;
97 
98  case 0xED:
99  next = readbyte_cb(addr++);
100  bytes++;
101  dasm = &dasm_ed[next];
102  if(dasm->mnemonic == NULL)
103  {
104  strncpy(output,"NOP*",output_size-1);
105  *t_states=8;
106  dasm=NULL;
107  }
108  break;
109 
110  case 0xCB:
111  next = readbyte_cb(addr++);
112  bytes++;
113  dasm = &dasm_cb[next];
114  break;
115 
116  default:
117  dasm = &dasm_base[opc];
118  break;
119  }
120 
121  if(dasm!=NULL)
122  {
123  const char *mpos;
124  int arglen;
125  Z80EX_BYTE hi,lo;
126  char *outpos=output;
127 
128  for(mpos=(dasm->mnemonic); *mpos && out_len < output_size; mpos++)
129  {
130  *stmp='\0';
131 
132  switch(*mpos)
133  {
134  case '@':
135  lo=readbyte_cb(addr++);
136  hi=readbyte_cb(addr++);
137  bytes+=2;
138 
139  arglen=snprintf(stmp,STMP_SIZE,words_format,(int)(lo+hi*0x100));
140 
141  break;
142 
143  case '$':
144  case '%':
145  if(!have_disp) disp_u = readbyte_cb(addr++);
146  bytes++;
147  disp = (disp_u & 0x80)? -(((~disp_u) & 0x7f)+1): disp_u;
148 
149  if(*mpos == '$')
150  arglen=snprintf(stmp,STMP_SIZE,bytes_format,(int)disp);
151  else
152  arglen=snprintf(stmp,STMP_SIZE,words_format,(int)((Z80EX_WORD)(addr+disp)));
153 
154  break;
155 
156  case '#':
157  lo = readbyte_cb(addr++);
158  bytes++;
159 
160  arglen=snprintf(stmp,STMP_SIZE,bytes_format,(int)lo);
161 
162  break;
163 
164  default:
165  *(outpos++) = *mpos;
166  out_len++;
167  arglen=0;
168  break;
169  }
170 
171  if(arglen)
172  {
173  if(out_len+arglen >= output_size) break;
174  strcpy(outpos,stmp);
175  out_len+=arglen;
176  outpos+=arglen;
177  }
178  }
179 
180  *outpos = '\0';
181 
182  *t_states+=dasm->t_states;
183  *t_states2+=dasm->t_states2;
184  }
185 
186  if(*t_states == *t_states2) *t_states2=0;
187 
188  return(bytes);
189 }
190 
191 
flags
Uint8 flags
Definition: z8k1.c:126
WORDS_DEC
@ WORDS_DEC
Definition: z80ex_dasm.h:21
z80ex_opc_dasm::mnemonic
const char * mnemonic
Definition: z80ex_dasm.c:27
addr
int addr
Definition: dma65.c:81
z80ex_opc_dasm::t_states
int t_states
Definition: z80ex_dasm.c:28
Z80EX_SIGNED_BYTE
signed char Z80EX_SIGNED_BYTE
Definition: z80ex.h:50
Z80EX_WORD
unsigned short Z80EX_WORD
Definition: z80ex.h:51
z80ex_dasm.h
z80ex_dasm_readbyte_cb
Z80EX_BYTE(* z80ex_dasm_readbyte_cb)(Z80EX_WORD addr)
Definition: z80ex_dasm.h:17
next
Uint8 next
Definition: input_devices.c:77
Z80EX_BYTE
unsigned char Z80EX_BYTE
Definition: z80ex.h:49
z80ex_opc_dasm
Definition: z80ex_dasm.c:26
z80ex_opc_dasm::t_states2
int t_states2
Definition: z80ex_dasm.c:29
BYTES_DEC
@ BYTES_DEC
Definition: z80ex_dasm.h:22
readbyte_cb
Z80EX_BYTE readbyte_cb(Z80EX_WORD addr, void *user_data)
Definition: dasm.c:13
z80ex_dasm
int z80ex_dasm(char *output, int output_size, unsigned flags, int *t_states, int *t_states2, z80ex_dasm_readbyte_cb readbyte_cb, Z80EX_WORD addr)
Definition: z80ex_dasm.c:42
STMP_SIZE
#define STMP_SIZE
Definition: z80ex_dasm.c:40
opcodes_dasm.c