all repos — mgba @ a7f15672861a46767a37cd0fec1398c05a2790fc

mGBA Game Boy Advance Emulator

DS GX: Stub out GX
Vicki Pfau vi@endrift.com
Sat, 25 Feb 2017 15:25:50 -0800
commit

a7f15672861a46767a37cd0fec1398c05a2790fc

parent

d41b904485e18f85a287101722351f93b6d9764e

M include/mgba/internal/ds/ds.hinclude/mgba/internal/ds/ds.h

@@ -14,6 +14,7 @@ #include <mgba/core/log.h>

#include <mgba/core/timing.h> #include <mgba-util/circle-buffer.h> +#include <mgba/internal/ds/gx.h> #include <mgba/internal/ds/memory.h> #include <mgba/internal/ds/timer.h> #include <mgba/internal/ds/video.h>

@@ -78,6 +79,7 @@ struct DSCommon ds7;

struct DSCommon ds9; struct DSMemory memory; struct DSVideo video; + struct DSGX gx; struct mCoreSync* sync; struct mTimingEvent slice;
A include/mgba/internal/ds/gx.h

@@ -0,0 +1,87 @@

+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#ifndef DS_GX_H +#define DS_GX_H + +#include <mgba-util/common.h> + +CXX_GUARD_START + +#include <mgba/core/log.h> +#include <mgba/core/timing.h> +#include <mgba-util/circle-buffer.h> + +mLOG_DECLARE_CATEGORY(DS_GX); + +enum DSGXCommand { + DS_GX_CMD_NOP = 0, + DS_GX_CMD_MTX_MODE = 0x10, + DS_GX_CMD_MTX_PUSH = 0x11, + DS_GX_CMD_MTX_POP = 0x12, + DS_GX_CMD_MTX_STORE = 0x13, + DS_GX_CMD_MTX_RESTORE = 0x14, + DS_GX_CMD_MTX_IDENTITY = 0x15, + DS_GX_CMD_MTX_LOAD_4x4 = 0x16, + DS_GX_CMD_MTX_LOAD_4x3 = 0x17, + DS_GX_CMD_MTX_MULT_4x4 = 0x18, + DS_GX_CMD_MTX_MULT_4x3 = 0x19, + DS_GX_CMD_MTX_MULT_3x3 = 0x1A, + DS_GX_CMD_MTX_SCALE = 0x1B, + DS_GX_CMD_MTX_TRANS = 0x1C, + DS_GX_CMD_COLOR = 0x20, + DS_GX_CMD_NORMAL = 0x21, + DS_GX_CMD_TEXCOORD = 0x22, + DS_GX_CMD_VTX_16 = 0x23, + DS_GX_CMD_VTX_10 = 0x24, + DS_GX_CMD_VTX_XY = 0x25, + DS_GX_CMD_VTX_XZ = 0x26, + DS_GX_CMD_VTX_YZ = 0x27, + DS_GX_CMD_VTX_DIFF = 0x28, + DS_GX_CMD_POLYGON_ATTR = 0x29, + DS_GX_CMD_TEXIMAGE_PARAM = 0x2A, + DS_GX_CMD_PLTT_BASE = 0x2B, + DS_GX_CMD_DIF_AMB = 0x30, + DS_GX_CMD_SPE_EMI = 0x31, + DS_GX_CMD_LIGHT_VECTOR = 0x32, + DS_GX_CMD_LIGHT_COLOR = 0x33, + DS_GX_CMD_SHININESS = 0x34, + DS_GX_CMD_BEGIN_VTXS = 0x40, + DS_GX_CMD_END_VTXS = 0x41, + DS_GX_CMD_SWAP_BUFFERS = 0x50, + DS_GX_CMD_VIEWPORT = 0x60, + DS_GX_CMD_BOX_TEST = 0x70, + DS_GX_CMD_POS_TEST = 0x71, + DS_GX_CMD_VEC_TEST = 0x72, + + DS_GX_CMD_MAX +}; + +#pragma pack(push, 1) +struct DSGXEntry { + uint8_t command; + uint8_t params[4]; +}; +#pragma pack(pop) + +struct DS; +struct DSGX { + struct DS* p; + struct DSGXEntry pipe[4]; + struct CircleBuffer fifo; + + struct mTimingEvent fifoEvent; +}; + +void DSGXInit(struct DSGX*); +void DSGXDeinit(struct DSGX*); +void DSGXReset(struct DSGX*); + +uint16_t DSGXWriteRegister(struct DSGX*, uint32_t address, uint16_t value); +uint32_t DSGXWriteRegister32(struct DSGX*, uint32_t address, uint32_t value); + +CXX_GUARD_END + +#endif
M include/mgba/internal/ds/io.hinclude/mgba/internal/ds/io.h

