mirror of
https://github.com/holub/mame
synced 2025-05-04 21:43:05 +03:00
Changed direct access EEPROM interface to return the "bus width" of the
EEPROM data, and the size is in terms of units, not bytes. Updated all drivers accordingly. Changed the ROM loading code to actually alter the region flags based on the CPU endianness and bus width when creating the region, rather than fixing them up on the fly. This means that callers to memory_region_flags() will get the correct results. Changed the expression engine to use two callbacks for read/write rather than relying on externally defined functions. Expanded memory access support in the expression engine. Memory accesses can now be specified as [space][num]<size>@<address>. 'space' can be one of the following: p = program address space of CPU #num (default) d = data address space of CPU #num i = I/O address space of CPU #num o = opcode address space of CPU #num (R/W access to decrypted opcodes) r = direct RAM space of CPU #num (always allows writes, even for ROM) e = EEPROM index #num c = direct REGION_CPU#num access u = direct REGION_USER#num access g = direct REGION_GFX#num access s = direct REGION_SOUND#num access The 'num' field is optional for p/d/i/o/r, where is defaults to the current CPU, and for e, where it defaults to EEPROM #0. 'num' is required for all region-related prefixes. Some examples: w@curpc = word at 'curpc' in the active CPU's program address space dd@0 = dword at 0x0 in the active CPU's data address space r2b@100 = byte at 0x100 from a RAM/ROM region in CPU #2's program space ew@7f = word from EEPROM address 0x7f u2q@40 = qword from REGION_USER2, offset 0x40 The 'size' field is always required, and can be b/w/d/q for byte, word, dword, and qword accesses.
This commit is contained in:
parent
b859963772
commit
b5f2aa1240
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "debugger.h"
|
||||
#include "deprecat.h"
|
||||
#include "uiinput.h"
|
||||
#include "machine/eeprom.h"
|
||||
#include <ctype.h>
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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 =
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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*/
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user