Laying groundwork for emulation, re-implementing memory bus
This commit is contained in:
-140
@@ -1,140 +0,0 @@
|
||||
/* This file is included through vue.c and cannot be built directly. */
|
||||
#ifdef VUEAPI
|
||||
|
||||
/* Read bytes from host memory */
|
||||
static void busReadBytes(uint8_t *src, uint8_t *dest, uint32_t address,
|
||||
uint32_t size, uint32_t length) {
|
||||
|
||||
/* There is no source data */
|
||||
if (src == NULL)
|
||||
while (length-- > 0)
|
||||
*dest++ = 0;
|
||||
|
||||
/* Copy bytes from the source as a circular buffer */
|
||||
else for (size--; length-- > 0;)
|
||||
*dest++ = src[address++ & size];
|
||||
}
|
||||
|
||||
/* Read a value directly from host memory */
|
||||
static int32_t busReadMemory(uint8_t *data, uint32_t offset, int type) {
|
||||
int32_t value; /* Value read */
|
||||
|
||||
/* There is no source data */
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
|
||||
/* Locate the value */
|
||||
data = &data[offset];
|
||||
|
||||
/* Read the value */
|
||||
switch (type) {
|
||||
case VUE_S8 : value = *(int8_t *)data; break;
|
||||
case VUE_U8 : value = *(uint8_t *)data; break;
|
||||
case VUE_S16: value = *(int16_t *)data; break;
|
||||
case VUE_U16: value = *(uint16_t *)data; break;
|
||||
case VUE_S32: value = *(int32_t *)data; break;
|
||||
}
|
||||
|
||||
/* Host memory is big-endian */
|
||||
#ifdef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S32:
|
||||
value = (value >> 16 & 0x0000FFFF) | value << 16;
|
||||
/* Fallthrough */
|
||||
case VUE_S16:
|
||||
case VUE_U16:
|
||||
value = (value >> 8 & 0x00FF00FF) | (value << 8 & 0xFF00FF00);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Read a value from the CPU bus */
|
||||
static int32_t busReadValue(VUE *vue, uint32_t address, int type) {
|
||||
address &= -TYPE_SIZES[type];
|
||||
switch (address >> 24 & 7) {
|
||||
case 1: /* Fallthrough */ /* VSU (write-only) */
|
||||
case 3: /* Fallthrough */ /* Unmapped */
|
||||
case 4: /* Cartridge expansion (not supported) */
|
||||
return 0;
|
||||
case 5: /* System WRAM */
|
||||
return busReadMemory(vue->bus.wram, address & 0xFFFF, type);
|
||||
case 6: return busReadMemory(vue->bus.sram, /* Cartridge RAM */
|
||||
address & (vue->bus.sramSize - 1), type);
|
||||
case 7: return busReadMemory(vue->bus.rom , /* Cartridge ROM */
|
||||
address & (vue->bus.romSize - 1), type);
|
||||
}
|
||||
return 0; /* Unreachable */
|
||||
}
|
||||
|
||||
/* Perform a system reset */
|
||||
static void busReset(VUE *vue) {
|
||||
int x;
|
||||
for (x = 0; x < 0x10000; x++)
|
||||
vue->bus.wram[x] = 0;
|
||||
}
|
||||
|
||||
/* Write bytes to host memory */
|
||||
static void busWriteBytes(uint8_t *dest, uint8_t *src, uint32_t address,
|
||||
uint32_t size, uint32_t length) {
|
||||
if (dest != NULL)
|
||||
for (size--; length-- > 0;)
|
||||
dest[address++ & size] = *src++;
|
||||
}
|
||||
|
||||
/* Write a value directly to host memory */
|
||||
static void busWriteMemory(uint8_t *data, uint32_t offset, int type,
|
||||
int32_t value) {
|
||||
|
||||
/* There is no destination data */
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
/* Locate the value */
|
||||
data = &data[offset];
|
||||
|
||||
/* Host memory is big-endian */
|
||||
#ifdef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S32:
|
||||
value = (value >> 16 & 0x0000FFFF) | value << 16;
|
||||
/* Fallthrough */
|
||||
case VUE_S16:
|
||||
case VUE_U16:
|
||||
value = (value >> 8 & 0x00FF00FF) | (value << 8 & 0xFF00FF00);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Write the value */
|
||||
switch (type) {
|
||||
case VUE_S8 : /* Fallthrough */
|
||||
case VUE_U8 : *(uint8_t *)data = (uint8_t) value; break;
|
||||
case VUE_S16: /* Fallthrough */
|
||||
case VUE_U16: *(uint16_t *)data = (int16_t) value; break;
|
||||
case VUE_S32: *(int32_t *)data = (int32_t) value; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Write a value to the CPU bus */
|
||||
static void busWriteValue(VUE *vue, uint32_t address, int type, int32_t value){
|
||||
address &= -TYPE_SIZES[type];
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: /* System WRAM */
|
||||
busWriteMemory(vue->bus.wram, address & 0xFFFF, type, value);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
busWriteMemory(vue->bus.sram,
|
||||
address & (vue->bus.sramSize - 1), type, value);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
busWriteMemory(vue->bus.rom ,
|
||||
address & (vue->bus.romSize - 1), type, value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* VUEAPI */
|
||||
+5
-5
@@ -124,7 +124,7 @@ static void cpuDecode(VUE_INST *inst, int32_t bits) {
|
||||
}
|
||||
|
||||
/* Read a system register */
|
||||
static int32_t cpuGetSystemRegister(VUE *vue, int index) {
|
||||
static int32_t cpuGetSystemRegister(VUE *vue, int32_t index) {
|
||||
switch (index) {
|
||||
case VUE_ADTRE: return vue->cpu.adtre;
|
||||
case VUE_EIPC : return vue->cpu.eipc;
|
||||
@@ -159,7 +159,7 @@ static int32_t cpuGetSystemRegister(VUE *vue, int index) {
|
||||
}
|
||||
|
||||
/* Write a system register */
|
||||
static int32_t cpuSetSystemRegister(VUE *vue, int index, int32_t value,
|
||||
static int32_t cpuSetSystemRegister(VUE *vue, int32_t index, int32_t value,
|
||||
vbool debug) {
|
||||
switch (index) {
|
||||
case VUE_ADTRE: return vue->cpu.adtre = value & 0xFFFFFFFE;
|
||||
@@ -225,9 +225,9 @@ static int32_t cpuSetSystemRegister(VUE *vue, int index, int32_t value,
|
||||
return 1; /* Unreachable */
|
||||
}
|
||||
|
||||
/* Perform a system reset */
|
||||
/* System reset */
|
||||
static void cpuReset(VUE *vue) {
|
||||
int x;
|
||||
int32_t x;
|
||||
|
||||
/* Configure instance fields */
|
||||
vue->cpu.cycles = 0; /* Duration of first fetch */
|
||||
@@ -251,7 +251,7 @@ static void cpuReset(VUE *vue) {
|
||||
}
|
||||
|
||||
/* Test a condition */
|
||||
static int8_t cpuTest(VUE *vue, int condition) {
|
||||
static int8_t cpuTest(VUE *vue, int32_t condition) {
|
||||
switch (condition) {
|
||||
case 0: return vue->cpu.psw_ov;
|
||||
case 1: return vue->cpu.psw_cy;
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/* This file is included through vue.c and cannot be built directly. */
|
||||
#ifdef VUEAPI
|
||||
|
||||
/*****************************************************************************
|
||||
* Module Functions *
|
||||
*****************************************************************************/
|
||||
|
||||
/* System reset */
|
||||
static void pakReset(VUE *vue) {
|
||||
vue->pak.wcr_exp1w = 0;
|
||||
vue->pak.wcr_rom1w = 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
+20
-14
@@ -159,19 +159,12 @@ typedef struct {
|
||||
|
||||
/* Emulation state */
|
||||
typedef struct {
|
||||
VUE_INST inst; /* Instruction state */
|
||||
|
||||
/* Memory bus */
|
||||
struct {
|
||||
uint8_t *rom; /* Cartridge ROM */
|
||||
uint32_t romSize; /* Number of bytes in cartridge ROM */
|
||||
uint8_t *sram; /* Cartridge RAM */
|
||||
uint32_t sramSize; /* Number of bytes in cartridge RAM */
|
||||
uint8_t wram[0x10000]; /* System memory */
|
||||
} bus;
|
||||
int32_t breakCode; /* Application break code */
|
||||
uint8_t wram[0x10000]; /* System memory */
|
||||
|
||||
/* CPU state */
|
||||
struct {
|
||||
VUE_INST inst; /* Instruction state */
|
||||
uint32_t cycles; /* Cycles until next stage */
|
||||
int32_t jumpFrom[3]; /* Source PCs of most recent jumps */
|
||||
int32_t jumpTo [3]; /* Destination PCs of most recent jumps */
|
||||
@@ -222,6 +215,16 @@ typedef struct {
|
||||
uint16_t ecr_fecc; /* Fatal Error Cause Code */
|
||||
} cpu;
|
||||
|
||||
/* Game pak */
|
||||
struct {
|
||||
uint8_t *ram; /* Cartridge SRAM */
|
||||
uint32_t ramSize; /* Number of bytes in cartridge SRAM */
|
||||
uint8_t *rom; /* Cartridge ROM */
|
||||
uint32_t romSize; /* Number of bytes in cartridge ROM */
|
||||
int8_t wcr_exp1w; /* Expansion one-wait mode */
|
||||
int8_t wcr_rom1w; /* ROM one-wait mode */
|
||||
} pak;
|
||||
|
||||
} VUE;
|
||||
|
||||
|
||||
@@ -230,13 +233,16 @@ typedef struct {
|
||||
* Function Prototypes *
|
||||
*****************************************************************************/
|
||||
|
||||
VUEAPI int32_t vueGetRegister(VUE *vue, int index, vbool system);
|
||||
VUEAPI int32_t vueEmulate (VUE *vue, int32_t maxCycles);
|
||||
VUEAPI int32_t vueGetRegister(VUE *vue, int32_t index, vbool system);
|
||||
VUEAPI void vueInitialize (VUE *vue);
|
||||
VUEAPI vbool vueRead (VUE *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
||||
VUEAPI int32_t vueRead (VUE *vue, uint32_t address, int32_t type);
|
||||
VUEAPI vbool vueReadBytes (VUE *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
||||
VUEAPI void vueReset (VUE *vue);
|
||||
VUEAPI int32_t vueSetRegister(VUE *vue, int index, vbool system, int32_t value);
|
||||
VUEAPI int32_t vueSetRegister(VUE *vue, int32_t index, vbool system, int32_t value);
|
||||
VUEAPI vbool vueSetROM (VUE *vue, uint8_t *rom, uint32_t size);
|
||||
VUEAPI vbool vueWrite (VUE *vue, uint32_t address, uint8_t *src, uint32_t length);
|
||||
VUEAPI void vueWrite (VUE *vue, uint32_t address, int32_t type, int32_t value);
|
||||
VUEAPI vbool vueWriteBytes (VUE *vue, uint32_t address, uint8_t *src, uint32_t length);
|
||||
|
||||
|
||||
|
||||
|
||||
+231
-50
@@ -18,7 +18,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
/* Memory access type sizes */
|
||||
static const int TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||
static const uint32_t TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||
|
||||
|
||||
|
||||
@@ -26,8 +26,132 @@ static const int TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||
* Component Includes *
|
||||
*****************************************************************************/
|
||||
|
||||
#include "bus.c"
|
||||
#include "cpu.c"
|
||||
#include "gamepak.c"
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* Module Functions *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Read a value from a byte buffer */
|
||||
static int32_t readBuffer(uint8_t *data, uint32_t datlen, uint32_t address,
|
||||
int32_t type) {
|
||||
uint32_t size = TYPE_SIZES[type]; /* Size of data type */
|
||||
int32_t value = 0;
|
||||
|
||||
/* Error checking */
|
||||
if (data == NULL)
|
||||
return 0;
|
||||
|
||||
/* Common processing */
|
||||
address &= (~size + 1) & (datlen - 1);
|
||||
|
||||
/* The host is little-endian */
|
||||
#ifndef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S8 : value = *( int8_t *)&data[address]; break;
|
||||
case VUE_U8 : value = *(uint8_t *)&data[address]; break;
|
||||
case VUE_S16: value = *( int16_t *)&data[address]; break;
|
||||
case VUE_U16: value = *(uint16_t *)&data[address]; break;
|
||||
case VUE_S32: value = *( int32_t *)&data[address]; break;
|
||||
}
|
||||
|
||||
/* The host is big-endian */
|
||||
#else
|
||||
switch (type) {
|
||||
case VUE_S32: value =
|
||||
data[address + 3] << 24 |
|
||||
(data[address + 2] & 0xFF) << 16;
|
||||
/* Fallthrough */
|
||||
case VUE_S16: /* Fallthrough */
|
||||
case VUE_U16: value |=
|
||||
(data[address + 1] & 0xFF) << 8;
|
||||
/* Fallthrough */
|
||||
case VUE_S8 : /* Fallthrough */
|
||||
case VUE_U8 : value |=
|
||||
data[address ] & 0xFF;
|
||||
}
|
||||
|
||||
/* Sign-extend the value if appropriate */
|
||||
if (type & 1) {
|
||||
size <<= 3;
|
||||
value = SIGN_EXTEND(size, value);
|
||||
}
|
||||
#endif
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Read bytes from a byte buffer */
|
||||
static void readBytes(uint8_t *data, uint32_t datlen, uint32_t address,
|
||||
uint8_t *dest, uint32_t length) {
|
||||
|
||||
/* The source does not exist */
|
||||
if (data == NULL) {
|
||||
while (length--)
|
||||
*dest++ = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Transfer bytes from the source as a circular buffer */
|
||||
while (length--)
|
||||
*dest++ = data[address++ & (datlen - 1)];
|
||||
}
|
||||
|
||||
/* Write a value to a byte buffer */
|
||||
static void writeBuffer(uint8_t *data, uint32_t datlen, uint32_t address,
|
||||
int32_t type, int32_t value) {
|
||||
uint32_t size = TYPE_SIZES[type]; /* Size of data type */
|
||||
|
||||
/* Error checking */
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
/* Common processing */
|
||||
address &= (~size + 1) & (datlen - 1);
|
||||
|
||||
/* The host is little-endian */
|
||||
#ifndef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S8 : /* Fallthrough */
|
||||
case VUE_U8 : *(int8_t *)&data[address] = (int8_t ) value; break;
|
||||
case VUE_S16: /* Fallthrough */
|
||||
case VUE_U16: *(int16_t *)&data[address] = (int16_t ) value; break;
|
||||
case VUE_S32: *(int32_t *)&data[address] = (int32_t ) value; break;
|
||||
}
|
||||
|
||||
/* The host is big-endian */
|
||||
#else
|
||||
switch (type) {
|
||||
case VUE_S32:
|
||||
data[address + 3] = (uint8_t) (value >> 24);
|
||||
data[address + 2] = (uint8_t) (value >> 16);
|
||||
/* Fallthrough */
|
||||
case VUE_S16: /* Fallthrough */
|
||||
case VUE_U16:
|
||||
data[address + 1] = (uint8_t) (value >> 8);
|
||||
/* Fallthrough */
|
||||
case VUE_S8 : /* Fallthrough */
|
||||
case VUE_U8 : value |=
|
||||
data[address ] = (uint8_t) value;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Write bytes to a byte buffer */
|
||||
static void writeBytes(uint8_t *data, uint32_t datlen, uint32_t address,
|
||||
uint8_t *src, uint32_t length) {
|
||||
|
||||
/* The destination does not exist */
|
||||
if (data == NULL)
|
||||
return;
|
||||
|
||||
/* Transfer bytes to the destination as a circular buffer */
|
||||
while (length--)
|
||||
data[address++ & (datlen - 1)] = *src++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +159,47 @@ static const int TYPE_SIZES[] = { 1, 1, 2, 2, 4 };
|
||||
* Library Functions *
|
||||
*****************************************************************************/
|
||||
|
||||
/* Process the simulation */
|
||||
int32_t vueEmulate(VUE *vue, int32_t maxCycles) {
|
||||
int32_t cycles; /* Number of cycles to process */
|
||||
|
||||
/* Process up to the given number of cycles */
|
||||
do {
|
||||
|
||||
/* Determine the number of cycles during which nothing will happen */
|
||||
cycles = maxCycles;
|
||||
/*cycles = cpuUntil (vue, cycles);*/
|
||||
/*cycles = padUntil (vue, cycles);*/
|
||||
/*cycles = linkUntil (vue, cycles);*/
|
||||
/*cycles = timerUntil(vue, cycles);*/
|
||||
/*cycles = vipUntil (vue, cycles);*/
|
||||
/*cycles = vsuUntil (vue, cycles);*/
|
||||
|
||||
/* Process all system components */
|
||||
vue->breakCode = 0;
|
||||
/*gamePad.emulate(cycles);*/
|
||||
/*gamePak.emulate(cycles);*/
|
||||
/*link .emulate(cycles);*/
|
||||
/*timer .emulate(cycles);*/
|
||||
/*vip .emulate(cycles);*/
|
||||
/*vsu .emulate(cycles);*/
|
||||
/*cpu .emulate(cycles);*/
|
||||
|
||||
/* An application break was requested */
|
||||
if (vue->breakCode != 0)
|
||||
break;
|
||||
|
||||
/* Update the number of cycles remaining */
|
||||
if (maxCycles >= 0)
|
||||
maxCycles -= cycles;
|
||||
} while (maxCycles != 0);
|
||||
|
||||
/* A break condition has occurred */
|
||||
return maxCycles;
|
||||
}
|
||||
|
||||
/* Retrieve the value of a register */
|
||||
int32_t vueGetRegister(VUE *vue, int index, vbool system) {
|
||||
int32_t vueGetRegister(VUE *vue, int32_t index, vbool system) {
|
||||
|
||||
/* Error checking */
|
||||
if (vue == NULL)
|
||||
@@ -63,12 +226,22 @@ int32_t vueGetRegister(VUE *vue, int index, vbool system) {
|
||||
void vueInitialize(VUE *vue) {
|
||||
if (vue == NULL)
|
||||
return;
|
||||
vue->bus.rom = NULL;
|
||||
vue->bus.sram = NULL;
|
||||
vue->pak.ram = NULL;
|
||||
vue->pak.rom = NULL;
|
||||
}
|
||||
|
||||
/* Read a value from the CPU bus */
|
||||
int32_t vueRead(VUE *vue, uint32_t address, int32_t type) {
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: return readBuffer(vue->wram , 0x10000,address,type);
|
||||
case 6: return readBuffer(vue->pak.ram,vue->pak.ramSize,address,type);
|
||||
case 7: return readBuffer(vue->pak.rom,vue->pak.romSize,address,type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read bytes from the CPU bus */
|
||||
vbool vueRead(VUE *vue, uint32_t address, uint8_t *dest, uint32_t length) {
|
||||
vbool vueReadBytes(VUE *vue, uint32_t address, uint8_t *dest, uint32_t length){
|
||||
uint32_t count; /* Bytes to read in one iteration */
|
||||
|
||||
/* Error checking */
|
||||
@@ -76,45 +249,46 @@ vbool vueRead(VUE *vue, uint32_t address, uint8_t *dest, uint32_t length) {
|
||||
return VUE_FALSE;
|
||||
|
||||
/* Perform the operation */
|
||||
for (; length > 0; address += count, length -= count, dest += count) {
|
||||
|
||||
/* Determine the maximum number of bytes to process at once */
|
||||
while (length > 0) {
|
||||
count = 0x01000000 - (address & 0x00FFFFFF);
|
||||
if (count > length)
|
||||
if (length < count)
|
||||
count = length;
|
||||
|
||||
/* Process by component */
|
||||
switch (address >> 24 & 7) {
|
||||
case 1: /* Fallthrough */ /* VSU (write-only) */
|
||||
case 3: /* Fallthrough */ /* Unmapped */
|
||||
case 4: /* Cartridge expansion (not supported) */
|
||||
busReadBytes(NULL, dest, address, 0, count);
|
||||
break;
|
||||
case 5: busReadBytes(vue->bus.wram, dest, /* System WRAM */
|
||||
address, 0x10000 , count);
|
||||
break;
|
||||
case 6: busReadBytes(vue->bus.sram, dest, /* Cartridge RAM */
|
||||
address, vue->bus.sramSize, count);
|
||||
break;
|
||||
case 7: busReadBytes(vue->bus.rom , dest, /* Cartridge ROM */
|
||||
address, vue->bus.romSize , count);
|
||||
break;
|
||||
case 5: readBytes(vue->wram , 0x10000,
|
||||
address, dest, count); break;
|
||||
case 6: readBytes(vue->pak.ram, vue->pak.ramSize,
|
||||
address, dest, count); break;
|
||||
case 7: readBytes(vue->pak.rom, vue->pak.romSize,
|
||||
address, dest, count); break;
|
||||
default:
|
||||
for (address += count, length -= count; count--;)
|
||||
*dest++ = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
};
|
||||
address += count;
|
||||
length -= count;
|
||||
dest += count;
|
||||
}
|
||||
return VUE_TRUE;
|
||||
}
|
||||
|
||||
/* Initialize all system components */
|
||||
void vueReset(VUE *vue) {
|
||||
uint32_t x; /* Iterator */
|
||||
|
||||
/* Error checking */
|
||||
if (vue == NULL)
|
||||
return;
|
||||
busReset(vue);
|
||||
|
||||
/* Reset state */
|
||||
cpuReset(vue);
|
||||
pakReset(vue);
|
||||
for (x = 0; x < 0x1000; x++)
|
||||
vue->wram[x] = 0;
|
||||
}
|
||||
|
||||
/* Specify a value for a register */
|
||||
int32_t vueSetRegister(VUE *vue, int index, vbool system, int32_t value) {
|
||||
int32_t vueSetRegister(VUE *vue, int32_t index, vbool system, int32_t value) {
|
||||
return vue == NULL ? 0 :
|
||||
index == VUE_PC && system ? vue->cpu.pc = value & 0xFFFFFFFE :
|
||||
index < 0 || index > 31 ? 0 :
|
||||
@@ -135,13 +309,25 @@ vbool vueSetROM(VUE *vue, uint8_t *rom, uint32_t size) {
|
||||
) return VUE_FALSE;
|
||||
|
||||
/* Accept the new ROM buffer */
|
||||
vue->bus.rom = rom;
|
||||
vue->bus.romSize = size;
|
||||
vue->pak.rom = rom;
|
||||
vue->pak.romSize = size;
|
||||
return VUE_TRUE;
|
||||
}
|
||||
|
||||
/* Write a value to the CPU bus */
|
||||
void vueWrite(VUE *vue, uint32_t address, int32_t type, int32_t value) {
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: writeBuffer(vue->wram , 0x1000,
|
||||
address, type, value); break;
|
||||
case 6: writeBuffer(vue->pak.ram, vue->pak.ramSize,
|
||||
address, type, value); break;
|
||||
case 7: writeBuffer(vue->pak.rom, vue->pak.romSize,
|
||||
address, type, value); break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write bytes to the CPU bus */
|
||||
vbool vueWrite(VUE *vue, uint32_t address, uint8_t *src, uint32_t length) {
|
||||
vbool vueWriteBytes(VUE *vue, uint32_t address, uint8_t *src, uint32_t length){
|
||||
uint32_t count; /* Bytes to write in one iteration */
|
||||
|
||||
/* Error checking */
|
||||
@@ -149,26 +335,21 @@ vbool vueWrite(VUE *vue, uint32_t address, uint8_t *src, uint32_t length) {
|
||||
return VUE_FALSE;
|
||||
|
||||
/* Perform the operation */
|
||||
for (; length > 0; address += count, length -= count, src += count) {
|
||||
|
||||
/* Determine the maximum number of bytes to process at once */
|
||||
while (length > 0) {
|
||||
count = 0x01000000 - (address & 0x00FFFFFF);
|
||||
if (count > length)
|
||||
if (length < count)
|
||||
count = length;
|
||||
|
||||
/* Process by component */
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: /* System WRAM */
|
||||
busWriteBytes(vue->bus.wram, src, address, 0x10000, count);
|
||||
break;
|
||||
case 6: busWriteBytes(vue->bus.sram, src, /* Cartridge RAM */
|
||||
address, vue->bus.sramSize, count);
|
||||
break;
|
||||
case 7: busWriteBytes(vue->bus.rom , src, /* Cartridge ROM */
|
||||
address, vue->bus.romSize , count);
|
||||
break;
|
||||
case 5: writeBytes(vue->wram , 0x10000,
|
||||
address, src, count); break;
|
||||
case 6: writeBytes(vue->pak.ram, vue->pak.ramSize,
|
||||
address, src, count); break;
|
||||
case 7: writeBytes(vue->pak.rom, vue->pak.ramSize,
|
||||
address, src, count); break;
|
||||
}
|
||||
|
||||
};
|
||||
address += count;
|
||||
length -= count;
|
||||
src += count;
|
||||
}
|
||||
return VUE_TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user