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:
Aaron Giles 2008-07-17 08:07:12 +00:00
parent b859963772
commit b5f2aa1240
22 changed files with 764 additions and 223 deletions

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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));
}

View File

@ -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);
/* 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 */
offset = ADDR2BYTE(offset, info, space);
address = ADDR2BYTE(address, info, space);
/* switch contexts and do the read */
cpuintrf_push_context(cpuindex);
switch (size)
{
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;
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;
}
}

View File

@ -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;

View File

@ -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)

View File

@ -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_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)
};
@ -151,11 +161,15 @@ union _int_ptr
};
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 */
token_type type; /* type of token */
token_info info; /* info for token */
UINT32 offset; /* offset within the string */
int_ptr value; /* value of token */
};
@ -164,7 +178,7 @@ struct _parse_token
typedef struct _internal_symbol_entry internal_symbol_entry;
struct _internal_symbol_entry
{
internal_symbol_entry *next; /* pointer to the next entry */
internal_symbol_entry * next; /* pointer to the next entry */
const char * name; /* name of the symbol */
symbol_entry entry; /* actual entry data */
};
@ -173,20 +187,21 @@ struct _internal_symbol_entry
/* 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) */
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 */
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,7 +1671,7 @@ 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;
@ -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;

View File

@ -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,8 +118,8 @@ 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 */
@ -99,7 +127,7 @@ struct _symbol_entry
{
UINT16 minparams; /* minimum expected parameters */
UINT16 maxparams; /* maximum expected parameters */
UINT64 (*execute)(UINT32, UINT32, UINT64 *);/* execute */
function_execute_func execute; /* execute callback */
} func;
/* generic 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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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__ */

View File

@ -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 =

View File

@ -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);
}
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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*/
{

View File

@ -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;
}
}
}