@@ -166,7 +166,6 @@ DS9_REG_A_MOSAIC = 0x04C,

DS9_REG_A_BLDCNT = 0x050, DS9_REG_A_BLDALPHA = 0x052, DS9_REG_A_BLDY = 0x054, - DS9_REG_DISP3DCNT = 0x060, DS9_REG_DISPCAPCNT_LO = 0x064, DS9_REG_DISPCAPCNT_HI = 0x066, DS9_REG_DISP_MMEM_FIFO_LO = 0x068,

@@ -255,6 +254,173 @@ DS9_REG_SQRT_PARAM_0 = 0x2B8,

DS9_REG_SQRT_PARAM_1 = 0x2BA, DS9_REG_SQRT_PARAM_2 = 0x2BC, DS9_REG_SQRT_PARAM_3 = 0x2BE, + + // GX + DS9_REG_DISP3DCNT = 0x060, + DS9_REG_RDLINES_COUNT = 0x320, + DS9_REG_EDGE_COLOR_0 = 0x330, + DS9_REG_EDGE_COLOR_1 = 0x332, + DS9_REG_EDGE_COLOR_2 = 0x334, + DS9_REG_EDGE_COLOR_3 = 0x336, + DS9_REG_EDGE_COLOR_4 = 0x338, + DS9_REG_EDGE_COLOR_5 = 0x33A, + DS9_REG_EDGE_COLOR_6 = 0x33C, + DS9_REG_EDGE_COLOR_7 = 0x33E, + DS9_REG_ALPHA_TEST_REF = 0x340, + DS9_REG_CLEAR_COLOR_LO = 0x350, + DS9_REG_CLEAR_COLOR_HI = 0x352, + DS9_REG_CLEAR_DEPTH = 0x354, + DS9_REG_CLRIMAGE_OFFSET = 0x356, + DS9_REG_FOG_COLOR_LO = 0x358, + DS9_REG_FOG_COLOR_HI = 0x35A, + DS9_REG_FOG_OFFSET = 0x35C, + DS9_REG_FOG_TABLE_0 = 0x360, + DS9_REG_FOG_TABLE_1 = 0x362, + DS9_REG_FOG_TABLE_2 = 0x364, + DS9_REG_FOG_TABLE_3 = 0x366, + DS9_REG_FOG_TABLE_4 = 0x368, + DS9_REG_FOG_TABLE_5 = 0x36A, + DS9_REG_FOG_TABLE_6 = 0x36C, + DS9_REG_FOG_TABLE_7 = 0x36E, + DS9_REG_FOG_TABLE_8 = 0x370, + DS9_REG_FOG_TABLE_9 = 0x372, + DS9_REG_FOG_TABLE_A = 0x374, + DS9_REG_FOG_TABLE_B = 0x376, + DS9_REG_FOG_TABLE_C = 0x378, + DS9_REG_FOG_TABLE_D = 0x37A, + DS9_REG_FOG_TABLE_E = 0x37C, + DS9_REG_FOG_TABLE_F = 0x37E, + DS9_REG_TOON_TABLE_00 = 0x380, + DS9_REG_TOON_TABLE_01 = 0x382, + DS9_REG_TOON_TABLE_02 = 0x384, + DS9_REG_TOON_TABLE_03 = 0x386, + DS9_REG_TOON_TABLE_04 = 0x388, + DS9_REG_TOON_TABLE_05 = 0x38A, + DS9_REG_TOON_TABLE_06 = 0x38C, + DS9_REG_TOON_TABLE_07 = 0x38E, + DS9_REG_TOON_TABLE_08 = 0x390, + DS9_REG_TOON_TABLE_09 = 0x392, + DS9_REG_TOON_TABLE_0A = 0x394, + DS9_REG_TOON_TABLE_0B = 0x396, + DS9_REG_TOON_TABLE_0C = 0x398, + DS9_REG_TOON_TABLE_0D = 0x39A, + DS9_REG_TOON_TABLE_0E = 0x39C, + DS9_REG_TOON_TABLE_0F = 0x39E, + DS9_REG_TOON_TABLE_10 = 0x3A0, + DS9_REG_TOON_TABLE_11 = 0x3A2, + DS9_REG_TOON_TABLE_12 = 0x3A4, + DS9_REG_TOON_TABLE_13 = 0x3A6, + DS9_REG_TOON_TABLE_14 = 0x3A8, + DS9_REG_TOON_TABLE_15 = 0x3AA, + DS9_REG_TOON_TABLE_16 = 0x3AC, + DS9_REG_TOON_TABLE_17 = 0x3AE, + DS9_REG_TOON_TABLE_18 = 0x3B0, + DS9_REG_TOON_TABLE_19 = 0x3B2, + DS9_REG_TOON_TABLE_1A = 0x3B4, + DS9_REG_TOON_TABLE_1B = 0x3B6, + DS9_REG_TOON_TABLE_1C = 0x3B8, + DS9_REG_TOON_TABLE_1D = 0x3BA, + DS9_REG_TOON_TABLE_1E = 0x3BC, + DS9_REG_TOON_TABLE_1F = 0x3BE, + DS9_REG_GXFIFO_00 = 0x400, + DS9_REG_GXFIFO_01 = 0x402, + DS9_REG_GXFIFO_02 = 0x404, + DS9_REG_GXFIFO_03 = 0x406, + DS9_REG_GXFIFO_04 = 0x408, + DS9_REG_GXFIFO_05 = 0x40A, + DS9_REG_GXFIFO_06 = 0x40C, + DS9_REG_GXFIFO_07 = 0x40E, + DS9_REG_GXFIFO_08 = 0x410, + DS9_REG_GXFIFO_09 = 0x412, + DS9_REG_GXFIFO_0A = 0x414, + DS9_REG_GXFIFO_0B = 0x416, + DS9_REG_GXFIFO_0C = 0x418, + DS9_REG_GXFIFO_0D = 0x41A, + DS9_REG_GXFIFO_0E = 0x41C, + DS9_REG_GXFIFO_0F = 0x41E, + DS9_REG_GXFIFO_10 = 0x420, + DS9_REG_GXFIFO_11 = 0x422, + DS9_REG_GXFIFO_12 = 0x424, + DS9_REG_GXFIFO_13 = 0x426, + DS9_REG_GXFIFO_14 = 0x428, + DS9_REG_GXFIFO_15 = 0x42A, + DS9_REG_GXFIFO_16 = 0x42C, + DS9_REG_GXFIFO_17 = 0x42E, + DS9_REG_GXFIFO_18 = 0x430, + DS9_REG_GXFIFO_19 = 0x432, + DS9_REG_GXFIFO_1A = 0x434, + DS9_REG_GXFIFO_1B = 0x436, + DS9_REG_GXFIFO_1C = 0x438, + DS9_REG_GXFIFO_1D = 0x43A, + DS9_REG_GXFIFO_1E = 0x43C, + DS9_REG_GXFIFO_1F = 0x43E, + DS9_REG_GXSTAT_LO = 0x600, + DS9_REG_GXSTAT_HI = 0x602, + DS9_REG_RAM_COUNT_LO = 0x604, + DS9_REG_RAM_COUNT_HI = 0x606, + DS9_REG_DISP_1DOT_DEPTH = 0x610, + DS9_REG_POS_RESULT_0 = 0x620, + DS9_REG_POS_RESULT_1 = 0x622, + DS9_REG_POS_RESULT_2 = 0x624, + DS9_REG_POS_RESULT_3 = 0x626, + DS9_REG_POS_RESULT_4 = 0x628, + DS9_REG_POS_RESULT_5 = 0x62A, + DS9_REG_POS_RESULT_6 = 0x62C, + DS9_REG_POS_RESULT_7 = 0x62E, + DS9_REG_VEC_RESULT_0 = 0x630, + DS9_REG_VEC_RESULT_1 = 0x632, + DS9_REG_VEC_RESULT_2 = 0x634, + DS9_REG_CLIPMTX_RESULT_00 = 0x640, + DS9_REG_CLIPMTX_RESULT_01 = 0x642, + DS9_REG_CLIPMTX_RESULT_02 = 0x644, + DS9_REG_CLIPMTX_RESULT_03 = 0x646, + DS9_REG_CLIPMTX_RESULT_04 = 0x648, + DS9_REG_CLIPMTX_RESULT_05 = 0x64A, + DS9_REG_CLIPMTX_RESULT_06 = 0x64C, + DS9_REG_CLIPMTX_RESULT_07 = 0x64E, + DS9_REG_CLIPMTX_RESULT_08 = 0x650, + DS9_REG_CLIPMTX_RESULT_09 = 0x652, + DS9_REG_CLIPMTX_RESULT_0A = 0x654, + DS9_REG_CLIPMTX_RESULT_0B = 0x656, + DS9_REG_CLIPMTX_RESULT_0C = 0x658, + DS9_REG_CLIPMTX_RESULT_0D = 0x65A, + DS9_REG_CLIPMTX_RESULT_0E = 0x65C, + DS9_REG_CLIPMTX_RESULT_0F = 0x65E, + DS9_REG_CLIPMTX_RESULT_10 = 0x660, + DS9_REG_CLIPMTX_RESULT_11 = 0x662, + DS9_REG_CLIPMTX_RESULT_12 = 0x664, + DS9_REG_CLIPMTX_RESULT_13 = 0x666, + DS9_REG_CLIPMTX_RESULT_14 = 0x668, + DS9_REG_CLIPMTX_RESULT_15 = 0x66A, + DS9_REG_CLIPMTX_RESULT_16 = 0x66C, + DS9_REG_CLIPMTX_RESULT_17 = 0x66E, + DS9_REG_CLIPMTX_RESULT_18 = 0x670, + DS9_REG_CLIPMTX_RESULT_19 = 0x672, + DS9_REG_CLIPMTX_RESULT_1A = 0x674, + DS9_REG_CLIPMTX_RESULT_1B = 0x676, + DS9_REG_CLIPMTX_RESULT_1C = 0x678, + DS9_REG_CLIPMTX_RESULT_1D = 0x67A, + DS9_REG_CLIPMTX_RESULT_1E = 0x67C, + DS9_REG_CLIPMTX_RESULT_1F = 0x67E, + DS9_REG_VECMTX_RESULT_00 = 0x680, + DS9_REG_VECMTX_RESULT_01 = 0x682, + DS9_REG_VECMTX_RESULT_02 = 0x684, + DS9_REG_VECMTX_RESULT_03 = 0x686, + DS9_REG_VECMTX_RESULT_04 = 0x688, + DS9_REG_VECMTX_RESULT_05 = 0x68A, + DS9_REG_VECMTX_RESULT_06 = 0x68C, + DS9_REG_VECMTX_RESULT_07 = 0x68E, + DS9_REG_VECMTX_RESULT_08 = 0x690, + DS9_REG_VECMTX_RESULT_09 = 0x692, + DS9_REG_VECMTX_RESULT_0A = 0x694, + DS9_REG_VECMTX_RESULT_0B = 0x696, + DS9_REG_VECMTX_RESULT_0C = 0x698, + DS9_REG_VECMTX_RESULT_0D = 0x69A, + DS9_REG_VECMTX_RESULT_0E = 0x69C, + DS9_REG_VECMTX_RESULT_0F = 0x69E, + DS9_REG_VECMTX_RESULT_10 = 0x6A0, + DS9_REG_VECMTX_RESULT_11 = 0x6A2, + DS9_REG_VECMTX_RESULT_12 = 0x6A4, DS9_REG_MAX = 0x106E,
M src/ds/ds.csrc/ds/ds.c

