diff --git a/src/emu/cpu/i386/i386.c b/src/emu/cpu/i386/i386.c index 956d4954d09..9b909ee70d5 100644 --- a/src/emu/cpu/i386/i386.c +++ b/src/emu/cpu/i386/i386.c @@ -441,7 +441,7 @@ static void I386OP(decode_two_byte)(void) /*************************************************************************/ -static UINT64 i386_debug_segbase(UINT32 ref, UINT32 params, UINT64 *param) +static UINT64 i386_debug_segbase(UINT32 ref, UINT32 params, const UINT64 *param) { UINT32 result; I386_SREG seg; @@ -460,7 +460,7 @@ static UINT64 i386_debug_segbase(UINT32 ref, UINT32 params, UINT64 *param) return result; } -static UINT64 i386_debug_seglimit(UINT32 ref, UINT32 params, UINT64 *param) +static UINT64 i386_debug_seglimit(UINT32 ref, UINT32 params, const UINT64 *param) { UINT32 result = 0; I386_SREG seg; diff --git a/src/emu/cpu/sh2/sh2drc.c b/src/emu/cpu/sh2/sh2drc.c index 657ca049b0b..1884c8a0816 100644 --- a/src/emu/cpu/sh2/sh2drc.c +++ b/src/emu/cpu/sh2/sh2drc.c @@ -27,7 +27,7 @@ ***************************************************************************/ #define FORCE_C_BACKEND (0) // use the C backend even when a native one is available -#define LOG_UML (0) // log UML assembly +#define LOG_UML (1) // log UML assembly #define LOG_NATIVE (0) // log native assembly #define SET_EA (0) // makes slower but "shows work" in the EA fake register like the interpreter diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c index 5457d17aebf..9d870857d84 100644 --- a/src/emu/debug/debugcmd.c +++ b/src/emu/debug/debugcmd.c @@ -49,9 +49,9 @@ static struct static void debug_command_exit(running_machine *machine); -static UINT64 execute_min(UINT32 ref, UINT32 params, UINT64 *param); -static UINT64 execute_max(UINT32 ref, UINT32 params, UINT64 *param); -static UINT64 execute_if(UINT32 ref, UINT32 params, UINT64 *param); +static UINT64 execute_min(UINT32 ref, UINT32 params, const UINT64 *param); +static UINT64 execute_max(UINT32 ref, UINT32 params, const UINT64 *param); +static UINT64 execute_if(UINT32 ref, UINT32 params, const UINT64 *param); static UINT64 global_get(UINT32 ref); static void global_set(UINT32 ref, UINT64 value); @@ -279,7 +279,7 @@ static void debug_command_exit(running_machine *machine) execute_min - return the minimum of two values -------------------------------------------------*/ -static UINT64 execute_min(UINT32 ref, UINT32 params, UINT64 *param) +static UINT64 execute_min(UINT32 ref, UINT32 params, const UINT64 *param) { return (param[0] < param[1]) ? param[0] : param[1]; } @@ -289,7 +289,7 @@ static UINT64 execute_min(UINT32 ref, UINT32 params, UINT64 *param) execute_max - return the maximum of two values -------------------------------------------------*/ -static UINT64 execute_max(UINT32 ref, UINT32 params, UINT64 *param) +static UINT64 execute_max(UINT32 ref, UINT32 params, const UINT64 *param) { return (param[0] > param[1]) ? param[0] : param[1]; } @@ -299,7 +299,7 @@ static UINT64 execute_max(UINT32 ref, UINT32 params, UINT64 *param) execute_if - if (a) return b; else return c; -------------------------------------------------*/ -static UINT64 execute_if(UINT32 ref, UINT32 params, UINT64 *param) +static UINT64 execute_if(UINT32 ref, UINT32 params, const UINT64 *param) { return param[0] ? param[1] : param[2]; } @@ -361,7 +361,7 @@ static void global_set(UINT32 ref, UINT64 value) int debug_command_parameter_number(const char *param, UINT64 *result) { - EXPRERR err = expression_evaluate(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, result); + EXPRERR err = expression_evaluate(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, &debug_expression_callbacks, result); if (err == EXPRERR_NONE) return 1; debug_console_printf("Error in expression: %s\n", param); @@ -378,7 +378,7 @@ int debug_command_parameter_number(const char *param, UINT64 *result) static int debug_command_parameter_expression(const char *param, parsed_expression **result) { - EXPRERR err = expression_parse(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, result); + EXPRERR err = expression_parse(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, &debug_expression_callbacks, result); if (err == EXPRERR_NONE) return 1; debug_console_printf("Error in expression: %s\n", param); diff --git a/src/emu/debug/debugcon.c b/src/emu/debug/debugcon.c index 3dc268bdad8..5c89a2d443f 100644 --- a/src/emu/debug/debugcon.c +++ b/src/emu/debug/debugcon.c @@ -329,7 +329,7 @@ static CMDERR internal_parse_command(const char *original_command, int execute) if (isexpr && paramcount == 1) { UINT64 expresult; - EXPRERR exprerr = expression_evaluate(command_start, debug_get_cpu_info(cpu_getactivecpu())->symtable, &expresult); + EXPRERR exprerr = expression_evaluate(command_start, debug_get_cpu_info(cpu_getactivecpu())->symtable, &debug_expression_callbacks, &expresult); if (exprerr != EXPRERR_NONE) return MAKE_CMDERR_EXPRESSION_ERROR(EXPRERR_ERROR_OFFSET(exprerr)); } diff --git a/src/emu/debug/debugcpu.c b/src/emu/debug/debugcpu.c index a78eaaf36af..b91ddfa19af 100644 --- a/src/emu/debug/debugcpu.c +++ b/src/emu/debug/debugcpu.c @@ -26,6 +26,7 @@ #include "debugger.h" #include "deprecat.h" #include "uiinput.h" +#include "machine/eeprom.h" #include @@ -84,7 +85,6 @@ static debugger_private global; - /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ @@ -97,6 +97,18 @@ static void breakpoint_check(debug_cpu_info *info, offs_t pc); static void watchpoint_check(int cpunum, int spacenum, int type, offs_t address, UINT64 value_to_write, UINT64 mem_mask); static void check_hotspots(int cpunum, int spacenum, offs_t address); +/* expression handlers */ +static UINT64 expression_read_memory(int space, int index, UINT32 address, int size); +static UINT64 expression_read_address_space(int cpuindex, int space, offs_t address, int size); +static UINT64 expression_read_program_direct(int cpuindex, int opcode, offs_t address, int size); +static UINT64 expression_read_memory_region(int rgnindex, int rgntype, offs_t address, int size); +static UINT64 expression_read_eeprom(offs_t address, int size); +static void expression_write_memory(int space, int index, UINT32 address, int size, UINT64 data); +static void expression_write_address_space(int cpuindex, int space, offs_t address, int size, UINT64 data); +static void expression_write_program_direct(int cpuindex, int opcode, offs_t address, int size, UINT64 data); +static void expression_write_memory_region(int rgnindex, int rgntype, offs_t address, int size, UINT64 data); +static void expression_write_eeprom(offs_t address, int size, UINT64 data); + /* variable getters/setters */ static UINT64 get_wpaddr(UINT32 ref); static UINT64 get_wpdata(UINT32 ref); @@ -113,6 +125,17 @@ static UINT64 get_cpu_reg(UINT32 ref); static void set_cpu_reg(UINT32 ref, UINT64 value); +/*************************************************************************** + GLOBAL CONSTANTS +***************************************************************************/ + +const express_callbacks debug_expression_callbacks = +{ + expression_read_memory, + expression_write_memory +}; + + /*************************************************************************** FRONTENDS FOR OLDER FUNCTIONS @@ -573,12 +596,15 @@ void debug_cpu_instruction_hook(running_machine *machine, offs_t curpc) while (global.execution_state == EXECUTION_STATE_STOPPED) { /* clear the memory modified flag and wait */ - global.memory_modified = 0; + global.memory_modified = FALSE; osd_wait_for_debugger(); /* if something modified memory, update the screen */ if (global.memory_modified) + { + debug_disasm_update_all(); debugger_refresh_display(machine); + } /* check for commands in the source file */ process_source_file(); @@ -2098,48 +2124,473 @@ UINT64 debug_read_opcode(offs_t address, int size, int arg) /*------------------------------------------------- - external_read_memory - read 1,2,4 or 8 bytes at - the given offset in the given address space + expression_read_memory - read 1,2,4 or 8 bytes + at the given offset in the given address + space -------------------------------------------------*/ -UINT64 external_read_memory(int space, UINT32 offset, int size) +static UINT64 expression_read_memory(int space, int index, UINT32 address, int size) { - const debug_cpu_info *info = &global.cpuinfo[cpu_getactivecpu()]; - if (info->space[space].databytes == 0) - return ~0; + int cpuindex; - /* adjust the address into a byte address */ - offset = ADDR2BYTE(offset, info, space); - switch (size) + switch (space) { - case 1: return debug_read_byte(space, offset, TRUE); - case 2: return debug_read_word(space, offset, TRUE); - case 4: return debug_read_dword(space, offset, TRUE); - case 8: return debug_read_qword(space, offset, TRUE); + case EXPSPACE_PROGRAM: + case EXPSPACE_DATA: + case EXPSPACE_IO: + cpuindex = (index == -1) ? cpu_getactivecpu() : index; + space = ADDRESS_SPACE_PROGRAM + (space - EXPSPACE_PROGRAM); + return expression_read_address_space(cpuindex, space, address, size); + + case EXPSPACE_OPCODE: + case EXPSPACE_RAMWRITE: + cpuindex = (index == -1) ? cpu_getactivecpu() : index; + return expression_read_program_direct(cpuindex, (space == EXPSPACE_OPCODE), address, size); + + case EXPSPACE_EEPROM: + return expression_read_eeprom(address, size); + + case EXPSPACE_CPU: + case EXPSPACE_USER: + case EXPSPACE_GFX: + case EXPSPACE_SOUND: + if (index < 1) + break; + space = ADDRESS_SPACE_PROGRAM + (space - EXPSPACE_PROGRAM); + return expression_read_memory_region(index, space, address, size); } - return ~0; + return ~(UINT64)0 >> (64 - 8*size); } /*------------------------------------------------- - external_write_memory - write 1,2,4 or 8 bytes to - the given offset in the given address space + expression_read_address_space - read memory + from a specific CPU's address space -------------------------------------------------*/ -void external_write_memory(int space, UINT32 offset, int size, UINT64 value) +static UINT64 expression_read_address_space(int cpuindex, int space, offs_t address, int size) { - const debug_cpu_info *info = &global.cpuinfo[cpu_getactivecpu()]; - if (info->space[space].databytes == 0) - return; + const debug_cpu_info *info = &global.cpuinfo[cpuindex]; + UINT64 result = ~(UINT64)0 >> (64 - 8*size); - /* adjust the address into a byte address */ - offset = ADDR2BYTE(offset, info, space); - switch (size) + /* only process if in of range and we have a bus */ + if (cpuindex < ARRAY_LENGTH(global.cpuinfo) && info->space[space].databytes != 0) { - case 1: debug_write_byte(space, offset, value, TRUE); break; - case 2: debug_write_word(space, offset, value, TRUE); break; - case 4: debug_write_dword(space, offset, value, TRUE); break; - case 8: debug_write_qword(space, offset, value, TRUE); break; + /* adjust the address into a byte address */ + address = ADDR2BYTE(address, info, space); + + /* switch contexts and do the read */ + cpuintrf_push_context(cpuindex); + switch (size) + { + case 1: result = debug_read_byte(space, address, TRUE); break; + case 2: result = debug_read_word(space, address, TRUE); break; + case 4: result = debug_read_dword(space, address, TRUE); break; + case 8: result = debug_read_qword(space, address, TRUE); break; + } + cpuintrf_pop_context(); + } + return result; +} + + +/*------------------------------------------------- + expression_read_program_direct - read memory + directly from an opcode or RAM pointer +-------------------------------------------------*/ + +static UINT64 expression_read_program_direct(int cpuindex, int opcode, offs_t address, int size) +{ + const debug_cpu_info *info = &global.cpuinfo[cpuindex]; + UINT64 result = ~(UINT64)0 >> (64 - 8*size); + UINT8 *base; + + /* only process if in of range and we have a bus */ + if (cpuindex < ARRAY_LENGTH(global.cpuinfo) && info->space[ADDRESS_SPACE_PROGRAM].databytes != 0) + { + /* adjust the address into a byte address, but not if being called recursively */ + if ((opcode & 2) == 0) + address = ADDR2BYTE(address, info, ADDRESS_SPACE_PROGRAM); + + /* call ourself recursively until we are byte-sized */ + if (size > 1) + { + int halfsize = size / 2; + UINT64 r0, r1; + + /* read each half, from lower address to upper address */ + r0 = expression_read_program_direct(cpuindex, opcode | 2, address + 0, halfsize); + r1 = expression_read_program_direct(cpuindex, opcode | 2, address + halfsize, halfsize); + + /* assemble based on the target endianness */ + if (info->endianness == CPU_IS_LE) + result = r0 | (r1 << (8 * halfsize)); + else + result = r1 | (r0 << (8 * halfsize)); + } + + /* handle the byte-sized final requests */ + else + { + /* lowmask specified which address bits are within the databus width */ + offs_t lowmask = info->space[ADDRESS_SPACE_PROGRAM].databytes - 1; + + /* get the base of memory, aligned to the address minus the lowbits */ + if (opcode & 1) + base = memory_get_op_ptr(cpuindex, address & ~lowmask, FALSE); + else + base = memory_get_read_ptr(cpuindex, ADDRESS_SPACE_PROGRAM, address & ~lowmask); + + /* if we have a valid base, return the appropriate byte */ + if (base != NULL) + { + if (info->endianness == CPU_IS_LE) + result = base[BYTE8_XOR_LE(address) & lowmask]; + else + result = base[BYTE8_XOR_BE(address) & lowmask]; + } + } + } + return result; +} + + +/*------------------------------------------------- + expression_read_memory_region - read memory + from a memory region +-------------------------------------------------*/ + +static UINT64 expression_read_memory_region(int rgnindex, int rgntype, offs_t address, int size) +{ + UINT64 result = ~(UINT64)0 >> (64 - 8*size); + int rgnnum = -1; + + /* convert to a region number */ + switch (rgntype) + { + case EXPSPACE_CPU: rgnnum = REGION_CPU1 + (rgnindex - 1); break; + case EXPSPACE_USER: rgnnum = REGION_USER1 + (rgnindex - 1); break; + case EXPSPACE_GFX: rgnnum = REGION_GFX1 + (rgnindex - 1); break; + case EXPSPACE_SOUND: rgnnum = REGION_SOUND1 + (rgnindex - 1); break; + } + + /* process if it exists */ + if (rgnnum != -1) + { + UINT8 *base = memory_region(Machine, rgnnum); + + /* make sure we get a valid base before proceeding */ + if (base != NULL) + { + UINT32 length = memory_region_length(Machine, rgnnum); + UINT32 flags = memory_region_flags(Machine, rgnnum); + + /* call ourself recursively until we are byte-sized */ + if (size > 1) + { + int halfsize = size / 2; + UINT64 r0, r1; + + /* read each half, from lower address to upper address */ + r0 = expression_read_memory_region(rgnindex, rgntype, address + 0, halfsize); + r1 = expression_read_memory_region(rgnindex, rgntype, address + halfsize, halfsize); + + /* assemble based on the target endianness */ + if ((flags & ROMREGION_ENDIANMASK) == ROMREGION_LE) + result = r0 | (r1 << (8 * halfsize)); + else + result = r1 | (r0 << (8 * halfsize)); + } + + /* only process if we're within range */ + else if (address < length) + { + /* lowmask specified which address bits are within the databus width */ + UINT32 lowmask = (1 << (flags & ROMREGION_WIDTHMASK)) - 1; + base += address & ~lowmask; + + /* if we have a valid base, return the appropriate byte */ + if ((flags & ROMREGION_ENDIANMASK) == ROMREGION_LE) + result = base[BYTE8_XOR_LE(address) & lowmask]; + else + result = base[BYTE8_XOR_BE(address) & lowmask]; + } + } + } + return result; +} + + +/*------------------------------------------------- + expression_read_eeprom - read EEPROM data +-------------------------------------------------*/ + +static UINT64 expression_read_eeprom(offs_t address, int size) +{ + UINT64 result = ~(UINT64)0 >> (64 - 8*size); + UINT32 eelength, eesize; + void *base; + + /* make sure we get a valid base before proceeding */ + base = eeprom_get_data_pointer(&eelength, &eesize); + if (base != NULL && address < eelength) + { + /* switch off the size */ + switch (eesize) + { + case 1: result &= ((UINT8 *)base)[address]; break; + case 2: result &= BIG_ENDIANIZE_INT16(((UINT16 *)base)[address]); break; + } + } + return result; +} + + +/*------------------------------------------------- + expression_write_memory - write 1,2,4 or 8 + bytes at the given offset in the given address + space +-------------------------------------------------*/ + +static void expression_write_memory(int space, int index, UINT32 address, int size, UINT64 data) +{ + int cpuindex; + + switch (space) + { + case EXPSPACE_PROGRAM: + case EXPSPACE_DATA: + case EXPSPACE_IO: + cpuindex = (index == -1) ? cpu_getactivecpu() : index; + space = ADDRESS_SPACE_PROGRAM + (space - EXPSPACE_PROGRAM); + expression_write_address_space(cpuindex, space, address, size, data); + break; + + case EXPSPACE_OPCODE: + case EXPSPACE_RAMWRITE: + cpuindex = (index == -1) ? cpu_getactivecpu() : index; + expression_write_program_direct(cpuindex, (space == EXPSPACE_OPCODE), address, size, data); + break; + + case EXPSPACE_EEPROM: + expression_write_eeprom(address, size, data); + break; + + case EXPSPACE_CPU: + case EXPSPACE_USER: + case EXPSPACE_GFX: + case EXPSPACE_SOUND: + if (index < 1) + break; + space = ADDRESS_SPACE_PROGRAM + (space - EXPSPACE_PROGRAM); + expression_write_memory_region(index, space, address, size, data); + break; + } +} + + +/*------------------------------------------------- + expression_write_address_space - write memory + to a specific CPU's address space +-------------------------------------------------*/ + +static void expression_write_address_space(int cpuindex, int space, offs_t address, int size, UINT64 data) +{ + const debug_cpu_info *info = &global.cpuinfo[cpuindex]; + + /* only process if in of range and we have a bus */ + if (cpuindex < ARRAY_LENGTH(global.cpuinfo) && info->space[space].databytes != 0) + { + /* adjust the address into a byte address */ + address = ADDR2BYTE(address, info, space); + + /* switch contexts and do the write */ + cpuintrf_push_context(cpuindex); + switch (size) + { + case 1: debug_write_byte(space, address, data, TRUE); break; + case 2: debug_write_word(space, address, data, TRUE); break; + case 4: debug_write_dword(space, address, data, TRUE); break; + case 8: debug_write_qword(space, address, data, TRUE); break; + } + cpuintrf_pop_context(); + } +} + + +/*------------------------------------------------- + expression_write_program_direct - write memory + directly to an opcode or RAM pointer +-------------------------------------------------*/ + +static void expression_write_program_direct(int cpuindex, int opcode, offs_t address, int size, UINT64 data) +{ + const debug_cpu_info *info = &global.cpuinfo[cpuindex]; + UINT8 *base; + + /* only process if in of range and we have a bus */ + if (cpuindex < ARRAY_LENGTH(global.cpuinfo) && info->space[ADDRESS_SPACE_PROGRAM].databytes != 0) + { + /* adjust the address into a byte address, but not if being called recursively */ + if ((opcode & 2) == 0) + address = ADDR2BYTE(address, info, ADDRESS_SPACE_PROGRAM); + + /* call ourself recursively until we are byte-sized */ + if (size > 1) + { + int halfsize = size / 2; + UINT64 r0, r1, halfmask; + + /* break apart based on the target endianness */ + halfmask = ~(UINT64)0 >> (64 - 8 * halfsize); + if (info->endianness == CPU_IS_LE) + { + r0 = data & halfmask; + r1 = (data >> (8 * halfsize)) & halfmask; + } + else + { + r0 = (data >> (8 * halfsize)) & halfmask; + r1 = data & halfmask; + } + + /* write each half, from lower address to upper address */ + expression_write_program_direct(cpuindex, opcode | 2, address + 0, halfsize, r0); + expression_write_program_direct(cpuindex, opcode | 2, address + halfsize, halfsize, r1); + } + + /* handle the byte-sized final case */ + else + { + /* lowmask specified which address bits are within the databus width */ + offs_t lowmask = info->space[ADDRESS_SPACE_PROGRAM].databytes - 1; + + /* get the base of memory, aligned to the address minus the lowbits */ + if (opcode & 1) + base = memory_get_op_ptr(cpuindex, address & ~lowmask, FALSE); + else + base = memory_get_read_ptr(cpuindex, ADDRESS_SPACE_PROGRAM, address & ~lowmask); + + /* if we have a valid base, write the appropriate byte */ + if (base != NULL) + { + if (info->endianness == CPU_IS_LE) + base[BYTE8_XOR_LE(address) & lowmask] = data; + else + base[BYTE8_XOR_BE(address) & lowmask] = data; + global.memory_modified = TRUE; + } + } + } +} + + +/*------------------------------------------------- + expression_write_memory_region - write memory + from a memory region +-------------------------------------------------*/ + +static void expression_write_memory_region(int rgnindex, int rgntype, offs_t address, int size, UINT64 data) +{ + int rgnnum = -1; + + /* convert to a region number */ + switch (rgntype) + { + case EXPSPACE_CPU: rgnnum = REGION_CPU1 + (rgnindex - 1); break; + case EXPSPACE_USER: rgnnum = REGION_USER1 + (rgnindex - 1); break; + case EXPSPACE_GFX: rgnnum = REGION_GFX1 + (rgnindex - 1); break; + case EXPSPACE_SOUND: rgnnum = REGION_SOUND1 + (rgnindex - 1); break; + } + + /* process if it exists */ + if (rgnnum != -1) + { + UINT8 *base = memory_region(Machine, rgnnum); + + /* make sure we get a valid base before proceeding */ + if (base != NULL) + { + UINT32 length = memory_region_length(Machine, rgnnum); + UINT32 flags = memory_region_flags(Machine, rgnnum); + + /* call ourself recursively until we are byte-sized */ + if (size > 1) + { + int halfsize = size / 2; + UINT64 r0, r1, halfmask; + + /* break apart based on the target endianness */ + halfmask = ~(UINT64)0 >> (64 - 8 * halfsize); + if ((flags & ROMREGION_ENDIANMASK) == ROMREGION_LE) + { + r0 = data & halfmask; + r1 = (data >> (8 * halfsize)) & halfmask; + } + else + { + r0 = (data >> (8 * halfsize)) & halfmask; + r1 = data & halfmask; + } + + /* write each half, from lower address to upper address */ + expression_write_memory_region(rgnindex, rgntype, address + 0, halfsize, r0); + expression_write_memory_region(rgnindex, rgntype, address + halfsize, halfsize, r1); + } + + /* only process if we're within range */ + else if (address < length) + { + /* lowmask specified which address bits are within the databus width */ + UINT32 lowmask = (1 << (flags & ROMREGION_WIDTHMASK)) - 1; + base += address & ~lowmask; + + /* if we have a valid base, set the appropriate byte */ + if ((flags & ROMREGION_ENDIANMASK) == ROMREGION_LE) + base[BYTE8_XOR_LE(address) & lowmask] = data; + else + base[BYTE8_XOR_BE(address) & lowmask] = data; + global.memory_modified = TRUE; + } + } + } +} + + +/*------------------------------------------------- + expression_write_eeprom - write EEPROM data +-------------------------------------------------*/ + +static void expression_write_eeprom(offs_t address, int size, UINT64 data) +{ + UINT32 eelength, eesize; + void *vbase = eeprom_get_data_pointer(&eelength, &eesize); + + /* make sure we get a valid base before proceeding */ + if (vbase != NULL && address < eelength) + { + UINT64 mask = ~(UINT64)0 >> (64 - 8*size); + + /* switch off the size */ + switch (eesize) + { + case 1: + { + UINT8 *base = (UINT8 *)vbase + address; + *base = (*base & ~mask) | (data & mask); + break; + } + + case 2: + { + UINT16 *base = (UINT16 *)vbase + address; + UINT16 value = BIG_ENDIANIZE_INT16(*base); + value = (value & ~mask) | (data & mask); + *base = BIG_ENDIANIZE_INT16(value); + break; + } + } + global.memory_modified = TRUE; } } diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index 16ab211a1e6..9d878256e47 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -204,6 +204,7 @@ struct _debug_cpu_watchpoint extern FILE *debug_source_file; extern symbol_table *global_symtable; +extern const express_callbacks debug_expression_callbacks; diff --git a/src/emu/debug/debugvw.c b/src/emu/debug/debugvw.c index fc3f17cf471..b2df25091bb 100644 --- a/src/emu/debug/debugvw.c +++ b/src/emu/debug/debugvw.c @@ -1635,7 +1635,7 @@ static void disasm_update(debug_view *view) parsed_expression *expr; /* parse the new expression */ - exprerr = expression_parse(dasmdata->expression_string, debug_get_cpu_info(dasmdata->cpunum)->symtable, &expr); + exprerr = expression_parse(dasmdata->expression_string, debug_get_cpu_info(dasmdata->cpunum)->symtable, &debug_expression_callbacks, &expr); /* if it worked, update the expression */ if (exprerr == EXPRERR_NONE) @@ -2706,7 +2706,7 @@ static void memory_update(debug_view *view) parsed_expression *expr; /* parse the new expression */ - exprerr = expression_parse(memdata->expression_string, debug_get_cpu_info(memdata->cpunum)->symtable, &expr); + exprerr = expression_parse(memdata->expression_string, debug_get_cpu_info(memdata->cpunum)->symtable, &debug_expression_callbacks, &expr); /* if it worked, update the expression */ if (exprerr == EXPRERR_NONE) diff --git a/src/emu/debug/express.c b/src/emu/debug/express.c index 83dd01e39d9..2a135b2fb7c 100644 --- a/src/emu/debug/express.c +++ b/src/emu/debug/express.c @@ -80,11 +80,21 @@ enum TIN_MEMORY_DWORD = (2 << TIN_MEMORY_SIZE_SHIFT), TIN_MEMORY_QWORD = (3 << TIN_MEMORY_SIZE_SHIFT), - TIN_MEMORY_SPACE_SHIFT = 10, - TIN_MEMORY_SPACE_MASK = (3 << TIN_MEMORY_SPACE_SHIFT), - TIN_MEMORY_PROGRAM = (EXPSPACE_PROGRAM << TIN_MEMORY_SPACE_SHIFT), - TIN_MEMORY_DATA = (EXPSPACE_DATA << TIN_MEMORY_SPACE_SHIFT), - TIN_MEMORY_IO = (EXPSPACE_IO << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_SPACE_SHIFT = 12, + TIN_MEMORY_SPACE_MASK = (0xf << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_PROGRAM = (EXPSPACE_PROGRAM << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_DATA = (EXPSPACE_DATA << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_IO = (EXPSPACE_IO << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_OPCODE = (EXPSPACE_OPCODE << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_RAMWRITE = (EXPSPACE_RAMWRITE << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_EEPROM = (EXPSPACE_EEPROM << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_CPU = (EXPSPACE_CPU << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_USER = (EXPSPACE_USER << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_GFX = (EXPSPACE_GFX << TIN_MEMORY_SPACE_SHIFT), + TIN_MEMORY_SOUND = (EXPSPACE_SOUND << TIN_MEMORY_SPACE_SHIFT), + + TIN_MEMORY_INDEX_SHIFT = 16, + TIN_MEMORY_INDEX_MASK = (0xf << TIN_MEMORY_INDEX_SHIFT) }; @@ -146,47 +156,52 @@ enum typedef union _int_ptr int_ptr; union _int_ptr { - void * p; /* pointer value */ - UINT64 i; /* integer value */ + void * p; /* pointer value */ + UINT64 i; /* integer value */ }; +typedef UINT32 token_type; +typedef UINT32 token_info; + + typedef struct _parse_token parse_token; struct _parse_token { - UINT16 type; /* type of token */ - UINT16 info; /* info for token */ - UINT32 offset; /* offset within the string */ - int_ptr value; /* value of token */ + token_type type; /* type of token */ + token_info info; /* info for token */ + UINT32 offset; /* offset within the string */ + int_ptr value; /* value of token */ }; typedef struct _internal_symbol_entry internal_symbol_entry; struct _internal_symbol_entry { - internal_symbol_entry *next; /* pointer to the next entry */ - const char * name; /* name of the symbol */ - symbol_entry entry; /* actual entry data */ + internal_symbol_entry * next; /* pointer to the next entry */ + const char * name; /* name of the symbol */ + symbol_entry entry; /* actual entry data */ }; /* typedef struct _symbol_table symbol_table -- defined in express.h */ struct _symbol_table { - symbol_table *parent; /* pointer to the parent symbol table */ - internal_symbol_entry *hash[SYM_TABLE_HASH_SIZE]; /* hash table */ + symbol_table * parent; /* pointer to the parent symbol table */ + internal_symbol_entry * hash[SYM_TABLE_HASH_SIZE]; /* hash table */ }; /* typedef struct _parsed_expression parsed_expression -- defined in express.h */ struct _parsed_expression { - const symbol_table *table; /* symbol table */ - char * original_string;/* original string (prior to parsing) */ - char * string[MAX_EXPRESSION_STRINGS]; /* string table */ - parse_token token[MAX_TOKENS];/* array of tokens */ - int token_stack_ptr;/* stack poointer */ - parse_token token_stack[MAX_STACK_DEPTH];/* token stack */ + const symbol_table * table; /* symbol table */ + char * original_string; /* original string (prior to parsing) */ + express_callbacks callbacks; /* callbacks */ + char * string[MAX_EXPRESSION_STRINGS]; /* string table */ + parse_token token[MAX_TOKENS]; /* array of tokens */ + int token_stack_ptr; /* stack poointer */ + parse_token token_stack[MAX_STACK_DEPTH]; /* token stack */ }; @@ -313,10 +328,16 @@ INLINE EXPRERR pop_token_rval(parsed_expression *expr, parse_token *token, const /* memory tokens get resolved down to number tokens */ else if (token->type == TOK_MEMORY) { + int index = (token->info & TIN_MEMORY_INDEX_MASK) >> TIN_MEMORY_INDEX_SHIFT; int space = (token->info & TIN_MEMORY_SPACE_MASK) >> TIN_MEMORY_SPACE_SHIFT; int size = (token->info & TIN_MEMORY_SIZE_MASK) >> TIN_MEMORY_SIZE_SHIFT; + if ((token->info & TIN_MEMORY_INDEX_MASK) == TIN_MEMORY_INDEX_MASK) + index = -1; token->type = TOK_NUMBER; - token->value.i = external_read_memory(space, token->value.i, 1 << size); + if (expr->callbacks.read != NULL) + token->value.i = (*expr->callbacks.read)(space, index, token->value.i, 1 << size); + else + token->value.i = 0; } /* to be an rval, the token must be a number */ @@ -331,7 +352,7 @@ INLINE EXPRERR pop_token_rval(parsed_expression *expr, parse_token *token, const for a SYMBOL token -------------------------------------------------*/ -INLINE UINT64 get_lval_value(parse_token *token, const symbol_table *table) +INLINE UINT64 get_lval_value(parsed_expression *expr, parse_token *token, const symbol_table *table) { if (token->type == TOK_SYMBOL) { @@ -341,9 +362,13 @@ INLINE UINT64 get_lval_value(parse_token *token, const symbol_table *table) } else if (token->type == TOK_MEMORY) { + int index = (token->info & TIN_MEMORY_INDEX_MASK) >> TIN_MEMORY_INDEX_SHIFT; int space = (token->info & TIN_MEMORY_SPACE_MASK) >> TIN_MEMORY_SPACE_SHIFT; int size = (token->info & TIN_MEMORY_SIZE_MASK) >> TIN_MEMORY_SIZE_SHIFT; - return external_read_memory(space, token->value.i, 1 << size); + if ((token->info & TIN_MEMORY_INDEX_MASK) == TIN_MEMORY_INDEX_MASK) + index = -1; + if (expr->callbacks.read != NULL) + return (*expr->callbacks.read)(space, index, token->value.i, 1 << size); } return 0; } @@ -354,7 +379,7 @@ INLINE UINT64 get_lval_value(parse_token *token, const symbol_table *table) for a SYMBOL token -------------------------------------------------*/ -INLINE void set_lval_value(parse_token *token, const symbol_table *table, UINT64 value) +INLINE void set_lval_value(parsed_expression *expr, parse_token *token, const symbol_table *table, UINT64 value) { if (token->type == TOK_SYMBOL) { @@ -364,9 +389,13 @@ INLINE void set_lval_value(parse_token *token, const symbol_table *table, UINT64 } else if (token->type == TOK_MEMORY) { + int index = (token->info & TIN_MEMORY_INDEX_MASK) >> TIN_MEMORY_INDEX_SHIFT; int space = (token->info & TIN_MEMORY_SPACE_MASK) >> TIN_MEMORY_SPACE_SHIFT; int size = (token->info & TIN_MEMORY_SIZE_MASK) >> TIN_MEMORY_SIZE_SHIFT; - external_write_memory(space, token->value.i, 1 << size, value); + if ((token->info & TIN_MEMORY_INDEX_MASK) == TIN_MEMORY_INDEX_MASK) + index = -1; + if (expr->callbacks.write != NULL) + (*expr->callbacks.write)(space, index, token->value.i, 1 << size, value); } } @@ -480,18 +509,21 @@ static void print_tokens(FILE *out, parsed_expression *expr) forms of memory operators -------------------------------------------------*/ -static int parse_memory_operator(const char *buffer, UINT16 *flags) +static int parse_memory_operator(const char *buffer, token_info *flags) { int length = (int)strlen(buffer); int space = 'p', size; + int index = -1; *flags = 0; - /* length 2 means space, then size */ - if (length == 2) + /* length 2 or more means space, optional index, then size */ + if (length >= 2) { space = buffer[0]; - size = buffer[1]; + if (length >= 3) + sscanf(&buffer[1], "%d", &index); + size = buffer[length - 1]; } /* length 1 means size */ @@ -508,6 +540,13 @@ static int parse_memory_operator(const char *buffer, UINT16 *flags) case 'p': *flags |= TIN_MEMORY_PROGRAM; break; case 'd': *flags |= TIN_MEMORY_DATA; break; case 'i': *flags |= TIN_MEMORY_IO; break; + case 'o': *flags |= TIN_MEMORY_OPCODE; break; + case 'r': *flags |= TIN_MEMORY_RAMWRITE; break; + case 'e': *flags |= TIN_MEMORY_EEPROM; break; + case 'c': *flags |= TIN_MEMORY_CPU; break; + case 'u': *flags |= TIN_MEMORY_USER; break; + case 'g': *flags |= TIN_MEMORY_GFX; break; + case 's': *flags |= TIN_MEMORY_SOUND; break; default: return 0; } @@ -520,6 +559,10 @@ static int parse_memory_operator(const char *buffer, UINT16 *flags) case 'q': *flags |= TIN_MEMORY_QWORD; break; default: return 0; } + + /* add the index to flags */ + *flags |= index << TIN_MEMORY_INDEX_SHIFT; + return 1; } @@ -781,7 +824,7 @@ static EXPRERR parse_string_into_tokens(const char *stringstart, parsed_expressi /* check for memory @ operators */ if (string[0] == '@') { - UINT16 info; + token_info info; if (parse_memory_operator(buffer, &info)) { SET_TOKEN_INFO(1, TOK_OPERATOR, TVL_MEMORYAT, TIN_PRECEDENCE_2 | info); @@ -1196,34 +1239,34 @@ static EXPRERR execute_tokens(parsed_expression *expr, UINT64 *result) { case TVL_PREINCREMENT: exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table) + 1; + tempnum.value.i = get_lval_value(expr, &t1, expr->table) + 1; tempnum.offset = t1.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_PREDECREMENT: exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table) - 1; + tempnum.value.i = get_lval_value(expr, &t1, expr->table) - 1; tempnum.offset = t1.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_POSTINCREMENT: exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.offset = t1.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i + 1); + set_lval_value(expr, &t1, expr->table, tempnum.value.i + 1); break; case TVL_POSTDECREMENT: exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.offset = t1.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i - 1); + set_lval_value(expr, &t1, expr->table, tempnum.value.i - 1); break; case TVL_COMPLEMENT: @@ -1404,109 +1447,109 @@ static EXPRERR execute_tokens(parsed_expression *expr, UINT64 *result) exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; push_token(expr, &t2); - set_lval_value(&t1, expr->table, t2.value.i); + set_lval_value(expr, &t1, expr->table, t2.value.i); break; case TVL_ASSIGNMULTIPLY: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i *= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNDIVIDE: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); if (t2.value.i == 0) return MAKE_EXPRERR_DIVIDE_BY_ZERO(t2.offset); tempnum.value.i /= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNMODULO: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); if (t2.value.i == 0) return MAKE_EXPRERR_DIVIDE_BY_ZERO(t2.offset); tempnum.value.i %= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNADD: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i += t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNSUBTRACT: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i -= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNLSHIFT: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i <<= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNRSHIFT: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i >>= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNBAND: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i &= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNBXOR: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i ^= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_ASSIGNBOR: exprerr = pop_token_rval(expr, &t2, expr->table); if (exprerr != 0) return exprerr; exprerr = pop_token_lval(expr, &t1, expr->table); if (exprerr != 0) return exprerr; - tempnum.value.i = get_lval_value(&t1, expr->table); + tempnum.value.i = get_lval_value(expr, &t1, expr->table); tempnum.value.i |= t2.value.i; tempnum.offset = (t1.offset < t2.offset) ? t1.offset : t2.offset; exprerr = push_token(expr, &tempnum); if (exprerr != 0) return exprerr; - set_lval_value(&t1, expr->table, tempnum.value.i); + set_lval_value(expr, &t1, expr->table, tempnum.value.i); break; case TVL_COMMA: @@ -1589,7 +1632,7 @@ static void free_expression_strings(parsed_expression *expr) expression using the passed symbol table -------------------------------------------------*/ -EXPRERR expression_evaluate(const char *expression, const symbol_table *table, UINT64 *result) +EXPRERR expression_evaluate(const char *expression, const symbol_table *table, const express_callbacks *callbacks, UINT64 *result) { parsed_expression temp_expression; EXPRERR exprerr; @@ -1610,6 +1653,10 @@ EXPRERR expression_evaluate(const char *expression, const symbol_table *table, U /* debugging */ print_tokens(stdout, &temp_expression); + /* copy the callbacks */ + if (callbacks != NULL) + temp_expression.callbacks = *callbacks; + /* execute the expression to get the result */ exprerr = execute_tokens(&temp_expression, result); @@ -1624,11 +1671,11 @@ cleanup: return an allocated token array -------------------------------------------------*/ -EXPRERR expression_parse(const char *expression, const symbol_table *table, parsed_expression **result) +EXPRERR expression_parse(const char *expression, const symbol_table *table, const express_callbacks *callbacks, parsed_expression **result) { parsed_expression temp_expression; EXPRERR exprerr; - + /* first parse the tokens into the token array in order */ exprerr = parse_string_into_tokens(expression, &temp_expression, table); if (exprerr != EXPRERR_NONE) @@ -1647,6 +1694,10 @@ EXPRERR expression_parse(const char *expression, const symbol_table *table, pars goto cleanup; } + /* copy the callbacks */ + if (callbacks != NULL) + temp_expression.callbacks = *callbacks; + /* copy the final expression and return */ **result = temp_expression; return EXPRERR_NONE; @@ -1853,7 +1904,7 @@ int symtable_add_register(symbol_table *table, const char *name, UINT32 ref, UIN function symbol to a symbol table -------------------------------------------------*/ -int symtable_add_function(symbol_table *table, const char *name, UINT32 ref, UINT16 minparams, UINT16 maxparams, UINT64 (*execute)(UINT32, UINT32, UINT64 *)) +int symtable_add_function(symbol_table *table, const char *name, UINT32 ref, UINT16 minparams, UINT16 maxparams, function_execute_func execute) { symbol_entry symbol; diff --git a/src/emu/debug/express.h b/src/emu/debug/express.h index 4f3d1419e9b..3cae4fd0059 100644 --- a/src/emu/debug/express.h +++ b/src/emu/debug/express.h @@ -45,6 +45,13 @@ #define EXPSPACE_PROGRAM (0) #define EXPSPACE_DATA (1) #define EXPSPACE_IO (2) +#define EXPSPACE_OPCODE (3) +#define EXPSPACE_RAMWRITE (4) +#define EXPSPACE_EEPROM (5) +#define EXPSPACE_CPU (6) +#define EXPSPACE_USER (7) +#define EXPSPACE_GFX (8) +#define EXPSPACE_SOUND (9) @@ -79,6 +86,27 @@ TYPE DEFINITIONS ***************************************************************************/ +/* callback functions for getting/setting a symbol value */ +typedef UINT64 (*symbol_getter_func)(UINT32 ref); +typedef void (*symbol_setter_func)(UINT32 ref, UINT64 value); + +/* callback function for execution a function */ +typedef UINT64 (*function_execute_func)(UINT32 ref, UINT32 numparams, const UINT64 *paramlist); + +/* callback function for memory reads/writes */ +typedef UINT64 (*express_read_func)(int space, int index, UINT32 offset, int size); +typedef void (*express_write_func)(int space, int index, UINT32 offset, int size, UINT64 value); + + +/* callback parameter for executing expressions */ +typedef struct _express_callbacks express_callbacks; +struct _express_callbacks +{ + express_read_func read; /* read callback */ + express_write_func write; /* write callback */ +}; + + /* symbol_entry describes a symbol in a symbol table */ typedef struct _symbol_entry symbol_entry; struct _symbol_entry @@ -90,23 +118,23 @@ struct _symbol_entry /* register info */ struct { - UINT64 (*getter)(UINT32); /* value getter */ - void (*setter)(UINT32, UINT64); /* value setter */ + symbol_getter_func getter; /* value getter */ + symbol_setter_func setter; /* value setter */ } reg; /* function info */ struct { - UINT16 minparams; /* minimum expected parameters */ - UINT16 maxparams; /* maximum expected parameters */ - UINT64 (*execute)(UINT32, UINT32, UINT64 *);/* execute */ + UINT16 minparams; /* minimum expected parameters */ + UINT16 maxparams; /* maximum expected parameters */ + function_execute_func execute; /* execute callback */ } func; /* generic info */ struct generic_info { - void * ptr; /* generic pointer */ - UINT64 value; /* generic value */ + void * ptr; /* generic pointer */ + UINT64 value; /* generic value */ } gen; } info; }; @@ -125,23 +153,13 @@ typedef UINT32 EXPRERR; -/*************************************************************************** - EXTERNAL DEPENDENCIES -***************************************************************************/ - -/* These must be provided by the caller */ -UINT64 external_read_memory(int space, UINT32 offset, int size); -void external_write_memory(int space, UINT32 offset, int size, UINT64 value); - - - /*************************************************************************** FUNCTION PROTOTYPES ***************************************************************************/ /* expression evaluation */ -EXPRERR expression_evaluate(const char *expression, const symbol_table *table, UINT64 *result); -EXPRERR expression_parse(const char *expression, const symbol_table *table, parsed_expression **result); +EXPRERR expression_evaluate(const char *expression, const symbol_table *table, const express_callbacks *callbacks, UINT64 *result); +EXPRERR expression_parse(const char *expression, const symbol_table *table, const express_callbacks *callbacks, parsed_expression **result); EXPRERR expression_execute(parsed_expression *expr, UINT64 *result); void expression_free(parsed_expression *expr); const char * expression_original_string(parsed_expression *expr); @@ -150,8 +168,8 @@ const char * exprerr_to_string(EXPRERR error); /* symbol table manipulation */ symbol_table * symtable_alloc(symbol_table *parent); int symtable_add(symbol_table *table, const char *name, const symbol_entry *entry); -int symtable_add_register(symbol_table *table, const char *name, UINT32 ref, UINT64 (*getter)(UINT32), void (*setter)(UINT32, UINT64)); -int symtable_add_function(symbol_table *table, const char *name, UINT32 ref, UINT16 minparams, UINT16 maxparams, UINT64 (*execute)(UINT32, UINT32, UINT64 *)); +int symtable_add_register(symbol_table *table, const char *name, UINT32 ref, symbol_getter_func getter, symbol_setter_func setter); +int symtable_add_function(symbol_table *table, const char *name, UINT32 ref, UINT16 minparams, UINT16 maxparams, function_execute_func execute); int symtable_add_value(symbol_table *table, const char *name, UINT64 value); const symbol_entry * symtable_find(const symbol_table *table, const char *name); const char * symtable_find_indexed(const symbol_table *table, int index, const symbol_entry **entry); diff --git a/src/emu/machine/eeprom.c b/src/emu/machine/eeprom.c index eb1147bed8c..62a7e6c2751 100644 --- a/src/emu/machine/eeprom.c +++ b/src/emu/machine/eeprom.c @@ -365,10 +365,12 @@ void eeprom_set_data(const UINT8 *data, int length) memcpy(eeprom_data, data, length); } -UINT8 * eeprom_get_data_pointer(int * length) +void *eeprom_get_data_pointer(UINT32 *length, UINT32 *size) { - if(length) - *length = MEMORY_SIZE; + if (length != NULL && intf != NULL) + *length = 1 << intf->address_bits; + if (size != NULL && intf != NULL) + *size = intf->data_bits / 8; return eeprom_data; } diff --git a/src/emu/machine/eeprom.h b/src/emu/machine/eeprom.h index 2dab30ceb1a..75098cb74c5 100644 --- a/src/emu/machine/eeprom.h +++ b/src/emu/machine/eeprom.h @@ -29,7 +29,7 @@ void eeprom_load(mame_file *file); void eeprom_save(mame_file *file); void eeprom_set_data(const UINT8 *data, int length); -UINT8 * eeprom_get_data_pointer(int * length); +void *eeprom_get_data_pointer(UINT32 *length, UINT32 *size); /* 93C46 */ extern const eeprom_interface eeprom_interface_93C46; diff --git a/src/emu/mame.c b/src/emu/mame.c index 8ee5c7e88d2..43117582e11 100644 --- a/src/emu/mame.c +++ b/src/emu/mame.c @@ -844,7 +844,7 @@ UINT8 *new_memory_region(running_machine *machine, int type, UINT32 length, UINT break; if (num < 0) fatalerror("Out of memory regions!"); - + /* allocate the region */ mame->mem_region[num].length = length; mame->mem_region[num].type = type; diff --git a/src/emu/romload.c b/src/emu/romload.c index 067dbc48317..dead855a571 100644 --- a/src/emu/romload.c +++ b/src/emu/romload.c @@ -447,33 +447,23 @@ static void display_rom_load_results(rom_load_data *romdata) byte swapping and inverting data as necessary -------------------------------------------------*/ -static void region_post_process(rom_load_data *romdata, const rom_entry *regiondata) +static void region_post_process(running_machine *machine, rom_load_data *romdata, int regnum) { - int type = ROMREGION_GETTYPE(regiondata); - int datawidth = ROMREGION_GETWIDTH(regiondata) / 8; - int littleendian = ROMREGION_ISLITTLEENDIAN(regiondata); + UINT32 regionlength = memory_region_length(machine, regnum); + UINT32 regionflags = memory_region_flags(machine, regnum); + UINT8 *regionbase = memory_region(machine, regnum); + int littleendian = ((regionflags & ROMREGION_ENDIANMASK) == ROMREGION_LE); + int datawidth = 1 << (regionflags & ROMREGION_WIDTHMASK); UINT8 *base; int i, j; debugload("+ datawidth=%d little=%d\n", datawidth, littleendian); - /* if this is a CPU region, override with the CPU width and endianness */ - if (type >= REGION_CPU1 && type < REGION_CPU1 + MAX_CPU) - { - cpu_type cputype = Machine->config->cpu[type - REGION_CPU1].type; - if (cputype != CPU_DUMMY) - { - datawidth = cputype_databus_width(cputype, ADDRESS_SPACE_PROGRAM) / 8; - littleendian = (cputype_endianness(cputype) == CPU_IS_LE); - debugload("+ CPU region #%d: datawidth=%d little=%d\n", type - REGION_CPU1, datawidth, littleendian); - } - } - /* if the region is inverted, do that now */ - if (ROMREGION_ISINVERTED(regiondata)) + if (regionflags & ROMREGION_INVERTMASK) { debugload("+ Inverting region\n"); - for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i++) + for (i = 0, base = regionbase; i < regionlength; i++) *base++ ^= 0xff; } @@ -485,7 +475,7 @@ static void region_post_process(rom_load_data *romdata, const rom_entry *regiond #endif { debugload("+ Byte swapping region\n"); - for (i = 0, base = romdata->regionbase; i < romdata->regionlength; i += datawidth) + for (i = 0, base = regionbase; i < regionlength; i += datawidth) { UINT8 temp[8]; memcpy(temp, base, datawidth); @@ -1052,6 +1042,39 @@ next: } +/*------------------------------------------------- + normalize_flags_for_cpu - modify the region + flags for the given CPU index +-------------------------------------------------*/ + +static UINT32 normalize_flags_for_cpu(running_machine *machine, UINT32 startflags, int cpunum) +{ + int cputype = machine->config->cpu[cpunum].type; + int buswidth; + + /* set the endianness */ + startflags &= ~ROMREGION_ENDIANMASK; + if (cputype_endianness(cputype) == CPU_IS_LE) + startflags |= ROMREGION_LE; + else + startflags |= ROMREGION_BE; + + /* set the width */ + startflags &= ~ROMREGION_WIDTHMASK; + buswidth = cputype_databus_width(cputype, ADDRESS_SPACE_PROGRAM); + if (buswidth <= 8) + startflags |= ROMREGION_8BIT; + else if (buswidth <= 16) + startflags |= ROMREGION_16BIT; + else if (buswidth <= 32) + startflags |= ROMREGION_32BIT; + else + startflags |= ROMREGION_64BIT; + + return startflags; +} + + /*------------------------------------------------- rom_init - new, more flexible ROM loading system @@ -1089,16 +1112,22 @@ void rom_init(running_machine *machine, const rom_entry *romp) /* loop until we hit the end */ for (region = romp, regnum = 0; region; region = rom_next_region(region), regnum++) { + UINT32 regionlength = ROMREGION_GETLENGTH(region); + UINT32 regionflags = ROMREGION_GETFLAGS(region); int regiontype = ROMREGION_GETTYPE(region); - debugload("Processing region %02X (length=%X)\n", regiontype, ROMREGION_GETLENGTH(region)); + debugload("Processing region %02X (length=%X)\n", regiontype, regionlength); /* the first entry must be a region */ assert(ROMENTRY_ISREGION(region)); + /* if this is a CPU region, override with the CPU width and endianness */ + if (regiontype >= REGION_CPU1 && regiontype < REGION_CPU1 + MAX_CPU) + regionflags = normalize_flags_for_cpu(machine, regionflags, regiontype - REGION_CPU1); + /* remember the base and length */ - romdata.regionbase = new_memory_region(machine, regiontype, ROMREGION_GETLENGTH(region), ROMREGION_GETFLAGS(region)); - romdata.regionlength = ROMREGION_GETLENGTH(region); + romdata.regionbase = new_memory_region(machine, regiontype, regionlength, regionflags); + romdata.regionlength = regionlength; debugload("Allocated %X bytes @ %p\n", romdata.regionlength, romdata.regionbase); /* clear the region if it's requested */ @@ -1131,9 +1160,7 @@ void rom_init(running_machine *machine, const rom_entry *romp) if (regionlist[regnum]) { debugload("Post-processing region %02X\n", regnum); - romdata.regionlength = memory_region_length(machine, regnum); - romdata.regionbase = memory_region(machine, regnum); - region_post_process(&romdata, regionlist[regnum]); + region_post_process(machine, &romdata, regnum); } /* display the results and exit */ diff --git a/src/emu/romload.h b/src/emu/romload.h index 971959dd587..a21502e634e 100644 --- a/src/emu/romload.h +++ b/src/emu/romload.h @@ -27,11 +27,11 @@ enum { ROMENTRYTYPE_REGION = 1, /* this entry marks the start of a region */ - ROMENTRYTYPE_END, /* this entry marks the end of a region */ + ROMENTRYTYPE_END, /* this entry marks the end of a region */ ROMENTRYTYPE_RELOAD, /* this entry reloads the previous ROM */ ROMENTRYTYPE_CONTINUE, /* this entry continues loading the previous ROM */ - ROMENTRYTYPE_FILL, /* this entry fills an area with a constant value */ - ROMENTRYTYPE_COPY, /* this entry copies data from another region/offset */ + ROMENTRYTYPE_FILL, /* this entry fills an area with a constant value */ + ROMENTRYTYPE_COPY, /* this entry copies data from another region/offset */ ROMENTRYTYPE_CARTRIDGE, /* this entry specifies a cartridge (MESS) */ ROMENTRYTYPE_IGNORE, /* this entry continues loading the previous ROM but throws the data away */ ROMENTRYTYPE_SYSTEM_BIOS, /* this entry specifies a bios */ diff --git a/src/emu/uimenu.c b/src/emu/uimenu.c index f21f40b0b65..da3f074c142 100644 --- a/src/emu/uimenu.c +++ b/src/emu/uimenu.c @@ -665,6 +665,36 @@ const char *ui_menu_pool_strdup(ui_menu *menu, const char *string) } +/*------------------------------------------------- + ui_menu_get_selection - retrieves the index + of the currently selected menu item +-------------------------------------------------*/ + +void *ui_menu_get_selection(ui_menu *menu) +{ + return (menu->selected >= 0 && menu->selected < menu->numitems) ? menu->item[menu->selected].ref : NULL; +} + + +/*------------------------------------------------- + ui_menu_set_selection - changes the index + of the currently selected menu item +-------------------------------------------------*/ + +void ui_menu_set_selection(ui_menu *menu, void *selected_itemref) +{ + int itemnum; + + menu->selected = -1; + for (itemnum = 0; itemnum < menu->numitems; itemnum++) + if (menu->item[itemnum].ref == selected_itemref) + { + menu->selected = itemnum; + break; + } +} + + /*************************************************************************** INTERNAL MENU PROCESSING @@ -3126,35 +3156,3 @@ static void menu_render_triangle(bitmap_t *dest, const bitmap_t *source, const r ACCESSORS ***************************************************************************/ -/*------------------------------------------------- - ui_menu_get_selection - retrieves the index - of the currently selected menu item --------------------------------------------------*/ - -void *ui_menu_get_selection(ui_menu *menu) -{ - return (menu->selected >= 0) && (menu->selected < menu->numitems) - ? menu->item[menu->selected].ref - : NULL; -} - - - -/*------------------------------------------------- - ui_menu_set_selection - changes the index - of the currently selected menu item --------------------------------------------------*/ - -void ui_menu_set_selection(ui_menu *menu, void *selected_itemref) -{ - int i; - for (i = 0; i < menu->numitems; i++) - { - if (menu->item[i].ref == selected_itemref) - { - menu->selected = i; - return; - } - } - menu->selected = -1; -} diff --git a/src/emu/uimenu.h b/src/emu/uimenu.h index cc60d7b7880..adfd4c8306a 100644 --- a/src/emu/uimenu.h +++ b/src/emu/uimenu.h @@ -114,6 +114,12 @@ void *ui_menu_pool_alloc(ui_menu *menu, size_t size); /* make a temporary string copy in the menu's memory pool */ const char *ui_menu_pool_strdup(ui_menu *menu, const char *string); +/* retrieves the index of the currently selected menu item */ +void *ui_menu_get_selection(ui_menu *menu); + +/* changes the index of the currently selected menu item */ +void ui_menu_set_selection(ui_menu *menu, void *selected_itemref); + /* ----- menu stack management ----- */ @@ -139,15 +145,4 @@ void ui_menu_force_game_select(void); int ui_menu_is_force_game_select(void); - -/* ----- accessors ----- */ - -/* retrieves the index of the currently selected menu item */ -void *ui_menu_get_selection(ui_menu *menu); - -/* changes the index of the currently selected menu item */ -void ui_menu_set_selection(ui_menu *menu, void *selected_itemref); - - - #endif /* __UIMENU_H__ */ diff --git a/src/mame/drivers/cave.c b/src/mame/drivers/cave.c index 15f9b0dd822..7b87f8c9d9e 100644 --- a/src/mame/drivers/cave.c +++ b/src/mame/drivers/cave.c @@ -1963,7 +1963,7 @@ static MACHINE_RESET( cave ) /* modify the eeprom on a reset with the desired region for the games that have the region factory set in eeprom */ if (cave_region_byte >= 0) - eeprom_get_data_pointer(0)[cave_region_byte] = input_port_read(machine, "EEPROM"); + ((UINT8 *)eeprom_get_data_pointer(NULL,NULL))[cave_region_byte] = input_port_read(machine, "EEPROM"); } static const struct YMZ280Binterface ymz280b_intf = diff --git a/src/mame/drivers/deco32.c b/src/mame/drivers/deco32.c index 562405a58dc..00d77860e5e 100644 --- a/src/mame/drivers/deco32.c +++ b/src/mame/drivers/deco32.c @@ -487,7 +487,7 @@ static WRITE32_HANDLER( tattass_control_w ) static int pendingCommand=0; /* 1 = read, 2 = write */ static int readBitCount=0; static int byteAddr=0; - UINT8 *eeprom=eeprom_get_data_pointer(0); + UINT8 *eeprom=eeprom_get_data_pointer(NULL,NULL); /* Eprom in low byte */ if (mem_mask==0x000000ff) { /* Byte write to low byte only (different from word writing including low byte) */ @@ -1846,10 +1846,9 @@ static NVRAM_HANDLER(tattass) eeprom_save(file); else { - int len; eeprom_init(&eeprom_interface_tattass); if (file) eeprom_load(file); - else memcpy(eeprom_get_data_pointer(&len),tattass_default_eprom,0x160); + else memcpy(eeprom_get_data_pointer(NULL,NULL),tattass_default_eprom,0x160); } } diff --git a/src/mame/drivers/pntnpuzl.c b/src/mame/drivers/pntnpuzl.c index d7daf3a7226..6034516ba1b 100644 --- a/src/mame/drivers/pntnpuzl.c +++ b/src/mame/drivers/pntnpuzl.c @@ -147,11 +147,11 @@ static NVRAM_HANDLER( pntnpuzl ) eeprom_load(file); else { - int length; + UINT32 length, size; UINT8 *dat; - dat = eeprom_get_data_pointer(&length); - memset(dat, 0, length); + dat = eeprom_get_data_pointer(&length, &size); + memset(dat, 0, length * size); } } } diff --git a/src/mame/drivers/psikyo4.c b/src/mame/drivers/psikyo4.c index aed3ddc21ed..3c53ce606de 100644 --- a/src/mame/drivers/psikyo4.c +++ b/src/mame/drivers/psikyo4.c @@ -188,11 +188,11 @@ static NVRAM_HANDLER(93C56) } else // these games want the eeprom all zeros by default { - int length; + UINT32 length, size; UINT8 *dat; - dat = eeprom_get_data_pointer(&length); - memset(dat, 0, length); + dat = eeprom_get_data_pointer(&length, &size); + memset(dat, 0, length * size); } } } diff --git a/src/mame/drivers/psikyosh.c b/src/mame/drivers/psikyosh.c index 9f1c8222811..a65af3918c1 100644 --- a/src/mame/drivers/psikyosh.c +++ b/src/mame/drivers/psikyosh.c @@ -346,11 +346,11 @@ static NVRAM_HANDLER(93C56) } else // these games want the eeprom all zeros by default { - int length; + UINT32 length, size; UINT8 *dat; - dat = eeprom_get_data_pointer(&length); - memset(dat, 0, length); + dat = eeprom_get_data_pointer(&length, &size); + memset(dat, 0, length * size); if (use_factory_eeprom!=eeprom_0) /* Set the EEPROM to Factory Defaults for games needing them*/ { diff --git a/src/mame/drivers/seta2.c b/src/mame/drivers/seta2.c index 8a58cab6f96..dd6e431347c 100644 --- a/src/mame/drivers/seta2.c +++ b/src/mame/drivers/seta2.c @@ -501,12 +501,11 @@ static NVRAM_HANDLER(93C46_gundamex) } else { - int length; - UINT8 *dat; + UINT32 length, size; + UINT16 *dat; - dat = eeprom_get_data_pointer(&length); - dat[0]=0x70; - dat[1]=0x08; + dat = eeprom_get_data_pointer(&length, &size); + dat[0] = 0x7008; } } }