Home | History | Annotate | Line # | Download | only in m68hc11
m68hc11_sim.c revision 1.1.1.4
      1      1.1  christos /* m6811_cpu.c -- 68HC11&68HC12 CPU Emulation
      2  1.1.1.4  christos    Copyright 1999-2016 Free Software Foundation, Inc.
      3      1.1  christos    Written by Stephane Carrez (stcarrez (at) nerim.fr)
      4      1.1  christos 
      5      1.1  christos This file is part of GDB, GAS, and the GNU binutils.
      6      1.1  christos 
      7      1.1  christos This program is free software; you can redistribute it and/or modify
      8      1.1  christos it under the terms of the GNU General Public License as published by
      9      1.1  christos the Free Software Foundation; either version 3 of the License, or
     10      1.1  christos (at your option) any later version.
     11      1.1  christos 
     12      1.1  christos This program is distributed in the hope that it will be useful,
     13      1.1  christos but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1  christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1  christos GNU General Public License for more details.
     16      1.1  christos 
     17      1.1  christos You should have received a copy of the GNU General Public License
     18      1.1  christos along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     19      1.1  christos 
     20      1.1  christos #include "sim-main.h"
     21      1.1  christos #include "sim-assert.h"
     22      1.1  christos #include "sim-module.h"
     23      1.1  christos #include "sim-options.h"
     24      1.1  christos 
     25      1.1  christos enum {
     26      1.1  christos   OPTION_CPU_RESET = OPTION_START,
     27      1.1  christos   OPTION_EMUL_OS,
     28      1.1  christos   OPTION_CPU_CONFIG,
     29      1.1  christos   OPTION_CPU_BOOTSTRAP,
     30      1.1  christos   OPTION_CPU_MODE
     31      1.1  christos };
     32      1.1  christos 
     33      1.1  christos static DECLARE_OPTION_HANDLER (cpu_option_handler);
     34      1.1  christos 
     35      1.1  christos static const OPTION cpu_options[] =
     36      1.1  christos {
     37      1.1  christos   { {"cpu-reset", no_argument, NULL, OPTION_CPU_RESET },
     38      1.1  christos       '\0', NULL, "Reset the CPU",
     39      1.1  christos       cpu_option_handler },
     40      1.1  christos 
     41      1.1  christos   { {"emulos",    no_argument, NULL, OPTION_EMUL_OS },
     42      1.1  christos       '\0', NULL, "Emulate some OS system calls (read, write, ...)",
     43      1.1  christos       cpu_option_handler },
     44      1.1  christos 
     45      1.1  christos   { {"cpu-config", required_argument, NULL, OPTION_CPU_CONFIG },
     46      1.1  christos       '\0', NULL, "Specify the initial CPU configuration register",
     47      1.1  christos       cpu_option_handler },
     48      1.1  christos 
     49      1.1  christos   { {"bootstrap", no_argument, NULL, OPTION_CPU_BOOTSTRAP },
     50      1.1  christos       '\0', NULL, "Start the processing in bootstrap mode",
     51      1.1  christos       cpu_option_handler },
     52      1.1  christos 
     53      1.1  christos   { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
     54      1.1  christos };
     55      1.1  christos 
     56      1.1  christos 
     57      1.1  christos static SIM_RC
     58      1.1  christos cpu_option_handler (SIM_DESC sd, sim_cpu *cpu,
     59      1.1  christos                     int opt, char *arg, int is_command)
     60      1.1  christos {
     61      1.1  christos   int val;
     62      1.1  christos 
     63      1.1  christos   cpu = STATE_CPU (sd, 0);
     64      1.1  christos   switch (opt)
     65      1.1  christos     {
     66      1.1  christos     case OPTION_CPU_RESET:
     67      1.1  christos       sim_board_reset (sd);
     68      1.1  christos       break;
     69      1.1  christos 
     70      1.1  christos     case OPTION_EMUL_OS:
     71      1.1  christos       cpu->cpu_emul_syscall = 1;
     72      1.1  christos       break;
     73      1.1  christos 
     74      1.1  christos     case OPTION_CPU_CONFIG:
     75      1.1  christos       if (sscanf(arg, "0x%x", &val) == 1
     76      1.1  christos           || sscanf(arg, "%d", &val) == 1)
     77      1.1  christos         {
     78      1.1  christos           cpu->cpu_config = val;
     79      1.1  christos           cpu->cpu_use_local_config = 1;
     80      1.1  christos         }
     81      1.1  christos       else
     82      1.1  christos         cpu->cpu_use_local_config = 0;
     83      1.1  christos       break;
     84      1.1  christos 
     85      1.1  christos     case OPTION_CPU_BOOTSTRAP:
     86      1.1  christos        cpu->cpu_start_mode = "bootstrap";
     87      1.1  christos        break;
     88      1.1  christos 
     89      1.1  christos     case OPTION_CPU_MODE:
     90      1.1  christos       break;
     91      1.1  christos     }
     92      1.1  christos 
     93      1.1  christos   return SIM_RC_OK;
     94      1.1  christos }
     95      1.1  christos 
     96      1.1  christos 
     97      1.1  christos void
     98      1.1  christos cpu_call (sim_cpu *cpu, uint16 addr)
     99      1.1  christos {
    100      1.1  christos 
    101      1.1  christos   cpu_set_pc (cpu, addr);
    102      1.1  christos }
    103      1.1  christos 
    104      1.1  christos void
    105      1.1  christos cpu_return (sim_cpu *cpu)
    106      1.1  christos {
    107      1.1  christos }
    108      1.1  christos 
    109      1.1  christos /* Set the stack pointer and re-compute the current frame.  */
    110      1.1  christos void
    111      1.1  christos cpu_set_sp (sim_cpu *cpu, uint16 val)
    112      1.1  christos {
    113      1.1  christos   cpu->cpu_regs.sp = val;
    114      1.1  christos }
    115      1.1  christos 
    116      1.1  christos uint16
    117      1.1  christos cpu_get_reg (sim_cpu* cpu, uint8 reg)
    118      1.1  christos {
    119      1.1  christos   switch (reg)
    120      1.1  christos     {
    121      1.1  christos     case 0:
    122      1.1  christos       return cpu_get_x (cpu);
    123      1.1  christos 
    124      1.1  christos     case 1:
    125      1.1  christos       return cpu_get_y (cpu);
    126      1.1  christos 
    127      1.1  christos     case 2:
    128      1.1  christos       return cpu_get_sp (cpu);
    129      1.1  christos 
    130      1.1  christos     case 3:
    131      1.1  christos       return cpu_get_pc (cpu);
    132      1.1  christos 
    133      1.1  christos     default:
    134      1.1  christos       return 0;
    135      1.1  christos     }
    136      1.1  christos }
    137      1.1  christos 
    138      1.1  christos uint16
    139      1.1  christos cpu_get_src_reg (sim_cpu* cpu, uint8 reg)
    140      1.1  christos {
    141      1.1  christos   switch (reg)
    142      1.1  christos     {
    143      1.1  christos     case 0:
    144      1.1  christos       return cpu_get_a (cpu);
    145      1.1  christos 
    146      1.1  christos     case 1:
    147      1.1  christos       return cpu_get_b (cpu);
    148      1.1  christos 
    149      1.1  christos     case 2:
    150      1.1  christos       return cpu_get_ccr (cpu);
    151      1.1  christos 
    152      1.1  christos     case 3:
    153      1.1  christos       return cpu_get_tmp3 (cpu);
    154      1.1  christos 
    155      1.1  christos     case 4:
    156      1.1  christos       return cpu_get_d (cpu);
    157      1.1  christos 
    158      1.1  christos     case 5:
    159      1.1  christos       return cpu_get_x (cpu);
    160      1.1  christos 
    161      1.1  christos     case 6:
    162      1.1  christos       return cpu_get_y (cpu);
    163      1.1  christos 
    164      1.1  christos     case 7:
    165      1.1  christos       return cpu_get_sp (cpu);
    166      1.1  christos 
    167      1.1  christos     default:
    168      1.1  christos       return 0;
    169      1.1  christos     }
    170      1.1  christos }
    171      1.1  christos 
    172      1.1  christos void
    173      1.1  christos cpu_set_dst_reg (sim_cpu* cpu, uint8 reg, uint16 val)
    174      1.1  christos {
    175      1.1  christos   switch (reg)
    176      1.1  christos     {
    177      1.1  christos     case 0:
    178      1.1  christos       cpu_set_a (cpu, val);
    179      1.1  christos       break;
    180      1.1  christos 
    181      1.1  christos     case 1:
    182      1.1  christos       cpu_set_b (cpu, val);
    183      1.1  christos       break;
    184      1.1  christos 
    185      1.1  christos     case 2:
    186      1.1  christos       cpu_set_ccr (cpu, val);
    187      1.1  christos       break;
    188      1.1  christos 
    189      1.1  christos     case 3:
    190      1.1  christos       cpu_set_tmp2 (cpu, val);
    191      1.1  christos       break;
    192      1.1  christos 
    193      1.1  christos     case 4:
    194      1.1  christos       cpu_set_d (cpu, val);
    195      1.1  christos       break;
    196      1.1  christos 
    197      1.1  christos     case 5:
    198      1.1  christos       cpu_set_x (cpu, val);
    199      1.1  christos       break;
    200      1.1  christos 
    201      1.1  christos     case 6:
    202      1.1  christos       cpu_set_y (cpu, val);
    203      1.1  christos       break;
    204      1.1  christos 
    205      1.1  christos     case 7:
    206      1.1  christos       cpu_set_sp (cpu, val);
    207      1.1  christos       break;
    208      1.1  christos 
    209      1.1  christos     default:
    210      1.1  christos       break;
    211      1.1  christos     }
    212      1.1  christos }
    213      1.1  christos 
    214      1.1  christos void
    215      1.1  christos cpu_set_reg (sim_cpu* cpu, uint8 reg, uint16 val)
    216      1.1  christos {
    217      1.1  christos   switch (reg)
    218      1.1  christos     {
    219      1.1  christos     case 0:
    220      1.1  christos       cpu_set_x (cpu, val);
    221      1.1  christos       break;
    222      1.1  christos 
    223      1.1  christos     case 1:
    224      1.1  christos       cpu_set_y (cpu, val);
    225      1.1  christos       break;
    226      1.1  christos 
    227      1.1  christos     case 2:
    228      1.1  christos       cpu_set_sp (cpu, val);
    229      1.1  christos       break;
    230      1.1  christos 
    231      1.1  christos     case 3:
    232      1.1  christos       cpu_set_pc (cpu, val);
    233      1.1  christos       break;
    234      1.1  christos 
    235      1.1  christos     default:
    236      1.1  christos       break;
    237      1.1  christos     }
    238      1.1  christos }
    239      1.1  christos 
    240      1.1  christos /* Returns the address of a 68HC12 indexed operand.
    241      1.1  christos    Pre and post modifications are handled on the source register.  */
    242      1.1  christos uint16
    243  1.1.1.3  christos cpu_get_indexed_operand_addr (sim_cpu* cpu, int restricted)
    244      1.1  christos {
    245      1.1  christos   uint8 reg;
    246      1.1  christos   uint16 sval;
    247      1.1  christos   uint16 addr;
    248      1.1  christos   uint8 code;
    249      1.1  christos 
    250      1.1  christos   code = cpu_fetch8 (cpu);
    251      1.1  christos 
    252      1.1  christos   /* n,r with 5-bit signed constant.  */
    253      1.1  christos   if ((code & 0x20) == 0)
    254      1.1  christos     {
    255      1.1  christos       reg = (code >> 6) & 3;
    256      1.1  christos       sval = (code & 0x1f);
    257      1.1  christos       if (code & 0x10)
    258      1.1  christos 	sval |= 0xfff0;
    259      1.1  christos 
    260      1.1  christos       addr = cpu_get_reg (cpu, reg);
    261      1.1  christos       addr += sval;
    262      1.1  christos     }
    263      1.1  christos 
    264      1.1  christos   /* Auto pre/post increment/decrement.  */
    265      1.1  christos   else if ((code & 0xc0) != 0xc0)
    266      1.1  christos     {
    267      1.1  christos       reg = (code >> 6) & 3;
    268      1.1  christos       sval = (code & 0x0f);
    269      1.1  christos       if (sval & 0x8)
    270      1.1  christos 	{
    271      1.1  christos 	  sval |= 0xfff0;
    272      1.1  christos 	}
    273      1.1  christos       else
    274      1.1  christos 	{
    275      1.1  christos 	  sval = sval + 1;
    276      1.1  christos 	}
    277      1.1  christos       addr = cpu_get_reg (cpu, reg);
    278      1.1  christos       cpu_set_reg (cpu, reg, addr + sval);
    279      1.1  christos       if ((code & 0x10) == 0)
    280      1.1  christos 	{
    281      1.1  christos 	  addr += sval;
    282      1.1  christos 	}
    283      1.1  christos     }
    284      1.1  christos 
    285      1.1  christos   /* [n,r] 16-bits offset indexed indirect.  */
    286      1.1  christos   else if ((code & 0x07) == 3)
    287      1.1  christos     {
    288  1.1.1.3  christos       if (restricted)
    289      1.1  christos 	{
    290      1.1  christos 	  return 0;
    291      1.1  christos 	}
    292      1.1  christos       reg = (code >> 3) & 0x03;
    293      1.1  christos       addr = cpu_get_reg (cpu, reg);
    294      1.1  christos       addr += cpu_fetch16 (cpu);
    295      1.1  christos       addr = memory_read16 (cpu, addr);
    296      1.1  christos       cpu_add_cycles (cpu, 1);
    297      1.1  christos     }
    298      1.1  christos   else if ((code & 0x4) == 0)
    299      1.1  christos     {
    300  1.1.1.3  christos       if (restricted)
    301      1.1  christos 	{
    302      1.1  christos 	  return 0;
    303      1.1  christos 	}
    304      1.1  christos       reg = (code >> 3) & 0x03;
    305      1.1  christos       addr = cpu_get_reg (cpu, reg);
    306      1.1  christos       if (code & 0x2)
    307      1.1  christos 	{
    308      1.1  christos 	  sval = cpu_fetch16 (cpu);
    309      1.1  christos 	  cpu_add_cycles (cpu, 1);
    310      1.1  christos 	}
    311      1.1  christos       else
    312      1.1  christos 	{
    313      1.1  christos 	  sval = cpu_fetch8 (cpu);
    314      1.1  christos 	  if (code & 0x1)
    315      1.1  christos 	    sval |= 0xff00;
    316      1.1  christos 	  cpu_add_cycles (cpu, 1);
    317      1.1  christos 	}
    318      1.1  christos       addr += sval;
    319      1.1  christos     }
    320      1.1  christos   else
    321      1.1  christos     {
    322      1.1  christos       reg = (code >> 3) & 0x03;
    323      1.1  christos       addr = cpu_get_reg (cpu, reg);
    324      1.1  christos       switch (code & 3)
    325      1.1  christos 	{
    326      1.1  christos 	case 0:
    327      1.1  christos 	  addr += cpu_get_a (cpu);
    328      1.1  christos 	  break;
    329      1.1  christos 	case 1:
    330      1.1  christos 	  addr += cpu_get_b (cpu);
    331      1.1  christos 	  break;
    332      1.1  christos 	case 2:
    333      1.1  christos 	  addr += cpu_get_d (cpu);
    334      1.1  christos 	  break;
    335      1.1  christos 	case 3:
    336      1.1  christos 	default:
    337      1.1  christos 	  addr += cpu_get_d (cpu);
    338      1.1  christos 	  addr = memory_read16 (cpu, addr);
    339      1.1  christos 	  cpu_add_cycles (cpu, 1);
    340      1.1  christos 	  break;
    341      1.1  christos 	}
    342      1.1  christos     }
    343      1.1  christos 
    344      1.1  christos   return addr;
    345      1.1  christos }
    346      1.1  christos 
    347      1.1  christos uint8
    348  1.1.1.3  christos cpu_get_indexed_operand8 (sim_cpu* cpu, int restricted)
    349      1.1  christos {
    350      1.1  christos   uint16 addr;
    351      1.1  christos 
    352  1.1.1.3  christos   addr = cpu_get_indexed_operand_addr (cpu, restricted);
    353      1.1  christos   return memory_read8 (cpu, addr);
    354      1.1  christos }
    355      1.1  christos 
    356      1.1  christos uint16
    357  1.1.1.3  christos cpu_get_indexed_operand16 (sim_cpu* cpu, int restricted)
    358      1.1  christos {
    359      1.1  christos   uint16 addr;
    360      1.1  christos 
    361  1.1.1.3  christos   addr = cpu_get_indexed_operand_addr (cpu, restricted);
    362      1.1  christos   return memory_read16 (cpu, addr);
    363      1.1  christos }
    364      1.1  christos 
    365      1.1  christos void
    366      1.1  christos cpu_move8 (sim_cpu *cpu, uint8 code)
    367      1.1  christos {
    368      1.1  christos   uint8 src;
    369      1.1  christos   uint16 addr;
    370      1.1  christos 
    371      1.1  christos   switch (code)
    372      1.1  christos     {
    373      1.1  christos     case 0x0b:
    374      1.1  christos       src = cpu_fetch8 (cpu);
    375      1.1  christos       addr = cpu_fetch16 (cpu);
    376      1.1  christos       break;
    377      1.1  christos 
    378      1.1  christos     case 0x08:
    379      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    380      1.1  christos       src = cpu_fetch8 (cpu);
    381      1.1  christos       break;
    382      1.1  christos 
    383      1.1  christos     case 0x0c:
    384      1.1  christos       addr = cpu_fetch16 (cpu);
    385      1.1  christos       src = memory_read8 (cpu, addr);
    386      1.1  christos       addr = cpu_fetch16 (cpu);
    387      1.1  christos       break;
    388      1.1  christos 
    389      1.1  christos     case 0x09:
    390      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    391      1.1  christos       src = memory_read8 (cpu, cpu_fetch16 (cpu));
    392      1.1  christos       break;
    393      1.1  christos 
    394      1.1  christos     case 0x0d:
    395      1.1  christos       src = cpu_get_indexed_operand8 (cpu, 1);
    396      1.1  christos       addr = cpu_fetch16 (cpu);
    397      1.1  christos       break;
    398      1.1  christos 
    399      1.1  christos     case 0x0a:
    400      1.1  christos       src = cpu_get_indexed_operand8 (cpu, 1);
    401      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    402      1.1  christos       break;
    403      1.1  christos 
    404      1.1  christos     default:
    405      1.1  christos       sim_engine_abort (CPU_STATE (cpu), cpu, 0,
    406      1.1  christos 			"Invalid code 0x%0x -- internal error?", code);
    407      1.1  christos       return;
    408      1.1  christos     }
    409      1.1  christos   memory_write8 (cpu, addr, src);
    410      1.1  christos }
    411      1.1  christos 
    412      1.1  christos void
    413      1.1  christos cpu_move16 (sim_cpu *cpu, uint8 code)
    414      1.1  christos {
    415      1.1  christos   uint16 src;
    416      1.1  christos   uint16 addr;
    417      1.1  christos 
    418      1.1  christos   switch (code)
    419      1.1  christos     {
    420      1.1  christos     case 0x03:
    421      1.1  christos       src = cpu_fetch16 (cpu);
    422      1.1  christos       addr = cpu_fetch16 (cpu);
    423      1.1  christos       break;
    424      1.1  christos 
    425      1.1  christos     case 0x00:
    426      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    427      1.1  christos       src = cpu_fetch16 (cpu);
    428      1.1  christos       break;
    429      1.1  christos 
    430      1.1  christos     case 0x04:
    431      1.1  christos       addr = cpu_fetch16 (cpu);
    432      1.1  christos       src = memory_read16 (cpu, addr);
    433      1.1  christos       addr = cpu_fetch16 (cpu);
    434      1.1  christos       break;
    435      1.1  christos 
    436      1.1  christos     case 0x01:
    437      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    438      1.1  christos       src = memory_read16 (cpu, cpu_fetch16 (cpu));
    439      1.1  christos       break;
    440      1.1  christos 
    441      1.1  christos     case 0x05:
    442      1.1  christos       src = cpu_get_indexed_operand16 (cpu, 1);
    443      1.1  christos       addr = cpu_fetch16 (cpu);
    444      1.1  christos       break;
    445      1.1  christos 
    446      1.1  christos     case 0x02:
    447      1.1  christos       src = cpu_get_indexed_operand16 (cpu, 1);
    448      1.1  christos       addr = cpu_get_indexed_operand_addr (cpu, 1);
    449      1.1  christos       break;
    450      1.1  christos 
    451      1.1  christos     default:
    452      1.1  christos       sim_engine_abort (CPU_STATE (cpu), cpu, 0,
    453      1.1  christos 			"Invalid code 0x%0x -- internal error?", code);
    454      1.1  christos       return;
    455      1.1  christos     }
    456      1.1  christos   memory_write16 (cpu, addr, src);
    457      1.1  christos }
    458      1.1  christos 
    459      1.1  christos int
    460      1.1  christos cpu_initialize (SIM_DESC sd, sim_cpu *cpu)
    461      1.1  christos {
    462      1.1  christos   sim_add_option_table (sd, 0, cpu_options);
    463      1.1  christos 
    464      1.1  christos   memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
    465      1.1  christos 
    466      1.1  christos   cpu->cpu_absolute_cycle = 0;
    467      1.1  christos   cpu->cpu_current_cycle  = 0;
    468      1.1  christos   cpu->cpu_emul_syscall   = 1;
    469      1.1  christos   cpu->cpu_running        = 1;
    470      1.1  christos   cpu->cpu_stop_on_interrupt = 0;
    471      1.1  christos   cpu->cpu_frequency = 8 * 1000 * 1000;
    472      1.1  christos   cpu->cpu_use_elf_start = 0;
    473      1.1  christos   cpu->cpu_elf_start     = 0;
    474      1.1  christos   cpu->cpu_use_local_config = 0;
    475      1.1  christos   cpu->bank_start = 0;
    476      1.1  christos   cpu->bank_end   = 0;
    477      1.1  christos   cpu->bank_shift = 0;
    478      1.1  christos   cpu->cpu_config        = M6811_NOSEC | M6811_NOCOP | M6811_ROMON |
    479      1.1  christos     M6811_EEON;
    480      1.1  christos   interrupts_initialize (sd, cpu);
    481      1.1  christos 
    482      1.1  christos   cpu->cpu_is_initialized = 1;
    483      1.1  christos   return 0;
    484      1.1  christos }
    485      1.1  christos 
    486      1.1  christos 
    487      1.1  christos /* Reinitialize the processor after a reset.  */
    488      1.1  christos int
    489      1.1  christos cpu_reset (sim_cpu *cpu)
    490      1.1  christos {
    491      1.1  christos   /* Initialize the config register.
    492      1.1  christos      It is only initialized at reset time.  */
    493      1.1  christos   memset (cpu->ios, 0, sizeof (cpu->ios));
    494      1.1  christos   if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
    495      1.1  christos     cpu->ios[M6811_INIT] = 0x1;
    496      1.1  christos   else
    497      1.1  christos     cpu->ios[M6811_INIT] = 0;
    498      1.1  christos 
    499      1.1  christos   /* Output compare registers set to 0xFFFF.  */
    500      1.1  christos   cpu->ios[M6811_TOC1_H] = 0xFF;
    501      1.1  christos   cpu->ios[M6811_TOC1_L] = 0xFF;
    502      1.1  christos   cpu->ios[M6811_TOC2_H] = 0xFF;
    503      1.1  christos   cpu->ios[M6811_TOC2_L] = 0xFF;
    504      1.1  christos   cpu->ios[M6811_TOC3_H] = 0xFF;
    505      1.1  christos   cpu->ios[M6811_TOC4_L] = 0xFF;
    506      1.1  christos   cpu->ios[M6811_TOC5_H] = 0xFF;
    507      1.1  christos   cpu->ios[M6811_TOC5_L] = 0xFF;
    508      1.1  christos 
    509      1.1  christos   /* Setup the processor registers.  */
    510      1.1  christos   memset (&cpu->cpu_regs, 0, sizeof(cpu->cpu_regs));
    511      1.1  christos   cpu->cpu_absolute_cycle = 0;
    512      1.1  christos   cpu->cpu_current_cycle  = 0;
    513      1.1  christos   cpu->cpu_is_initialized = 0;
    514      1.1  christos 
    515      1.1  christos   /* Reset interrupts.  */
    516      1.1  christos   interrupts_reset (&cpu->cpu_interrupts);
    517      1.1  christos 
    518      1.1  christos   /* Reinitialize the CPU operating mode.  */
    519      1.1  christos   cpu->ios[M6811_HPRIO] = cpu->cpu_mode;
    520      1.1  christos   return 0;
    521      1.1  christos }
    522      1.1  christos 
    523      1.1  christos /* Reinitialize the processor after a reset.  */
    524      1.1  christos int
    525      1.1  christos cpu_restart (sim_cpu *cpu)
    526      1.1  christos {
    527      1.1  christos   uint16 addr;
    528      1.1  christos 
    529      1.1  christos   /* Get CPU starting address depending on the CPU mode.  */
    530      1.1  christos   if (cpu->cpu_use_elf_start == 0)
    531      1.1  christos     {
    532      1.1  christos       switch ((cpu->ios[M6811_HPRIO]) & (M6811_SMOD | M6811_MDA))
    533      1.1  christos         {
    534      1.1  christos           /* Single Chip  */
    535      1.1  christos         default:
    536      1.1  christos         case 0 :
    537      1.1  christos           addr = memory_read16 (cpu, 0xFFFE);
    538      1.1  christos           break;
    539      1.1  christos 
    540      1.1  christos           /* Expanded Multiplexed  */
    541      1.1  christos         case M6811_MDA:
    542      1.1  christos           addr = memory_read16 (cpu, 0xFFFE);
    543      1.1  christos           break;
    544      1.1  christos 
    545      1.1  christos           /* Special Bootstrap  */
    546      1.1  christos         case M6811_SMOD:
    547      1.1  christos           addr = 0;
    548      1.1  christos           break;
    549      1.1  christos 
    550      1.1  christos           /* Factory Test  */
    551      1.1  christos         case M6811_MDA | M6811_SMOD:
    552      1.1  christos           addr = memory_read16 (cpu, 0xFFFE);
    553      1.1  christos           break;
    554      1.1  christos         }
    555      1.1  christos     }
    556      1.1  christos   else
    557      1.1  christos     {
    558      1.1  christos       addr = cpu->cpu_elf_start;
    559      1.1  christos     }
    560      1.1  christos 
    561      1.1  christos   /* Setup the processor registers.  */
    562      1.1  christos   cpu->cpu_insn_pc  = addr;
    563      1.1  christos   cpu->cpu_regs.pc  = addr;
    564      1.1  christos   cpu->cpu_regs.ccr = M6811_X_BIT | M6811_I_BIT | M6811_S_BIT;
    565      1.1  christos   cpu->cpu_absolute_cycle = 0;
    566      1.1  christos   cpu->cpu_is_initialized = 1;
    567      1.1  christos   cpu->cpu_current_cycle  = 0;
    568      1.1  christos 
    569      1.1  christos   cpu_call (cpu, addr);
    570      1.1  christos 
    571      1.1  christos   return 0;
    572      1.1  christos }
    573      1.1  christos 
    574      1.1  christos void
    575      1.1  christos print_io_reg_desc (SIM_DESC sd, io_reg_desc *desc, int val, int mode)
    576      1.1  christos {
    577      1.1  christos   while (desc->mask)
    578      1.1  christos     {
    579      1.1  christos       if (val & desc->mask)
    580      1.1  christos 	sim_io_printf (sd, "%s",
    581      1.1  christos 		       mode == 0 ? desc->short_name : desc->long_name);
    582      1.1  christos       desc++;
    583      1.1  christos     }
    584      1.1  christos }
    585      1.1  christos 
    586      1.1  christos void
    587      1.1  christos print_io_byte (SIM_DESC sd, const char *name, io_reg_desc *desc,
    588      1.1  christos 	       uint8 val, uint16 addr)
    589      1.1  christos {
    590      1.1  christos   sim_io_printf (sd, "  %-9.9s @ 0x%04x 0x%02x ", name, addr, val);
    591      1.1  christos   if (desc)
    592      1.1  christos     print_io_reg_desc (sd, desc, val, 0);
    593      1.1  christos }
    594      1.1  christos 
    595      1.1  christos void
    596      1.1  christos print_io_word (SIM_DESC sd, const char *name, io_reg_desc *desc,
    597      1.1  christos 	       uint16 val, uint16 addr)
    598      1.1  christos {
    599      1.1  christos   sim_io_printf (sd, "  %-9.9s @ 0x%04x 0x%04x ", name, addr, val);
    600      1.1  christos   if (desc)
    601      1.1  christos     print_io_reg_desc (sd, desc, val, 0);
    602      1.1  christos }
    603      1.1  christos 
    604      1.1  christos void
    605      1.1  christos cpu_ccr_update_tst8 (sim_cpu *proc, uint8 val)
    606      1.1  christos {
    607      1.1  christos   cpu_set_ccr_V (proc, 0);
    608      1.1  christos   cpu_set_ccr_N (proc, val & 0x80 ? 1 : 0);
    609      1.1  christos   cpu_set_ccr_Z (proc, val == 0 ? 1 : 0);
    610      1.1  christos }
    611      1.1  christos 
    612      1.1  christos 
    613      1.1  christos uint16
    614      1.1  christos cpu_fetch_relbranch (sim_cpu *cpu)
    615      1.1  christos {
    616      1.1  christos   uint16 addr = (uint16) cpu_fetch8 (cpu);
    617      1.1  christos 
    618      1.1  christos   if (addr & 0x0080)
    619      1.1  christos     {
    620      1.1  christos       addr |= 0xFF00;
    621      1.1  christos     }
    622      1.1  christos   addr += cpu->cpu_regs.pc;
    623      1.1  christos   return addr;
    624      1.1  christos }
    625      1.1  christos 
    626      1.1  christos uint16
    627      1.1  christos cpu_fetch_relbranch16 (sim_cpu *cpu)
    628      1.1  christos {
    629      1.1  christos   uint16 addr = cpu_fetch16 (cpu);
    630      1.1  christos 
    631      1.1  christos   addr += cpu->cpu_regs.pc;
    632      1.1  christos   return addr;
    633      1.1  christos }
    634      1.1  christos 
    635      1.1  christos /* Push all the CPU registers (when an interruption occurs).  */
    636      1.1  christos void
    637      1.1  christos cpu_push_all (sim_cpu *cpu)
    638      1.1  christos {
    639      1.1  christos   if (cpu->cpu_configured_arch->arch == bfd_arch_m68hc11)
    640      1.1  christos     {
    641      1.1  christos       cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.pc);
    642      1.1  christos       cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.iy);
    643      1.1  christos       cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.ix);
    644      1.1  christos       cpu_m68hc11_push_uint16 (cpu, cpu->cpu_regs.d);
    645      1.1  christos       cpu_m68hc11_push_uint8 (cpu, cpu->cpu_regs.ccr);
    646      1.1  christos     }
    647      1.1  christos   else
    648      1.1  christos     {
    649      1.1  christos       cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.pc);
    650      1.1  christos       cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.iy);
    651      1.1  christos       cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.ix);
    652      1.1  christos       cpu_m68hc12_push_uint16 (cpu, cpu->cpu_regs.d);
    653      1.1  christos       cpu_m68hc12_push_uint8 (cpu, cpu->cpu_regs.ccr);
    654      1.1  christos     }
    655      1.1  christos }
    656      1.1  christos 
    657      1.1  christos /* Simulation of the dbcc/ibcc/tbcc 68HC12 conditional branch operations.  */
    658      1.1  christos void
    659      1.1  christos cpu_dbcc (sim_cpu* cpu)
    660      1.1  christos {
    661      1.1  christos   uint8 code;
    662      1.1  christos   uint16 addr;
    663      1.1  christos   uint16 inc;
    664      1.1  christos   uint16 reg;
    665      1.1  christos 
    666      1.1  christos   code = cpu_fetch8 (cpu);
    667      1.1  christos   switch (code & 0xc0)
    668      1.1  christos     {
    669      1.1  christos     case 0x80: /* ibcc */
    670      1.1  christos       inc = 1;
    671      1.1  christos       break;
    672      1.1  christos     case 0x40: /* tbcc */
    673      1.1  christos       inc = 0;
    674      1.1  christos       break;
    675      1.1  christos     case 0:    /* dbcc */
    676      1.1  christos       inc = -1;
    677      1.1  christos       break;
    678      1.1  christos     default:
    679      1.1  christos       abort ();
    680      1.1  christos       break;
    681      1.1  christos     }
    682      1.1  christos 
    683      1.1  christos   addr = cpu_fetch8 (cpu);
    684      1.1  christos   if (code & 0x10)
    685      1.1  christos     addr |= 0xff00;
    686      1.1  christos 
    687      1.1  christos   addr += cpu_get_pc (cpu);
    688      1.1  christos   reg = cpu_get_src_reg (cpu, code & 0x07);
    689      1.1  christos   reg += inc;
    690      1.1  christos 
    691      1.1  christos   /* Branch according to register value.  */
    692      1.1  christos   if ((reg != 0 && (code & 0x20)) || (reg == 0 && !(code & 0x20)))
    693      1.1  christos     {
    694      1.1  christos       cpu_set_pc (cpu, addr);
    695      1.1  christos     }
    696      1.1  christos   cpu_set_dst_reg (cpu, code & 0x07, reg);
    697      1.1  christos }
    698      1.1  christos 
    699      1.1  christos void
    700      1.1  christos cpu_exg (sim_cpu* cpu, uint8 code)
    701      1.1  christos {
    702      1.1  christos   uint8 r1, r2;
    703      1.1  christos   uint16 src1;
    704      1.1  christos   uint16 src2;
    705      1.1  christos 
    706      1.1  christos   r1 = (code >> 4) & 0x07;
    707      1.1  christos   r2 = code & 0x07;
    708      1.1  christos   if (code & 0x80)
    709      1.1  christos     {
    710      1.1  christos       src1 = cpu_get_src_reg (cpu, r1);
    711      1.1  christos       src2 = cpu_get_src_reg (cpu, r2);
    712      1.1  christos       if (r2 == 1 || r2 == 2)
    713      1.1  christos         src2 |= 0xff00;
    714      1.1  christos 
    715      1.1  christos       cpu_set_dst_reg (cpu, r2, src1);
    716      1.1  christos       cpu_set_dst_reg (cpu, r1, src2);
    717      1.1  christos     }
    718      1.1  christos   else
    719      1.1  christos     {
    720      1.1  christos       src1 = cpu_get_src_reg (cpu, r1);
    721      1.1  christos 
    722      1.1  christos       /* Sign extend the 8-bit registers (A, B, CCR).  */
    723      1.1  christos       if ((r1 == 0 || r1 == 1 || r1 == 2) && (src1 & 0x80))
    724      1.1  christos         src1 |= 0xff00;
    725      1.1  christos 
    726      1.1  christos       cpu_set_dst_reg (cpu, r2, src1);
    727      1.1  christos     }
    728      1.1  christos }
    729      1.1  christos 
    730      1.1  christos /* Handle special instructions.  */
    731      1.1  christos void
    732      1.1  christos cpu_special (sim_cpu *cpu, enum M6811_Special special)
    733      1.1  christos {
    734      1.1  christos   switch (special)
    735      1.1  christos     {
    736      1.1  christos     case M6811_RTI:
    737      1.1  christos       {
    738      1.1  christos         uint8 ccr;
    739      1.1  christos 
    740      1.1  christos         ccr = cpu_m68hc11_pop_uint8 (cpu);
    741      1.1  christos         cpu_set_ccr (cpu, ccr);
    742      1.1  christos         cpu_set_d (cpu, cpu_m68hc11_pop_uint16 (cpu));
    743      1.1  christos         cpu_set_x (cpu, cpu_m68hc11_pop_uint16 (cpu));
    744      1.1  christos         cpu_set_y (cpu, cpu_m68hc11_pop_uint16 (cpu));
    745      1.1  christos         cpu_set_pc (cpu, cpu_m68hc11_pop_uint16 (cpu));
    746      1.1  christos 	cpu_return (cpu);
    747      1.1  christos         break;
    748      1.1  christos       }
    749      1.1  christos 
    750      1.1  christos     case M6812_RTI:
    751      1.1  christos       {
    752      1.1  christos         uint8 ccr;
    753      1.1  christos 
    754      1.1  christos         ccr = cpu_m68hc12_pop_uint8 (cpu);
    755      1.1  christos         cpu_set_ccr (cpu, ccr);
    756      1.1  christos         cpu_set_d (cpu, cpu_m68hc12_pop_uint16 (cpu));
    757      1.1  christos         cpu_set_x (cpu, cpu_m68hc12_pop_uint16 (cpu));
    758      1.1  christos         cpu_set_y (cpu, cpu_m68hc12_pop_uint16 (cpu));
    759      1.1  christos         cpu_set_pc (cpu, cpu_m68hc12_pop_uint16 (cpu));
    760      1.1  christos 	cpu_return (cpu);
    761      1.1  christos         break;
    762      1.1  christos       }
    763      1.1  christos 
    764      1.1  christos     case M6811_WAI:
    765      1.1  christos       /* In the ELF-start mode, we are in a special mode where
    766      1.1  christos 	 the WAI corresponds to an exit.  */
    767      1.1  christos       if (cpu->cpu_use_elf_start)
    768      1.1  christos         {
    769      1.1  christos           cpu_set_pc (cpu, cpu->cpu_insn_pc);
    770      1.1  christos           sim_engine_halt (CPU_STATE (cpu), cpu,
    771      1.1  christos                            NULL, NULL_CIA, sim_exited,
    772      1.1  christos                            cpu_get_d (cpu));
    773      1.1  christos           return;
    774      1.1  christos         }
    775      1.1  christos       /* SCz: not correct... */
    776      1.1  christos       cpu_push_all (cpu);
    777      1.1  christos       break;
    778      1.1  christos 
    779      1.1  christos     case M6811_SWI:
    780      1.1  christos       interrupts_raise (&cpu->cpu_interrupts, M6811_INT_SWI);
    781      1.1  christos       interrupts_process (&cpu->cpu_interrupts);
    782      1.1  christos       break;
    783      1.1  christos 
    784      1.1  christos     case M6811_EMUL_SYSCALL:
    785      1.1  christos     case M6811_ILLEGAL:
    786      1.1  christos       if (cpu->cpu_emul_syscall)
    787      1.1  christos         {
    788      1.1  christos           uint8 op = memory_read8 (cpu,
    789      1.1  christos                                    cpu_get_pc (cpu) - 1);
    790      1.1  christos           if (op == 0x41)
    791      1.1  christos             {
    792      1.1  christos 	      cpu_set_pc (cpu, cpu->cpu_insn_pc);
    793      1.1  christos 	      sim_engine_halt (CPU_STATE (cpu), cpu,
    794      1.1  christos 			       NULL, NULL_CIA, sim_exited,
    795      1.1  christos 			       cpu_get_d (cpu));
    796      1.1  christos 	      return;
    797      1.1  christos             }
    798      1.1  christos           else
    799      1.1  christos             {
    800      1.1  christos               emul_os (op, cpu);
    801      1.1  christos             }
    802      1.1  christos           return;
    803      1.1  christos         }
    804      1.1  christos 
    805      1.1  christos       interrupts_raise (&cpu->cpu_interrupts, M6811_INT_ILLEGAL);
    806      1.1  christos       interrupts_process (&cpu->cpu_interrupts);
    807      1.1  christos       break;
    808      1.1  christos 
    809      1.1  christos     case M6811_TEST:
    810      1.1  christos     case M6812_BGND:
    811      1.1  christos       {
    812      1.1  christos         SIM_DESC sd;
    813      1.1  christos 
    814      1.1  christos         sd = CPU_STATE (cpu);
    815      1.1  christos 
    816      1.1  christos         /* Breakpoint instruction if we are under gdb.  */
    817      1.1  christos         if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    818      1.1  christos           {
    819      1.1  christos             cpu->cpu_regs.pc --;
    820      1.1  christos             sim_engine_halt (CPU_STATE (cpu), cpu,
    821      1.1  christos                              0, cpu_get_pc (cpu), sim_stopped,
    822      1.1  christos                              SIM_SIGTRAP);
    823      1.1  christos           }
    824      1.1  christos         /* else this is a nop but not in test factory mode.  */
    825      1.1  christos         break;
    826      1.1  christos       }
    827      1.1  christos 
    828      1.1  christos     case M6812_IDIVS:
    829      1.1  christos       {
    830      1.1  christos         int32 src1 = (int16) cpu_get_d (cpu);
    831      1.1  christos         int32 src2 = (int16) cpu_get_x (cpu);
    832      1.1  christos 
    833      1.1  christos         if (src2 == 0)
    834      1.1  christos           {
    835      1.1  christos             cpu_set_ccr_C (cpu, 1);
    836      1.1  christos           }
    837      1.1  christos         else
    838      1.1  christos           {
    839      1.1  christos             cpu_set_d (cpu, src1 % src2);
    840      1.1  christos             src1 = src1 / src2;
    841      1.1  christos             cpu_set_x (cpu, src1);
    842      1.1  christos             cpu_set_ccr_C (cpu, 0);
    843      1.1  christos             cpu_set_ccr_Z (cpu, src1 == 0);
    844      1.1  christos             cpu_set_ccr_N (cpu, src1 & 0x8000);
    845      1.1  christos             cpu_set_ccr_V (cpu, src1 >= 32768 || src1 < -32768);
    846      1.1  christos           }
    847      1.1  christos       }
    848      1.1  christos       break;
    849      1.1  christos 
    850      1.1  christos     case M6812_EDIV:
    851      1.1  christos       {
    852      1.1  christos         uint32 src1 = (uint32) cpu_get_x (cpu);
    853      1.1  christos         uint32 src2 = (uint32) (cpu_get_y (cpu) << 16)
    854      1.1  christos           | (uint32) (cpu_get_d (cpu));
    855      1.1  christos 
    856      1.1  christos         if (src1 == 0)
    857      1.1  christos           {
    858      1.1  christos             cpu_set_ccr_C (cpu, 1);
    859      1.1  christos           }
    860      1.1  christos         else
    861      1.1  christos           {
    862      1.1  christos             cpu_set_ccr_C (cpu, 0);
    863      1.1  christos             cpu_set_d (cpu, src2 % src1);
    864      1.1  christos             src2 = src2 / src1;
    865      1.1  christos             cpu_set_y (cpu, src2);
    866      1.1  christos             cpu_set_ccr_Z (cpu, src2 == 0);
    867      1.1  christos             cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0);
    868      1.1  christos             cpu_set_ccr_V (cpu, (src2 & 0xffff0000) != 0);
    869      1.1  christos           }
    870      1.1  christos       }
    871      1.1  christos       break;
    872      1.1  christos 
    873      1.1  christos     case M6812_EDIVS:
    874      1.1  christos       {
    875      1.1  christos         int32 src1 = (int16) cpu_get_x (cpu);
    876      1.1  christos         int32 src2 = (uint32) (cpu_get_y (cpu) << 16)
    877      1.1  christos           | (uint32) (cpu_get_d (cpu));
    878      1.1  christos 
    879      1.1  christos         if (src1 == 0)
    880      1.1  christos           {
    881      1.1  christos             cpu_set_ccr_C (cpu, 1);
    882      1.1  christos           }
    883      1.1  christos         else
    884      1.1  christos           {
    885      1.1  christos             cpu_set_ccr_C (cpu, 0);
    886      1.1  christos             cpu_set_d (cpu, src2 % src1);
    887      1.1  christos             src2 = src2 / src1;
    888      1.1  christos             cpu_set_y (cpu, src2);
    889      1.1  christos             cpu_set_ccr_Z (cpu, src2 == 0);
    890      1.1  christos             cpu_set_ccr_N (cpu, (src2 & 0x8000) != 0);
    891      1.1  christos             cpu_set_ccr_V (cpu, src2 > 32767 || src2 < -32768);
    892      1.1  christos           }
    893      1.1  christos       }
    894      1.1  christos       break;
    895      1.1  christos 
    896      1.1  christos     case M6812_EMULS:
    897      1.1  christos       {
    898      1.1  christos         int32 src1, src2;
    899      1.1  christos 
    900      1.1  christos         src1 = (int16) cpu_get_d (cpu);
    901      1.1  christos         src2 = (int16) cpu_get_y (cpu);
    902      1.1  christos         src1 = src1 * src2;
    903      1.1  christos         cpu_set_d (cpu, src1 & 0x0ffff);
    904      1.1  christos         cpu_set_y (cpu, src1 >> 16);
    905      1.1  christos         cpu_set_ccr_Z (cpu, src1 == 0);
    906      1.1  christos         cpu_set_ccr_N (cpu, (src1 & 0x80000000) != 0);
    907      1.1  christos         cpu_set_ccr_C (cpu, (src1 & 0x00008000) != 0);
    908      1.1  christos       }
    909      1.1  christos       break;
    910      1.1  christos 
    911      1.1  christos     case M6812_EMACS:
    912      1.1  christos       {
    913      1.1  christos         int32 src1, src2;
    914      1.1  christos         uint16 addr;
    915      1.1  christos 
    916      1.1  christos         addr = cpu_fetch16 (cpu);
    917      1.1  christos         src1 = (int16) memory_read16 (cpu, cpu_get_x (cpu));
    918      1.1  christos         src2 = (int16) memory_read16 (cpu, cpu_get_y (cpu));
    919      1.1  christos         src1 = src1 * src2;
    920      1.1  christos         src2 = (((uint32) memory_read16 (cpu, addr)) << 16)
    921      1.1  christos           | (uint32) memory_read16 (cpu, addr + 2);
    922      1.1  christos 
    923      1.1  christos         memory_write16 (cpu, addr, (src1 + src2) >> 16);
    924      1.1  christos         memory_write16 (cpu, addr + 2, (src1 + src2));
    925      1.1  christos 
    926      1.1  christos 
    927      1.1  christos       }
    928      1.1  christos       break;
    929      1.1  christos 
    930      1.1  christos     case M6812_CALL:
    931      1.1  christos       {
    932      1.1  christos         uint8 page;
    933      1.1  christos         uint16 addr;
    934      1.1  christos 
    935      1.1  christos         addr = cpu_fetch16 (cpu);
    936      1.1  christos         page = cpu_fetch8 (cpu);
    937      1.1  christos 
    938      1.1  christos         cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
    939      1.1  christos         cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
    940      1.1  christos 
    941      1.1  christos         cpu_set_page (cpu, page);
    942      1.1  christos         cpu_set_pc (cpu, addr);
    943      1.1  christos       }
    944      1.1  christos       break;
    945      1.1  christos 
    946      1.1  christos     case M6812_CALL_INDIRECT:
    947      1.1  christos       {
    948      1.1  christos         uint8 code;
    949      1.1  christos         uint16 addr;
    950      1.1  christos         uint8 page;
    951      1.1  christos 
    952      1.1  christos         code = memory_read8 (cpu, cpu_get_pc (cpu));
    953      1.1  christos         /* Indirect addressing call has the page specified in the
    954      1.1  christos            memory location pointed to by the address.  */
    955      1.1  christos         if ((code & 0xE3) == 0xE3)
    956      1.1  christos           {
    957      1.1  christos             addr = cpu_get_indexed_operand_addr (cpu, 0);
    958      1.1  christos             page = memory_read8 (cpu, addr + 2);
    959      1.1  christos             addr = memory_read16 (cpu, addr);
    960      1.1  christos           }
    961      1.1  christos         else
    962      1.1  christos           {
    963      1.1  christos             /* Otherwise, page is in the opcode.  */
    964      1.1  christos             addr = cpu_get_indexed_operand16 (cpu, 0);
    965      1.1  christos             page = cpu_fetch8 (cpu);
    966      1.1  christos           }
    967      1.1  christos         cpu_m68hc12_push_uint16 (cpu, cpu_get_pc (cpu));
    968      1.1  christos         cpu_m68hc12_push_uint8 (cpu, cpu_get_page (cpu));
    969      1.1  christos         cpu_set_page (cpu, page);
    970      1.1  christos         cpu_set_pc (cpu, addr);
    971      1.1  christos       }
    972      1.1  christos       break;
    973      1.1  christos 
    974      1.1  christos     case M6812_RTC:
    975      1.1  christos       {
    976      1.1  christos         uint8 page = cpu_m68hc12_pop_uint8 (cpu);
    977      1.1  christos         uint16 addr = cpu_m68hc12_pop_uint16 (cpu);
    978      1.1  christos 
    979      1.1  christos         cpu_set_page (cpu, page);
    980      1.1  christos         cpu_set_pc (cpu, addr);
    981      1.1  christos       }
    982      1.1  christos       break;
    983      1.1  christos 
    984      1.1  christos     case M6812_ETBL:
    985      1.1  christos     default:
    986      1.1  christos       sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
    987      1.1  christos                        cpu_get_pc (cpu), sim_stopped,
    988      1.1  christos                        SIM_SIGILL);
    989      1.1  christos       break;
    990      1.1  christos     }
    991      1.1  christos }
    992      1.1  christos 
    993      1.1  christos 
    994      1.1  christos void
    995      1.1  christos cpu_single_step (sim_cpu *cpu)
    996      1.1  christos {
    997      1.1  christos   cpu->cpu_current_cycle = 0;
    998      1.1  christos   cpu->cpu_insn_pc = cpu_get_pc (cpu);
    999      1.1  christos 
   1000      1.1  christos   /* Handle the pending interrupts.  If an interrupt is handled,
   1001      1.1  christos      treat this as an single step.  */
   1002      1.1  christos   if (interrupts_process (&cpu->cpu_interrupts))
   1003      1.1  christos     {
   1004      1.1  christos       cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
   1005      1.1  christos       return;
   1006      1.1  christos     }
   1007      1.1  christos 
   1008      1.1  christos   /*  printf("PC = 0x%04x\n", cpu_get_pc (cpu));*/
   1009      1.1  christos   cpu->cpu_interpretor (cpu);
   1010      1.1  christos   cpu->cpu_absolute_cycle += cpu->cpu_current_cycle;
   1011      1.1  christos }
   1012      1.1  christos 
   1013      1.1  christos /* VARARGS */
   1014      1.1  christos void
   1015      1.1  christos sim_memory_error (sim_cpu *cpu, SIM_SIGNAL excep,
   1016      1.1  christos 		  uint16 addr, const char *message, ...)
   1017      1.1  christos {
   1018      1.1  christos   char buf[1024];
   1019      1.1  christos   va_list args;
   1020      1.1  christos 
   1021      1.1  christos   va_start (args, message);
   1022      1.1  christos   vsprintf (buf, message, args);
   1023      1.1  christos   va_end (args);
   1024      1.1  christos 
   1025      1.1  christos   sim_io_printf (CPU_STATE (cpu), "%s\n", buf);
   1026      1.1  christos   cpu_memory_exception (cpu, excep, addr, buf);
   1027      1.1  christos }
   1028      1.1  christos 
   1029      1.1  christos 
   1030      1.1  christos void
   1031      1.1  christos cpu_memory_exception (sim_cpu *cpu, SIM_SIGNAL excep,
   1032      1.1  christos                       uint16 addr, const char *message)
   1033      1.1  christos {
   1034      1.1  christos   if (cpu->cpu_running == 0)
   1035      1.1  christos     return;
   1036      1.1  christos 
   1037      1.1  christos   cpu_set_pc (cpu, cpu->cpu_insn_pc);
   1038      1.1  christos   sim_engine_halt (CPU_STATE (cpu), cpu, NULL,
   1039      1.1  christos                    cpu_get_pc (cpu), sim_stopped, excep);
   1040      1.1  christos 
   1041      1.1  christos #if 0
   1042      1.1  christos   cpu->mem_exception = excep;
   1043      1.1  christos   cpu->fault_addr    = addr;
   1044      1.1  christos   cpu->fault_msg     = strdup (message);
   1045      1.1  christos 
   1046      1.1  christos   if (cpu->cpu_use_handler)
   1047      1.1  christos     {
   1048      1.1  christos       longjmp (&cpu->cpu_exception_handler, 1);
   1049      1.1  christos     }
   1050      1.1  christos   (* cpu->callback->printf_filtered)
   1051      1.1  christos     (cpu->callback, "Fault at 0x%04x: %s\n", addr, message);
   1052      1.1  christos #endif
   1053      1.1  christos }
   1054      1.1  christos 
   1055      1.1  christos void
   1056      1.1  christos cpu_info (SIM_DESC sd, sim_cpu *cpu)
   1057      1.1  christos {
   1058      1.1  christos   sim_io_printf (sd, "CPU info:\n");
   1059      1.1  christos   sim_io_printf (sd, "  Absolute cycle: %s\n",
   1060      1.1  christos                  cycle_to_string (cpu, cpu->cpu_absolute_cycle,
   1061      1.1  christos                                   PRINT_TIME | PRINT_CYCLE));
   1062      1.1  christos 
   1063      1.1  christos   sim_io_printf (sd, "  Syscall emulation: %s\n",
   1064      1.1  christos                  cpu->cpu_emul_syscall ? "yes, via 0xcd <n>" : "no");
   1065      1.1  christos   sim_io_printf (sd, "  Memory errors detection: %s\n",
   1066      1.1  christos                  cpu->cpu_check_memory ? "yes" : "no");
   1067      1.1  christos   sim_io_printf (sd, "  Stop on interrupt: %s\n",
   1068      1.1  christos                  cpu->cpu_stop_on_interrupt ? "yes" : "no");
   1069      1.1  christos }
   1070      1.1  christos 
   1071