static void mon_register_set_val(int mem, int reg_id, WORD val) { mos6510_regs_t *reg_ptr; if (monitor_diskspace_dnr(mem) >= 0) if (!check_drive_emu_level_ok(monitor_diskspace_dnr(mem) + 8)) return; reg_ptr = mon_interfaces[mem]->cpu_regs; switch(reg_id) { case e_A: MOS6510_REGS_SET_A(reg_ptr, (BYTE)val); break; case e_X: MOS6510_REGS_SET_X(reg_ptr, (BYTE)val); break; case e_Y: MOS6510_REGS_SET_Y(reg_ptr, (BYTE)val); break; case e_PC: MOS6510_REGS_SET_PC(reg_ptr, val); if (monitor_diskspace_dnr(mem) >= 0) mon_interfaces[mem]->set_bank_base(mon_interfaces[mem]->context); break; case e_SP: MOS6510_REGS_SET_SP(reg_ptr, (BYTE)val); break; default: log_error(LOG_ERR, "Unknown register!"); return; } force_array[mem] = 1; }
int maincpu_snapshot_read_module(snapshot_t *s) { BYTE a, x, y, sp, status; WORD pc; BYTE major, minor; snapshot_module_t *m; m = snapshot_module_open(s, snap_module_name, &major, &minor); if (m == NULL) { return -1; } /* FIXME: This is a mighty kludge to prevent VIC-II from stealing the wrong number of cycles. */ maincpu_rmw_flag = 0; /* XXX: Assumes `CLOCK' is the same size as a `DWORD'. */ if (0 || SMR_DW(m, &maincpu_clk) < 0 || SMR_B(m, &a) < 0 || SMR_B(m, &x) < 0 || SMR_B(m, &y) < 0 || SMR_B(m, &sp) < 0 || SMR_W(m, &pc) < 0 || SMR_B(m, &status) < 0 || SMR_DW_UINT(m, &last_opcode_info) < 0) { goto fail; } MOS6510_REGS_SET_A(&maincpu_regs, a); MOS6510_REGS_SET_X(&maincpu_regs, x); MOS6510_REGS_SET_Y(&maincpu_regs, y); MOS6510_REGS_SET_SP(&maincpu_regs, sp); MOS6510_REGS_SET_PC(&maincpu_regs, pc); MOS6510_REGS_SET_STATUS(&maincpu_regs, status); if (interrupt_read_snapshot(maincpu_int_status, m) < 0) { goto fail; } if (interrupt_read_new_snapshot(maincpu_int_status, m) < 0) { goto fail; } return snapshot_module_close(m); fail: if (m != NULL) { snapshot_module_close(m); } return -1; }
/* Handle a ROM trap. */ inline static DWORD drive_trap_handler(drive_context_t *drv) { if (MOS6510_REGS_GET_PC(&(drv->cpu->cpu_regs)) == (WORD)drv->drive->trap) { MOS6510_REGS_SET_PC(&(drv->cpu->cpu_regs), drv->drive->trapcont); if (drv->drive->idling_method == DRIVE_IDLE_TRAP_IDLE) { CLOCK next_clk; next_clk = alarm_context_next_pending_clk(drv->cpu->alarm_context); if (next_clk > drv->cpu->stop_clk) { next_clk = drv->cpu->stop_clk; } *(drv->clk_ptr) = next_clk; } return 0; } return (DWORD)-1; }
DWORD traps_handler(void) { traplist_t *p = traplist; unsigned int pc; int result; if (machine_class == VICE_MACHINE_C64DTV) { pc = MOS6510DTV_REGS_GET_PC(&maincpu_regs); } else if (machine_class == VICE_MACHINE_SCPU64) { /* FIXME: PBR also needed ?? */ pc = WDC65816_REGS_GET_PC(&maincpu_regs); } else { pc = MOS6510_REGS_GET_PC(&maincpu_regs); } while (p) { if (p->trap->address == pc) { /* This allows the trap function to remove traps. */ WORD resume_address = p->trap->resume_address; result = (*p->trap->func)(); if (!result) { return (p->trap->check[0] | (p->trap->check[1] << 8) | (p->trap->check[2] << 16)); } /* XXX ALERT! `p' might not be valid anymore here, because `p->trap->func()' might have removed all the traps. */ if (machine_class == VICE_MACHINE_C64DTV) { MOS6510DTV_REGS_SET_PC(&maincpu_regs, resume_address); } else { MOS6510_REGS_SET_PC(&maincpu_regs, resume_address); } return 0; } p = p->next; } return (DWORD)-1; }
void maincpu_set_pc(int pc) { MOS6510_REGS_SET_PC(&maincpu_regs, pc); }
int drivecpu_snapshot_read_module(drive_context_t *drv, snapshot_t *s) { BYTE major, minor; snapshot_module_t *m; BYTE a, x, y, sp, status; WORD pc; drivecpu_context_t *cpu; cpu = drv->cpu; m = snapshot_module_open(s, drv->cpu->snap_module_name, &major, &minor); if (m == NULL) { return -1; } /* Before we start make sure all devices are reset. */ drivecpu_reset(drv); /* XXX: Assumes `CLOCK' is the same size as a `DWORD'. */ if (0 || SMR_DW(m, drv->clk_ptr) < 0 || SMR_B(m, &a) < 0 || SMR_B(m, &x) < 0 || SMR_B(m, &y) < 0 || SMR_B(m, &sp) < 0 || SMR_W(m, &pc) < 0 || SMR_B(m, &status) < 0 || SMR_DW_UINT(m, &(cpu->last_opcode_info)) < 0 || SMR_DW(m, &(cpu->last_clk)) < 0 || SMR_DW(m, &(cpu->cycle_accum)) < 0 || SMR_DW(m, &(cpu->last_exc_cycles)) < 0 || SMR_DW(m, &(cpu->stop_clk)) < 0 ) { goto fail; } MOS6510_REGS_SET_A(&(cpu->cpu_regs), a); MOS6510_REGS_SET_X(&(cpu->cpu_regs), x); MOS6510_REGS_SET_Y(&(cpu->cpu_regs), y); MOS6510_REGS_SET_SP(&(cpu->cpu_regs), sp); MOS6510_REGS_SET_PC(&(cpu->cpu_regs), pc); MOS6510_REGS_SET_STATUS(&(cpu->cpu_regs), status); log_message(drv->drive->log, "RESET (For undump)."); interrupt_cpu_status_reset(cpu->int_status); machine_drive_reset(drv); if (interrupt_read_snapshot(cpu->int_status, m) < 0) { goto fail; } if (drv->drive->type == DRIVE_TYPE_1540 || drv->drive->type == DRIVE_TYPE_1541 || drv->drive->type == DRIVE_TYPE_1541II || drv->drive->type == DRIVE_TYPE_1551 || drv->drive->type == DRIVE_TYPE_1570 || drv->drive->type == DRIVE_TYPE_1571 || drv->drive->type == DRIVE_TYPE_1571CR || drv->drive->type == DRIVE_TYPE_2031) { if (SMR_BA(m, drv->drive->drive_ram, 0x800) < 0) { goto fail; } } if (drv->drive->type == DRIVE_TYPE_1581 || drv->drive->type == DRIVE_TYPE_2000 || drv->drive->type == DRIVE_TYPE_4000) { if (SMR_BA(m, drv->drive->drive_ram, 0x2000) < 0) { goto fail; } } if (drive_check_old(drv->drive->type)) { if (SMR_BA(m, drv->drive->drive_ram, 0x1100) < 0) { goto fail; } } /* Update `*bank_base'. */ JUMP(reg_pc); if (interrupt_read_new_snapshot(drv->cpu->int_status, m) < 0) { goto fail; } return snapshot_module_close(m); fail: if (m != NULL) { snapshot_module_close(m); } return -1; }