src/ds/gx.c (view raw)
1/* Copyright (c) 2013-2017 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/ds/gx.h>
7
8#include <mgba/internal/ds/io.h>
9
10mLOG_DEFINE_CATEGORY(DS_GX, "DS GX");
11
12#define DS_GX_FIFO_SIZE 256
13
14static const int32_t _gxCommandCycleBase[DS_GX_CMD_MAX] = {
15 [DS_GX_CMD_NOP] = 0,
16 [DS_GX_CMD_MTX_MODE] = 2,
17 [DS_GX_CMD_MTX_PUSH] = 34,
18 [DS_GX_CMD_MTX_POP] = 72,
19 [DS_GX_CMD_MTX_STORE] = 34,
20 [DS_GX_CMD_MTX_RESTORE] = 72,
21 [DS_GX_CMD_MTX_IDENTITY] = 38,
22 [DS_GX_CMD_MTX_LOAD_4x4] = 68,
23 [DS_GX_CMD_MTX_LOAD_4x3] = 60,
24 [DS_GX_CMD_MTX_MULT_4x4] = 70,
25 [DS_GX_CMD_MTX_MULT_4x3] = 62,
26 [DS_GX_CMD_MTX_MULT_3x3] = 56,
27 [DS_GX_CMD_MTX_SCALE] = 44,
28 [DS_GX_CMD_MTX_TRANS] = 44,
29 [DS_GX_CMD_COLOR] = 2,
30 [DS_GX_CMD_NORMAL] = 18,
31 [DS_GX_CMD_TEXCOORD] = 2,
32 [DS_GX_CMD_VTX_16] = 18,
33 [DS_GX_CMD_VTX_10] = 16,
34 [DS_GX_CMD_VTX_XY] = 16,
35 [DS_GX_CMD_VTX_XZ] = 16,
36 [DS_GX_CMD_VTX_YZ] = 16,
37 [DS_GX_CMD_VTX_DIFF] = 16,
38 [DS_GX_CMD_POLYGON_ATTR] = 2,
39 [DS_GX_CMD_TEXIMAGE_PARAM] = 2,
40 [DS_GX_CMD_PLTT_BASE] = 2,
41 [DS_GX_CMD_DIF_AMB] = 8,
42 [DS_GX_CMD_SPE_EMI] = 8,
43 [DS_GX_CMD_LIGHT_VECTOR] = 12,
44 [DS_GX_CMD_LIGHT_COLOR] = 2,
45 [DS_GX_CMD_SHININESS] = 64,
46 [DS_GX_CMD_BEGIN_VTXS] = 2,
47 [DS_GX_CMD_END_VTXS] = 2,
48 [DS_GX_CMD_SWAP_BUFFERS] = 784,
49 [DS_GX_CMD_VIEWPORT] = 2,
50 [DS_GX_CMD_BOX_TEST] = 206,
51 [DS_GX_CMD_POS_TEST] = 18,
52 [DS_GX_CMD_VEC_TEST] = 10,
53};
54
55void DSGXInit(struct DSGX* gx) {
56 CircleBufferInit(&gx->fifo, sizeof(struct DSGXEntry) * DS_GX_FIFO_SIZE);
57}
58
59void DSGXDeinit(struct DSGX* gx) {
60 CircleBufferDeinit(&gx->fifo);
61}
62
63void DSGXReset(struct DSGX* gx) {
64 CircleBufferClear(&gx->fifo);
65}
66
67uint16_t DSGXWriteRegister(struct DSGX* gx, uint32_t address, uint16_t value) {
68 switch (address) {
69 case DS9_REG_DISP3DCNT:
70 case DS9_REG_GXSTAT_LO:
71 case DS9_REG_GXSTAT_HI:
72 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
73 break;
74 default:
75 if (address < DS9_REG_GXFIFO_00) {
76 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
77 } else if (address < DS9_REG_GXSTAT_LO) {
78 mLOG(DS_GX, STUB, "Unimplemented FIFO write %03X:%04X", address, value);
79 } else {
80 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
81 }
82 break;
83 }
84 return value;
85}
86
87uint32_t DSGXWriteRegister32(struct DSGX* gx, uint32_t address, uint32_t value) {
88 switch (address) {
89 case DS9_REG_DISP3DCNT:
90 case DS9_REG_GXSTAT_LO:
91 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
92 break;
93 default:
94 if (address < DS9_REG_GXFIFO_00) {
95 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
96 } else if (address < DS9_REG_GXSTAT_LO) {
97 mLOG(DS_GX, STUB, "Unimplemented FIFO write %03X:%04X", address, value);
98 } else {
99 mLOG(DS_GX, STUB, "Unimplemented GX write %03X:%04X", address, value);
100 }
101 break;
102 }
103 return value;
104}