trunk/src/emu/devcpu.c
| r32087 | r32088 | |
| 39 | 39 | { |
| 40 | 40 | } |
| 41 | 41 | |
| 42 | | |
| 43 | | //------------------------------------------------- |
| 44 | | // legacy_cpu_device - constructor |
| 45 | | //------------------------------------------------- |
| 46 | | |
| 47 | | legacy_cpu_device::legacy_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, cpu_get_info_func get_info) |
| 48 | | : cpu_device(mconfig, type, "CPU", tag, owner, clock, "", ""), |
| 49 | | m_get_info(get_info), |
| 50 | | m_token(NULL), |
| 51 | | m_set_info(reinterpret_cast<cpu_set_info_func>(get_legacy_fct(CPUINFO_FCT_SET_INFO))), |
| 52 | | m_execute(reinterpret_cast<cpu_execute_func>(get_legacy_fct(CPUINFO_FCT_EXECUTE))), |
| 53 | | m_burn(reinterpret_cast<cpu_burn_func>(get_legacy_fct(CPUINFO_FCT_BURN))), |
| 54 | | m_translate(reinterpret_cast<cpu_translate_func>(get_legacy_fct(CPUINFO_FCT_TRANSLATE))), |
| 55 | | m_read(reinterpret_cast<cpu_read_func>(get_legacy_fct(CPUINFO_FCT_READ))), |
| 56 | | m_write(reinterpret_cast<cpu_write_func>(get_legacy_fct(CPUINFO_FCT_WRITE))), |
| 57 | | m_readop(reinterpret_cast<cpu_readop_func>(get_legacy_fct(CPUINFO_FCT_READOP))), |
| 58 | | m_disassemble(reinterpret_cast<cpu_disassemble_func>(get_legacy_fct(CPUINFO_FCT_DISASSEMBLE))), |
| 59 | | m_state_import(reinterpret_cast<cpu_state_io_func>(get_legacy_fct(CPUINFO_FCT_IMPORT_STATE))), |
| 60 | | m_state_export(reinterpret_cast<cpu_state_io_func>(get_legacy_fct(CPUINFO_FCT_EXPORT_STATE))), |
| 61 | | m_string_export(reinterpret_cast<cpu_string_io_func>(get_legacy_fct(CPUINFO_FCT_EXPORT_STRING))), |
| 62 | | m_exit(reinterpret_cast<cpu_exit_func>(get_legacy_fct(CPUINFO_FCT_EXIT))), |
| 63 | | m_using_legacy_state(false), |
| 64 | | m_inited(false) |
| 65 | | { |
| 66 | | // build up our address spaces; legacy devices don't have logical spaces |
| 67 | | memset(m_space_config, 0, sizeof(m_space_config)); |
| 68 | | for (address_spacenum spacenum = AS_0; spacenum < ARRAY_LENGTH(m_space_config); spacenum++) |
| 69 | | { |
| 70 | | m_space_config[spacenum].m_name = (spacenum == 1) ? "data" : (spacenum == 2) ? "i/o" : "program"; |
| 71 | | m_space_config[spacenum].m_endianness = static_cast<endianness_t>(get_legacy_int(CPUINFO_INT_ENDIANNESS)); |
| 72 | | m_space_config[spacenum].m_databus_width = get_legacy_int(CPUINFO_INT_DATABUS_WIDTH + spacenum); |
| 73 | | m_space_config[spacenum].m_addrbus_width = get_legacy_int(CPUINFO_INT_ADDRBUS_WIDTH + spacenum); |
| 74 | | m_space_config[spacenum].m_addrbus_shift = get_legacy_int(CPUINFO_INT_ADDRBUS_SHIFT + spacenum); |
| 75 | | m_space_config[spacenum].m_logaddr_width = get_legacy_int(CPUINFO_INT_LOGADDR_WIDTH + spacenum); |
| 76 | | if (m_space_config[spacenum].m_logaddr_width == 0) |
| 77 | | m_space_config[spacenum].m_logaddr_width = m_space_config[spacenum].m_addrbus_width; |
| 78 | | m_space_config[spacenum].m_page_shift = get_legacy_int(CPUINFO_INT_PAGE_SHIFT + spacenum); |
| 79 | | m_space_config[spacenum].m_internal_map = reinterpret_cast<address_map_constructor>(get_legacy_fct(CPUINFO_PTR_INTERNAL_MEMORY_MAP + spacenum)); |
| 80 | | m_space_config[spacenum].m_default_map = reinterpret_cast<address_map_constructor>(get_legacy_fct(CPUINFO_PTR_DEFAULT_MEMORY_MAP + spacenum)); |
| 81 | | } |
| 82 | | |
| 83 | | // set the real name |
| 84 | | m_name = get_legacy_string(CPUINFO_STR_NAME); |
| 85 | | m_shortname = get_legacy_string(CPUINFO_STR_SHORTNAME); |
| 86 | | m_source = get_legacy_string(CPUINFO_STR_SOURCE_FILE); |
| 87 | | m_searchpath = m_shortname; |
| 88 | | |
| 89 | | int tokenbytes = get_legacy_int(CPUINFO_INT_CONTEXT_SIZE); |
| 90 | | if (tokenbytes == 0) |
| 91 | | throw emu_fatalerror("Device %s specifies a 0 context size!\n", tag); |
| 92 | | |
| 93 | | // allocate memory for the token |
| 94 | | m_token = global_alloc_array_clear(UINT8, tokenbytes); |
| 95 | | // set hex or octal output |
| 96 | | m_is_octal = get_legacy_int(CPUINFO_IS_OCTAL); |
| 97 | | } |
| 98 | | |
| 99 | | |
| 100 | | //------------------------------------------------- |
| 101 | | // legacy_cpu_device - destructor |
| 102 | | //------------------------------------------------- |
| 103 | | |
| 104 | | legacy_cpu_device::~legacy_cpu_device() |
| 105 | | { |
| 106 | | global_free_array((UINT8 *)m_token); |
| 107 | | } |
| 108 | | |
| 109 | | |
| 110 | | //------------------------------------------------- |
| 111 | | // device_start - start up the device |
| 112 | | //------------------------------------------------- |
| 113 | | |
| 114 | | void legacy_cpu_device::device_start() |
| 115 | | { |
| 116 | | // standard init |
| 117 | | cpu_init_func init = reinterpret_cast<cpu_init_func>(get_legacy_fct(CPUINFO_FCT_INIT)); |
| 118 | | (*init)(this, device_irq_acknowledge_delegate(FUNC(legacy_cpu_device::standard_irq_callback_member), this)); |
| 119 | | m_inited = true; |
| 120 | | |
| 121 | | // fetch information about the CPU states |
| 122 | | if (m_state_list.count() == 0) |
| 123 | | { |
| 124 | | m_using_legacy_state = true; |
| 125 | | for (int index = 0; index < MAX_REGS; index++) |
| 126 | | { |
| 127 | | const char *string = get_legacy_string(CPUINFO_STR_REGISTER + index); |
| 128 | | if (strchr(string, ':') != NULL) |
| 129 | | { |
| 130 | | astring tempstr(string); |
| 131 | | bool noshow = (tempstr.chr(0, '~') == 0); |
| 132 | | if (noshow) |
| 133 | | tempstr.substr(1, -1); |
| 134 | | |
| 135 | | int colon = tempstr.chr(0, ':'); |
| 136 | | int length = tempstr.len() - colon - 1; |
| 137 | | |
| 138 | | tempstr.substr(0, colon).trimspace(); |
| 139 | | |
| 140 | | astring formatstr; |
| 141 | | formatstr.printf("%%%ds", length); |
| 142 | | device_state_entry &entry = state_add(index, tempstr, m_state_io).callimport().callexport().formatstr(formatstr); |
| 143 | | if (noshow) |
| 144 | | entry.noshow(); |
| 145 | | } |
| 146 | | } |
| 147 | | state_add(STATE_GENPC, "curpc", m_state_io).callimport().callexport().formatstr("%8s").noshow(); |
| 148 | | state_add(STATE_GENPCBASE, "curpcbase", m_state_io).callimport().callexport().formatstr("%8s").noshow(); |
| 149 | | |
| 150 | | const char *string = get_legacy_string(CPUINFO_STR_FLAGS); |
| 151 | | if (string != NULL && string[0] != 0) |
| 152 | | { |
| 153 | | astring flagstr; |
| 154 | | flagstr.printf("%%%"SIZETFMT"s", strlen(string)); |
| 155 | | state_add(STATE_GENFLAGS, "GENFLAGS", m_state_io).callimport().callexport().formatstr(flagstr).noshow(); |
| 156 | | } |
| 157 | | } |
| 158 | | |
| 159 | | // get our icount pointer |
| 160 | | m_icountptr = reinterpret_cast<int *>(get_legacy_ptr(CPUINFO_PTR_INSTRUCTION_COUNTER)); |
| 161 | | assert(m_icountptr != 0); |
| 162 | | *m_icountptr = 0; |
| 163 | | } |
| 164 | | |
| 165 | | |
| 166 | | //------------------------------------------------- |
| 167 | | // device_reset - reset up the device |
| 168 | | //------------------------------------------------- |
| 169 | | |
| 170 | | void legacy_cpu_device::device_reset() |
| 171 | | { |
| 172 | | cpu_reset_func reset = reinterpret_cast<cpu_reset_func>(get_legacy_fct(CPUINFO_FCT_RESET)); |
| 173 | | if (reset != NULL) |
| 174 | | (*reset)(this); |
| 175 | | } |
| 176 | | |
| 177 | | |
| 178 | | //------------------------------------------------- |
| 179 | | // device_stop - clean up before the machine goes |
| 180 | | // away |
| 181 | | //------------------------------------------------- |
| 182 | | |
| 183 | | void legacy_cpu_device::device_stop() |
| 184 | | { |
| 185 | | // call the CPU's exit function if present |
| 186 | | if (m_inited && m_exit != NULL) |
| 187 | | (*m_exit)(this); |
| 188 | | } |
| 189 | | |
| 190 | | |
| 191 | | //------------------------------------------------- |
| 192 | | // execute_clocks_to_cycles - convert the raw |
| 193 | | // clock into cycles per second |
| 194 | | //------------------------------------------------- |
| 195 | | |
| 196 | | UINT64 legacy_cpu_device::execute_clocks_to_cycles(UINT64 clocks) const |
| 197 | | { |
| 198 | | UINT32 multiplier = get_legacy_int(CPUINFO_INT_CLOCK_MULTIPLIER); |
| 199 | | UINT32 divider = get_legacy_int(CPUINFO_INT_CLOCK_DIVIDER); |
| 200 | | |
| 201 | | if (multiplier == 0) multiplier = 1; |
| 202 | | if (divider == 0) divider = 1; |
| 203 | | |
| 204 | | return (clocks * multiplier + divider - 1) / divider; |
| 205 | | } |
| 206 | | |
| 207 | | |
| 208 | | //------------------------------------------------- |
| 209 | | // execute_cycles_to_clocks - convert a cycle |
| 210 | | // count back to raw clocks |
| 211 | | //------------------------------------------------- |
| 212 | | |
| 213 | | UINT64 legacy_cpu_device::execute_cycles_to_clocks(UINT64 cycles) const |
| 214 | | { |
| 215 | | UINT32 multiplier = get_legacy_int(CPUINFO_INT_CLOCK_MULTIPLIER); |
| 216 | | UINT32 divider = get_legacy_int(CPUINFO_INT_CLOCK_DIVIDER); |
| 217 | | |
| 218 | | if (multiplier == 0) multiplier = 1; |
| 219 | | if (divider == 0) divider = 1; |
| 220 | | |
| 221 | | return (cycles * divider + multiplier - 1) / multiplier; |
| 222 | | } |
| 223 | | |
| 224 | | |
| 225 | | //------------------------------------------------- |
| 226 | | // execute_run - execute for the provided number |
| 227 | | // of cycles |
| 228 | | //------------------------------------------------- |
| 229 | | |
| 230 | | void legacy_cpu_device::execute_run() |
| 231 | | { |
| 232 | | (*m_execute)(this); |
| 233 | | } |
| 234 | | |
| 235 | | |
| 236 | | //------------------------------------------------- |
| 237 | | // execute_burn - burn the requested number of cycles |
| 238 | | //------------------------------------------------- |
| 239 | | |
| 240 | | void legacy_cpu_device::execute_burn(INT32 cycles) |
| 241 | | { |
| 242 | | if (m_burn != NULL) |
| 243 | | (*m_burn)(this, cycles); |
| 244 | | } |
| 245 | | |
| 246 | | |
| 247 | | //------------------------------------------------- |
| 248 | | // memory_translate - perform address translation |
| 249 | | // on the provided address |
| 250 | | //------------------------------------------------- |
| 251 | | |
| 252 | | bool legacy_cpu_device::memory_translate(address_spacenum spacenum, int intention, offs_t &address) |
| 253 | | { |
| 254 | | if (m_translate != NULL) |
| 255 | | return (*m_translate)(this, spacenum, intention, &address) ? true : false; |
| 256 | | return true; |
| 257 | | } |
| 258 | | |
| 259 | | |
| 260 | | //------------------------------------------------- |
| 261 | | // memory_read - read device memory, allowing for |
| 262 | | // device specific overrides |
| 263 | | //------------------------------------------------- |
| 264 | | |
| 265 | | bool legacy_cpu_device::memory_read(address_spacenum spacenum, offs_t offset, int size, UINT64 &value) |
| 266 | | { |
| 267 | | if (m_read != NULL) |
| 268 | | return (*m_read)(this, spacenum, offset, size, &value) ? true : false; |
| 269 | | return false; |
| 270 | | } |
| 271 | | |
| 272 | | |
| 273 | | //------------------------------------------------- |
| 274 | | // memory_write - write device memory, allowing |
| 275 | | // for device specific overrides |
| 276 | | //------------------------------------------------- |
| 277 | | |
| 278 | | bool legacy_cpu_device::memory_write(address_spacenum spacenum, offs_t offset, int size, UINT64 value) |
| 279 | | { |
| 280 | | if (m_write != NULL) |
| 281 | | return (*m_write)(this, spacenum, offset, size, value) ? true : false; |
| 282 | | return false; |
| 283 | | } |
| 284 | | |
| 285 | | |
| 286 | | //------------------------------------------------- |
| 287 | | // memory_read - read device opcode memory, |
| 288 | | // allowing for device specific overrides |
| 289 | | //------------------------------------------------- |
| 290 | | |
| 291 | | bool legacy_cpu_device::memory_readop(offs_t offset, int size, UINT64 &value) |
| 292 | | { |
| 293 | | if (m_readop != NULL) |
| 294 | | return (*m_readop)(this, offset, size, &value) ? true : false; |
| 295 | | return false; |
| 296 | | } |
| 297 | | |
| 298 | | |
| 299 | | //------------------------------------------------- |
| 300 | | // debug_setup - set up any device-specific |
| 301 | | // debugging commands or state |
| 302 | | //------------------------------------------------- |
| 303 | | |
| 304 | | void legacy_cpu_device::device_debug_setup() |
| 305 | | { |
| 306 | | cpu_debug_init_func init = reinterpret_cast<cpu_debug_init_func>(get_legacy_fct(CPUINFO_FCT_DEBUG_INIT)); |
| 307 | | if (init != NULL) |
| 308 | | (*init)(this); |
| 309 | | } |
| 310 | | |
| 311 | | |
| 312 | | //------------------------------------------------- |
| 313 | | // disassemble - disassemble the provided opcode |
| 314 | | // data to a buffer |
| 315 | | //------------------------------------------------- |
| 316 | | |
| 317 | | offs_t legacy_cpu_device::disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options) |
| 318 | | { |
| 319 | | // if we have a callback, just use that |
| 320 | | if (m_disassemble != NULL) |
| 321 | | return (*m_disassemble)(this, buffer, pc, oprom, opram, options); |
| 322 | | |
| 323 | | // if not, just output vanilla bytes |
| 324 | | int width = min_opcode_bytes(); |
| 325 | | switch (width) |
| 326 | | { |
| 327 | | case 1: |
| 328 | | default: |
| 329 | | sprintf(buffer, "$%02X", *(UINT8 *)oprom); |
| 330 | | break; |
| 331 | | |
| 332 | | case 2: |
| 333 | | sprintf(buffer, "$%04X", *(UINT16 *)oprom); |
| 334 | | break; |
| 335 | | |
| 336 | | case 4: |
| 337 | | sprintf(buffer, "$%08X", *(UINT32 *)oprom); |
| 338 | | break; |
| 339 | | |
| 340 | | case 8: |
| 341 | | sprintf(buffer, "$%08X%08X", (UINT32)(*(UINT64 *)oprom >> 32), (UINT32)(*(UINT64 *)oprom >> 0)); |
| 342 | | break; |
| 343 | | } |
| 344 | | return width; |
| 345 | | } |
| 346 | | |
| 347 | | |
| 348 | | //------------------------------------------------- |
| 349 | | // get_legacy_int - return a legacy integer value |
| 350 | | //------------------------------------------------- |
| 351 | | |
| 352 | | INT64 legacy_cpu_device::get_legacy_int(UINT32 state) const |
| 353 | | { |
| 354 | | cpuinfo info = { 0 }; |
| 355 | | (*m_get_info)(const_cast<legacy_cpu_device *>(this), state, &info); |
| 356 | | return info.i; |
| 357 | | } |
| 358 | | |
| 359 | | |
| 360 | | //------------------------------------------------- |
| 361 | | // get_legacy_ptr - return a legacy pointer value |
| 362 | | //------------------------------------------------- |
| 363 | | |
| 364 | | void *legacy_cpu_device::get_legacy_ptr(UINT32 state) const |
| 365 | | { |
| 366 | | cpuinfo info = { 0 }; |
| 367 | | (*m_get_info)(const_cast<legacy_cpu_device *>(this), state, &info); |
| 368 | | return info.p; |
| 369 | | } |
| 370 | | |
| 371 | | |
| 372 | | //------------------------------------------------- |
| 373 | | // get_legacy_fct - return a legacy function value |
| 374 | | //------------------------------------------------- |
| 375 | | |
| 376 | | genf *legacy_cpu_device::get_legacy_fct(UINT32 state) const |
| 377 | | { |
| 378 | | cpuinfo info = { 0 }; |
| 379 | | (*m_get_info)(const_cast<legacy_cpu_device *>(this), state, &info); |
| 380 | | return info.f; |
| 381 | | } |
| 382 | | |
| 383 | | |
| 384 | | //------------------------------------------------- |
| 385 | | // get_legacy_string - return a legacy |
| 386 | | // string value |
| 387 | | //------------------------------------------------- |
| 388 | | extern char *get_temp_string_buffer(void); |
| 389 | | |
| 390 | | const char *legacy_cpu_device::get_legacy_string(UINT32 state) const |
| 391 | | { |
| 392 | | cpuinfo info; |
| 393 | | info.s = get_temp_string_buffer(); |
| 394 | | (*m_get_info)(const_cast<legacy_cpu_device *>(this), state, &info); |
| 395 | | return info.s; |
| 396 | | } |
| 397 | | |
| 398 | | |
| 399 | | //------------------------------------------------- |
| 400 | | // set_legacy_int - call the get info function |
| 401 | | // to set an integer value |
| 402 | | //------------------------------------------------- |
| 403 | | |
| 404 | | void legacy_cpu_device::set_legacy_int(UINT32 state, INT64 value) |
| 405 | | { |
| 406 | | cpuinfo info = { 0 }; |
| 407 | | info.i = value; |
| 408 | | (*m_set_info)(this, state, &info); |
| 409 | | } |
| 410 | | |
| 411 | | |
| 412 | | |
| 413 | | void legacy_cpu_device::state_import(const device_state_entry &entry) |
| 414 | | { |
| 415 | | if (m_using_legacy_state) |
| 416 | | { |
| 417 | | if (entry.index() == STATE_GENFLAGS) |
| 418 | | ; // do nothing |
| 419 | | else |
| 420 | | set_legacy_int(CPUINFO_INT_REGISTER + entry.index(), m_state_io); |
| 421 | | } |
| 422 | | else if (m_state_import != NULL) |
| 423 | | (*m_state_import)(this, entry); |
| 424 | | } |
| 425 | | |
| 426 | | |
| 427 | | void legacy_cpu_device::state_export(const device_state_entry &entry) |
| 428 | | { |
| 429 | | if (m_using_legacy_state) |
| 430 | | { |
| 431 | | if (entry.index() == STATE_GENFLAGS) |
| 432 | | { |
| 433 | | const char *temp = get_legacy_string(CPUINFO_STR_FLAGS); |
| 434 | | m_state_io = 0; |
| 435 | | while (*temp != 0) |
| 436 | | m_state_io = ((m_state_io << 5) | (m_state_io >> (64-5))) ^ *temp++; |
| 437 | | } |
| 438 | | else |
| 439 | | m_state_io = get_legacy_int(CPUINFO_INT_REGISTER + entry.index()); |
| 440 | | } |
| 441 | | else if (m_state_export != NULL) |
| 442 | | (*m_state_export)(this, entry); |
| 443 | | } |
| 444 | | |
| 445 | | |
| 446 | | void legacy_cpu_device::state_string_export(const device_state_entry &entry, astring &string) |
| 447 | | { |
| 448 | | if (m_using_legacy_state) |
| 449 | | { |
| 450 | | if (entry.index() == STATE_GENFLAGS) |
| 451 | | string.cpy(get_legacy_string(CPUINFO_STR_FLAGS)); |
| 452 | | else |
| 453 | | string.cpy(strchr(get_legacy_string(CPUINFO_STR_REGISTER + entry.index()), ':') + 1); |
| 454 | | } |
| 455 | | else if (m_string_export != NULL) |
| 456 | | (*m_string_export)(this, entry, string); |
| 457 | | } |
trunk/src/emu/devcpu.h
| r32087 | r32088 | |
| 29 | 29 | { |
| 30 | 30 | // --- the following bits of info are returned as 64-bit signed integers --- |
| 31 | 31 | CPUINFO_INT_FIRST = 0x00000, |
| 32 | | CPUINFO_INT_ENDIANNESS = CPUINFO_INT_FIRST, // R/O: either ENDIANNESS_BIG or ENDIANNESS_LITTLE |
| 33 | | CPUINFO_INT_DATABUS_WIDTH, // R/O: data bus size for each address space (8,16,32,64) |
| 34 | | CPUINFO_INT_DATABUS_WIDTH_0 = CPUINFO_INT_DATABUS_WIDTH + 0, |
| 35 | | CPUINFO_INT_DATABUS_WIDTH_1 = CPUINFO_INT_DATABUS_WIDTH + 1, |
| 36 | | CPUINFO_INT_DATABUS_WIDTH_2 = CPUINFO_INT_DATABUS_WIDTH + 2, |
| 37 | | CPUINFO_INT_DATABUS_WIDTH_3 = CPUINFO_INT_DATABUS_WIDTH + 3, |
| 38 | | CPUINFO_INT_DATABUS_WIDTH_LAST = CPUINFO_INT_DATABUS_WIDTH + ADDRESS_SPACES - 1, |
| 39 | | CPUINFO_INT_ADDRBUS_WIDTH, // R/O: address bus size for each address space (12-32) |
| 40 | | CPUINFO_INT_ADDRBUS_WIDTH_0 = CPUINFO_INT_ADDRBUS_WIDTH + 0, |
| 41 | | CPUINFO_INT_ADDRBUS_WIDTH_1 = CPUINFO_INT_ADDRBUS_WIDTH + 1, |
| 42 | | CPUINFO_INT_ADDRBUS_WIDTH_2 = CPUINFO_INT_ADDRBUS_WIDTH + 2, |
| 43 | | CPUINFO_INT_ADDRBUS_WIDTH_3 = CPUINFO_INT_ADDRBUS_WIDTH + 3, |
| 44 | | CPUINFO_INT_ADDRBUS_WIDTH_LAST = CPUINFO_INT_ADDRBUS_WIDTH + ADDRESS_SPACES - 1, |
| 45 | | CPUINFO_INT_ADDRBUS_SHIFT, // R/O: shift applied to addresses each address space (+3 means >>3, -1 means <<1) |
| 46 | | CPUINFO_INT_ADDRBUS_SHIFT_0 = CPUINFO_INT_ADDRBUS_SHIFT + 0, |
| 47 | | CPUINFO_INT_ADDRBUS_SHIFT_1 = CPUINFO_INT_ADDRBUS_SHIFT + 1, |
| 48 | | CPUINFO_INT_ADDRBUS_SHIFT_2 = CPUINFO_INT_ADDRBUS_SHIFT + 2, |
| 49 | | CPUINFO_INT_ADDRBUS_SHIFT_3 = CPUINFO_INT_ADDRBUS_SHIFT + 3, |
| 50 | | CPUINFO_INT_ADDRBUS_SHIFT_LAST = CPUINFO_INT_ADDRBUS_SHIFT + ADDRESS_SPACES - 1, |
| 51 | 32 | |
| 52 | | // CPU-specific additionsg |
| 53 | | CPUINFO_INT_CONTEXT_SIZE = 0x04000, // R/O: size of CPU context in bytes |
| 54 | | CPUINFO_INT_INPUT_LINES, // R/O: number of input lines |
| 55 | | CPUINFO_INT_DEFAULT_IRQ_VECTOR, // R/O: default IRQ vector |
| 56 | | CPUINFO_INT_CLOCK_MULTIPLIER, // R/O: internal clock multiplier |
| 57 | | CPUINFO_INT_CLOCK_DIVIDER, // R/O: internal clock divider |
| 58 | | CPUINFO_INT_MIN_INSTRUCTION_BYTES, // R/O: minimum bytes per instruction |
| 59 | | CPUINFO_INT_MAX_INSTRUCTION_BYTES, // R/O: maximum bytes per instruction |
| 60 | | CPUINFO_INT_MIN_CYCLES, // R/O: minimum cycles for a single instruction |
| 61 | | CPUINFO_INT_MAX_CYCLES, // R/O: maximum cycles for a single instruction |
| 62 | | |
| 63 | | CPUINFO_INT_LOGADDR_WIDTH, // R/O: address bus size for logical accesses in each space (0=same as physical) |
| 64 | | CPUINFO_INT_LOGADDR_WIDTH_PROGRAM = CPUINFO_INT_LOGADDR_WIDTH + AS_PROGRAM, |
| 65 | | CPUINFO_INT_LOGADDR_WIDTH_DATA = CPUINFO_INT_LOGADDR_WIDTH + AS_DATA, |
| 66 | | CPUINFO_INT_LOGADDR_WIDTH_IO = CPUINFO_INT_LOGADDR_WIDTH + AS_IO, |
| 67 | | CPUINFO_INT_LOGADDR_WIDTH_LAST = CPUINFO_INT_LOGADDR_WIDTH + ADDRESS_SPACES - 1, |
| 68 | | CPUINFO_INT_PAGE_SHIFT, // R/O: size of a page log 2 (i.e., 12=4096), or 0 if paging not supported |
| 69 | | CPUINFO_INT_PAGE_SHIFT_PROGRAM = CPUINFO_INT_PAGE_SHIFT + AS_PROGRAM, |
| 70 | | CPUINFO_INT_PAGE_SHIFT_DATA = CPUINFO_INT_PAGE_SHIFT + AS_DATA, |
| 71 | | CPUINFO_INT_PAGE_SHIFT_IO = CPUINFO_INT_PAGE_SHIFT + AS_IO, |
| 72 | | CPUINFO_INT_PAGE_SHIFT_LAST = CPUINFO_INT_PAGE_SHIFT + ADDRESS_SPACES - 1, |
| 73 | | |
| 74 | | CPUINFO_INT_INPUT_STATE, // R/W: states for each input line |
| 75 | | CPUINFO_INT_INPUT_STATE_LAST = CPUINFO_INT_INPUT_STATE + MAX_INPUT_LINES - 1, |
| 76 | | CPUINFO_INT_REGISTER = CPUINFO_INT_INPUT_STATE_LAST + 10, // R/W: values of up to MAX_REGs registers |
| 77 | | CPUINFO_INT_SP = CPUINFO_INT_REGISTER + STATE_GENSP, // R/W: the current stack pointer value |
| 78 | | CPUINFO_INT_PC = CPUINFO_INT_REGISTER + STATE_GENPC, // R/W: the current PC value |
| 79 | | CPUINFO_INT_PREVIOUSPC = CPUINFO_INT_REGISTER + STATE_GENPCBASE, // R/W: the previous PC value |
| 80 | | |
| 81 | | CPUINFO_IS_OCTAL = CPUINFO_INT_REGISTER + MAX_REGS - 2, // R/O: determine if default is octal or hexadecimal |
| 82 | | |
| 83 | | CPUINFO_INT_REGISTER_LAST = CPUINFO_INT_REGISTER + MAX_REGS - 1, |
| 84 | | |
| 85 | 33 | CPUINFO_INT_CPU_SPECIFIC = 0x08000, // R/W: CPU-specific values start here |
| 86 | 34 | |
| 87 | 35 | // --- the following bits of info are returned as pointers to data or functions --- |
| 88 | 36 | CPUINFO_PTR_FIRST = 0x10000, |
| 89 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP = CPUINFO_PTR_FIRST, // R/O: address_map_constructor map |
| 90 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP_0 = CPUINFO_PTR_INTERNAL_MEMORY_MAP + 0, |
| 91 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP_1 = CPUINFO_PTR_INTERNAL_MEMORY_MAP + 1, |
| 92 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP_2 = CPUINFO_PTR_INTERNAL_MEMORY_MAP + 2, |
| 93 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP_3 = CPUINFO_PTR_INTERNAL_MEMORY_MAP + 3, |
| 94 | | CPUINFO_PTR_INTERNAL_MEMORY_MAP_LAST = CPUINFO_PTR_INTERNAL_MEMORY_MAP + ADDRESS_SPACES - 1, |
| 95 | 37 | |
| 96 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP, // R/O: address_map_constructor map |
| 97 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP_0 = CPUINFO_PTR_DEFAULT_MEMORY_MAP + 0, |
| 98 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP_1 = CPUINFO_PTR_DEFAULT_MEMORY_MAP + 1, |
| 99 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP_2 = CPUINFO_PTR_DEFAULT_MEMORY_MAP + 2, |
| 100 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP_3 = CPUINFO_PTR_DEFAULT_MEMORY_MAP + 3, |
| 101 | | CPUINFO_PTR_DEFAULT_MEMORY_MAP_LAST = CPUINFO_PTR_DEFAULT_MEMORY_MAP + ADDRESS_SPACES - 1, |
| 102 | | |
| 103 | 38 | // CPU-specific additions |
| 104 | 39 | CPUINFO_PTR_INSTRUCTION_COUNTER = 0x14000, |
| 105 | 40 | // R/O: int *icount |
| r32087 | r32088 | |
| 109 | 44 | // --- the following bits of info are returned as pointers to functions --- |
| 110 | 45 | CPUINFO_FCT_FIRST = 0x20000, |
| 111 | 46 | |
| 112 | | // CPU-specific additions |
| 113 | | CPUINFO_FCT_SET_INFO = 0x24000, // R/O: void (*set_info)(legacy_cpu_device *device, UINT32 state, INT64 data, void *ptr) |
| 114 | | CPUINFO_FCT_INIT, // R/O: void (*init)(legacy_cpu_device *device, int index, int clock, int (*irqcallback)(legacy_cpu_device *device, int)) |
| 115 | | CPUINFO_FCT_RESET, // R/O: void (*reset)(legacy_cpu_device *device) |
| 116 | | CPUINFO_FCT_EXIT, // R/O: void (*exit)(legacy_cpu_device *device) |
| 117 | | CPUINFO_FCT_EXECUTE, // R/O: int (*execute)(legacy_cpu_device *device, int cycles) |
| 118 | | CPUINFO_FCT_BURN, // R/O: void (*burn)(legacy_cpu_device *device, int cycles) |
| 119 | | CPUINFO_FCT_DISASSEMBLE, // R/O: offs_t (*disassemble)(cpu_device *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, int options) |
| 120 | | CPUINFO_FCT_TRANSLATE, // R/O: int (*translate)(legacy_cpu_device *device, address_spacenum space, int intention, offs_t *address) |
| 121 | | CPUINFO_FCT_READ, // R/O: int (*read)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 *value) |
| 122 | | CPUINFO_FCT_WRITE, // R/O: int (*write)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 value) |
| 123 | | CPUINFO_FCT_READOP, // R/O: int (*readop)(legacy_cpu_device *device, UINT32 offset, int size, UINT64 *value) |
| 124 | | CPUINFO_FCT_DEBUG_INIT, // R/O: void (*debug_init)(legacy_cpu_device *device) |
| 125 | | CPUINFO_FCT_IMPORT_STATE, // R/O: void (*import_state)(legacy_cpu_device *device, const device_state_entry &entry) |
| 126 | | CPUINFO_FCT_EXPORT_STATE, // R/O: void (*export_state)(legacy_cpu_device *device, const device_state_entry &entry) |
| 127 | | CPUINFO_FCT_IMPORT_STRING, // R/O: void (*import_string)(legacy_cpu_device *device, const device_state_entry &entry, astring &string) |
| 128 | | CPUINFO_FCT_EXPORT_STRING, // R/O: void (*export_string)(legacy_cpu_device *device, const device_state_entry &entry, astring &string) |
| 129 | | |
| 130 | 47 | CPUINFO_FCT_CPU_SPECIFIC = 0x28000, // R/W: CPU-specific values start here |
| 131 | 48 | |
| 132 | 49 | // --- the following bits of info are returned as NULL-terminated strings --- |
| 133 | 50 | CPUINFO_STR_FIRST = 0x30000, |
| 134 | | CPUINFO_STR_NAME = CPUINFO_STR_FIRST, // R/O: name of the device |
| 135 | | CPUINFO_STR_SHORTNAME, // R/O: search path of device, used for media loading |
| 136 | | CPUINFO_STR_FAMILY, // R/O: family of the device |
| 137 | | CPUINFO_STR_VERSION, // R/O: version of the device |
| 138 | | CPUINFO_STR_SOURCE_FILE, // R/O: file containing the device implementation |
| 139 | | CPUINFO_STR_CREDITS, // R/O: credits for the device implementation |
| 140 | | // CPU-specific additions |
| 141 | | CPUINFO_STR_REGISTER = 0x34000 + 10, // R/O: string representation of up to MAX_REGs registers |
| 142 | | CPUINFO_STR_FLAGS = CPUINFO_STR_REGISTER + STATE_GENFLAGS, // R/O: string representation of the main flags value |
| 143 | | CPUINFO_STR_REGISTER_LAST = CPUINFO_STR_REGISTER + MAX_REGS - 1, |
| 144 | 51 | |
| 145 | 52 | CPUINFO_STR_CPU_SPECIFIC = 0x38000 // R/W: CPU-specific values start here |
| 146 | 53 | }; |
| r32087 | r32088 | |
| 176 | 83 | // MACROS |
| 177 | 84 | //************************************************************************** |
| 178 | 85 | |
| 179 | | // macro for defining the implementation needed for configuration and device classes |
| 180 | | #define DEFINE_LEGACY_CPU_DEVICE(name, basename) \ |
| 181 | | \ |
| 182 | | basename##_device::basename##_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock) \ |
| 183 | | : legacy_cpu_device(mconfig, type, tag, owner, clock, CPU_GET_INFO_NAME(basename)) \ |
| 184 | | { \ |
| 185 | | } \ |
| 186 | | \ |
| 187 | | const device_type name = &legacy_device_creator<basename##_device> |
| 188 | | |
| 189 | | |
| 190 | | |
| 191 | | // CPU interface functions |
| 192 | | #define CPU_GET_INFO_NAME(name) cpu_get_info_##name |
| 193 | | #define CPU_GET_INFO(name) void CPU_GET_INFO_NAME(name)(legacy_cpu_device *device, UINT32 state, cpuinfo *info) |
| 194 | | #define CPU_GET_INFO_CALL(name) CPU_GET_INFO_NAME(name)(device, state, info) |
| 195 | | |
| 196 | | #define CPU_SET_INFO_NAME(name) cpu_set_info_##name |
| 197 | | #define CPU_SET_INFO(name) void CPU_SET_INFO_NAME(name)(legacy_cpu_device *device, UINT32 state, cpuinfo *info) |
| 198 | | #define CPU_SET_INFO_CALL(name) CPU_SET_INFO_NAME(name)(device, state, info) |
| 199 | | |
| 200 | | #define CPU_INIT_NAME(name) cpu_init_##name |
| 201 | | #define CPU_INIT(name) void CPU_INIT_NAME(name)(legacy_cpu_device *device, device_irq_acknowledge_delegate irqcallback) |
| 202 | | #define CPU_INIT_CALL(name) CPU_INIT_NAME(name)(device, irqcallback) |
| 203 | | |
| 204 | | #define CPU_RESET_NAME(name) cpu_reset_##name |
| 205 | | #define CPU_RESET(name) void CPU_RESET_NAME(name)(legacy_cpu_device *device) |
| 206 | | #define CPU_RESET_CALL(name) CPU_RESET_NAME(name)(device) |
| 207 | | |
| 208 | | #define CPU_EXIT_NAME(name) cpu_exit_##name |
| 209 | | #define CPU_EXIT(name) void CPU_EXIT_NAME(name)(legacy_cpu_device *device) |
| 210 | | #define CPU_EXIT_CALL(name) CPU_EXIT_NAME(name)(device) |
| 211 | | |
| 212 | | #define CPU_EXECUTE_NAME(name) cpu_execute_##name |
| 213 | | #define CPU_EXECUTE(name) void CPU_EXECUTE_NAME(name)(legacy_cpu_device *device) |
| 214 | | #define CPU_EXECUTE_CALL(name) CPU_EXECUTE_NAME(name)(device, cycles) |
| 215 | | |
| 216 | | #define CPU_BURN_NAME(name) cpu_burn_##name |
| 217 | | #define CPU_BURN(name) void CPU_BURN_NAME(name)(legacy_cpu_device *device, int cycles) |
| 218 | | #define CPU_BURN_CALL(name) CPU_BURN_NAME(name)(device, cycles) |
| 219 | | |
| 220 | | #define CPU_TRANSLATE_NAME(name) cpu_translate_##name |
| 221 | | #define CPU_TRANSLATE(name) int CPU_TRANSLATE_NAME(name)(legacy_cpu_device *device, address_spacenum space, int intention, offs_t *address) |
| 222 | | #define CPU_TRANSLATE_CALL(name) CPU_TRANSLATE_NAME(name)(device, space, intention, address) |
| 223 | | |
| 224 | | #define CPU_READ_NAME(name) cpu_read_##name |
| 225 | | #define CPU_READ(name) int CPU_READ_NAME(name)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 *value) |
| 226 | | #define CPU_READ_CALL(name) CPU_READ_NAME(name)(device, space, offset, size, value) |
| 227 | | |
| 228 | | #define CPU_WRITE_NAME(name) cpu_write_##name |
| 229 | | #define CPU_WRITE(name) int CPU_WRITE_NAME(name)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 value) |
| 230 | | #define CPU_WRITE_CALL(name) CPU_WRITE_NAME(name)(device, space, offset, size, value) |
| 231 | | |
| 232 | | #define CPU_READOP_NAME(name) cpu_readop_##name |
| 233 | | #define CPU_READOP(name) int CPU_READOP_NAME(name)(legacy_cpu_device *device, UINT32 offset, int size, UINT64 *value) |
| 234 | | #define CPU_READOP_CALL(name) CPU_READOP_NAME(name)(device, offset, size, value) |
| 235 | | |
| 236 | | #define CPU_DEBUG_INIT_NAME(name) cpu_debug_init_##name |
| 237 | | #define CPU_DEBUG_INIT(name) void CPU_DEBUG_INIT_NAME(name)(legacy_cpu_device *device) |
| 238 | | #define CPU_DEBUG_INIT_CALL(name) CPU_DEBUG_INIT_NAME(name)(device) |
| 239 | | |
| 240 | 86 | #define CPU_DISASSEMBLE_NAME(name) cpu_disassemble_##name |
| 241 | 87 | #define CPU_DISASSEMBLE(name) offs_t CPU_DISASSEMBLE_NAME(name)(cpu_device *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, int options) |
| 242 | 88 | #define CPU_DISASSEMBLE_CALL(name) CPU_DISASSEMBLE_NAME(name)(device, buffer, pc, oprom, opram, options) |
| 243 | 89 | |
| 244 | | #define CPU_IMPORT_STATE_NAME(name) cpu_state_import_##name |
| 245 | | #define CPU_IMPORT_STATE(name) void CPU_IMPORT_STATE_NAME(name)(legacy_cpu_device *device, const device_state_entry &entry) |
| 246 | | #define CPU_IMPORT_STATE_CALL(name) CPU_IMPORT_STATE_NAME(name)(device, entry) |
| 247 | 90 | |
| 248 | | #define CPU_EXPORT_STATE_NAME(name) cpu_state_export_##name |
| 249 | | #define CPU_EXPORT_STATE(name) void CPU_EXPORT_STATE_NAME(name)(legacy_cpu_device *device, const device_state_entry &entry) |
| 250 | | #define CPU_EXPORT_STATE_CALL(name) CPU_EXPORT_STATE_NAME(name)(device, entry) |
| 251 | | |
| 252 | | #define CPU_EXPORT_STRING_NAME(name) cpu_string_export_##name |
| 253 | | #define CPU_EXPORT_STRING(name) void CPU_EXPORT_STRING_NAME(name)(legacy_cpu_device *device, const device_state_entry &entry, astring &string) |
| 254 | | #define CPU_EXPORT_STRING_CALL(name) CPU_EXPORT_STRING_NAME(name)(device, entry, string) |
| 255 | | |
| 256 | | |
| 257 | | // this template function creates a stub which constructs a device |
| 258 | | template<class _DeviceClass> |
| 259 | | device_t *legacy_device_creator(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 260 | | { |
| 261 | | return global_alloc(_DeviceClass(mconfig, &legacy_device_creator<_DeviceClass>, tag, owner, clock)); |
| 262 | | } |
| 263 | | |
| 264 | | // this template function creates a stub which constructs a device |
| 265 | | template<class _DeviceClass1,class _DeviceClass2> |
| 266 | | device_t *legacy_device_creator_drc(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 267 | | { |
| 268 | | if (mconfig.options().drc()) |
| 269 | | return global_alloc(_DeviceClass2(mconfig, &legacy_device_creator<_DeviceClass2>, tag, owner, clock)); |
| 270 | | else |
| 271 | | return global_alloc(_DeviceClass1(mconfig, &legacy_device_creator<_DeviceClass1>, tag, owner, clock)); |
| 272 | | } |
| 273 | | |
| 274 | 91 | //************************************************************************** |
| 275 | 92 | // TYPE DEFINITIONS |
| 276 | 93 | //************************************************************************** |
| 277 | 94 | |
| 278 | | // forward declaration of types |
| 279 | | union cpuinfo; |
| 280 | | class cpu_device; |
| 281 | | class legacy_cpu_device; |
| 282 | | |
| 283 | | |
| 284 | | // CPU interface functions |
| 285 | | typedef void (*cpu_get_info_func)(legacy_cpu_device *device, UINT32 state, cpuinfo *info); |
| 286 | | typedef void (*cpu_set_info_func)(legacy_cpu_device *device, UINT32 state, cpuinfo *info); |
| 287 | | typedef void (*cpu_init_func)(legacy_cpu_device *device, device_irq_acknowledge_delegate irqcallback); |
| 288 | | typedef void (*cpu_reset_func)(legacy_cpu_device *device); |
| 289 | | typedef void (*cpu_exit_func)(legacy_cpu_device *device); |
| 290 | | typedef void (*cpu_execute_func)(legacy_cpu_device *device); |
| 291 | | typedef void (*cpu_burn_func)(legacy_cpu_device *device, int cycles); |
| 292 | | typedef int (*cpu_translate_func)(legacy_cpu_device *device, address_spacenum space, int intention, offs_t *address); |
| 293 | | typedef int (*cpu_read_func)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 *value); |
| 294 | | typedef int (*cpu_write_func)(legacy_cpu_device *device, address_spacenum space, UINT32 offset, int size, UINT64 value); |
| 295 | | typedef int (*cpu_readop_func)(legacy_cpu_device *device, UINT32 offset, int size, UINT64 *value); |
| 296 | | typedef void (*cpu_debug_init_func)(legacy_cpu_device *device); |
| 297 | | typedef offs_t (*cpu_disassemble_func)(cpu_device *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, int options); |
| 298 | | typedef void (*cpu_state_io_func)(legacy_cpu_device *device, const device_state_entry &entry); |
| 299 | | typedef void (*cpu_string_io_func)(legacy_cpu_device *device, const device_state_entry &entry, astring &string); |
| 300 | | |
| 301 | | |
| 302 | | // cpuinfo union used to pass data to/from the get_info/set_info functions |
| 303 | | union cpuinfo |
| 304 | | { |
| 305 | | INT64 i; // generic integers |
| 306 | | void * p; // generic pointers |
| 307 | | genf * f; // generic function pointers |
| 308 | | char * s; // generic strings |
| 309 | | |
| 310 | | cpu_set_info_func setinfo; // CPUINFO_FCT_SET_INFO |
| 311 | | cpu_init_func init; // CPUINFO_FCT_INIT |
| 312 | | cpu_reset_func reset; // CPUINFO_FCT_RESET |
| 313 | | cpu_exit_func exit; // CPUINFO_FCT_EXIT |
| 314 | | cpu_execute_func execute; // CPUINFO_FCT_EXECUTE |
| 315 | | cpu_burn_func burn; // CPUINFO_FCT_BURN |
| 316 | | cpu_translate_func translate; // CPUINFO_FCT_TRANSLATE |
| 317 | | cpu_read_func read; // CPUINFO_FCT_READ |
| 318 | | cpu_write_func write; // CPUINFO_FCT_WRITE |
| 319 | | cpu_readop_func readop; // CPUINFO_FCT_READOP |
| 320 | | cpu_debug_init_func debug_init; // CPUINFO_FCT_DEBUG_INIT |
| 321 | | cpu_disassemble_func disassemble; // CPUINFO_FCT_DISASSEMBLE |
| 322 | | cpu_state_io_func import_state; // CPUINFO_FCT_IMPORT_STATE |
| 323 | | cpu_state_io_func export_state; // CPUINFO_FCT_EXPORT_STATE |
| 324 | | cpu_string_io_func import_string; // CPUINFO_FCT_IMPORT_STRING |
| 325 | | cpu_string_io_func export_string; // CPUINFO_FCT_EXPORT_STRING |
| 326 | | int * icount; // CPUINFO_PTR_INSTRUCTION_COUNTER |
| 327 | | address_map_constructor internal_map8; // CPUINFO_PTR_INTERNAL_MEMORY_MAP |
| 328 | | address_map_constructor internal_map16; // CPUINFO_PTR_INTERNAL_MEMORY_MAP |
| 329 | | address_map_constructor internal_map32; // CPUINFO_PTR_INTERNAL_MEMORY_MAP |
| 330 | | address_map_constructor internal_map64; // CPUINFO_PTR_INTERNAL_MEMORY_MAP |
| 331 | | address_map_constructor default_map8; // CPUINFO_PTR_DEFAULT_MEMORY_MAP |
| 332 | | address_map_constructor default_map16; // CPUINFO_PTR_DEFAULT_MEMORY_MAP |
| 333 | | address_map_constructor default_map32; // CPUINFO_PTR_DEFAULT_MEMORY_MAP |
| 334 | | address_map_constructor default_map64; // CPUINFO_PTR_DEFAULT_MEMORY_MAP |
| 335 | | }; |
| 336 | | |
| 337 | | |
| 338 | | |
| 339 | 95 | // ======================> cpu_device |
| 340 | 96 | |
| 341 | 97 | class cpu_device : public device_t, |
| r32087 | r32088 | |
| 353 | 109 | }; |
| 354 | 110 | |
| 355 | 111 | |
| 112 | typedef offs_t (*cpu_disassemble_func)(cpu_device *device, char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, int options); |
| 356 | 113 | |
| 357 | | // ======================> legacy_cpu_device |
| 358 | 114 | |
| 359 | | class legacy_cpu_device : public cpu_device |
| 360 | | { |
| 361 | | friend resource_pool_object<legacy_cpu_device>::~resource_pool_object(); |
| 362 | | |
| 363 | | protected: |
| 364 | | // construction/destruction |
| 365 | | legacy_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, UINT32 clock, cpu_get_info_func info); |
| 366 | | virtual ~legacy_cpu_device(); |
| 367 | | |
| 368 | | public: |
| 369 | | void *token() const { return m_token; } |
| 370 | | |
| 371 | | protected: |
| 372 | | // device-level overrides |
| 373 | | virtual void device_start(); |
| 374 | | virtual void device_reset(); |
| 375 | | virtual void device_stop(); |
| 376 | | virtual void device_debug_setup(); |
| 377 | | |
| 378 | | // device_execute_interface overrides |
| 379 | | virtual UINT64 execute_clocks_to_cycles(UINT64 clocks) const; |
| 380 | | virtual UINT64 execute_cycles_to_clocks(UINT64 cycles) const; |
| 381 | | virtual UINT32 execute_min_cycles() const { return get_legacy_int(CPUINFO_INT_MIN_CYCLES); } |
| 382 | | virtual UINT32 execute_max_cycles() const { return get_legacy_int(CPUINFO_INT_MAX_CYCLES); } |
| 383 | | virtual UINT32 execute_input_lines() const { return get_legacy_int(CPUINFO_INT_INPUT_LINES); } |
| 384 | | virtual UINT32 execute_default_irq_vector() const { return get_legacy_int(CPUINFO_INT_DEFAULT_IRQ_VECTOR); } |
| 385 | | virtual void execute_run(); |
| 386 | | virtual void execute_burn(INT32 cycles); |
| 387 | | virtual void execute_set_input(int inputnum, int state) { set_legacy_int(CPUINFO_INT_INPUT_STATE + inputnum, state); } |
| 388 | | |
| 389 | | // device_memory_interface overrides |
| 390 | | virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum < ARRAY_LENGTH(m_space_config) && m_space_config[spacenum].m_addrbus_width != 0) ? &m_space_config[spacenum] : NULL; } |
| 391 | | virtual bool memory_translate(address_spacenum spacenum, int intention, offs_t &address); |
| 392 | | virtual bool memory_read(address_spacenum spacenum, offs_t offset, int size, UINT64 &value); |
| 393 | | virtual bool memory_write(address_spacenum spacenum, offs_t offset, int size, UINT64 value); |
| 394 | | virtual bool memory_readop(offs_t offset, int size, UINT64 &value); |
| 395 | | |
| 396 | | // device_state_interface overrides |
| 397 | | virtual void state_import(const device_state_entry &entry); |
| 398 | | virtual void state_export(const device_state_entry &entry); |
| 399 | | virtual void state_string_export(const device_state_entry &entry, astring &string); |
| 400 | | |
| 401 | | // device_disasm_interface overrides |
| 402 | | virtual UINT32 disasm_min_opcode_bytes() const { return get_legacy_int(CPUINFO_INT_MIN_INSTRUCTION_BYTES); } |
| 403 | | virtual UINT32 disasm_max_opcode_bytes() const { return get_legacy_int(CPUINFO_INT_MAX_INSTRUCTION_BYTES); } |
| 404 | | virtual offs_t disasm_disassemble(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opram, UINT32 options); |
| 405 | | |
| 406 | | // helpers to access data via the legacy get_info functions |
| 407 | | INT64 get_legacy_int(UINT32 state) const; |
| 408 | | void *get_legacy_ptr(UINT32 state) const; |
| 409 | | genf *get_legacy_fct(UINT32 state) const; |
| 410 | | const char *get_legacy_string(UINT32 state) const; |
| 411 | | void set_legacy_int(UINT32 state, INT64 value); |
| 412 | | |
| 413 | | protected: |
| 414 | | // internal state |
| 415 | | cpu_get_info_func m_get_info; |
| 416 | | address_space_config m_space_config[3]; // array of address space configs |
| 417 | | void * m_token; // pointer to our state |
| 418 | | |
| 419 | | cpu_set_info_func m_set_info; // extracted legacy function pointers |
| 420 | | cpu_execute_func m_execute; // |
| 421 | | cpu_burn_func m_burn; // |
| 422 | | cpu_translate_func m_translate; // |
| 423 | | cpu_read_func m_read; // |
| 424 | | cpu_write_func m_write; // |
| 425 | | cpu_readop_func m_readop; // |
| 426 | | cpu_disassemble_func m_disassemble; // |
| 427 | | cpu_state_io_func m_state_import; // |
| 428 | | cpu_state_io_func m_state_export; // |
| 429 | | cpu_string_io_func m_string_export; // |
| 430 | | cpu_exit_func m_exit; // |
| 431 | | |
| 432 | | UINT64 m_state_io; // temporary buffer for state I/O |
| 433 | | bool m_using_legacy_state; // true if we are using the old-style state access |
| 434 | | bool m_inited; |
| 435 | | }; |
| 436 | | |
| 437 | | |
| 438 | 115 | #endif /* __CPUINTRF_H__ */ |