@@ -196,6 +196,9 @@

DSVideoInit(&ds->video); ds->video.p = ds; + DSGXInit(&ds->gx); + ds->gx.p = ds; + ds->ds7.springIRQ = 0; ds->ds9.springIRQ = 0; DSTimerInit(ds);

@@ -234,6 +237,7 @@ CircleBufferDeinit(&ds->ds7.fifo);

CircleBufferDeinit(&ds->ds9.fifo); DSUnloadROM(ds); DSMemoryDeinit(ds); + DSGXDeinit(&ds->gx); mTimingDeinit(&ds->ds7.timing); mTimingDeinit(&ds->ds9.timing); }

@@ -318,6 +322,7 @@ struct DS* ds = (struct DS*) cpu->master;

mTimingClear(&ds->ds9.timing); CircleBufferInit(&ds->ds9.fifo, 64); DSVideoReset(&ds->video); + DSGXReset(&ds->gx); DSDMAReset(&ds->ds9); DS9IOInit(ds);
A src/ds/gx.c

@@ -0,0 +1,104 @@

+/* Copyright (c) 2013-2017 Jeffrey Pfau + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include <mgba/internal/ds/gx.h> + +#include <mgba/internal/ds/io.h> + +mLOG_DEFINE_CATEGORY(DS_GX, "DS GX"); + +#define DS_GX_FIFO_SIZE 256 + +static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = { + [DS_GX_CMD_NOP] = 0, + [DS_GX_CMD_MTX_MODE] = 2, + [DS_GX_CMD_MTX_PUSH] = 34, + [DS_GX_CMD_MTX_POP] = 72, + [DS_GX_CMD_MTX_STORE] = 34, + [DS_GX_CMD_MTX_RESTORE] = 72, + [DS_GX_CMD_MTX_IDENTITY] = 38, + [DS_GX_CMD_MTX_LOAD_4x4] = 68, + [DS_GX_CMD_MTX_LOAD_4x3] = 60, + [DS_GX_CMD_MTX_MULT_4x4] = 70, + [DS_GX_CMD_MTX_MULT_4x3] = 62, + [DS_GX_CMD_MTX_MULT_3x3] = 56, + [DS_GX_CMD_MTX_SCALE] = 44, + [DS_GX_CMD_MTX_TRANS] = 44, + [DS_GX_CMD_COLOR] = 2, + [DS_GX_CMD_NORMAL] = 18, + [DS_GX_CMD_TEXCOORD] = 2, + [DS_GX_CMD_VTX_16] = 18, + [DS_GX_CMD_VTX_10] = 16, + [DS_GX_CMD_VTX_XY] = 16, + [DS_GX_CMD_VTX_XZ] = 16, + [DS_GX_CMD_VTX_YZ] = 16, + [DS_GX_CMD_VTX_DIFF] = 16, + [DS_GX_CMD_POLYGON_ATTR] = 2, + [DS_GX_CMD_TEXIMAGE_PARAM] = 2, + [DS_GX_CMD_PLTT_BASE] = 2, + [DS_GX_CMD_DIF_AMB] = 8, + [DS_GX_CMD_SPE_EMI] = 8, + [DS_GX_CMD_LIGHT_VECTOR] = 12, + [DS_GX_CMD_LIGHT_COLOR] = 2, + [DS_GX_CMD_SHININESS] = 64, + [DS_GX_CMD_BEGIN_VTXS] = 2, + [DS_GX_CMD_END_VTXS] = 2, + [DS_GX_CMD_SWAP_BUFFERS] = 784, + [DS_GX_CMD_VIEWPORT] = 2, + [DS_GX_CMD_BOX_TEST] = 206, + [DS_GX_CMD_POS_TEST] = 18, + [DS_GX_CMD_VEC_TEST] = 10, +}; + +void DSGXInit(struct DSGX* gx) { + CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE); +} + +void DSGXDeinit(struct DSGX* gx) { + CircleBufferDeinit(&gx->fifo); +} + +void DSGXReset(struct DSGX* gx) { + CircleBufferClear(&gx->fifo); +} + +uint16_t DSGXWriteRegister(struct DSGX* gx, uint32_t address, uint16_t value) { + switch (address) { + case DS9_REG_DISP3DCNT: + case DS9_REG_GXSTAT_LO: + case DS9_REG_GXSTAT_HI: + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + break; + default: + if (address < DS9_REG_GXFIFO_00) { + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + } else if (address < DS9_REG_GXSTAT_LO) { + mLOG(DS_GX, STUB, "Unimplemented FIFO write %03X:%04X", address, value); + } else { + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + } + break; + } + return value; +} + +uint32_t DSGXWriteRegister32(struct DSGX* gx, uint32_t address, uint32_t value) { + switch (address) { + case DS9_REG_DISP3DCNT: + case DS9_REG_GXSTAT_LO: + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + break; + default: + if (address < DS9_REG_GXFIFO_00) { + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + } else if (address < DS9_REG_GXSTAT_LO) { + mLOG(DS_GX, STUB, "Unimplemented FIFO write %03X:%04X", address, value); + } else { + mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value); + } + break; + } + return value; +}
M src/ds/io.csrc/ds/io.c

@@ -7,6 +7,7 @@ #include <mgba/internal/ds/io.h>

#include <mgba/core/interface.h> #include <mgba/internal/ds/ds.h> +#include <mgba/internal/ds/gx.h> #include <mgba/internal/ds/ipc.h> #include <mgba/internal/ds/slot1.h> #include <mgba/internal/ds/spi.h>

@@ -415,6 +416,7 @@ void DS9IOInit(struct DS* ds) {

memset(ds->memory.io9, 0, sizeof(ds->memory.io9)); ds->memory.io9[DS_REG_IPCFIFOCNT >> 1] = 0x0101; ds->memory.io9[DS_REG_POSTFLG >> 1] = 0x0001; + ds->memory.io9[DS9_REG_GXSTAT_HI >> 1] = 0x0600; DS9IOWrite(ds, DS9_REG_VRAMCNT_G, 0x0300); }

@@ -423,6 +425,8 @@ if (address <= DS9_REG_A_BLDY && (address > DS_REG_VCOUNT || address == DS9_REG_A_DISPCNT_LO || address == DS9_REG_A_DISPCNT_HI)) {

value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); } else if (address >= DS9_REG_B_DISPCNT_LO && address <= DS9_REG_B_BLDY) { value = ds->video.renderer->writeVideoRegister(ds->video.renderer, address, value); + } else if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) { + value = DSGXWriteRegister(&ds->gx, address, value); } else { uint16_t oldValue; switch (address) {

@@ -514,37 +518,41 @@ }

} void DS9IOWrite32(struct DS* ds, uint32_t address, uint32_t value) { - switch (address) { - case DS_REG_DMA0SAD_LO: - case DS_REG_DMA1SAD_LO: - case DS_REG_DMA2SAD_LO: - case DS_REG_DMA3SAD_LO: - case DS_REG_DMA0DAD_LO: - case DS_REG_DMA1DAD_LO: - case DS_REG_DMA2DAD_LO: - case DS_REG_DMA3DAD_LO: - case DS_REG_IPCFIFOSEND_LO: - case DS_REG_IE_LO: - value = DSIOWrite32(&ds->ds9, address, value); - break; + if ((address >= DS9_REG_RDLINES_COUNT && address <= DS9_REG_VECMTX_RESULT_12) || address == DS9_REG_DISP3DCNT) { + value = DSGXWriteRegister32(&ds->gx, address, value); + } else { + switch (address) { + case DS_REG_DMA0SAD_LO: + case DS_REG_DMA1SAD_LO: + case DS_REG_DMA2SAD_LO: + case DS_REG_DMA3SAD_LO: + case DS_REG_DMA0DAD_LO: + case DS_REG_DMA1DAD_LO: + case DS_REG_DMA2DAD_LO: + case DS_REG_DMA3DAD_LO: + case DS_REG_IPCFIFOSEND_LO: + case DS_REG_IE_LO: + value = DSIOWrite32(&ds->ds9, address, value); + break; - case DS_REG_DMA0CNT_LO: - DS9DMAWriteCNT(&ds->ds9, 0, value); - break; - case DS_REG_DMA1CNT_LO: - DS9DMAWriteCNT(&ds->ds9, 1, value); - break; - case DS_REG_DMA2CNT_LO: - DS9DMAWriteCNT(&ds->ds9, 2, value); - break; - case DS_REG_DMA3CNT_LO: - DS9DMAWriteCNT(&ds->ds9, 3, value); - break; + case DS_REG_DMA0CNT_LO: + DS9DMAWriteCNT(&ds->ds9, 0, value); + break; + case DS_REG_DMA1CNT_LO: + DS9DMAWriteCNT(&ds->ds9, 1, value); + break; + case DS_REG_DMA2CNT_LO: + DS9DMAWriteCNT(&ds->ds9, 2, value); + break; + case DS_REG_DMA3CNT_LO: + DS9DMAWriteCNT(&ds->ds9, 3, value); + break; - default: - DS9IOWrite(ds, address, value & 0xFFFF); - DS9IOWrite(ds, address | 2, value >> 16); - return; + default: + DS9IOWrite(ds, address, value & 0xFFFF); + DS9IOWrite(ds, address | 2, value >> 16); + return; + } } ds->ds9.memory.io[address >> 1] = value; ds->ds9.memory.io[(address >> 1) + 1] = value >> 16;

@@ -608,6 +616,8 @@ case DS9_REG_SQRT_PARAM_3:

case DS9_REG_SQRT_RESULT_LO: case DS9_REG_SQRT_RESULT_HI: case DS_REG_POSTFLG: + case DS9_REG_GXSTAT_LO: + case DS9_REG_GXSTAT_HI: // Handled transparently by the registers break; case DS_REG_AUXSPICNT: