Finishing viewRead()/viewWrite()
This commit is contained in:
+117
-30
@@ -1,47 +1,134 @@
|
||||
/* This file is included through vue.c and cannot be built directly. */
|
||||
#ifdef VUEAPI
|
||||
|
||||
/* Read a value directly from host memory */
|
||||
static int32_t busReadMemory(uint8_t *data, int type) {
|
||||
/* Read bytes from host memory */
|
||||
static void busReadBytes(uint8_t *src, uint8_t *dest, uint32_t address,
|
||||
uint32_t size, uint32_t length) {
|
||||
|
||||
/* Host memory is little-endian */
|
||||
#ifndef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S8 : return *(int8_t *)data;
|
||||
case VUE_U8 : return *(uint8_t *)data;
|
||||
case VUE_S16: return *(int16_t *)data;
|
||||
case VUE_U16: return *(uint16_t *)data;
|
||||
case VUE_S32: return *(int32_t *)data;
|
||||
}
|
||||
/* 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 */
|
||||
#else
|
||||
#ifdef VUE_BIGENDIAN
|
||||
switch (type) {
|
||||
case VUE_S8 : return (int8_t ) data[0];
|
||||
case VUE_U8 : return (uint8_t ) data[0];
|
||||
case VUE_S16: return (int16_t ) data[0] << 8 | data[1];
|
||||
case VUE_U16: return (uint16_t) data[0] << 8 | data[1];
|
||||
case VUE_S32: return (int32_t )
|
||||
data[0] << 24 | data[1] << 16 | data[2] << 8 | data[3];
|
||||
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 0; /* Unreachable, but the compiler doesn't know that */
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Perform a read operation */
|
||||
static int32_t busReadValue(VUE *vue, uint32_t address, int type, vbool debug){
|
||||
address &= ~TYPE_SIZES[type] + 1;
|
||||
/* 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 3: /* Unmapped */
|
||||
case 4: return 0; /* Cartridge expansion */
|
||||
case 5: return busReadMemory(&vue->wram[address & 8191], type);
|
||||
case 6: return vue->sram == NULL ? 0 :
|
||||
busReadMemory(&vue->sram[address & (vue->sram_size - 1)], type);
|
||||
case 7: return vue->rom == NULL ? 0 :
|
||||
busReadMemory(&vue->rom [address & (vue->rom_size - 1)], type);
|
||||
case 1: /* Fallthrough */ /* VSU (write-only) */
|
||||
case 3: /* Fallthrough */ /* Unmapped */
|
||||
case 4: /* Cartridge expansion (not supported) */
|
||||
return 0;
|
||||
case 5: return /* System WRAM */
|
||||
busReadMemory(vue->wram, address & 0xFFFF , type);
|
||||
case 6: return /* Cartridge RAM */
|
||||
busReadMemory(vue->sram, address & (vue->sram_size - 1), type);
|
||||
case 7: return /* Cartridge ROM */
|
||||
busReadMemory(vue->rom , address & (vue->rom_size - 1), type);
|
||||
}
|
||||
return 0; /* Unreachable */
|
||||
}
|
||||
|
||||
/* 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->wram,
|
||||
address & 0xFFFF , type, value);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
busWriteMemory(vue->sram,
|
||||
address & (vue->sram_size - 1), type, value);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
busWriteMemory(vue->rom ,
|
||||
address & (vue->rom_size - 1), type, value);
|
||||
break;
|
||||
}
|
||||
return debug * 0; /* Unreachable */
|
||||
}
|
||||
|
||||
#endif /* VUEAPI */
|
||||
|
||||
@@ -55,8 +55,9 @@ typedef struct {
|
||||
*****************************************************************************/
|
||||
|
||||
VUEAPI void vueInitialize(VUE *vue);
|
||||
VUEAPI vbool vueRead (VUE *vue, uint32_t address, uint8_t *data, uint32_t length);
|
||||
VUEAPI vbool vueRead (VUE *vue, uint32_t address, uint8_t *dest, uint32_t length);
|
||||
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);
|
||||
|
||||
|
||||
|
||||
|
||||
+52
-9
@@ -30,19 +30,16 @@ void vueInitialize(VUE *vue) {
|
||||
vue->sram = NULL;
|
||||
}
|
||||
|
||||
/* Perform a read operation */
|
||||
vbool vueRead(VUE *vue, uint32_t address, uint8_t *data, uint32_t length) {
|
||||
/* Read bytes from the CPU bus */
|
||||
vbool vueRead(VUE *vue, uint32_t address, uint8_t *dest, uint32_t length) {
|
||||
uint32_t count; /* Bytes to read in one iteration */
|
||||
|
||||
/* Error checking */
|
||||
if (
|
||||
vue == NULL ||
|
||||
data == NULL ||
|
||||
length > 0x01000000
|
||||
) return VUE_FALSE;
|
||||
if (vue == NULL || dest == NULL)
|
||||
return VUE_FALSE;
|
||||
|
||||
/* Perform the operation */
|
||||
for (; length > 0; address += count, length -= count, data += count) {
|
||||
for (; length > 0; address += count, length -= count, dest += count) {
|
||||
|
||||
/* Determine the maximum number of bytes to process at once */
|
||||
count = 0x01000000 - (address & 0x00FFFFFF);
|
||||
@@ -51,7 +48,20 @@ vbool vueRead(VUE *vue, uint32_t address, uint8_t *data, uint32_t length) {
|
||||
|
||||
/* Process by component */
|
||||
switch (address >> 24 & 7) {
|
||||
/* case 7: ROM, etc */
|
||||
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: /* System WRAM */
|
||||
busReadBytes(vue->wram, dest, address, 0x10000 , count);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
busReadBytes(vue->sram, dest, address, vue->sram_size, count);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
busReadBytes(vue->rom , dest, address, vue->rom_size , count);
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -74,3 +84,36 @@ vbool vueSetROM(VUE *vue, uint8_t *rom, uint32_t size) {
|
||||
vue->rom_size = size;
|
||||
return VUE_TRUE;
|
||||
}
|
||||
|
||||
/* Write bytes to the CPU bus */
|
||||
vbool vueWrite(VUE *vue, uint32_t address, uint8_t *src, uint32_t length) {
|
||||
uint32_t count; /* Bytes to write in one iteration */
|
||||
|
||||
/* Error checking */
|
||||
if (vue == NULL || src == NULL)
|
||||
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 */
|
||||
count = 0x01000000 - (address & 0x00FFFFFF);
|
||||
if (count > length)
|
||||
count = length;
|
||||
|
||||
/* Process by component */
|
||||
switch (address >> 24 & 7) {
|
||||
case 5: /* System WRAM */
|
||||
busWriteBytes(vue->wram, src, address, 0x10000 , count);
|
||||
break;
|
||||
case 6: /* Cartridge RAM */
|
||||
busWriteBytes(vue->sram, src, address, vue->sram_size, count);
|
||||
break;
|
||||
case 7: /* Cartridge ROM */
|
||||
busWriteBytes(vue->rom , src, address, vue->rom_size , count);
|
||||
break;
|
||||
}
|
||||
|
||||
};
|
||||
return VUE_TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user