ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_z80.cpp
(Generate patch)

Comparing mon/src/mon_z80.cpp (file contents):
Revision 1.1 by cebix, 2000-10-15T15:07:16Z vs.
Revision 1.8 by cebix, 2007-01-21T17:32:05Z

# Line 1 | Line 1
1   /*
2   *  mon_z80.cpp - Z80 disassembler
3   *
4 < *  cxmon (C) 1997-2000 Christian Bauer, Marc Hellwig
4 > *  cxmon (C) 1997-2007 Christian Bauer, Marc Hellwig
5   *
6   *  This program is free software; you can redistribute it and/or modify
7   *  it under the terms of the GNU General Public License as published by
# Line 27 | Line 27
27  
28  
29   // Addressing modes
30 < enum {
30 > enum AddrMode {
31          A_IMPL,
32          A_IMM8,         // xx
33          A_IMM16,        // xxxx
# Line 46 | Line 46 | enum {
46          A_COND,         // condition code (bits 3..5 of opcode)
47          A_COND2,        // condition code (bits 3..4 of opcode)
48          A_BIT,          // bit number (bits 3..5 of opcode)
49 +        A_BIT_REG1,     // bit number (bits 3..5 of opcode) followed by 8-bit register (bits 0..2 of opcode)
50          A_RST,          // restart
51          A_BC_IND,       // (bc)
52          A_DE_IND,       // (de)
53          A_HL_IND,       // (hl) or (ix) or (iy)
54 +        A_XY_IND,       // (ix+d) or (iy+d)
55          A_SP_IND,       // (sp)
56          A_DE_HL,        // de,hl
57          A_AF_AF,        // af,af'
58   };
59  
60   // Mnemonics
61 < enum {
61 > enum Mnemonic {
62          M_ADC, M_ADD, M_AND, M_BIT, M_CALL, M_CCF, M_CP, M_CPD, M_CPDR, M_CPI,
63          M_CPIR, M_CPL, M_DAA, M_DEC, M_DI, M_DJNZ, M_EI, M_EX, M_EXX, M_HALT,
64          M_IM0, M_IM1, M_IM2, M_IN, M_INC, M_IND, M_INDR, M_INI, M_INIR, M_JP,
# Line 77 | Line 79 | static const char mnem_3[] = "cddtlf ddi
79   static const char mnem_4[] = "    l   r r    z   t012   r r    r r   rr di h  in   a    a            ";
80  
81   // Mnemonic for each opcode
82 < static const char mnemonic[256] = {
82 > static const Mnemonic mnemonic[256] = {
83          M_NOP , M_LD , M_LD , M_INC    , M_INC , M_DEC    , M_LD  , M_RLCA,     // 00
84          M_EX  , M_ADD, M_LD , M_DEC    , M_INC , M_DEC    , M_LD  , M_RRCA,
85          M_DJNZ, M_LD , M_LD , M_INC    , M_INC , M_DEC    , M_LD  , M_RLA ,     // 10
# Line 115 | Line 117 | static const char mnemonic[256] = {
117   // Source/destination addressing modes for each opcode
118   #define A(d,s) (((A_ ## d) << 8) | (A_ ## s))
119  
120 < static const short adr_mode[256] = {
120 > static const int adr_mode[256] = {
121          A(IMPL,IMPL)  , A(REG3,IMM16) , A(BC_IND,A)  , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,       // 00
122          A(AF_AF,IMPL) , A(HL,REG3)    , A(A,BC_IND)  , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,
123          A(REL,IMPL)   , A(REG3,IMM16) , A(DE_IND,A)  , A(REG3,IMPL) , A(REG2,IMPL) , A(REG2,IMPL) , A(REG2,IMM8) , A(IMPL,IMPL) ,       // 10
# Line 206 | Line 208 | static void operand(SFILE *f, char mode,
208                          break;
209  
210                  case A_REL:
211 <                        mon_sprintf(f, "$%04x", (adr + 2 + (int8)mon_read_byte(adr)) & 0xffff); adr++;
211 >                        mon_sprintf(f, "$%04x", (adr + 1 + (int8)mon_read_byte(adr)) & 0xffff); adr++;
212                          break;
213  
214                  case A_A:
# Line 227 | Line 229 | static void operand(SFILE *f, char mode,
229                          if (reg == 6) {
230                                  if (ix || iy) {
231                                          mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
232 <                                } else
232 >                                } else {
233                                          mon_sprintf(f, "(hl)");
234 <                        } else if (mode == A_REG1)
234 >                                }
235 >                        } else if (mode == A_REG1) {
236                                  mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg]));
237 <                        else
237 >                        } else {
238                                  mon_sprintf(f, "%s", reg_name[reg]);
239 +                        }
240                          break;
241                  }
242  
# Line 242 | Line 246 | static void operand(SFILE *f, char mode,
246                          if (reg == 6) {
247                                  if (ix || iy) {
248                                          mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
249 <                                } else
249 >                                } else {
250                                          mon_sprintf(f, "(hl)");
251 <                        } else if (mode == A_REG2)
251 >                                }
252 >                        } else if (mode == A_REG2) {
253                                  mon_sprintf(f, "%s", ix ? reg_name_ix[reg] : (iy ? reg_name_iy[reg] : reg_name[reg]));
254 <                        else
254 >                        } else {
255                                  mon_sprintf(f, "%s", reg_name[reg]);
256 +                        }
257                          break;
258                  }
259  
260 <                case A_REG3:
261 <                        mon_sprintf(f, reg_name_16[(op >> 4) & 3]);
260 >                case A_REG3: {
261 >                        int reg = (op >> 4) & 3;
262 >                        if (reg == 2 && (ix || iy)) {
263 >                                mon_sprintf(f, ix ? "ix" : "iy");
264 >                        } else {
265 >                                mon_sprintf(f, reg_name_16[reg]);
266 >                        }
267                          break;
268 +                }
269  
270 <                case A_REG4:
271 <                        mon_sprintf(f, reg_name_16_2[(op >> 4) & 3]);
270 >                case A_REG4: {
271 >                        int reg = (op >> 4) & 3;
272 >                        if (reg == 2 && (ix || iy)) {
273 >                                mon_sprintf(f, ix ? "ix" : "iy");
274 >                        } else {
275 >                                mon_sprintf(f, reg_name_16_2[reg]);
276 >                        }
277                          break;
278 +                }
279  
280                  case A_COND:
281                          mon_sprintf(f, cond_name[(op >> 3) & 7]);
# Line 271 | Line 289 | static void operand(SFILE *f, char mode,
289                          mon_sprintf(f, "%d", (op >> 3) & 7);
290                          break;
291  
292 +                case A_BIT_REG1: { // undoc
293 +                        int reg = op & 7;
294 +                        if (reg == 6) {
295 +                                mon_sprintf(f, "%d", (op >> 3) & 7);
296 +                        } else {
297 +                                mon_sprintf(f, "%d,%s", (op >> 3) & 7, reg_name[reg]);
298 +                        }
299 +                        break;
300 +                }
301 +
302                  case A_RST:
303                          mon_sprintf(f, "$%02x", op & 0x38);
304                          break;
# Line 287 | Line 315 | static void operand(SFILE *f, char mode,
315                          mon_sprintf(f, ix ? "(ix)" : (iy ? "(iy)" : "(hl)"));
316                          break;
317  
318 +                case A_XY_IND: // undoc
319 +                        mon_sprintf(f, "(%s+$%02x)", ix ? "ix" : "iy", mon_read_byte(adr)); adr++;
320 +                        break;
321 +
322                  case A_SP_IND:
323                          mon_sprintf(f, "(sp)");
324                          break;
# Line 301 | Line 333 | static void operand(SFILE *f, char mode,
333          }
334   }
335  
336 < static int print_instr(SFILE *f, char mnem, char dst_mode, char src_mode, uint32 adr, uint8 op, bool ix, bool iy)
336 > static int print_instr(SFILE *f, Mnemonic mnem, AddrMode dst_mode, AddrMode src_mode, uint32 adr, uint8 op, bool ix, bool iy)
337   {
338          uint32 orig_adr = adr;
339  
# Line 334 | Line 366 | static int disass_cb(SFILE *f, uint32 ad
366          }
367  
368          // Decode mnemonic and addressing modes
369 <        char mnem, dst_mode = A_IMPL, src_mode = A_IMPL;
369 >        Mnemonic mnem = M_ILLEGAL;
370 >        AddrMode dst_mode = A_IMPL, src_mode = A_IMPL;
371 >
372          switch (op & 0xc0) {
373                  case 0x00:
374 <                        dst_mode = A_REG1;
374 >                        dst_mode = A_REG1X;
375 >                        if ((ix || iy) && ((op & 7) != 6))
376 >                                src_mode = A_XY_IND;
377                          switch ((op >> 3) & 7) {
378                                  case 0: mnem = M_RLC; break;
379                                  case 1: mnem = M_RRC; break;
# Line 345 | Line 381 | static int disass_cb(SFILE *f, uint32 ad
381                                  case 3: mnem = M_RR; break;
382                                  case 4: mnem = M_SLA; break;
383                                  case 5: mnem = M_SRA; break;
384 <                                case 6: mnem = M_SL1; break;
384 >                                case 6: mnem = M_SL1; break; // undoc
385                                  case 7: mnem = M_SRL; break;
386                          }
387                          break;
388                  case 0x40:
389 <                        mnem = M_BIT; dst_mode = A_BIT; src_mode = A_REG1;
389 >                        mnem = M_BIT; dst_mode = A_BIT;
390 >                        if (ix || iy)
391 >                                src_mode = A_XY_IND;
392 >                        else
393 >                                src_mode = A_REG1;
394                          break;
395                  case 0x80:
396 <                        mnem = M_RES; dst_mode = A_BIT; src_mode = A_REG1;
396 >                        mnem = M_RES;
397 >                        if (ix || iy) {
398 >                                dst_mode = A_BIT_REG1;
399 >                                src_mode = A_XY_IND;
400 >                        } else {
401 >                                dst_mode = A_BIT;
402 >                                src_mode = A_REG1;
403 >                        }
404                          break;
405                  case 0xc0:
406 <                        mnem = M_SET; dst_mode = A_BIT; src_mode = A_REG1;
406 >                        mnem = M_SET;
407 >                        if (ix || iy) {
408 >                                dst_mode = A_BIT_REG1;
409 >                                src_mode = A_XY_IND;
410 >                        } else {
411 >                                dst_mode = A_BIT;
412 >                                src_mode = A_REG1;
413 >                        }
414                          break;
415          }
416  
# Line 371 | Line 425 | static int disass_ed(SFILE *f, uint32 ad
425          uint8 op = mon_read_byte(adr);
426  
427          // Decode mnemonic and addressing modes
428 <        char mnem, dst_mode = A_IMPL, src_mode = A_IMPL;
428 >        Mnemonic mnem;
429 >        AddrMode dst_mode = A_IMPL, src_mode = A_IMPL;
430 >
431          switch (op) {
432                  case 0x40:
433                  case 0x48:
# Line 380 | Line 436 | static int disass_ed(SFILE *f, uint32 ad
436                  case 0x60:
437                  case 0x68:
438                  case 0x78:
439 <                        mon_sprintf(f, "in\t%s,(c)", reg_name[(op >> 3) & 7]);
439 >                        mon_sprintf(f, "in   %s,(c)", reg_name[(op >> 3) & 7]);
440                          return 1;
441                  case 0x70:
442 <                        mon_sprintf(f, "in\t(c)");
442 >                        mon_sprintf(f, "in   (c)");
443                          return 1;
444  
445                  case 0x41:
# Line 393 | Line 449 | static int disass_ed(SFILE *f, uint32 ad
449                  case 0x61:
450                  case 0x69:
451                  case 0x79:
452 <                        mon_sprintf(f, "out\t(c),%s", reg_name[(op >> 3) & 7]);
452 >                        mon_sprintf(f, "out  (c),%s", reg_name[(op >> 3) & 7]);
453                          return 1;
454                  case 0x71:      // undoc
455 <                        mon_sprintf(f, "out\t(c),0");
455 >                        mon_sprintf(f, "out  (c),0");
456                          return 1;
457  
458                  case 0x42:
# Line 465 | Line 521 | static int disass_ed(SFILE *f, uint32 ad
521                          break;
522  
523                  case 0x47:
524 <                        mon_sprintf(f, "ld\ti,a");
524 >                        mon_sprintf(f, "ld   i,a");
525                          return 1;
526                  case 0x4f:
527 <                        mon_sprintf(f, "ld\tr,a");
527 >                        mon_sprintf(f, "ld   r,a");
528                          return 1;
529                  case 0x57:
530 <                        mon_sprintf(f, "ld\ta,i");
530 >                        mon_sprintf(f, "ld   a,i");
531                          return 1;
532                  case 0x5f:
533 <                        mon_sprintf(f, "ld\ta,r");
533 >                        mon_sprintf(f, "ld   a,r");
534                          return 1;
535  
536                  case 0x67: mnem = M_RRD; break;
# Line 498 | Line 554 | static int disass_ed(SFILE *f, uint32 ad
554                  case 0xbb: mnem = M_OTDR; break;
555  
556                  default:
557 <                        mnem = M_ILLEGAL;
557 >                        mnem = M_NOP;
558                          break;
559          }
560  
# Line 512 | Line 568 | static int disass(SFILE *f, uint32 adr,
568          if (op == 0xcb)
569                  return disass_cb(f, adr + 1, ix, iy) + 1;
570          else
571 <                return print_instr(f, mnemonic[op], adr_mode[op] >> 8, adr_mode[op] & 0xff, adr + 1, op, ix, iy) + 1;
571 >                return print_instr(f, mnemonic[op], AddrMode(adr_mode[op] >> 8), AddrMode(adr_mode[op] & 0xff), adr + 1, op, ix, iy) + 1;
572   }
573  
574   int disass_z80(FILE *f, uint32 adr)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines