added brand new tools

This commit is contained in:
farisawan-2000 2021-01-15 21:19:41 -05:00
parent 42249aa80a
commit 1973650ffc
34 changed files with 14276 additions and 2 deletions

View File

@ -1,10 +1,13 @@
CC := gcc
CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -std=c99 -O3 -s
PROGRAMS := iplfontutil n64graphics n64crc patch_libultra_math
CFLAGS := -I . -Wall -Wextra -Wno-unused-parameter -pedantic -O3 -s
PROGRAMS := iplfontutil n64graphics n64crc patch_libultra_math gfxdis_f3dex2
iplfontutil_SOURCES := iplfontutil.c
iplfontutil_CFLAGS := -O2 # faster compile time
gfxdis_f3dex2_SOURCES := gfxdis/gfxdis.c gfxdis/main.c
gfxdis_f3dex2_CFLAGS := -DF3DEX_GBI_2 -Igfxdis/include/ -Igfxdis/ -O2 -std=gnu99 -Wno-pedantic
n64crc_SOURCES := n64crc.c
n64crc_CFLAGS := -O2 # faster compile time

4983
tools/gfxdis/gfxdis.c Normal file

File diff suppressed because it is too large Load Diff

BIN
tools/gfxdis/gfxdis.f3dex2 Executable file

Binary file not shown.

373
tools/gfxdis/gfxdis.h Normal file
View File

@ -0,0 +1,373 @@
#ifndef GFXDIS_H
#define GFXDIS_H
#include <stdint.h>
#include <n64.h>
#include <vector/vector.h>
struct gfx_insn;
typedef int (*gfx_insn_dis_t)(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
typedef int (*gfx_insn_col_t)(struct gfx_insn *insn, int n_insn);
typedef int (*gfx_insn_strarg_t)(char *buf, uint32_t arg);
enum gfx_insn_def
{
GFX_ID_INVD,
GFX_ID_DPFILLRECTANGLE,
GFX_ID_DPFULLSYNC,
GFX_ID_DPLOADSYNC,
GFX_ID_DPTILESYNC,
GFX_ID_DPPIPESYNC,
GFX_ID_DPLOADTLUT_PAL16,
GFX_ID_DPLOADTLUT_PAL256,
GFX_ID_DPLOADMULTIBLOCKYUVS,
GFX_ID_DPLOADMULTIBLOCKYUV,
GFX_ID_DPLOADMULTIBLOCK_4BS,
GFX_ID_DPLOADMULTIBLOCK_4B,
GFX_ID_DPLOADMULTIBLOCKS,
GFX_ID_DPLOADMULTIBLOCK,
GFX_ID__DPLOADTEXTUREBLOCKYUVS,
GFX_ID__DPLOADTEXTUREBLOCKYUV,
GFX_ID__DPLOADTEXTUREBLOCK_4BS,
GFX_ID__DPLOADTEXTUREBLOCK_4B,
GFX_ID__DPLOADTEXTUREBLOCKS,
GFX_ID__DPLOADTEXTUREBLOCK,
GFX_ID_DPLOADTEXTUREBLOCKYUVS,
GFX_ID_DPLOADTEXTUREBLOCKYUV,
GFX_ID_DPLOADTEXTUREBLOCK_4BS,
GFX_ID_DPLOADTEXTUREBLOCK_4B,
GFX_ID_DPLOADTEXTUREBLOCKS,
GFX_ID_DPLOADTEXTUREBLOCK,
GFX_ID_DPLOADMULTITILEYUV,
GFX_ID_DPLOADMULTITILE_4B,
GFX_ID_DPLOADMULTITILE,
GFX_ID__DPLOADTEXTURETILEYUV,
GFX_ID__DPLOADTEXTURETILE_4B,
GFX_ID__DPLOADTEXTURETILE,
GFX_ID_DPLOADTEXTURETILEYUV,
GFX_ID_DPLOADTEXTURETILE_4B,
GFX_ID_DPLOADTEXTURETILE,
GFX_ID_DPLOADBLOCK,
GFX_ID_DPNOOP,
GFX_ID_DPNOOPTAG,
GFX_ID_DPPIPELINEMODE,
GFX_ID_DPSETBLENDCOLOR,
GFX_ID_DPSETENVCOLOR,
GFX_ID_DPSETFILLCOLOR,
GFX_ID_DPSETFOGCOLOR,
GFX_ID_DPSETPRIMCOLOR,
GFX_ID_DPSETCOLORIMAGE,
GFX_ID_DPSETDEPTHIMAGE,
GFX_ID_DPSETTEXTUREIMAGE,
GFX_ID_DPSETALPHACOMPARE,
GFX_ID_DPSETALPHADITHER,
GFX_ID_DPSETCOLORDITHER,
GFX_ID_DPSETCOMBINEMODE,
GFX_ID_DPSETCOMBINELERP,
GFX_ID_DPSETCONVERT,
GFX_ID_DPSETTEXTURECONVERT,
GFX_ID_DPSETCYCLETYPE,
GFX_ID_DPSETDEPTHSOURCE,
GFX_ID_DPSETCOMBINEKEY,
GFX_ID_DPSETKEYGB,
GFX_ID_DPSETKEYR,
GFX_ID_DPSETPRIMDEPTH,
GFX_ID_DPSETRENDERMODE,
GFX_ID_DPSETSCISSOR,
GFX_ID_DPSETSCISSORFRAC,
GFX_ID_DPSETTEXTUREDETAIL,
GFX_ID_DPSETTEXTUREFILTER,
GFX_ID_DPSETTEXTURELOD,
GFX_ID_DPSETTEXTURELUT,
GFX_ID_DPSETTEXTUREPERSP,
GFX_ID_DPSETTILE,
GFX_ID_DPSETTILESIZE,
GFX_ID_SP1TRIANGLE,
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
GFX_ID_SP2TRIANGLES,
GFX_ID_SP1QUADRANGLE,
GFX_ID_SPBRANCHLESSZ,
GFX_ID_SPBRANCHLESSZRG,
#endif
GFX_ID_SPBRANCHLIST,
GFX_ID_SPCLIPRATIO,
GFX_ID_SPCULLDISPLAYLIST,
GFX_ID_SPDISPLAYLIST,
GFX_ID_SPENDDISPLAYLIST,
GFX_ID_SPFOGPOSITION,
GFX_ID_SPFORCEMATRIX,
GFX_ID_SPSETGEOMETRYMODE,
GFX_ID_SPCLEARGEOMETRYMODE,
GFX_ID_SPLOADGEOMETRYMODE,
#if defined(F3D_GBI) || defined(F3DB_GBI) || defined(F3DEX_GBI)
GFX_ID_SPINSERTMATRIX,
#endif
GFX_ID_SPLINE3D,
GFX_ID_SPLINEW3D,
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
GFX_ID_SPLOADUCODE,
#endif
GFX_ID_SPLOOKATX,
GFX_ID_SPLOOKATY,
GFX_ID_SPLOOKAT,
GFX_ID_SPMATRIX,
GFX_ID_SPMODIFYVERTEX,
GFX_ID_SPPERSPNORMALIZE,
GFX_ID_SPPOPMATRIX,
#if defined(F3DEX_GBI_2)
GFX_ID_SPPOPMATRIXN,
#endif
GFX_ID_SPSEGMENT,
GFX_ID_SPSETLIGHTS1,
GFX_ID_SPSETLIGHTS2,
GFX_ID_SPSETLIGHTS3,
GFX_ID_SPSETLIGHTS4,
GFX_ID_SPSETLIGHTS5,
GFX_ID_SPSETLIGHTS6,
GFX_ID_SPSETLIGHTS7,
GFX_ID_SPNUMLIGHTS,
GFX_ID_SPLIGHT,
GFX_ID_SPLIGHTCOLOR,
GFX_ID_SPTEXTURE,
GFX_ID_SPTEXTURERECTANGLE,
GFX_ID_SPTEXTURERECTANGLEFLIP,
GFX_ID_SPVERTEX,
GFX_ID_SPVIEWPORT,
GFX_ID_DPLOADTLUTCMD,
GFX_ID_DPLOADTLUT,
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
GFX_ID_BRANCHZ,
#endif
GFX_ID_DISPLAYLIST,
GFX_ID_DPHALF1,
GFX_ID_DPHALF2,
GFX_ID_DPLOADTILE,
#if defined(F3DEX_GBI_2)
GFX_ID_SPGEOMETRYMODE,
#endif
GFX_ID_SPSETOTHERMODELO,
GFX_ID_SPSETOTHERMODEHI,
GFX_ID_DPSETOTHERMODE,
GFX_ID_MOVEWD,
GFX_ID_MOVEMEM,
#if defined(F3DEX_GBI_2)
GFX_ID_SPDMA_IO,
GFX_ID_SPDMAREAD,
GFX_ID_SPDMAWRITE,
#endif
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
GFX_ID_LOADUCODE,
GFX_ID_SPLOADUCODEEX,
#endif
GFX_ID_TEXRECT,
GFX_ID_TEXRECTFLIP,
GFX_ID_SPNOOP,
#if defined(F3DEX_GBI_2)
GFX_ID_SPECIAL3,
GFX_ID_SPECIAL2,
GFX_ID_SPECIAL1,
#endif
GFX_ID_MAX,
};
enum gfx_insn_type
{
GFX_IT_OP,
GFX_IT_MACRO,
GFX_IT_MULTIMACRO,
};
struct gfx_insn_info
{
const char *name;
enum gfx_insn_def def;
enum gfx_insn_type type;
int opcode;
int n_args;
void *handler;
};
struct gfx_insn
{
enum gfx_insn_def def;
int n_gfx;
uint32_t arg[18];
gfx_insn_strarg_t strarg[18];
};
struct gfxdis_cfg
{
_Bool dis_invd;
_Bool use_q;
_Bool dec_color;
};
int gfx_insn_dis(struct gfx_insn *insn, Gfx *gfx);
int gfx_insn_col(struct gfx_insn *insn, int n_insn);
char *gfx_insn_str(struct gfx_insn *insn, char *buf);
char *gfx_insn_str_dyn(struct gfx_insn *insn, const char *arg, char *buf);
int gfx_dis(struct vector *insn_vect, Gfx *gfx, int max);
int gfx_dis_invd(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpFillRectangle(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpFullSync(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpLoadSync(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpTileSync(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpPipeSync(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_dpLoadTLUT_pal16(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTLUT_pal256(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlockYuvS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlockYuv(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlock_4bS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlock_4b(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlockS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiBlock(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlockYuvS(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlockYuv(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlock_4bS(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlock_4b(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlockS(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureBlock(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlockYuvS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlockYuv(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlock_4bS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlock_4b(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlockS(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureBlock(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiTileYuv(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiTile_4b(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadMultiTile(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureTileYuv(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureTile_4b(struct gfx_insn *insn, int n_insn);
int gfx_col__dpLoadTextureTile(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureTileYuv(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureTile_4b(struct gfx_insn *insn, int n_insn);
int gfx_col_dpLoadTextureTile(struct gfx_insn *insn, int n_insn);
int gfx_dis_dpLoadBlock(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpNoOp(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpNoOpTag(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpPipelineMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetBlendColor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetEnvColor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetFillColor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetFogColor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetPrimColor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetColorImage(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetDepthImage(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureImage(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetAlphaCompare(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetAlphaDither(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetColorDither(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetCombineMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetCombineLERP(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetConvert(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureConvert(struct gfx_insn *insn,
uint32_t hi, uint32_t lo);
int gfx_dis_dpSetCycleType(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetDepthSource(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetCombineKey(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetKeyGB(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetKeyR(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetPrimDepth(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetRenderMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetScissor(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetScissorFrac(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureDetail(struct gfx_insn *insn,
uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureFilter(struct gfx_insn *insn,
uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureLOD(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTextureLUT(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTexturePersp(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTile(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetTileSize(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_sp1Triangle(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
int gfx_dis_sp2Triangles(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_sp1Quadrangle(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spBranchLessZ(struct gfx_insn *insn, int n_insn);
int gfx_col_spBranchLessZrg(struct gfx_insn *insn, int n_insn);
#endif
int gfx_dis_spBranchList(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spClipRatio(struct gfx_insn *insn, int n_insn);
int gfx_dis_spCullDisplayList(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spDisplayList(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spEndDisplayList(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spFogPosition(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spForceMatrix(struct gfx_insn *insn, int n_insn);
int gfx_dis_spSetGeometryMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spClearGeometryMode(struct gfx_insn *insn,
uint32_t hi, uint32_t lo);
int gfx_dis_spLoadGeometryMode(struct gfx_insn *insn,
uint32_t hi, uint32_t lo);
#if defined(F3D_GBI) || defined(F3DB_GBI) || defined(F3DEX_GBI)
int gfx_dis_spInsertMatrix(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#endif
int gfx_dis_spLine3D(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spLineW3D(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
int gfx_col_spLoadUcode(struct gfx_insn *insn, int n_insn);
#endif
int gfx_dis_spLookAtX(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spLookAtY(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spLookAt(struct gfx_insn *insn, int n_insn);
int gfx_dis_spMatrix(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spModifyVertex(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spPerspNormalize(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spPopMatrix(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#if defined(F3DEX_GBI_2)
int gfx_dis_spPopMatrixN(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#endif
int gfx_dis_spSegment(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spSetLights1(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights2(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights3(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights4(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights5(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights6(struct gfx_insn *insn, int n_insn);
int gfx_col_spSetLights7(struct gfx_insn *insn, int n_insn);
int gfx_dis_spNumLights(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spLight(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spLightColor(struct gfx_insn *insn, int n_insn);
int gfx_dis_spTexture(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spTextureRectangle(struct gfx_insn *insn, int n_insn);
int gfx_col_spTextureRectangleFlip(struct gfx_insn *insn, int n_insn);
int gfx_dis_spVertex(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spViewport(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpLoadTLUTCmd(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_dpLoadTLUT(struct gfx_insn *insn, int n_insn);
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
int gfx_dis_BranchZ(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#endif
int gfx_dis_DisplayList(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpHalf1(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpHalf2(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpLoadTile(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spGeometryMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spSetOtherModeLo(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spSetOtherModeHi(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_dpSetOtherMode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_MoveWd(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_MoveMem(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#if defined(F3DEX_GBI_2)
int gfx_dis_spDma_io(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spDmaRead(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spDmaWrite(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#endif
#if defined(F3DEX_GBI) || defined(F3DEX_GBI_2)
int gfx_dis_LoadUcode(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_col_spLoadUcodeEx(struct gfx_insn *insn, int n_insn);
#endif
int gfx_dis_TexRect(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_TexRectFlip(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_spNoOp(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#if defined(F3DEX_GBI_2)
int gfx_dis_Special3(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_Special2(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
int gfx_dis_Special1(struct gfx_insn *insn, uint32_t hi, uint32_t lo);
#endif
extern struct gfx_insn_info gfx_insn_info[];
extern struct gfxdis_cfg gfxdis_cfg;
#endif

View File

@ -0,0 +1,34 @@
#include <stddef.h>
#include <string.h>
#ifdef __cplusplus
extern "C"
{
#endif
typedef struct
{
const char *name;
void *data;
size_t size;
} grc_t;
extern grc_t __RESOURCE_LIST__[];
extern grc_t __RESOURCE_END__[];
int grc_resource_get(const char *res_name, void **data, size_t *size)
{
for (grc_t *r = __RESOURCE_LIST__; r < __RESOURCE_END__; ++r)
if (strcmp(res_name, r->name) == 0) {
if (data)
*data = r->data;
if (size)
*size = r->size;
return 1;
}
return 0;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,32 @@
#ifndef N64_GRC_H
#define N64_GRC_H
#include <stddef.h>
#include <stdint.h>
#include "n64.h"
#ifdef __cplusplus
extern "C"
{
#endif
struct grc_texture
{
g_ifmt_t im_fmt;
g_isiz_t im_siz;
uint16_t image_width;
uint16_t image_height;
uint16_t tile_width;
uint16_t tile_height;
uint16_t tiles_x;
uint16_t tiles_y;
uint16_t pad;
char texture_data[];
};
int grc_resource_get(const char *res_name, void **data, size_t *size);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,264 @@
/* list.c
* -glank
*/
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "list.h"
struct list_element_header
{
struct list_element_header *prev, *next;
};
#define MAX_ALIGN(N) (((N) + _Alignof(max_align_t) - 1) & \
~(_Alignof(max_align_t) - 1))
#define ELEMENT_HEADER_SIZE (MAX_ALIGN(sizeof(struct list_element_header)))
#ifdef __cplusplus
extern "C"
{
#endif
void list_init(struct list *list, size_t element_size)
{
list->element_size = element_size;
list->size = 0;
list->first = NULL;
list->last = NULL;
}
void *list_prev(const void *element)
{
const struct list_element_header *header =
(const struct list_element_header*)((const char*)element -
ELEMENT_HEADER_SIZE);
if (header->prev)
return (char*)header->prev + ELEMENT_HEADER_SIZE;
else
return NULL;
}
void *list_next(const void *element)
{
const struct list_element_header *header =
(const struct list_element_header*)((const char*)element -
ELEMENT_HEADER_SIZE);
if (header->next)
return (char*)header->next + ELEMENT_HEADER_SIZE;
else
return NULL;
}
void *list_prev_in(const struct list *list, const void *element)
{
if (!element)
return list->last;
return list_prev(element);
}
void *list_next_in(const struct list *list, const void *element)
{
if (!element)
return list->first;
return list_next(element);
}
void *list_at(const struct list *list, size_t position)
{
if (list->size == 0)
return NULL;
struct list_element_header *header = (struct list_element_header*)
((char*)list->first -
ELEMENT_HEADER_SIZE);
for (size_t i = 0; i < position; ++i) {
if (header->next)
header = header->next;
else
return NULL;
}
return (char*)header + ELEMENT_HEADER_SIZE;
}
void *list_insert_size(struct list *list, void *element, size_t size,
const void *data)
{
struct list_element_header *new_header = (struct list_element_header*)
malloc(ELEMENT_HEADER_SIZE + size);
if (!new_header)
return NULL;
void *new_data = (char*)new_header + ELEMENT_HEADER_SIZE;
if (data)
memcpy(new_data, data, size);
if (element) {
struct list_element_header *header = (struct list_element_header*)
((char*)element -
ELEMENT_HEADER_SIZE);
new_header->prev = header->prev;
new_header->next = header;
if (header->prev)
header->prev->next = new_header;
header->prev = new_header;
if (element == list->first)
list->first = new_data;
}
else {
if (list->size == 0) {
new_header->prev = NULL;
list->first = new_data;
}
else {
new_header->prev = (struct list_element_header*)((char*)list->last -
ELEMENT_HEADER_SIZE);
new_header->prev->next = new_header;
}
new_header->next = NULL;
list->last = new_data;
}
++list->size;
return new_data;
}
void list_transfer(struct list *dest, void *position,
struct list *src, void *element)
{
struct list_element_header *e_header = (struct list_element_header*)
((char*)element -
ELEMENT_HEADER_SIZE);
if (element == src->first) {
if (e_header->next)
src->first = (void*)((char*)e_header->next + ELEMENT_HEADER_SIZE);
else
src->first = NULL;
}
if (element == src->last) {
if (e_header->prev)
src->last = (void*)((char*)e_header->prev + ELEMENT_HEADER_SIZE);
else
src->last = NULL;
}
if (e_header->prev)
e_header->prev->next = e_header->next;
if (e_header->next)
e_header->next->prev = e_header->prev;
if (position) {
struct list_element_header *p_header = (struct list_element_header*)
((char*)position -
ELEMENT_HEADER_SIZE);
e_header->prev = p_header->prev;
e_header->next = p_header;
if (p_header->prev)
p_header->prev->next = e_header;
p_header->prev = e_header;
if (position == dest->first)
dest->first = element;
}
else {
if (dest->size == 0) {
e_header->prev = NULL;
dest->first = element;
}
else {
e_header->prev = (struct list_element_header*)((char*)dest->last -
ELEMENT_HEADER_SIZE);
e_header->prev->next = e_header;
}
e_header->next = NULL;
dest->last = element;
}
--src->size;
++dest->size;
}
void list_splice(struct list *dest, struct list *src)
{
if (!src->first)
return;
dest->size += src->size;
if (dest->last) {
struct list_element_header *f_header = (struct list_element_header*)
((char*)src->first -
ELEMENT_HEADER_SIZE);
struct list_element_header *l_header = (struct list_element_header*)
((char*)dest->last -
ELEMENT_HEADER_SIZE);
f_header->prev = l_header;
l_header->next = f_header;
}
else
dest->first = src->first;
dest->last = src->last;
src->first = NULL;
src->last = NULL;
src->size = 0;
}
void *list_insert(struct list *list, void *element, const void *data)
{
return list_insert_size(list, element, list->element_size, data);
}
void *list_insert_after_size(struct list *list, void *element, size_t size,
const void *data)
{
return list_insert_size(list, list_next_in(list, element), size, data);
}
void *list_insert_after(struct list *list, void *element, const void *data)
{
return list_insert_size(list, list_next_in(list, element),
list->element_size, data);
}
void *list_push_back_size(struct list *list, size_t size, const void *data)
{
return list_insert_size(list, NULL, size, data);
}
void *list_push_back(struct list *list, const void *data)
{
return list_insert_size(list, NULL, list->element_size, data);
}
void list_erase(struct list *list, void *element)
{
struct list_element_header *header = (struct list_element_header*)
((char*)element - ELEMENT_HEADER_SIZE);
if (element == list->first) {
if (header->next)
list->first = (void*)((char*)header->next + ELEMENT_HEADER_SIZE);
else
list->first = NULL;
}
if (element == list->last) {
if (header->prev)
list->last = (void*)((char*)header->prev + ELEMENT_HEADER_SIZE);
else
list->last = NULL;
}
if (header->prev)
header->prev->next = header->next;
if (header->next)
header->next->prev = header->prev;
free(header);
--list->size;
}
void list_destroy(struct list *list)
{
struct list_element_header *header = NULL;
if (list->first)
header = (struct list_element_header*)((char*)list->first -
ELEMENT_HEADER_SIZE);
while (header) {
struct list_element_header *next_header = header->next;
free(header);
header = next_header;
}
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,44 @@
/* list.h
* -glank
*/
#ifndef LIST_H
#define LIST_H
#include <stddef.h>
struct list
{
size_t element_size, size;
void *first, *last;
};
#ifdef __cplusplus
extern "C"
{
#endif
void list_init(struct list *list, size_t element_size);
void *list_prev(const void *element);
void *list_next(const void *element);
void *list_prev_in(const struct list *list, const void *element);
void *list_next_in(const struct list *list, const void *element);
void *list_at(const struct list *list, size_t position);
void *list_insert_size(struct list *list, void *element, size_t size,
const void *data);
void list_transfer(struct list *dest, void *position,
struct list *src, void *element);
void list_splice(struct list *dest, struct list *src);
void *list_insert(struct list *list, void *element, const void *data);
void *list_insert_after_size(struct list *list, void *element, size_t size,
const void *data);
void *list_insert_after(struct list *list, void *element, const void *data);
void *list_push_back_size(struct list *list, size_t size, const void *data);
void *list_push_back(struct list *list, const void *data);
void list_erase(struct list *list, void *element);
void list_destroy(struct list *list);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,214 @@
/* memory.c
* -glank
*/
#include <stddef.h>
#include <inttypes.h>
#include <sys/unistd.h>
#include "memory.h"
#ifndef MALLOC_PRINTF
#include <stdio.h>
#define MALLOC_PRINTF printf
#endif
#ifndef MALLOC_ARENA_SIZE
#define MALLOC_ARENA_SIZE (1024 * 1024 * 1)
#endif
#define MAX_ALIGN(N) (((N) + _Alignof(max_align_t) - 1) & \
~(_Alignof(max_align_t) - 1))
#define BLOCK_HEADER_SIZE (MAX_ALIGN(sizeof(struct block_header)))
struct block_header
{
int free;
size_t size;
struct block_header *prev_block, *next_block;
};
static int malloc_ready = 0;
static int malloc_debug_level = 0;
#ifdef MALLOC_STATIC_ARENA
_Alignas(max_align_t) static char arena[MALLOC_ARENA_SIZE];
#else
static char *arena = 0;
#endif
static struct block_header *first_free_block;
#ifdef __cplusplus
extern "C"
{
#endif
void malloc_init()
{
#ifndef MALLOC_STATIC_ARENA
if (!arena)
arena = (char*)sbrk(MALLOC_ARENA_SIZE);
#endif
first_free_block = (struct block_header*)arena;
first_free_block->free = 1;
first_free_block->size = MALLOC_ARENA_SIZE - BLOCK_HEADER_SIZE;
first_free_block->prev_block = 0;
first_free_block->next_block = 0;
}
void malloc_set_debug(int debug_level)
{
malloc_debug_level = debug_level;
}
int malloc_get_debug()
{
return malloc_debug_level;
}
void malloc_print_debug()
{
struct block_header *block_ptr, *prev_block = 0;
int i;
MALLOC_PRINTF("malloc debug:\n");
for (i = 0, block_ptr = (struct block_header*)arena; block_ptr;
++i, block_ptr = block_ptr->next_block)
{
MALLOC_PRINTF(" block no. %i%s:\n", i,
block_ptr == first_free_block ? " (first free)" : "");
MALLOC_PRINTF(" address: 0x%08" PRIx32 "\n", (uint32_t)block_ptr);
MALLOC_PRINTF(" free: %i\n", block_ptr->free);
MALLOC_PRINTF(" size: %i\n", block_ptr->size);
MALLOC_PRINTF(" prev_block: 0x%08" PRIx32 "\n",
(uint32_t)block_ptr->prev_block);
MALLOC_PRINTF(" next_block: 0x%08" PRIx32 "\n",
(uint32_t)block_ptr->next_block);
if (block_ptr->prev_block != prev_block)
MALLOC_PRINTF("malloc inconsistency!\n");
prev_block = block_ptr;
}
}
void *malloc(size_t size)
{
size = MAX_ALIGN(size);
if (!malloc_ready) {
malloc_init();
malloc_ready = 1;
}
if (malloc_debug_level >= MALLOC_DEBUG_SIMPLE) {
MALLOC_PRINTF("malloc(%u)\n", size);
if (malloc_debug_level >= MALLOC_DEBUG_VERBOSE)
malloc_print_debug();
}
struct block_header *block_ptr, *next_free_block;
for (block_ptr = first_free_block; block_ptr;
block_ptr = block_ptr->next_block)
{
if (block_ptr->free && block_ptr->size >= size) {
if (block_ptr->size - size >= (BLOCK_HEADER_SIZE + MAX_ALIGN(1))) {
next_free_block = (struct block_header*)((char*)block_ptr +
BLOCK_HEADER_SIZE + size);
next_free_block->free = 1;
next_free_block->size = block_ptr->size - size - BLOCK_HEADER_SIZE;
next_free_block->prev_block = block_ptr;
next_free_block->next_block = block_ptr->next_block;
if (block_ptr->next_block)
block_ptr->next_block->prev_block = next_free_block;
block_ptr->next_block = next_free_block;
block_ptr->size = size;
}
block_ptr->free = 0;
if (block_ptr == first_free_block) {
for (next_free_block = block_ptr->next_block; next_free_block;
next_free_block = next_free_block->next_block)
{
if (next_free_block->free)
break;
}
first_free_block = next_free_block;
}
if (malloc_debug_level >= MALLOC_DEBUG_VERBOSE)
malloc_print_debug();
return (char*)block_ptr + BLOCK_HEADER_SIZE;
}
}
if (malloc_debug_level >= MALLOC_DEBUG_SIMPLE)
MALLOC_PRINTF(" allocation failed\n");
return 0;
}
void free(void *ptr)
{
struct block_header *block_ptr = (struct block_header*)((char*)ptr -
BLOCK_HEADER_SIZE);
if (malloc_debug_level >= MALLOC_DEBUG_SIMPLE) {
MALLOC_PRINTF("free(0x%08" PRIx32 ")\n", (uint32_t)block_ptr);
if (malloc_debug_level >= MALLOC_DEBUG_VERBOSE)
malloc_print_debug();
}
if (block_ptr->next_block && block_ptr->next_block->free) {
block_ptr->size = ((char*)block_ptr->next_block +
block_ptr->next_block->size) - (char*)block_ptr;
if (block_ptr->next_block->next_block)
block_ptr->next_block->next_block->prev_block = block_ptr;
block_ptr->next_block = block_ptr->next_block->next_block;
}
if (block_ptr->prev_block && block_ptr->prev_block->free) {
block_ptr->prev_block->size = ((char*)block_ptr + block_ptr->size) -
(char*)block_ptr->prev_block;
block_ptr->prev_block->next_block = block_ptr->next_block;
if (block_ptr->next_block)
block_ptr->next_block->prev_block = block_ptr->prev_block;
block_ptr = block_ptr->prev_block;
}
else
block_ptr->free = 1;
if (first_free_block > block_ptr)
first_free_block = block_ptr;
if (malloc_debug_level >= MALLOC_DEBUG_VERBOSE)
malloc_print_debug();
}
void *memcpy(void *dest, const void *src, size_t size)
{
if (size == 0 || (char*)dest == (char*)src)
return dest;
char *c_dest = (char*)dest;
const char *c_src = (const char*)src;
while (size--)
*c_dest++ = *c_src++;
return dest;
}
static void *memcpy_reverse(void *dest, const void *src, size_t size)
{
if (size == 0 || (char*)dest == (char*)src)
return dest;
char *c_dest = (char*)dest + size;
const char *c_src = (const char*)src + size;
while (size--)
*--c_dest = *--c_src;
return dest;
}
void *memmove(void *dest, const void* src, size_t size)
{
if ((char*)dest < (char*)src)
return memcpy(dest, src, size);
else
return memcpy_reverse(dest, src, size);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,33 @@
/* memory.h
* -glank
*/
#ifndef MEMORY_H
#define MEMORY_H
#include <stddef.h>
#define MALLOC_DEBUG_NONE 0
#define MALLOC_DEBUG_SIMPLE 1
#define MALLOC_DEBUG_VERBOSE 2
#ifdef __cplusplus
extern "C"
{
#endif
void malloc_init();
void malloc_set_debug(int debug_level);
int malloc_get_debug();
void malloc_print_debug();
void *malloc(size_t size);
void free(void *ptr);
void *memcpy(void *dest, const void *src, size_t size);
void *memmove(void *dest, const void *src, size_t size);
#ifdef __cplusplus
}
#endif
#endif

591
tools/gfxdis/include/mips.h Normal file
View File

@ -0,0 +1,591 @@
/**
* mips.h version 0.1rc8
* nec vr4300, mips iii
* note: providing arguments with side-effects to these macros should
* be considered unsafe in general, as they may be evaluated more than once
* -glank
**/
#ifndef MIPS_H
#define MIPS_H
#include <stdint.h>
/**
* mips general
**/
/* field manipulation macros */
#define MIPS_GET_FIELD(f,x) ((MIPS_I_(x)&f##MASK)>>f##SHIFT)
#define MIPS_MAKE_FIELD(f,x) ((MIPS_I_(x)<<f##SHIFT)&f##MASK)
#define MIPS_CLEAR_FIELD(f,x) (MIPS_I_(x)&~f##MASK)
#define MIPS_SET_FIELD(f,x,y) (MIPS_CLEAR_FIELD(f,x)|MIPS_MAKE_FIELD(f,y))
#define MIPS_POSTMOD_FIELD(f,x,y) MIPS_SET_FIELD(f,x,MIPS_GET_FIELD(f,x) y)
#define MIPS_PREMOD_FIELD(f,y,x) MIPS_SET_FIELD(f,x,y MIPS_GET_FIELD(f,x))
/* segments */
#define MIPS_KUSEG_BASE MIPS_I_(0x00000000)
#define MIPS_KUSEG_SIZE MIPS_I_(0x80000000)
#define MIPS_KSEG0_BASE MIPS_I_(0x80000000)
#define MIPS_KSEG0_SIZE MIPS_I_(0x20000000)
#define MIPS_KSEG1_BASE MIPS_I_(0xA0000000)
#define MIPS_KSEG1_SIZE MIPS_I_(0x20000000)
#define MIPS_KSSEG_BASE MIPS_I_(0xC0000000)
#define MIPS_KSSEG_SIZE MIPS_I_(0x20000000)
#define MIPS_KSEG3_BASE MIPS_I_(0xE0000000)
#define MIPS_KSEG3_SIZE MIPS_I_(0x20000000)
#define MIPS_SUSEG_BASE MIPS_I_(0x00000000)
#define MIPS_SUSEG_SIZE MIPS_I_(0x80000000)
#define MIPS_SSEG_BASE MIPS_I_(0xC0000000)
#define MIPS_SSEG_SIZE MIPS_I_(0x20000000)
#define MIPS_USEG_BASE MIPS_I_(0x00000000)
#define MIPS_USEG_SIZE MIPS_I_(0x80000000)
/* exception vectors */
#define MIPS_EVSIZE 0x80
#define MIPS_EV_RNMI (MIPS_KSEG1_BASE+0x1FC00000)
#define MIPS_EV_TLBM (MIPS_KSEG0_BASE+0x00000000)
#define MIPS_EV_XTLBM (MIPS_KSEG0_BASE+0x00000080)
#define MIPS_EV_GE (MIPS_KSEG0_BASE+0x00000180)
/* address conversion */
#define MIPS_KSEG0_TO_KSEG1(x) (MIPS_I_(x)|0xA0000000)
#define MIPS_KSEG0_TO_PHYS(x) (MIPS_I_(x)&0x1FFFFFFF)
#define MIPS_KSEG1_TO_KSEG0(x) (MIPS_I_(x)&0x9FFFFFFF)
#define MIPS_KSEG1_TO_PHYS(x) (MIPS_I_(x)&0x1FFFFFFF)
#define MIPS_KDM_TO_PHYS(x) (MIPS_I_(x)&0x1FFFFFFF)
#define MIPS_PHYS_TO_KSEG0(x) (MIPS_I_(x)|0x80000000)
#define MIPS_PHYS_TO_KSEG1(x) (MIPS_I_(x)|0xA0000000)
/* address predicates */
#define MIPS_IS_KUSEG(x) (MIPS_I_(x)>=MIPS_KUSEG_BASE && \
MIPS_I_(x)<MIPS_KSEG0_BASE)
#define MIPS_IS_KSEG0(x) (MIPS_I_(x)>=MIPS_KSEG0_BASE && \
MIPS_I_(x)<MIPS_KSEG1_BASE)
#define MIPS_IS_KSEG1(x) (MIPS_I_(x)>=MIPS_KSEG1_BASE && \
MIPS_I_(x)<MIPS_KSSEG_BASE)
#define MIPS_IS_KDM(x) (MIPS_I_(x)>=MIPS_KSEG0_BASE && \
MIPS_I_(x)<MIPS_KSSEG_BASE)
#define MIPS_IS_KSSEG(x) (MIPS_I_(x)>=MIPS_KSSEG_BASE && \
MIPS_I_(x)<MIPS_KSEG3_BASE)
#define MIPS_IS_KSEG3(x) (MIPS_I_(x)>=MIPS_KSEG3_BASE)
#define MIPS_IS_SUSEG MIPS_IS_KUSEG
#define MIPS_IS_SSEG MIPS_IS_KSSEG
#define MIPS_IS_USEG MIPS_IS_KUSEG
/* status register */
#define MIPS_STATUS_CU3 MIPS_I_(0x80000000)
#define MIPS_STATUS_CU2 MIPS_I_(0x40000000)
#define MIPS_STATUS_CU1 MIPS_I_(0x20000000)
#define MIPS_STATUS_CU0 MIPS_I_(0x10000000)
#define MIPS_STATUS_RP MIPS_I_(0x08000000)
#define MIPS_STATUS_FR MIPS_I_(0x04000000)
#define MIPS_STATUS_RE MIPS_I_(0x02000000)
#define MIPS_STATUS_ITS MIPS_I_(0x01000000)
#define MIPS_STATUS_BEV MIPS_I_(0x00400000)
#define MIPS_STATUS_TS MIPS_I_(0x00200000)
#define MIPS_STATUS_SR MIPS_I_(0x00100000)
#define MIPS_STATUS_CH MIPS_I_(0x00040000)
#define MIPS_STATUS_CE MIPS_I_(0x00020000)
#define MIPS_STATUS_DE MIPS_I_(0x00010000)
#define MIPS_STATUS_IM7 MIPS_I_(0x00008000)
#define MIPS_STATUS_IM6 MIPS_I_(0x00004000)
#define MIPS_STATUS_IM5 MIPS_I_(0x00002000)
#define MIPS_STATUS_IM4 MIPS_I_(0x00001000)
#define MIPS_STATUS_IM3 MIPS_I_(0x00000800)
#define MIPS_STATUS_IM2 MIPS_I_(0x00000400)
#define MIPS_STATUS_IM1 MIPS_I_(0x00000200)
#define MIPS_STATUS_IM0 MIPS_I_(0x00000100)
#define MIPS_STATUS_KX MIPS_I_(0x00000080)
#define MIPS_STATUS_SX MIPS_I_(0x00000040)
#define MIPS_STATUS_UX MIPS_I_(0x00000020)
#define MIPS_STATUS_KSUMASK MIPS_I_(0x00000018)
#define MIPS_STATUS_KSUSHIFT 3
#define MIPS_STATUS_KSU_U 2
#define MIPS_STATUS_KSU_S 1
#define MIPS_STATUS_KSU_K 0
#define MIPS_STATUS_ERL MIPS_I_(0x00000004)
#define MIPS_STATUS_EXL MIPS_I_(0x00000002)
#define MIPS_STATUS_IE MIPS_I_(0x00000001)
/* cause register */
#define MIPS_CAUSE_BD MIPS_I_(0x80000000)
#define MIPS_CAUSE_CEMASK MIPS_I_(0x30000000)
#define MIPS_CAUSE_CESHIFT 28
#define MIPS_CAUSE_IP7 MIPS_I_(0x00008000)
#define MIPS_CAUSE_IP6 MIPS_I_(0x00004000)
#define MIPS_CAUSE_IP5 MIPS_I_(0x00002000)
#define MIPS_CAUSE_IP4 MIPS_I_(0x00001000)
#define MIPS_CAUSE_IP3 MIPS_I_(0x00000800)
#define MIPS_CAUSE_IP2 MIPS_I_(0x00000400)
#define MIPS_CAUSE_IP1 MIPS_I_(0x00000200)
#define MIPS_CAUSE_IP0 MIPS_I_(0x00000100)
#define MIPS_CAUSE_EXCMASK MIPS_I_(0x0000007C)
#define MIPS_CAUSE_EXCSHIFT 2
/* exception codes */
#define MIPS_EXC_INT 0
#define MIPS_EXC_MOD 1
#define MIPS_EXC_TLBL 2
#define MIPS_EXC_TLBS 3
#define MIPS_EXC_ADEL 4
#define MIPS_EXC_ADES 5
#define MIPS_EXC_IBE 6
#define MIPS_EXC_DBE 7
#define MIPS_EXC_SYS 8
#define MIPS_EXC_BP 9
#define MIPS_EXC_RI 10
#define MIPS_EXC_CPU 11
#define MIPS_EXC_OV 12
#define MIPS_EXC_TR 13
#define MIPS_EXC_FPE 15
#define MIPS_EXC_WATCH 23
/* prid */
#define MIPS_PRID_IMPMASK MIPS_I_(0xFF00)
#define MIPS_PRID_IMPSHIFT 8
#define MIPS_PRID_REVMASK MIPS_I_(0x00FF)
#define MIPS_PRID_REVSHIFT 0
/* cache targets */
#define MIPS_CACHEMASK MIPS_I_(0x03)
#define MIPS_CACHESHIFT 0
#define MIPS_CACHE_I 0
#define MIPS_CACHE_D 1
/* cache operations */
#define MIPS_CACHEOP(c,o) (MIPS_MAKE_FIELD(MIPS_CACHE,c)| \
MIPS_MAKE_FIELD(MIPS_CACHEOP,o))
#define MIPS_CACHEOPMASK MIPS_I_(0x1C)
#define MIPS_CACHEOPSHIFT 2
#define MIPS_CACHEOP_II 0
#define MIPS_CACHEOP_IWBI 0
#define MIPS_CACHEOP_ILT 1
#define MIPS_CACHEOP_IST 2
#define MIPS_CACHEOP_CDE 3
#define MIPS_CACHEOP_HI 4
#define MIPS_CACHEOP_HWBI 5
#define MIPS_CACHEOP_F 5
#define MIPS_CACHEOP_HWB 6
/* config register */
#define MIPS_CONFIG_ECMASK MIPS_I_(0x70000000)
#define MIPS_CONFIG_ECSHIFT 28
#define MIPS_CONFIG_EC_1_1 6
#define MIPS_CONFIG_EC_3_2 7
#define MIPS_CONFIG_EC_2_1 0
#define MIPS_CONFIG_EC_3_1 1
#define MIPS_CONFIG_EPMASK MIPS_I_(0x0F000000)
#define MIPS_CONFIG_EPSHIFT 24
#define MIPS_CONFIG_EP_D 0
#define MIPS_CONFIG_EP_DXXDXX 6
#define MIPS_CONFIG_BE MIPS_I_(0x00008000)
#define MIPS_CONFIG_K0MASK MIPS_I_(0x00000007)
#define MIPS_CONFIG_K0SHIFT 0
#define MIPS_CONFIG_K0_NC 2
#define MIPS_CONFIG_K0_C 3
/* taglo register */
#define MIPS_TAGLO_PTLMASK MIPS_I_(0x0FFFFF00)
#define MIPS_TAGLO_PTLSHIFT 8
#define MIPS_TAGLO_PSMASK MIPS_I_(0x000000C0)
#define MIPS_TAGLO_PSSHIFT 6
#define MIPS_TAGLO_PS_INVD 0
#define MIPS_TAGLO_PS_DIRTY 3
/* memory breakpoints */
#define MIPS_WATCHLO_PAMASK MIPS_I_(0xFFFFFFF8)
#define MIPS_WATCHLO_PASHIFT 3
#define MIPS_WATCHLO_R MIPS_I_(0x00000002)
#define MIPS_WATCHLO_W MIPS_I_(0x00000001)
/* cp0 registers */
#define MIPS_CP0_INDEX 0
#define MIPS_CP0_RANDOM 1
#define MIPS_CP0_ENTRYLO0 2
#define MIPS_CP0_ENTRYLO1 3
#define MIPS_CP0_CONTEXT 4
#define MIPS_CP0_PAGEMASK 5
#define MIPS_CP0_WIRED 6
#define MIPS_CP0_BADVADDR 8
#define MIPS_CP0_COUNT 9
#define MIPS_CP0_ENTRYHI 10
#define MIPS_CP0_COMPARE 11
#define MIPS_CP0_SR 12
#define MIPS_CP0_CAUSE 13
#define MIPS_CP0_EPC 14
#define MIPS_CP0_PRID 15
#define MIPS_CP0_CONFIG 16
#define MIPS_CP0_LLADDR 17
#define MIPS_CP0_WATCHLO 18
#define MIPS_CP0_WATCHHI 19
#define MIPS_CP0_XCONTEXT 20
#define MIPS_CP0_PERR 26
#define MIPS_CP0_CACHEERR 27
#define MIPS_CP0_TAGLO 28
#define MIPS_CP0_TAGHI 29
#define MIPS_CP0_ERREPC 30
/* floating point control registers */
#define MIPS_FCR_IR 0
#define MIPS_FCR_CS 31
/* floating point control and status register */
#define MIPS_FCSR_FS MIPS_I_(0x01000000)
#define MIPS_FCSR_C MIPS_I_(0x00800000)
#define MIPS_FCSR_CE MIPS_I_(0x00020000)
#define MIPS_FCSR_CV MIPS_I_(0x00010000)
#define MIPS_FCSR_CZ MIPS_I_(0x00008000)
#define MIPS_FCSR_CO MIPS_I_(0x00004000)
#define MIPS_FCSR_CU MIPS_I_(0x00002000)
#define MIPS_FCSR_CI MIPS_I_(0x00001000)
#define MIPS_FCSR_EV MIPS_I_(0x00000800)
#define MIPS_FCSR_EZ MIPS_I_(0x00000400)
#define MIPS_FCSR_EO MIPS_I_(0x00000200)
#define MIPS_FCSR_EU MIPS_I_(0x00000100)
#define MIPS_FCSR_EI MIPS_I_(0x00000080)
#define MIPS_FCSR_FV MIPS_I_(0x00000040)
#define MIPS_FCSR_FZ MIPS_I_(0x00000020)
#define MIPS_FCSR_FO MIPS_I_(0x00000010)
#define MIPS_FCSR_FU MIPS_I_(0x00000008)
#define MIPS_FCSR_FI MIPS_I_(0x00000004)
#define MIPS_FCSR_RMMASK MIPS_I_(0x00000003)
#define MIPS_FCSR_RMSHIFT 0
#define MIPS_FCSR_RM_RN 0
#define MIPS_FCSR_RM_RZ 1
#define MIPS_FCSR_RM_RP 2
#define MIPS_FCSR_RM_RM 3
/**
* inline assembly macros
**/
/* general purpose registers */
#define MIPS_R0 0
#define MIPS_AT 1
#define MIPS_V0 2
#define MIPS_V1 3
#define MIPS_A0 4
#define MIPS_A1 5
#define MIPS_A2 6
#define MIPS_A3 7
#define MIPS_T0 8
#define MIPS_T1 9
#define MIPS_T2 10
#define MIPS_T3 11
#define MIPS_T4 12
#define MIPS_T5 13
#define MIPS_T6 14
#define MIPS_T7 15
#define MIPS_S0 16
#define MIPS_S1 17
#define MIPS_S2 18
#define MIPS_S3 19
#define MIPS_S4 20
#define MIPS_S5 21
#define MIPS_S6 22
#define MIPS_S7 23
#define MIPS_T8 24
#define MIPS_T9 25
#define MIPS_K0 26
#define MIPS_K1 27
#define MIPS_GP 28
#define MIPS_SP 29
#define MIPS_FP 30
#define MIPS_RA 31
/* floating point registers */
#define MIPS_F0 0
#define MIPS_F1 1
#define MIPS_F2 2
#define MIPS_F3 3
#define MIPS_F4 4
#define MIPS_F5 5
#define MIPS_F6 6
#define MIPS_F7 7
#define MIPS_F8 8
#define MIPS_F9 9
#define MIPS_F10 10
#define MIPS_F11 11
#define MIPS_F12 12
#define MIPS_F13 13
#define MIPS_F14 14
#define MIPS_F15 15
#define MIPS_F16 16
#define MIPS_F17 17
#define MIPS_F18 18
#define MIPS_F19 19
#define MIPS_F20 20
#define MIPS_F21 21
#define MIPS_F22 22
#define MIPS_F23 23
#define MIPS_F24 24
#define MIPS_F25 25
#define MIPS_F26 26
#define MIPS_F27 27
#define MIPS_F28 28
#define MIPS_F29 29
#define MIPS_F30 30
#define MIPS_F31 31
/* loads and stores */
#define MIPS_LB(rt,of,rs) MIPS_INI_(0x20,rs,rt,of)
#define MIPS_LBU(rt,of,rs) MIPS_INI_(0x24,rs,rt,of)
#define MIPS_LD(rt,of,rs) MIPS_INI_(0x37,rs,rt,of)
#define MIPS_LDL(rt,of,rs) MIPS_INI_(0x1A,rs,rt,of)
#define MIPS_LDR(rt,of,rs) MIPS_INI_(0x1B,rs,rt,of)
#define MIPS_LH(rt,of,rs) MIPS_INI_(0x21,rs,rt,of)
#define MIPS_LHU(rt,of,rs) MIPS_INI_(0x25,rs,rt,of)
#define MIPS_LL(rt,of,rs) MIPS_INI_(0x30,rs,rt,of)
#define MIPS_LLD(rt,of,rs) MIPS_INI_(0x34,rs,rt,of)
#define MIPS_LW(rt,of,rs) MIPS_INI_(0x23,rs,rt,of)
#define MIPS_LWL(rt,of,rs) MIPS_INI_(0x22,rs,rt,of)
#define MIPS_LWR(rt,of,rs) MIPS_INI_(0x26,rs,rt,of)
#define MIPS_LWU(rt,of,rs) MIPS_INI_(0x27,rs,rt,of)
#define MIPS_SB(rt,of,rs) MIPS_INI_(0x28,rs,rt,of)
#define MIPS_SC(rt,of,rs) MIPS_INI_(0x38,rs,rt,of)
#define MIPS_SCD(rt,of,rs) MIPS_INI_(0x3C,rs,rt,of)
#define MIPS_SD(rt,of,rs) MIPS_INI_(0x3F,rs,rt,of)
#define MIPS_SDL(rt,of,rs) MIPS_INI_(0x2C,rs,rt,of)
#define MIPS_SDR(rt,of,rs) MIPS_INI_(0x2D,rs,rt,of)
#define MIPS_SH(rt,of,rs) MIPS_INI_(0x29,rs,rt,of)
#define MIPS_SW(rt,of,rs) MIPS_INI_(0x2B,rs,rt,of)
#define MIPS_SWL(rt,of,rs) MIPS_INI_(0x2A,rs,rt,of)
#define MIPS_SWR(rt,of,rs) MIPS_INI_(0x2E,rs,rt,of)
#define MIPS_SYNC() MIPS_INR_(0x0F,0,0,0)
/* integer operations */
#define MIPS_ADD(rd,rs,rt) MIPS_INR_(0x20,rs,rt,rd)
#define MIPS_ADDI(rt,rs,im) MIPS_INI_(0x08,rs,rt,im)
#define MIPS_ADDIU(rt,rs,im) MIPS_INI_(0x09,rs,rt,im)
#define MIPS_ADDU(rd,rs,rt) MIPS_INR_(0x21,rs,rt,rd)
#define MIPS_AND(rd,rs,rt) MIPS_INR_(0x24,rs,rt,rd)
#define MIPS_ANDI(rt,rs,im) MIPS_INI_(0x0C,rs,rt,im)
#define MIPS_DADD(rd,rs,rt) MIPS_INR_(0x2C,rs,rt,rd)
#define MIPS_DADDI(rt,rs,im) MIPS_INI_(0x18,rs,rt,im)
#define MIPS_DADDIU(rt,rs,im) MIPS_INI_(0x19,rs,rt,im)
#define MIPS_DADDU(rd,rs,rt) MIPS_INR_(0x2D,rs,rt,rd)
#define MIPS_DDIV(rs,rt) MIPS_INR_(0x1E,rs,rt,0)
#define MIPS_DDIVU(rs,rt) MIPS_INR_(0x1F,rs,rt,0)
#define MIPS_DIV(rs,rt) MIPS_INR_(0x1A,rs,rt,0)
#define MIPS_DIVU(rs,rt) MIPS_INR_(0x1B,rs,rt,0)
#define MIPS_DMULT(rs,rt) MIPS_INR_(0x1C,rs,rt,0)
#define MIPS_DMULTU(rs,rt) MIPS_INR_(0x1D,rs,rt,0)
#define MIPS_DSLL(rd,rt,sa) MIPS_INS_(0x38,0,rt,rd,sa)
#define MIPS_DSLL32(rd,rt,sa) MIPS_INS_(0x3C,0,rt,rd,sa)
#define MIPS_DSLLV(rd,rt,rs) MIPS_INR_(0x14,rs,rt,rd)
#define MIPS_DSRA(rd,rt,sa) MIPS_INS_(0x3B,0,rt,rd,sa)
#define MIPS_DSRA32(rd,rt,sa) MIPS_INS_(0x3F,0,rt,rd,sa)
#define MIPS_DSRAV(rd,rt,rs) MIPS_INR_(0x17,rs,rt,rd)
#define MIPS_DSRL(rd,rt,sa) MIPS_INS_(0x3A,0,rt,rd,sa)
#define MIPS_DSRL32(rd,rt,sa) MIPS_INS_(0x3E,0,rt,rd,sa)
#define MIPS_DSRLV(rd,rt,rs) MIPS_INR_(0x16,rs,rt,rd)
#define MIPS_DSUB(rd,rs,rt) MIPS_INR_(0x2E,rs,rt,rd)
#define MIPS_DSUBU(rd,rs,rt) MIPS_INR_(0x2F,rs,rt,rd)
#define MIPS_LUI(rt,im) MIPS_INI_(0x0F,0,rt,im)
#define MIPS_MFHI(rd) MIPS_INR_(0x10,0,0,rd)
#define MIPS_MFLO(rd) MIPS_INR_(0x12,0,0,rd)
#define MIPS_MTHI(rs) MIPS_INR_(0x11,rs,0,0)
#define MIPS_MTLO(rs) MIPS_INR_(0x13,rs,0,0)
#define MIPS_MULT(rs,rt) MIPS_INR_(0x18,rs,rt,0)
#define MIPS_MULTU(rs,rt) MIPS_INR_(0x19,rs,rt,0)
#define MIPS_NOR(rd,rs,rt) MIPS_INR_(0x27,rs,rt,rd)
#define MIPS_OR(rd,rs,rt) MIPS_INR_(0x25,rs,rt,rd)
#define MIPS_ORI(rt,rs,im) MIPS_INI_(0x0D,rs,rt,im)
#define MIPS_SLL(rd,rt,sa) MIPS_INS_(0x00,0,rt,rd,sa)
#define MIPS_SLLV(rd,rt,rs) MIPS_INR_(0x04,rs,rt,rd)
#define MIPS_SLT(rd,rs,rt) MIPS_INR_(0x2A,rs,rt,rd)
#define MIPS_SLTI(rt,rs,im) MIPS_INI_(0x0A,rs,rt,im)
#define MIPS_SLTIU(rt,rs,im) MIPS_INI_(0x0B,rs,rt,im)
#define MIPS_SLTU(rd,rs,rt) MIPS_INR_(0x2B,rs,rt,rd)
#define MIPS_SRA(rd,rt,sa) MIPS_INS_(0x03,0,rt,rd,sa)
#define MIPS_SRAV(rd,rt,rs) MIPS_INR_(0x07,rs,rt,rd)
#define MIPS_SRL(rd,rt,sa) MIPS_INS_(0x02,0,rt,rd,sa)
#define MIPS_SRLV(rd,rt,rs) MIPS_INR_(0x06,rs,rt,rd)
#define MIPS_SUB(rd,rs,rt) MIPS_INR_(0x22,rs,rt,rd)
#define MIPS_SUBU(rd,rs,rt) MIPS_INR_(0x23,rs,rt,rd)
#define MIPS_XOR(rd,rs,rt) MIPS_INR_(0x26,rs,rt,rd)
#define MIPS_XORI(rt,rs,im) MIPS_INI_(0x0E,rs,rt,im)
/* branching */
#define MIPS_BEQ(rs,rt,of) MIPS_INB_(0x04,rs,rt,of)
#define MIPS_BEQL(rs,rt,of) MIPS_INB_(0x14,rs,rt,of)
#define MIPS_BGEZ(rs,of) MIPS_INB_(0x01,rs,0x01,of)
#define MIPS_BGEZAL(rs,of) MIPS_INB_(0x01,rs,0x11,of)
#define MIPS_BGEZALL(rs,of) MIPS_INB_(0x01,rs,0x13,of)
#define MIPS_BGEZL(rs,of) MIPS_INB_(0x01,rs,0x03,of)
#define MIPS_BGTZ(rs,of) MIPS_INB_(0x07,rs,0x00,of)
#define MIPS_BGTZL(rs,of) MIPS_INB_(0x17,rs,0x00,of)
#define MIPS_BLEZ(rs,of) MIPS_INB_(0x06,rs,0x00,of)
#define MIPS_BLEZL(rs,of) MIPS_INB_(0x16,rs,0x00,of)
#define MIPS_BLTZ(rs,of) MIPS_INB_(0x01,rs,0x00,of)
#define MIPS_BLTZAL(rs,of) MIPS_INB_(0x01,rs,0x10,of)
#define MIPS_BLTZALL(rs,of) MIPS_INB_(0x01,rs,0x12,of)
#define MIPS_BLTZL(rs,of) MIPS_INB_(0x01,rs,0x02,of)
#define MIPS_BNE(rs,rt,of) MIPS_INB_(0x05,rs,rt,of)
#define MIPS_BNEL(rs,rt,of) MIPS_INB_(0x15,rs,rt,of)
#define MIPS_J(ad) MIPS_INJ_(0x02,ad)
#define MIPS_JAL(ad) MIPS_INJ_(0x03,ad)
#define MIPS_JALR(rd,rs) MIPS_INR_(0x09,rs,0,rd)
#define MIPS_JR(rs) MIPS_INR_(0x08,rs,0,0)
/* exceptions */
#define MIPS_BREAK(ec) MIPS_INE_(0x0D,ec)
#define MIPS_SYSCALL(ec) MIPS_INE_(0x0C,ec)
#define MIPS_TEQ(rs,rt,tc) MIPS_INT_(0x34,rs,rt,tc)
#define MIPS_TEQI(rs,im) MIPS_INI_(0x01,rs,0x0C,im)
#define MIPS_TGE(rs,rt,tc) MIPS_INT_(0x30,rs,rt,tc)
#define MIPS_TGEI(rs,im) MIPS_INI_(0x01,rs,0x08,im)
#define MIPS_TGEIU(rs,im) MIPS_INI_(0x01,rs,0x09,im)
#define MIPS_TGEU(rs,rt,tc) MIPS_INT_(0x31,rs,rt,tc)
#define MIPS_TLT(rs,rt,tc) MIPS_INT_(0x32,rs,rt,tc)
#define MIPS_TLTI(rs,im) MIPS_INI_(0x01,rs,0x0A,im)
#define MIPS_TLTIU(rs,im) MIPS_INI_(0x01,rs,0x0B,im)
#define MIPS_TLTU(rs,rt,tc) MIPS_INT_(0x33,rs,rt,tc)
#define MIPS_TNE(rs,rt,tc) MIPS_INT_(0x36,rs,rt,tc)
#define MIPS_TNEI(rs,im) MIPS_INI_(0x01,rs,0x0E,im)
/* system control */
#define MIPS_CACHE(op,of,rs) MIPS_INI_(0x2F,rs,op,of)
#define MIPS_ERET() MIPS_INC_(0x18,0x10,0,0)
#define MIPS_MFC0(rt,fs) MIPS_INC_(0x00,0x00,rt,fs)
#define MIPS_MTC0(rt,fs) MIPS_INC_(0x00,0x04,rt,fs)
#define MIPS_TLBP() MIPS_INC_(0x08,0x10,0,0)
#define MIPS_TLBR() MIPS_INC_(0x01,0x10,0,0)
#define MIPS_TLBWI() MIPS_INC_(0x02,0x10,0,0)
#define MIPS_TLBWR() MIPS_INC_(0x06,0x10,0,0)
/* floating point operations */
#define MIPS_ABSD(fd,fs) MIPS_INF_(0x05,MIPS_FMD_,0,fs,fd)
#define MIPS_ABSS(fd,fs) MIPS_INF_(0x05,MIPS_FMS_,0,fs,fd)
#define MIPS_ADDD(fd,fs,ft) MIPS_INF_(0x00,MIPS_FMD_,ft,fs,fd)
#define MIPS_ADDS(fd,fs,ft) MIPS_INF_(0x00,MIPS_FMS_,ft,fs,fd)
#define MIPS_BC1F(of) MIPS_INFB_(0x00,of)
#define MIPS_BC1FL(of) MIPS_INFB_(0x02,of)
#define MIPS_BC1T(of) MIPS_INFB_(0x01,of)
#define MIPS_BC1TL(of) MIPS_INFB_(0x03,of)
#define MIPS_CEILLD(fd,fs) MIPS_INF_(0x0A,MIPS_FMD_,0,fs,fd)
#define MIPS_CEILLS(fd,fs) MIPS_INF_(0x0A,MIPS_FMS_,0,fs,fd)
#define MIPS_CEILWD(fd,fs) MIPS_INF_(0x0E,MIPS_FMD_,0,fs,fd)
#define MIPS_CEILWS(fd,fs) MIPS_INF_(0x0E,MIPS_FMS_,0,fs,fd)
#define MIPS_CEQD(fs,ft) MIPS_INF_(0x32,MIPS_FMD_,ft,fs,0)
#define MIPS_CEQS(fs,ft) MIPS_INF_(0x32,MIPS_FMS_,ft,fs,0)
#define MIPS_CFC1(rt,fs) MIPS_INF_(0x00,0x02,rt,fs,0)
#define MIPS_CFD(fs,ft) MIPS_INF_(0x30,MIPS_FMD_,ft,fs,0)
#define MIPS_CFS(fs,ft) MIPS_INF_(0x30,MIPS_FMS_,ft,fs,0)
#define MIPS_CLED(fs,ft) MIPS_INF_(0x3E,MIPS_FMD_,ft,fs,0)
#define MIPS_CLES(fs,ft) MIPS_INF_(0x3E,MIPS_FMS_,ft,fs,0)
#define MIPS_CLTD(fs,ft) MIPS_INF_(0x3C,MIPS_FMD_,ft,fs,0)
#define MIPS_CLTS(fs,ft) MIPS_INF_(0x3C,MIPS_FMS_,ft,fs,0)
#define MIPS_CNGED(fs,ft) MIPS_INF_(0x3D,MIPS_FMD_,ft,fs,0)
#define MIPS_CNGES(fs,ft) MIPS_INF_(0x3D,MIPS_FMS_,ft,fs,0)
#define MIPS_CNGLD(fs,ft) MIPS_INF_(0x3B,MIPS_FMD_,ft,fs,0)
#define MIPS_CNGLED(fs,ft) MIPS_INF_(0x39,MIPS_FMD_,ft,fs,0)
#define MIPS_CNGLES(fs,ft) MIPS_INF_(0x39,MIPS_FMS_,ft,fs,0)
#define MIPS_CNGLS(fs,ft) MIPS_INF_(0x3B,MIPS_FMS_,ft,fs,0)
#define MIPS_CNGTD(fs,ft) MIPS_INF_(0x3F,MIPS_FMD_,ft,fs,0)
#define MIPS_CNGTS(fs,ft) MIPS_INF_(0x3F,MIPS_FMS_,ft,fs,0)
#define MIPS_COLED(fs,ft) MIPS_INF_(0x36,MIPS_FMD_,ft,fs,0)
#define MIPS_COLES(fs,ft) MIPS_INF_(0x36,MIPS_FMS_,ft,fs,0)
#define MIPS_COLTD(fs,ft) MIPS_INF_(0x34,MIPS_FMD_,ft,fs,0)
#define MIPS_COLTS(fs,ft) MIPS_INF_(0x34,MIPS_FMS_,ft,fs,0)
#define MIPS_CSEQD(fs,ft) MIPS_INF_(0x3A,MIPS_FMD_,ft,fs,0)
#define MIPS_CSEQS(fs,ft) MIPS_INF_(0x3A,MIPS_FMS_,ft,fs,0)
#define MIPS_CSFD(fs,ft) MIPS_INF_(0x38,MIPS_FMD_,ft,fs,0)
#define MIPS_CSFS(fs,ft) MIPS_INF_(0x38,MIPS_FMS_,ft,fs,0)
#define MIPS_CTC1(rt,fs) MIPS_INF_(0x00,0x06,rt,fs,0)
#define MIPS_CUEQD(fs,ft) MIPS_INF_(0x33,MIPS_FMD_,ft,fs,0)
#define MIPS_CUEQS(fs,ft) MIPS_INF_(0x33,MIPS_FMS_,ft,fs,0)
#define MIPS_CULED(fs,ft) MIPS_INF_(0x37,MIPS_FMD_,ft,fs,0)
#define MIPS_CULES(fs,ft) MIPS_INF_(0x37,MIPS_FMS_,ft,fs,0)
#define MIPS_CULTD(fs,ft) MIPS_INF_(0x35,MIPS_FMD_,ft,fs,0)
#define MIPS_CULTS(fs,ft) MIPS_INF_(0x35,MIPS_FMS_,ft,fs,0)
#define MIPS_CUND(fs,ft) MIPS_INF_(0x31,MIPS_FMD_,ft,fs,0)
#define MIPS_CUNS(fs,ft) MIPS_INF_(0x31,MIPS_FMS_,ft,fs,0)
#define MIPS_CVTDL(fd,fs) MIPS_INF_(0x21,MIPS_FML_,0,fs,fd)
#define MIPS_CVTDS(fd,fs) MIPS_INF_(0x21,MIPS_FMS_,0,fs,fd)
#define MIPS_CVTDW(fd,fs) MIPS_INF_(0x21,MIPS_FMW_,0,fs,fd)
#define MIPS_CVTLD(fd,fs) MIPS_INF_(0x25,MIPS_FMD_,0,fs,fd)
#define MIPS_CVTLS(fd,fs) MIPS_INF_(0x25,MIPS_FMS_,0,fs,fd)
#define MIPS_CVTSD(fd,fs) MIPS_INF_(0x20,MIPS_FMD_,0,fs,fd)
#define MIPS_CVTSL(fd,fs) MIPS_INF_(0x20,MIPS_FML_,0,fs,fd)
#define MIPS_CVTSW(fd,fs) MIPS_INF_(0x20,MIPS_FMW_,0,fs,fd)
#define MIPS_CVTWD(fd,fs) MIPS_INF_(0x24,MIPS_FMD_,0,fs,fd)
#define MIPS_CVTWS(fd,fs) MIPS_INF_(0x24,MIPS_FMS_,0,fs,fd)
#define MIPS_DIVD(fd,fs,ft) MIPS_INF_(0x03,MIPS_FMD_,ft,fs,fd)
#define MIPS_DIVS(fd,fs,ft) MIPS_INF_(0x03,MIPS_FMS_,ft,fs,fd)
#define MIPS_DMFC1(rt,fs) MIPS_INF_(0x00,0x01,rt,fs,0)
#define MIPS_DMTC1(rt,fs) MIPS_INF_(0x00,0x05,rt,fs,0)
#define MIPS_FLOORLD(fd,fs) MIPS_INF_(0x0B,MIPS_FMD_,0,fs,fd)
#define MIPS_FLOORLS(fd,fs) MIPS_INF_(0x0B,MIPS_FMS_,0,fs,fd)
#define MIPS_FLOORWD(fd,fs) MIPS_INF_(0x0F,MIPS_FMD_,0,fs,fd)
#define MIPS_FLOORWS(fd,fs) MIPS_INF_(0x0F,MIPS_FMS_,0,fs,fd)
#define MIPS_LDC1(ft,of,rs) MIPS_INI_(0x35,rs,ft,of)
#define MIPS_LWC1(ft,of,rs) MIPS_INI_(0x31,rs,ft,of)
#define MIPS_MFC1(rt,fs) MIPS_INF_(0x00,0x00,rt,fs,0)
#define MIPS_MTC1(rt,fs) MIPS_INF_(0x00,0x04,rt,fs,0)
#define MIPS_MOVD(fd,fs) MIPS_INF_(0x06,MIPS_FMD_,0,fs,fd)
#define MIPS_MOVS(fd,fs) MIPS_INF_(0x06,MIPS_FMS_,0,fs,fd)
#define MIPS_MULD(fd,fs,ft) MIPS_INF_(0x02,MIPS_FMD_,ft,fs,fd)
#define MIPS_MULS(fd,fs,ft) MIPS_INF_(0x02,MIPS_FMS_,ft,fs,fd)
#define MIPS_NEGD(fd,fs) MIPS_INF_(0x07,MIPS_FMD_,0,fs,fd)
#define MIPS_NEGS(fd,fs) MIPS_INF_(0x07,MIPS_FMS_,0,fs,fd)
#define MIPS_ROUNDLD(fd,fs) MIPS_INF_(0x08,MIPS_FMD_,0,fs,fd)
#define MIPS_ROUNDLS(fd,fs) MIPS_INF_(0x08,MIPS_FMS_,0,fs,fd)
#define MIPS_ROUNDWD(fd,fs) MIPS_INF_(0x0C,MIPS_FMD_,0,fs,fd)
#define MIPS_ROUNDWS(fd,fs) MIPS_INF_(0x0C,MIPS_FMS_,0,fs,fd)
#define MIPS_SDC1(ft,of,rs) MIPS_INI_(0x3D,rs,ft,of)
#define MIPS_SQRTD(fd,fs) MIPS_INF_(0x04,MIPS_FMD_,0,fs,fd)
#define MIPS_SQRTS(fd,fs) MIPS_INF_(0x04,MIPS_FMS_,0,fs,fd)
#define MIPS_SUBD(fd,fs,ft) MIPS_INF_(0x01,MIPS_FMD_,ft,fs,fd)
#define MIPS_SUBS(fd,fs,ft) MIPS_INF_(0x01,MIPS_FMS_,ft,fs,fd)
#define MIPS_SWC1(ft,of,rs) MIPS_INI_(0x39,rs,ft,of)
#define MIPS_TRUNCLD(fd,fs) MIPS_INF_(0x09,MIPS_FMD_,0,fs,fd)
#define MIPS_TRUNCLS(fd,fs) MIPS_INF_(0x09,MIPS_FMS_,0,fs,fd)
#define MIPS_TRUNCWD(fd,fs) MIPS_INF_(0x0D,MIPS_FMD_,0,fs,fd)
#define MIPS_TRUNCWS(fd,fs) MIPS_INF_(0x0D,MIPS_FMS_,0,fs,fd)
/* pseudo-instructions */
#define MIPS_NOP() MIPS_SLL(MIPS_R0,MIPS_R0,0)
/**
* private helper macros
**/
#define MIPS_I_(x) ((uint32_t)(x))
#define MIPS_OP_(x) ((MIPS_I_(x)&0x3F)<<26)
#define MIPS_RS_(x) ((MIPS_I_(x)&0x1F)<<21)
#define MIPS_RT_(x) ((MIPS_I_(x)&0x1F)<<16)
#define MIPS_RD_(x) ((MIPS_I_(x)&0x1F)<<11)
#define MIPS_SA_(x) ((MIPS_I_(x)&0x1F)<<6)
#define MIPS_EC_(x) ((MIPS_I_(x)&0xFFFFF)<<6)
#define MIPS_TC_(x) ((MIPS_I_(x)&0x3FF)<<6)
#define MIPS_FN_(x) (MIPS_I_(x)&0x3F)
#define MIPS_IM_(x) (MIPS_I_(x)&0xFFFF)
#define MIPS_AD_(x) ((MIPS_I_(x)&0xFFFFFFF)>>2)
#define MIPS_OF_(x) ((MIPS_I_(x)>>2)&0xFFFF)
#define MIPS_INI_(op,rs,rt,im) (MIPS_OP_(op)|MIPS_RS_(rs)| \
MIPS_RT_(rt)|MIPS_IM_(im))
#define MIPS_INB_(op,rs,rt,of) (MIPS_OP_(op)|MIPS_RS_(rs)| \
MIPS_RT_(rt)|MIPS_OF_(of))
#define MIPS_INS_(fn,rs,rt,rd,sa) (MIPS_RS_(rs)|MIPS_RT_(rt)| \
MIPS_RD_(rd)|MIPS_SA_(sa)| \
MIPS_FN_(fn))
#define MIPS_INR_(fn,rs,rt,rd) MIPS_INS_(fn,rs,rt,rd,0)
#define MIPS_INJ_(op,ad) (MIPS_OP_(op)|MIPS_AD_(ad))
#define MIPS_INC_(fn,fm,rt,fs) (MIPS_OP_(0x10)|MIPS_RS_(fm)| \
MIPS_RT_(rt)|MIPS_RD_(fs)| \
MIPS_FN_(fn))
#define MIPS_INF_(fn,fm,ft,fs,fd) (MIPS_OP_(0x11)|MIPS_RS_(fm)| \
MIPS_RT_(ft)|MIPS_RD_(fs)| \
MIPS_SA_(fd)|MIPS_FN_(fn))
#define MIPS_INE_(fn,ec) (MIPS_EC_(ec)|MIPS_FN_(fn))
#define MIPS_INT_(fn,rs,rt,tc) (MIPS_RS_(rs)|MIPS_RT_(rt)| \
MIPS_TC_(tc)|MIPS_FN_(fn))
#define MIPS_INFB_(nt,of) MIPS_INB_(0x11,0x08,nt,of)
#define MIPS_FMS_ 0x10
#define MIPS_FMD_ 0x11
#define MIPS_FMW_ 0x14
#define MIPS_FML_ 0x15
#endif

View File

@ -0,0 +1,15 @@
/* n64.h
* -glank
*/
#ifndef N64_H
#define N64_H
#include "n64/gbi.h"
#include "n64/message.h"
#include "n64/pi.h"
#include "n64/task.h"
#include "n64/thread.h"
#include "n64/vr4300.h"
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,52 @@
#ifndef N64_MESSAGE_H
#define N64_MESSAGE_H
#include <stdint.h>
#include "thread.h"
#define OS_NUM_EVENTS 15
#define OS_EVENT_SW1 0
#define OS_EVENT_SW2 1
#define OS_EVENT_CART 2
#define OS_EVENT_COUNTER 3
#define OS_EVENT_SP 4
#define OS_EVENT_SI 5
#define OS_EVENT_AI 6
#define OS_EVENT_VI 7
#define OS_EVENT_PI 8
#define OS_EVENT_DP 9
#define OS_EVENT_CPU_BREAK 10
#define OS_EVENT_SP_BREAK 11
#define OS_EVENT_FAULT 12
#define OS_EVENT_THREADSTATUS 13
#define OS_EVENT_PRENMI 14
#define OS_MESG_NOBLOCK 0
#define OS_MESG_BLOCK 1
#define MQ_GET_COUNT(mq) ((mq)->validCount)
#define MQ_IS_EMPTY(mq) (MQ_GET_COUNT(mq)==0)
#define MQ_IS_FULL(mq) (MQ_GET_COUNT(mq)>=(mq)->msgCount)
typedef uint32_t OSEvent;
typedef void *OSMesg;
typedef struct
{
OSThread *mtqueue; /* 0x0000 */
OSThread *fullqueue; /* 0x0004 */
int32_t validCount; /* 0x0008 */
int32_t first; /* 0x000C */
int32_t msgCount; /* 0x0010 */
OSMesg *msg; /* 0x0014 */
/* 0x0018 */
} OSMesgQueue;
typedef void (*osCreateMesgQueue_t)(OSMesgQueue*, OSMesg*, int32_t);
typedef int32_t (*osSendMesg_t) (OSMesgQueue*, OSMesg, int32_t);
typedef int32_t (*osJamMesg_t) (OSMesgQueue*, OSMesg, int32_t);
typedef int32_t (*osRecvMesg_t) (OSMesgQueue*, OSMesg*, int32_t);
typedef void (*osSetEventMesg_t) (OSEvent, OSMesgQueue*, OSMesg);
#endif

View File

@ -0,0 +1,109 @@
#ifndef N64_PI_H
#define N64_PI_H
#include <stdint.h>
#define PI_STATUS_DMA_BUSY 0x01
#define PI_STATUS_IO_BUSY 0x02
#define PI_STATUS_ERROR 0x04
#define PI_STATUS_RESET 0x01
#define PI_STATUS_CLR_INTR 0x02
#define DEVICE_TYPE_CART 0
#define DEVICE_TYPE_BULK 1
#define DEVICE_TYPE_64DD 2
#define DEVICE_TYPE_SRAM 3
#define DEVICE_TYPE_INIT 7
#define PI_DOMAIN1 0
#define PI_DOMAIN2 1
#define OS_MESG_TYPE_LOOPBACK 10
#define OS_MESG_TYPE_DMAREAD 11
#define OS_MESG_TYPE_DMAWRITE 12
#define OS_MESG_TYPE_VRETRACE 13
#define OS_MESG_TYPE_COUNTER 14
#define OS_MESG_TYPE_EDMAREAD 15
#define OS_MESG_TYPE_EDMAWRITE 16
#define OS_MESG_PRI_NORMAL 0
#define OS_MESG_PRI_HIGH 1
#define OS_READ 0
#define OS_WRITE 1
#define OS_OTHERS 2
typedef struct
{
uint32_t dram_addr; /* 0x0000 */
uint32_t cart_addr; /* 0x0004 */
uint32_t rd_len; /* 0x0008 */
uint32_t wr_len; /* 0x000C */
uint32_t status; /* 0x0010 */
/* 0x0014 */
} pi_regs_t;
typedef struct
{
uint32_t errStatus; /* 0x0000 */
void *dramAddr; /* 0x0004 */
void *C2Addr; /* 0x0008 */
uint32_t sectorSize; /* 0x000C */
uint32_t C1ErrNum; /* 0x0010 */
uint32_t C1ErrSector[4]; /* 0x0014 */
/* 0x0024 */
} __OSBlockInfo;
typedef struct
{
uint32_t cmdType; /* 0x0000 */
uint16_t transferMode; /* 0x0004 */
uint16_t blockNum; /* 0x0006 */
int32_t sectorNum; /* 0x0008 */
uint32_t devAddr; /* 0x000C */
uint32_t bmCtlShadow; /* 0x0010 */
uint32_t seqCtlShadow; /* 0x0014 */
__OSBlockInfo block[2]; /* 0x0018 */
/* 0x0060 */
} __OSTranxInfo;
typedef struct OSPiHandle_s OSPiHandle;
struct OSPiHandle_s
{
OSPiHandle *next; /* 0x0000 */
uint8_t type; /* 0x0004 */
uint8_t latency; /* 0x0005 */
uint8_t pageSize; /* 0x0006 */
uint8_t relDuration; /* 0x0007 */
uint8_t pulse; /* 0x0008 */
uint8_t domain; /* 0x0009 */
uint32_t baseAddress; /* 0x000C */
uint32_t speed; /* 0x0010 */
__OSTranxInfo transferInfo; /* 0x0014 */
/* 0x0074 */
};
typedef struct
{
uint16_t type; /* 0x0000 */
uint8_t pri; /* 0x0002 */
uint8_t status; /* 0x0003 */
OSMesgQueue *retQueue; /* 0x0004 */
/* 0x0008 */
} OSIoMesgHdr;
typedef struct
{
OSIoMesgHdr hdr; /* 0x0000 */
void *dramAddr; /* 0x0008 */
uint32_t devAddr; /* 0x000C */
uint32_t size; /* 0x0010 */
OSPiHandle *piHandle; /* 0x0014 */
/* 0x0018 */
} OSIoMesg;
typedef int32_t (*osEPiStartDma_t)(OSPiHandle*, OSIoMesg*, int32_t);
#define pi_regs (*(volatile pi_regs_t*)0xA4600000)
#endif

View File

@ -0,0 +1,43 @@
#ifndef N64_TASK_H
#define N64_TASK_H
#include <stdint.h>
#include "message.h"
typedef struct
{
_Alignas(8)
uint32_t type; /* 0x0000 */
uint32_t flags; /* 0x0004 */
uint64_t *ucode_boot; /* 0x0008 */
uint32_t ucode_boot_size; /* 0x000C */
uint64_t *ucode; /* 0x0010 */
uint32_t ucode_size; /* 0x0014 */
uint64_t *ucode_data; /* 0x0018 */
uint32_t ucode_data_size; /* 0x001C */
uint64_t *dram_stack; /* 0x0020 */
uint32_t dram_stack_size; /* 0x0024 */
uint64_t *output_buff; /* 0x0028 */
uint64_t *output_buff_size; /* 0x002C */
uint64_t *data_ptr; /* 0x0030 */
uint32_t data_size; /* 0x0034 */
uint64_t *yield_data_ptr; /* 0x0038 */
uint32_t yield_data_size; /* 0x003C */
/* 0x0040 */
} OSTask;
typedef struct OSScTask_s OSScTask;
struct OSScTask_s
{
OSScTask *next; /* 0x0000 */
uint32_t state; /* 0x0004 */
uint32_t flags; /* 0x0008 */
void *framebuffer; /* 0x000C */
OSTask list; /* 0x0010 */
OSMesgQueue *msgQ; /* 0x0050 */
OSMesg msg; /* 0x0054 */
/* 0x0058 */
};
#endif

View File

@ -0,0 +1,66 @@
#ifndef N64_THREAD_H
#define N64_THREAD_H
#include <stdint.h>
#define OS_STATE_STOPPED 1
#define OS_STATE_RUNNABLE 2
#define OS_STATE_RUNNING 4
#define OS_STATE_WAITING 8
#define OS_PRIORITY_IDLE 0
#define OS_PRIORITY_APPMAX 127
#define OS_PRIORITY_SIMGR 140
#define OS_PRIORITY_PIMGR 150
#define OS_PRIORITY_RMONSPIN 200
#define OS_PRIORITY_RMON 250
#define OS_PRIORITY_VIMGR 254
#define OS_PRIORITY_MAX 255
typedef int32_t OSPri;
typedef int32_t OSId;
typedef struct
{
uint64_t at, v0, v1, a0, a1, a2, a3,
t0, t1, t2, t3, t4, t5, t6, t7,
s0, s1, s2, s3, s4, s5, s6, s7,
t8, t9, gp, sp, s8, ra, lo, hi;
uint32_t sr, pc, cause, badvaddr, rcp;
uint32_t fpcsr;
union
{
float fp32[32];
double fp64[16];
};
/* 0x01D8 */
} __OSThreadContext;
typedef struct OSThread_s OSThread;
struct OSThread_s
{
OSThread *next; /* 0x0000 */
OSPri priority; /* 0x0004 */
OSThread **queue; /* 0x0008 */
OSThread *tlnext; /* 0x000C */
uint16_t state; /* 0x0010 */
uint16_t flags; /* 0x0012 */
OSId id; /* 0x0014 */
int32_t fp; /* 0x0018 */
__OSThreadContext context; /* 0x001C */
/* 0x01F4 */
};
typedef void (*osCreateThread_t) (OSThread*, OSId, void(*)(void*),
void*, void*, OSPri);
typedef void (*osDestroyThread_t) (OSThread*);
typedef void (*osYieldThread_t) (void);
typedef void (*osStartThread_t) (OSThread*);
typedef void (*osStopThread_t) (OSThread*);
typedef OSId (*osGetThreadId_t) (OSThread*);
typedef void (*osSetThreadPri_t) (OSThread*, OSPri);
typedef OSPri (*osGetThreadPri_t) (OSThread*);
typedef OSThread *(*osGetCurrFaultedThread_t) (void);
typedef OSThread *(*osGetNextFaultedThread_t) (OSThread*);
#endif

View File

@ -0,0 +1,7 @@
#ifndef N64_VR4300_H
#define N64_VR4300_H
#define OS_CLOCK_RATE 62500000
#define OS_CPU_COUNTER 46875000
#endif

View File

@ -0,0 +1,154 @@
/* set.c
* -glank
*/
#include <string.h>
#include <vector/vector.h>
#include "set.h"
#define MAX_ALIGN(N) (((N) + _Alignof(max_align_t) - 1) & \
~(_Alignof(max_align_t) - 1))
#ifdef __cplusplus
extern "C"
{
#endif
static size_t set_locate(const struct set *set, void *value, _Bool *match)
{
if (set->container.size == 0) {
*match = 0;
return 0;
}
size_t left = 0;
size_t right = set->container.size - 1;
size_t position = 0;
while (left <= right) {
position = (left + right) / 2;
void *element_value = vector_at(&set->container, position);
if (set->comparator(element_value, value)) {
++position;
left = position;
}
else if (set->comparator(value, element_value)) {
if (position == 0)
break;
right = position - 1;
}
else {
*match = 1;
return position;
}
}
*match = 0;
return position;
}
void set_init(struct set *set, size_t value_size,
_Bool (*comparator)(void *a, void *b))
{
set->comparator = comparator;
vector_init(&set->container, value_size);
}
void set_destroy(struct set *set)
{
vector_destroy(&set->container);
}
void *set_insert(struct set *set, void *value)
{
_Bool match;
size_t position = set_locate(set, value, &match);
if (match) {
void *old_value = vector_at(&set->container, position);
memcpy(old_value, value, set->container.element_size);
return old_value;
}
return vector_insert(&set->container, position, 1, value);
}
void *set_put(struct set *set, void *value)
{
_Bool match;
size_t position = set_locate(set, value, &match);
if (match)
return NULL;
return vector_insert(&set->container, position, 1, value);
}
void set_erase(struct set *set, void *value)
{
_Bool match;
size_t position = set_locate(set, value, &match);
if (match)
vector_erase(&set->container, position, 1);
}
void *set_get(const struct set *set, void *value)
{
_Bool match;
size_t position = set_locate(set, value, &match);
if (!match)
return NULL;
return vector_at(&set->container, position);
}
void *set_at(const struct set *set, size_t position)
{
return vector_at(&set->container, position);
}
void set_union(struct set *a, const struct set *b)
{
for (size_t i = 0; i < b->container.size; ++i) {
void *value = vector_at(&b->container, i);
_Bool match;
size_t position = set_locate(a, value, &match);
if (!match)
vector_insert(&a->container, position, 1, value);
}
}
void set_intersection(struct set *a, const struct set *b)
{
for (size_t i = 0; i < a->container.size; ) {
void *value = vector_at(&a->container, i);
_Bool match;
set_locate(b, value, &match);
if (!match)
vector_erase(&a->container, i, 1);
else
++i;
}
}
void set_difference(struct set *a, const struct set *b)
{
for (size_t i = 0; i < a->container.size; ) {
void *value = vector_at(&a->container, i);
_Bool match;
set_locate(b, value, &match);
if (match)
vector_erase(&a->container, i, 1);
else
++i;
}
}
void set_symmetric_difference(struct set *a, const struct set *b)
{
for (size_t i = 0; i < b->container.size; ++i) {
void *value = vector_at(&b->container, i);
_Bool match;
size_t position = set_locate(a, value, &match);
if (match)
vector_erase(&a->container, position, 1);
else
vector_insert(&a->container, position, 1, value);
}
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,38 @@
/* set.h
* -glank
*/
#ifndef SET_H
#define SET_H
#include <stddef.h>
#include <vector/vector.h>
struct set
{
_Bool (*comparator)(void *a, void *b);
struct vector container;
};
#ifdef __cplusplus
extern "C"
{
#endif
void set_init(struct set *set, size_t value_size,
_Bool (*comparator)(void *a, void *b));
void set_destroy(struct set *set);
void *set_insert(struct set *set, void *value);
void *set_put(struct set *set, void *value);
void set_erase(struct set *set, void *value);
void *set_get(const struct set *set, void *value);
void *set_at(const struct set *set, size_t position);
void set_union(struct set *a, const struct set *b);
void set_intersection(struct set *a, const struct set *b);
void set_difference(struct set *a, const struct set *b);
void set_symmetric_difference(struct set *a, const struct set *b);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,59 @@
/* startup.c
* -glank
*/
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif
#ifndef NO_STARTUP_LISTS
static __attribute__((section(".ctor_i"), used)) int32_t ctor_i = -1;
static __attribute__((section(".ctor_n"), used)) int32_t ctor_n = 0;
static __attribute__((section(".dtor_i"), used)) int32_t dtor_i = -1;
static __attribute__((section(".dtor_n"), used)) int32_t dtor_n = 0;
#endif
extern __attribute__((section(".bss"))) void *__bss_end;
extern __attribute__((section(".bss"))) void *__bss_start;
extern void (*__CTOR_LIST__[])(void);
extern void (*__DTOR_LIST__[])(void);
void clear_bss(void)
{
char *p = (char*)&__bss_start;
char *e = (char*)&__bss_end;
while (p < e)
*p++ = 0;
}
void do_global_ctors(void)
{
static _Bool global_ctors_done;
if (global_ctors_done)
return;
int32_t i = (int32_t)__CTOR_LIST__[0];
if (i == -1)
for (i = 0; __CTOR_LIST__[i + 1]; ++i)
;
while (i > 0)
__CTOR_LIST__[i--]();
global_ctors_done = 1;
}
void do_global_dtors(void)
{
static _Bool global_dtors_done;
if (global_dtors_done)
return;
for (void (**dtor)(void) = &__DTOR_LIST__[1]; *dtor; ++dtor)
(*dtor)();
global_dtors_done = 1;
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,34 @@
/* startup.h
* -glank
*/
#ifndef STARTUP_H
#define STARTUP_H
#ifdef __cplusplus
#define ENTRY extern "C" __attribute__((section(".text.startup")))
#define HOOK extern "C" __attribute__((section(".text.hook"), used))
extern "C"
{
#else
#define ENTRY __attribute__((section(".text.startup")))
#define HOOK __attribute__((section(".text.hook"), used))
#endif
void clear_bss(void);
void do_global_ctors(void);
void do_global_dtors(void);
#ifdef __cplusplus
}
#endif
static inline void init_gp(void)
{
__asm__ volatile("la $gp, _gp;");
}
#define CTOR __attribute__((constructor))
#define DTOR __attribute__((destructor))
#endif

View File

@ -0,0 +1,155 @@
/* vector.c
* -glank
*/
#include <stdlib.h>
#include <string.h>
#include "vector.h"
#ifdef __cplusplus
extern "C"
{
#endif
void vector_init(struct vector *vector, size_t element_size)
{
vector->element_size = element_size;
vector->size = 0;
vector->capacity = 0;
vector->begin = 0;
vector->end = 0;
vector->rbegin = 0;
vector->rend = 0;
}
void *vector_at(const struct vector *vector, size_t position)
{
if (!vector->begin || position >= vector->size)
return 0;
return (char*)vector->begin + vector->element_size * position;
}
int vector_reserve(struct vector *vector, size_t num)
{
size_t new_cap = vector->size + num;
if (new_cap <= vector->capacity)
return 1;
char *new_data = (char*)realloc(vector->begin, vector->element_size * new_cap);
if (!new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
vector->capacity = new_cap;
return 1;
}
void *vector_insert(struct vector *vector, size_t position, size_t num,
const void *data)
{
if (num == 0) {
if (vector->begin)
return vector->begin;
else
return (void*)1;
}
if (position > vector->size)
return 0;
size_t new_cap = vector->capacity;
if (new_cap == 0)
new_cap = num;
else {
if (new_cap < vector->size + num)
new_cap *= 2;
if (new_cap < vector->size + num)
new_cap = vector->size + num;
}
if (new_cap != vector->capacity) {
char *new_data = (char*)realloc(vector->begin,
vector->element_size * new_cap);
if (!new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->capacity = new_cap;
}
memmove((char*)vector->begin + vector->element_size * (position + num),
(char*)vector->begin + vector->element_size * position,
vector->element_size * (vector->size - position));
if (data)
memcpy((char*)vector->begin + vector->element_size * position, data,
vector->element_size * num);
vector->size += num;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
return (char*)vector->begin + vector->element_size * position;
}
void *vector_push_back(struct vector *vector, size_t num, const void *data)
{
return vector_insert(vector, vector->size, num, data);
}
int vector_erase(struct vector *vector, size_t position, size_t num)
{
if (!vector->begin || num > vector->size || position >= vector->size)
return 0;
if (num == vector->size) {
vector_clear(vector);
return 1;
}
memmove((char*)vector->begin + vector->element_size * position,
(char*)vector->begin + vector->element_size * (position + num),
vector->element_size * (vector->size - position - num));
vector->size -= num;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
return 1;
}
int vector_shrink_to_fit(struct vector *vector)
{
size_t new_cap = vector->size;
char *new_data = (char*)realloc(vector->begin,
vector->element_size * new_cap);
if (new_cap > 0 && !new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
vector->capacity = new_cap;
return 1;
}
void *vector_release(struct vector *vector)
{
void *data = vector->begin;
vector->size = 0;
vector->capacity = 0;
vector->begin = 0;
vector->end = 0;
vector->rbegin = 0;
vector->rend = 0;
return data;
}
void vector_clear(struct vector *vector)
{
vector->size = 0;
vector->end = vector->begin;
vector->rbegin = vector->begin;
vector->rend = vector->begin;
}
void vector_destroy(struct vector *vector)
{
if (vector->begin)
free(vector->begin);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,37 @@
/* vector.h
* -glank
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stddef.h>
struct vector
{
size_t element_size, size, capacity;
void *begin, *end;
void *rbegin, *rend;
};
#ifdef __cplusplus
extern "C"
{
#endif
void vector_init(struct vector *vector, size_t element_size);
void *vector_at(const struct vector *vector, size_t position);
int vector_reserve(struct vector *vector, size_t num);
void *vector_insert(struct vector *vector, size_t position, size_t num,
const void *data);
void *vector_push_back(struct vector *vector, size_t num, const void *data);
int vector_erase(struct vector *vector, size_t position, size_t num);
int vector_shrink_to_fit(struct vector *vector);
void *vector_release(struct vector *vector);
void vector_clear(struct vector *vector);
void vector_destroy(struct vector *vector);
#ifdef __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,392 @@
#ifndef VR4300_H
#define VR4300_H
#include <stdio.h>
#include <stdint.h>
#define VR4300_REG_CPU_FIRST VR4300_REG_R0
#define VR4300_REG_CPU_LAST VR4300_REG_RA
#define VR4300_REG_CP0_FIRST VR4300_REG_INDEX
#define VR4300_REG_CP0_LAST VR4300_REG_INVD6
#define VR4300_REG_CP1_FIRST VR4300_REG_F0
#define VR4300_REG_CP1_LAST VR4300_REG_F31
#define VR4300_REG_FCR_FIRST VR4300_REG_FCR0
#define VR4300_REG_FCR_LAST VR4300_REG_FCR31
enum vr4300_reg
{
/* cpu regs */
VR4300_REG_R0,
VR4300_REG_AT,
VR4300_REG_V0,
VR4300_REG_V1,
VR4300_REG_A0,
VR4300_REG_A1,
VR4300_REG_A2,
VR4300_REG_A3,
VR4300_REG_T0,
VR4300_REG_T1,
VR4300_REG_T2,
VR4300_REG_T3,
VR4300_REG_T4,
VR4300_REG_T5,
VR4300_REG_T6,
VR4300_REG_T7,
VR4300_REG_S0,
VR4300_REG_S1,
VR4300_REG_S2,
VR4300_REG_S3,
VR4300_REG_S4,
VR4300_REG_S5,
VR4300_REG_S6,
VR4300_REG_S7,
VR4300_REG_T8,
VR4300_REG_T9,
VR4300_REG_K0,
VR4300_REG_K1,
VR4300_REG_GP,
VR4300_REG_SP,
VR4300_REG_S8,
VR4300_REG_RA,
/* cop0 regs */
VR4300_REG_INDEX,
VR4300_REG_RANDOM,
VR4300_REG_ENTRYLO0,
VR4300_REG_ENTRYLO1,
VR4300_REG_CONTEXT,
VR4300_REG_PAGEMASK,
VR4300_REG_WIRED,
VR4300_REG_INVD0,
VR4300_REG_BADVADDR,
VR4300_REG_COUNT,
VR4300_REG_ENTRYHI,
VR4300_REG_COMPARE,
VR4300_REG_STATUS,
VR4300_REG_CAUSE,
VR4300_REG_EPC,
VR4300_REG_PRID,
VR4300_REG_CONFIG,
VR4300_REG_LLADDR,
VR4300_REG_WATCHLO,
VR4300_REG_WATCHHI,
VR4300_REG_XCONTEXT,
VR4300_REG_INVD1,
VR4300_REG_INVD2,
VR4300_REG_INVD3,
VR4300_REG_INVD4,
VR4300_REG_INVD5,
VR4300_REG_PERR,
VR4300_REG_CACHEERR,
VR4300_REG_TAGLO,
VR4300_REG_TAGHI,
VR4300_REG_ERROREPC,
VR4300_REG_INVD6,
/* cop1 regs */
VR4300_REG_F0,
VR4300_REG_F1,
VR4300_REG_F2,
VR4300_REG_F3,
VR4300_REG_F4,
VR4300_REG_F5,
VR4300_REG_F6,
VR4300_REG_F7,
VR4300_REG_F8,
VR4300_REG_F9,
VR4300_REG_F10,
VR4300_REG_F11,
VR4300_REG_F12,
VR4300_REG_F13,
VR4300_REG_F14,
VR4300_REG_F15,
VR4300_REG_F16,
VR4300_REG_F17,
VR4300_REG_F18,
VR4300_REG_F19,
VR4300_REG_F20,
VR4300_REG_F21,
VR4300_REG_F22,
VR4300_REG_F23,
VR4300_REG_F24,
VR4300_REG_F25,
VR4300_REG_F26,
VR4300_REG_F27,
VR4300_REG_F28,
VR4300_REG_F29,
VR4300_REG_F30,
VR4300_REG_F31,
/* cop1 control regs */
VR4300_REG_FCR0,
VR4300_REG_FCR1,
VR4300_REG_FCR2,
VR4300_REG_FCR3,
VR4300_REG_FCR4,
VR4300_REG_FCR5,
VR4300_REG_FCR6,
VR4300_REG_FCR7,
VR4300_REG_FCR8,
VR4300_REG_FCR9,
VR4300_REG_FCR10,
VR4300_REG_FCR11,
VR4300_REG_FCR12,
VR4300_REG_FCR13,
VR4300_REG_FCR14,
VR4300_REG_FCR15,
VR4300_REG_FCR16,
VR4300_REG_FCR17,
VR4300_REG_FCR18,
VR4300_REG_FCR19,
VR4300_REG_FCR20,
VR4300_REG_FCR21,
VR4300_REG_FCR22,
VR4300_REG_FCR23,
VR4300_REG_FCR24,
VR4300_REG_FCR25,
VR4300_REG_FCR26,
VR4300_REG_FCR27,
VR4300_REG_FCR28,
VR4300_REG_FCR29,
VR4300_REG_FCR30,
VR4300_REG_FCR31,
/* pseudo-registers */
VR4300_REG_LO,
VR4300_REG_HI,
VR4300_REG_CC,
VR4300_REG_MAX,
};
enum vr4300_op
{
VR4300_OP_ABSD,
VR4300_OP_ABSS,
VR4300_OP_ADD,
VR4300_OP_ADDD,
VR4300_OP_ADDI,
VR4300_OP_ADDIU,
VR4300_OP_ADDS,
VR4300_OP_ADDU,
VR4300_OP_AND,
VR4300_OP_ANDI,
VR4300_OP_BC1F,
VR4300_OP_BC1FL,
VR4300_OP_BC1T,
VR4300_OP_BC1TL,
VR4300_OP_BEQ,
VR4300_OP_BEQL,
VR4300_OP_BGEZ,
VR4300_OP_BGEZAL,
VR4300_OP_BGEZALL,
VR4300_OP_BGEZL,
VR4300_OP_BGTZ,
VR4300_OP_BGTZL,
VR4300_OP_BLEZ,
VR4300_OP_BLEZL,
VR4300_OP_BLTZ,
VR4300_OP_BLTZAL,
VR4300_OP_BLTZALL,
VR4300_OP_BLTZL,
VR4300_OP_BNE,
VR4300_OP_BNEL,
VR4300_OP_BREAK,
VR4300_OP_CACHE,
VR4300_OP_CEILLD,
VR4300_OP_CEILLS,
VR4300_OP_CEILWD,
VR4300_OP_CEILWS,
VR4300_OP_CEQD,
VR4300_OP_CEQS,
VR4300_OP_CFC1,
VR4300_OP_CFD,
VR4300_OP_CFS,
VR4300_OP_CLED,
VR4300_OP_CLES,
VR4300_OP_CLTD,
VR4300_OP_CLTS,
VR4300_OP_CNGED,
VR4300_OP_CNGES,
VR4300_OP_CNGLD,
VR4300_OP_CNGLED,
VR4300_OP_CNGLES,
VR4300_OP_CNGLS,
VR4300_OP_CNGTD,
VR4300_OP_CNGTS,
VR4300_OP_COLED,
VR4300_OP_COLES,
VR4300_OP_COLTD,
VR4300_OP_COLTS,
VR4300_OP_CSEQD,
VR4300_OP_CSEQS,
VR4300_OP_CSFD,
VR4300_OP_CSFS,
VR4300_OP_CTC1,
VR4300_OP_CUEQD,
VR4300_OP_CUEQS,
VR4300_OP_CULED,
VR4300_OP_CULES,
VR4300_OP_CULTD,
VR4300_OP_CULTS,
VR4300_OP_CUND,
VR4300_OP_CUNS,
VR4300_OP_CVTDL,
VR4300_OP_CVTDS,
VR4300_OP_CVTDW,
VR4300_OP_CVTLD,
VR4300_OP_CVTLS,
VR4300_OP_CVTSD,
VR4300_OP_CVTSL,
VR4300_OP_CVTSW,
VR4300_OP_CVTWD,
VR4300_OP_CVTWS,
VR4300_OP_DADD,
VR4300_OP_DADDI,
VR4300_OP_DADDIU,
VR4300_OP_DADDU,
VR4300_OP_DDIV,
VR4300_OP_DDIVU,
VR4300_OP_DIV,
VR4300_OP_DIVD,
VR4300_OP_DIVS,
VR4300_OP_DIVU,
VR4300_OP_DMFC1,
VR4300_OP_DMTC1,
VR4300_OP_DMULT,
VR4300_OP_DMULTU,
VR4300_OP_DSLL,
VR4300_OP_DSLL32,
VR4300_OP_DSLLV,
VR4300_OP_DSRA,
VR4300_OP_DSRA32,
VR4300_OP_DSRAV,
VR4300_OP_DSRL,
VR4300_OP_DSRL32,
VR4300_OP_DSRLV,
VR4300_OP_DSUB,
VR4300_OP_DSUBU,
VR4300_OP_ERET,
VR4300_OP_FLOORLD,
VR4300_OP_FLOORLS,
VR4300_OP_FLOORWD,
VR4300_OP_FLOORWS,
VR4300_OP_J,
VR4300_OP_JAL,
VR4300_OP_JALR,
VR4300_OP_JR,
VR4300_OP_LB,
VR4300_OP_LBU,
VR4300_OP_LD,
VR4300_OP_LDC1,
VR4300_OP_LDL,
VR4300_OP_LDR,
VR4300_OP_LH,
VR4300_OP_LHU,
VR4300_OP_LL,
VR4300_OP_LLD,
VR4300_OP_LUI,
VR4300_OP_LW,
VR4300_OP_LWC1,
VR4300_OP_LWL,
VR4300_OP_LWR,
VR4300_OP_LWU,
VR4300_OP_MFC0,
VR4300_OP_MFC1,
VR4300_OP_MFHI,
VR4300_OP_MFLO,
VR4300_OP_MOVD,
VR4300_OP_MOVS,
VR4300_OP_MTC0,
VR4300_OP_MTC1,
VR4300_OP_MTHI,
VR4300_OP_MTLO,
VR4300_OP_MULD,
VR4300_OP_MULS,
VR4300_OP_MULT,
VR4300_OP_MULTU,
VR4300_OP_NEGD,
VR4300_OP_NEGS,
VR4300_OP_NOR,
VR4300_OP_OR,
VR4300_OP_ORI,
VR4300_OP_ROUNDLD,
VR4300_OP_ROUNDLS,
VR4300_OP_ROUNDWD,
VR4300_OP_ROUNDWS,
VR4300_OP_SB,
VR4300_OP_SC,
VR4300_OP_SCD,
VR4300_OP_SD,
VR4300_OP_SDC1,
VR4300_OP_SDL,
VR4300_OP_SDR,
VR4300_OP_SH,
VR4300_OP_SLL,
VR4300_OP_SLLV,
VR4300_OP_SLT,
VR4300_OP_SLTI,
VR4300_OP_SLTIU,
VR4300_OP_SLTU,
VR4300_OP_SQRTD,
VR4300_OP_SQRTS,
VR4300_OP_SRA,
VR4300_OP_SRAV,
VR4300_OP_SRL,
VR4300_OP_SRLV,
VR4300_OP_SUB,
VR4300_OP_SUBD,
VR4300_OP_SUBS,
VR4300_OP_SUBU,
VR4300_OP_SW,
VR4300_OP_SWC1,
VR4300_OP_SWL,
VR4300_OP_SWR,
VR4300_OP_SYNC,
VR4300_OP_SYSCALL,
VR4300_OP_TEQ,
VR4300_OP_TEQI,
VR4300_OP_TGE,
VR4300_OP_TGEI,
VR4300_OP_TGEIU,
VR4300_OP_TGEU,
VR4300_OP_TLBP,
VR4300_OP_TLBR,
VR4300_OP_TLBWI,
VR4300_OP_TLBWR,
VR4300_OP_TLT,
VR4300_OP_TLTI,
VR4300_OP_TLTIU,
VR4300_OP_TLTU,
VR4300_OP_TNE,
VR4300_OP_TNEI,
VR4300_OP_TRUNCLD,
VR4300_OP_TRUNCLS,
VR4300_OP_TRUNCWD,
VR4300_OP_TRUNCWS,
VR4300_OP_XOR,
VR4300_OP_XORI,
};
enum vr4300_opnd_type
{
VR4300_OPND_NULL,
VR4300_OPND_CPU,
VR4300_OPND_CP0,
VR4300_OPND_CP1,
VR4300_OPND_FCR,
VR4300_OPND_JUMP,
VR4300_OPND_BRANCH,
VR4300_OPND_OFFSET,
VR4300_OPND_IMMEDIATE,
VR4300_OPND_CACHE,
};
struct vr4300_insn
{
enum vr4300_op opcode;
enum vr4300_opnd_type opnd_type[3];
int32_t opnd_value[3];
};
_Bool vr4300_decode_insn(uint32_t code, struct vr4300_insn *insn);
void vr4300_print_insn(struct vr4300_insn *insn, uint32_t addr, FILE *f);
extern const char *vr4300_reg_mnem[];
extern const char *vr4300_op_mnem[];
#endif

406
tools/gfxdis/main.c Normal file
View File

@ -0,0 +1,406 @@
#include <swap.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <vector/vector.h>
#include "gfxdis.h"
#include <n64.h>
#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
#endif
#if defined(F3D_GBI)
# if defined(F3D_BETA)
static const char *prog_name = "gfxdis.f3db";
# else
static const char *prog_name = "gfxdis.f3d";
# endif
#elif defined(F3DEX_GBI)
# if defined(F3D_BETA)
static const char *prog_name = "gfxdis.f3dexb";
# else
static const char *prog_name = "gfxdis.f3dex";
# endif
#elif defined(F3DEX_GBI_2)
static const char *prog_name = "gfxdis.f3dex2";
#endif
static int usage(void)
{
fprintf(stderr,
"gfxdis-0.6: display list disassembler\n"
"written by: glank\n"
"build date: " __TIME__ ", " __DATE__ "\n"
"usage:\n"
" %s [-x] [-i] [-dc] [-p] [-r] [-g <arg>] [-n <max>] [-a <offset>] "
"{ -f <file> | -d <data> }\n"
"options:\n"
" -x do not use fixed-point conversion macros\n"
" -i do not stop at unrecognized or malformed "
"instructions\n"
" -dc use decimal numbers for color components\n"
" -p print offsets\n"
" -r print raw data\n"
" -g <arg> generate dynamic macros with <arg> as the first "
"argument\n"
" -n <max> disassemble at most <max> instructions\n"
" -a <offset> start disassembling at <offset>\n"
" -f <file> disassemble <file>, '-' for stdin\n"
" -d <data> disassemble hexadecimal byte codes from the "
"command line\n",
prog_name);
return -1;
}
static int parse_number(const char *str, int base, int *num)
{
int sign = 1;
if (base < 0) {
if (str[0] == '+')
++str;
else if (str[0] == '-') {
sign = -1;
++str;
}
base = -base;
}
if (base <= 1) {
if (strncmp(str, "0x", 2) == 0 || strncmp(str, "0X", 2) == 0) {
base = 16;
str += 2;
}
else if (strncmp(str, "0b", 2) == 0 || strncmp(str, "0B", 2) == 0) {
base = 2;
str += 2;
}
else if (str[0] == '0' && str[1] != 0) {
base = 8;
++str;
}
else
base = 10;
}
int v = 0;
do {
int c = *str++;
if (c >= '0' && c <= '9')
c = c - '0';
else if (c >= 'a' && c <= 'f')
c = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
c = c - 'A' + 10;
else
return -1;
if (c >= base)
return -1;
v = v * base + c;
} while (*str);
v = v * sign;
*num = v;
return 0;
}
static int gfx_v_num(struct vector *gfx_v)
{
return gfx_v->size * gfx_v->element_size / sizeof(Gfx);
}
static _Bool gfx_v_ate(struct vector *gfx_v, int max)
{
return max >= 0 && gfx_v_num(gfx_v) >= max;
}
static int from_file(struct vector *gfx_v, const char *filename, int max,
int offset)
{
int result = 0;
#ifdef _WIN32
int mode = _O_TEXT;
#endif
FILE *f = NULL;
if (strcmp(filename, "-") == 0) {
filename = "stdin";
#ifdef _WIN32
mode = _setmode(_fileno(stdin), _O_BINARY);
if (mode == -1) {
fprintf(stderr, "%s: %s: %s\n", prog_name, strerror(errno), filename);
goto err;
}
#endif
f = stdin;
}
else {
f = fopen(filename, "rb");
if (!f) {
fprintf(stderr, "%s: %s: %s\n", prog_name, strerror(errno), filename);
goto err;
}
}
if (offset != 0 && fseek(f, offset, SEEK_SET)) {
for (int i = 0; i < offset; ++i) {
if (fgetc(f) == EOF) {
if (ferror(f)) {
fprintf(stderr, "%s: %s: %s\n", prog_name, strerror(errno),
filename);
goto err;
}
else
break;
}
}
}
while (!gfx_v_ate(gfx_v, max)) {
Gfx gfx;
if (fread(&gfx, sizeof(gfx), 1, f) != 1) {
if (ferror(f)) {
fprintf(stderr, "%s: %s: %s\n", prog_name, strerror(errno), filename);
goto err;
}
else
break;
}
int n = sizeof(gfx) / gfx_v->element_size;
if (!vector_push_back(gfx_v, n, &gfx)) {
fprintf(stderr, "%s: out of memory\n", prog_name);
goto err;
}
}
goto exit;
err:
result = -1;
exit:
if (f) {
if (f == stdin) {
#ifdef _WIN32
_setmode(_fileno(f), mode);
#endif
}
else
fclose(f);
}
return result;
}
static int from_line(struct vector *gfx_v, int argc, char *argv[], int argp,
int max, int offset)
{
int result = 0;
int pos = 0;
while (argp < argc) {
char *p = argv[argp++];
while (*p) {
unsigned char byte = 0;
for (int i = 0; i < 2 && *p; ++i) {
int c = *p++;
if (c >= '0' && c <= '9')
c = c - '0';
else if (c >= 'a' && c <= 'f')
c = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
c = c - 'A' + 10;
else {
fprintf(stderr, "%s: invalid input data: %c\n", prog_name, c);
goto err;
}
byte = byte * 16 + c;
}
if (pos++ >= offset && !gfx_v_ate(gfx_v, max)) {
int n = gfx_v->element_size / sizeof(byte);
if (!vector_push_back(gfx_v, n, &byte)) {
fprintf(stderr, "%s: out of memory\n", prog_name);
goto err;
}
}
}
}
goto exit;
err:
result = -1;
exit:
return result;
}
int main(int argc, char *argv[])
{
int result = 0;
struct vector gfx_v;
vector_init(&gfx_v, sizeof(unsigned char));
if (argc == 1) {
result = usage();
goto exit;
}
int argp = 1;
const char *opt_x = NULL;
const char *opt_i = NULL;
const char *opt_dc = NULL;
const char *opt_p = NULL;
const char *opt_r = NULL;
const char *opt_g = NULL;
const char *opt_n = NULL;
const char *opt_a = NULL;
const char *opt_f = NULL;
const char *opt_d = NULL;
while (argp < argc) {
_Bool param = 0;
const char **p_opt;
if (strcmp(argv[argp], "-x") == 0)
p_opt = &opt_x;
else if (strcmp(argv[argp], "-i") == 0)
p_opt = &opt_i;
else if (strcmp(argv[argp], "-dc") == 0)
p_opt = &opt_dc;
else if (strcmp(argv[argp], "-p") == 0)
p_opt = &opt_p;
else if (strcmp(argv[argp], "-r") == 0)
p_opt = &opt_r;
else if (strcmp(argv[argp], "-g") == 0) {
param = 1;
p_opt = &opt_g;
}
else if (strcmp(argv[argp], "-n") == 0) {
param = 1;
p_opt = &opt_n;
}
else if (strcmp(argv[argp], "-a") == 0) {
param = 1;
p_opt = &opt_a;
}
else if (strcmp(argv[argp], "-f") == 0) {
param = 1;
p_opt = &opt_f;
}
else if (strcmp(argv[argp], "-d") == 0)
p_opt = &opt_d;
else
break;
if (param) {
++argp;
if (argp >= argc) {
fprintf(stderr, "%s: option requires a parameter: %s\n", prog_name,
argv[argp - 1]);
goto err;
}
}
*p_opt = argv[argp++];
}
if (opt_f && argp != argc) {
fprintf(stderr, "%s: unrecognized option: %s\n", prog_name, argv[argp]);
goto err;
}
if ((opt_d != NULL) == (opt_f != NULL)) {
fprintf(stderr, "%s: specify either -f or -d\n", prog_name);
goto err;
}
int max = -1;
if (opt_n && parse_number(opt_n, 1, &max)) {
fprintf(stderr, "%s: bad number given for -n: %s\n", prog_name, opt_n);
goto err;
}
int offset = 0;
if (opt_a && parse_number(opt_a, 1, &offset)) {
fprintf(stderr, "%s: bad number given for -a: %s\n", prog_name, opt_a);
goto err;
}
if (opt_f)
result = from_file(&gfx_v, opt_f, max, offset);
else if (opt_d)
result = from_line(&gfx_v, argc, argv, argp, max, offset);
if (result)
goto exit;
gfxdis_cfg.dis_invd = (opt_i != NULL);
gfxdis_cfg.use_q = (opt_x == NULL);
gfxdis_cfg.dec_color = (opt_dc != NULL);
{
Gfx *raw = gfx_v.begin;
int raw_p = 0;
struct vector insn_vect;
result = gfx_dis(&insn_vect, raw, gfx_v_num(&gfx_v));
if (opt_g == NULL)
printf("{\n");
for (int i = 0; i < insn_vect.size; ++i) {
char s[1024];
struct gfx_insn *insn = vector_at(&insn_vect, i);
if (opt_g == NULL)
gfx_insn_str(insn, s);
else
gfx_insn_str_dyn(insn, opt_g, s);
if (opt_p || opt_r) {
int n = opt_r ? insn->n_gfx : 1;
for (int j = 0; j < n; ++j) {
if (opt_g == NULL)
printf(" /*");
else
printf("/*");
if (opt_p) {
uint32_t addr = offset + (raw_p + j) * sizeof(Gfx);
printf(" %08" PRIX32 ":", addr);
}
if (opt_r) {
uint32_t hi = btoh32(raw[raw_p + j].hi);
uint32_t lo = btoh32(raw[raw_p + j].lo);
printf(" %08" PRIX32 " %08" PRIX32, hi, lo);
}
if (j == 0) {
if (opt_g == NULL)
printf(" */ %s,\n", s);
else
printf(" */ %s;\n", s);
}
else
printf(" */\n");
}
}
else {
if (opt_g == NULL)
printf(" %s,\n", s);
else
printf("%s;\n", s);
}
raw_p += insn->n_gfx;
}
vector_destroy(&insn_vect);
if (opt_g == NULL)
printf("}\n");
if (result == -1)
fprintf(stderr, "%s: out of memory\n", prog_name);
}
goto exit;
err:
result = -1;
exit:
vector_destroy(&gfx_v);
return result;
}
#include <vector/vector.c>

82
tools/gfxdis/swap.h Normal file
View File

@ -0,0 +1,82 @@
#ifndef SWAP_H
#define SWAP_H
// #include <config.h>
#include <stdint.h>
static inline uint32_t htob32(uint32_t v)
{
#ifndef WORDS_BIGENDIAN
return ((v & 0xFF000000) >> 24) | ((v & 0x00FF0000) >> 8) |
((v & 0x0000FF00) << 8) | ((v & 0x000000FF) << 24);
#else
return v;
#endif
}
static inline uint32_t btoh32(uint32_t v)
{
#ifndef WORDS_BIGENDIAN
return ((v & 0xFF000000) >> 24) | ((v & 0x00FF0000) >> 8) |
((v & 0x0000FF00) << 8) | ((v & 0x000000FF) << 24);
#else
return v;
#endif
}
static inline uint16_t htob16(uint16_t v)
{
#ifndef WORDS_BIGENDIAN
return ((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8);
#else
return v;
#endif
}
static inline uint16_t btoh16(uint16_t v)
{
#ifndef WORDS_BIGENDIAN
return ((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8);
#else
return v;
#endif
}
static inline uint32_t htol32(uint32_t v)
{
#ifdef WORDS_BIGENDIAN
return ((v & 0xFF000000) >> 24) | ((v & 0x00FF0000) >> 8) |
((v & 0x0000FF00) << 8) | ((v & 0x000000FF) << 24);
#else
return v;
#endif
}
static inline uint32_t ltoh32(uint32_t v)
{
#ifdef WORDS_BIGENDIAN
return ((v & 0xFF000000) >> 24) | ((v & 0x00FF0000) >> 8) |
((v & 0x0000FF00) << 8) | ((v & 0x000000FF) << 24);
#else
return v;
#endif
}
static inline uint16_t htol16(uint16_t v)
{
#ifdef WORDS_BIGENDIAN
return ((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8);
#else
return v;
#endif
}
static inline uint16_t ltoh16(uint16_t v)
{
#ifdef WORDS_BIGENDIAN
return ((v & 0xFF00) >> 8) | ((v & 0x00FF) << 8);
#else
return v;
#endif
}
#endif

View File

@ -0,0 +1,155 @@
/* vector.c
* -glank
*/
#include <stdlib.h>
#include <string.h>
#include "vector.h"
#ifdef __cplusplus
extern "C"
{
#endif
void vector_init(struct vector *vector, size_t element_size)
{
vector->element_size = element_size;
vector->size = 0;
vector->capacity = 0;
vector->begin = 0;
vector->end = 0;
vector->rbegin = 0;
vector->rend = 0;
}
void *vector_at(const struct vector *vector, size_t position)
{
if (!vector->begin || position >= vector->size)
return 0;
return (char*)vector->begin + vector->element_size * position;
}
int vector_reserve(struct vector *vector, size_t num)
{
size_t new_cap = vector->size + num;
if (new_cap <= vector->capacity)
return 1;
char *new_data = (char*)realloc(vector->begin, vector->element_size * new_cap);
if (!new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
vector->capacity = new_cap;
return 1;
}
void *vector_insert(struct vector *vector, size_t position, size_t num,
const void *data)
{
if (num == 0) {
if (vector->begin)
return vector->begin;
else
return (void*)1;
}
if (position > vector->size)
return 0;
size_t new_cap = vector->capacity;
if (new_cap == 0)
new_cap = num;
else {
if (new_cap < vector->size + num)
new_cap *= 2;
if (new_cap < vector->size + num)
new_cap = vector->size + num;
}
if (new_cap != vector->capacity) {
char *new_data = (char*)realloc(vector->begin,
vector->element_size * new_cap);
if (!new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->capacity = new_cap;
}
memmove((char*)vector->begin + vector->element_size * (position + num),
(char*)vector->begin + vector->element_size * position,
vector->element_size * (vector->size - position));
if (data)
memcpy((char*)vector->begin + vector->element_size * position, data,
vector->element_size * num);
vector->size += num;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
return (char*)vector->begin + vector->element_size * position;
}
void *vector_push_back(struct vector *vector, size_t num, const void *data)
{
return vector_insert(vector, vector->size, num, data);
}
int vector_erase(struct vector *vector, size_t position, size_t num)
{
if (!vector->begin || num > vector->size || position >= vector->size)
return 0;
if (num == vector->size) {
vector_clear(vector);
return 1;
}
memmove((char*)vector->begin + vector->element_size * position,
(char*)vector->begin + vector->element_size * (position + num),
vector->element_size * (vector->size - position - num));
vector->size -= num;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
return 1;
}
int vector_shrink_to_fit(struct vector *vector)
{
size_t new_cap = vector->size;
char *new_data = (char*)realloc(vector->begin,
vector->element_size * new_cap);
if (new_cap > 0 && !new_data)
return 0;
vector->begin = new_data;
vector->rend = new_data - vector->element_size;
vector->end = (char*)vector->begin + vector->element_size * vector->size;
vector->rbegin = (char*)vector->end - vector->element_size;
vector->capacity = new_cap;
return 1;
}
void *vector_release(struct vector *vector)
{
void *data = vector->begin;
vector->size = 0;
vector->capacity = 0;
vector->begin = 0;
vector->end = 0;
vector->rbegin = 0;
vector->rend = 0;
return data;
}
void vector_clear(struct vector *vector)
{
vector->size = 0;
vector->end = vector->begin;
vector->rbegin = vector->begin;
vector->rend = vector->begin;
}
void vector_destroy(struct vector *vector)
{
if (vector->begin)
free(vector->begin);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,37 @@
/* vector.h
* -glank
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stddef.h>
struct vector
{
size_t element_size, size, capacity;
void *begin, *end;
void *rbegin, *rend;
};
#ifdef __cplusplus
extern "C"
{
#endif
void vector_init(struct vector *vector, size_t element_size);
void *vector_at(const struct vector *vector, size_t position);
int vector_reserve(struct vector *vector, size_t num);
void *vector_insert(struct vector *vector, size_t position, size_t num,
const void *data);
void *vector_push_back(struct vector *vector, size_t num, const void *data);
int vector_erase(struct vector *vector, size_t position, size_t num);
int vector_shrink_to_fit(struct vector *vector);
void *vector_release(struct vector *vector);
void vector_clear(struct vector *vector);
void vector_destroy(struct vector *vector);
#ifdef __cplusplus
}
#endif
#endif

BIN
tools/gfxdis_f3dex2 Executable file

Binary file not shown.

840
tools/scut/GeoFromBin.py Normal file
View File

@ -0,0 +1,840 @@
import struct
import math
from KirbyCSdatatypes import *
globBank = 0
globIndex = 0
symbols = {}
#-------------------------------------------------------------------------------
#Geo Block Functions
def SegPtrList(start,rom):
i=0
arr = []
while(True):
ar = struct.unpack(">L",rom[start+i:start+i+4])
arr.append(ar)
if ar[0] == 0:
break
i+=4
return arr
def GetGeoHeader(rom,start):
header = []
for s in Geo_Header.keys():
v = struct.unpack(">L",rom[start+s:start+s+4])
header.append([Geo_Header[s],v])
return header
def GetGeoVertRefs(rom,start,GH):
start = start+(GH[4][1][0]&0xFFFFFF)
symbols[start | 0x04000000] = "bank_%d_index_%d_vert_load_refs_%08X" % (globBank, globIndex, start | 0x04000000)
refs = SegPtrList(start,rom)
return refs
def GetGeoImgRefs(rom,start,GH):
start = start+(GH[3][1][0]&0xFFFFFF)
symbols[start | 0x04000000] = "bank_%d_index_%d_tex_img_refs_%08X" % (globBank, globIndex, start | 0x04000000)
refs = SegPtrList(start,rom)
return refs
def GetLayout(rom,start,GH,end):
start = start+(GH[0][1][0]&0xFFFFFF)
layout = []
end = end+(GH[0][1][0]&0xFFFFFF)
len = end-start
i=0
env = []
Envfx = False
symbols[start | 0x04000000] = "bank_%d_index_%d_layout_%08X" % (globBank, globIndex, start | 0x04000000)
while(True):
v = []
for s in Layout.keys():
q = struct.unpack(Layout.get(s)[0],rom[start+s+i:i+start+s+Layout.get(s)[2]])
if s == 4:
q2 = struct.unpack(Layout.get(s)[0],rom[start+s+i:i+start+s+Layout.get(s)[2]])[0]
if q2 != 0:
symbols[q2] = "bank_%d_index_%d_entry_point_%08X" % (globBank, globIndex, q2)
v.append([Layout.get(s)[1],q])
if Envfx:
env.append(v)
else:
layout.append(v)
if v[1][1][0] == 0x12 and (v[2][1][0]&0x80000000==0x80000000):
Envfx = True
elif v[1][1][0] == 0x12:
break
elif (Envfx == True and (v[0][1][0]&0x8000)==0x8000) or i>(len-48):
break
i+=44
return [layout,env]
def GetEntryPoints(rom,start,Layout,DLmembers):
entry = []
starts = []
for L in Layout:
#Only get ones in bank 4.
if L[2][1][0]&0xFF000000 !=0x04000000:
continue
Estart = start+(L[2][1][0]&0xFFFFFF)
starts.append(L[2][1][0])
i=0
E = []
while(True):
DLm = DLmembers+1
v = struct.unpack(">%dL"%DLm,rom[Estart+i:Estart+i+DLm*4])
E.append(v)
if v[0] == 4:
break
i+=DLm*4
entry.append(E)
return [entry,starts]
def GetEntryPoints14(rom,start,ptr):
entry = []
starts = []
Estart = start+(ptr&0xFFFFFF)
starts.append(ptr)
i=0
E = []
while(True):
v = struct.unpack(">2L",rom[Estart+i:Estart+i+8])
E.append(v)
if v[0] == 4:
break
i+=8
entry.append(E)
return [entry,starts]
def GetEntryPoints1B(rom,start,Layout):
entry = []
starts = []
for L in Layout:
#Only get ones in bank 4.
if L[2][1][0]&0xFF000000 !=0x04000000:
continue
Estart = start+(L[2][1][0]&0xFFFFFF)
starts.append(L[2][1][0])
i=0
E = []
v = struct.unpack(">L",rom[Estart+i:Estart+i+4])[0]
q = struct.unpack(">L",rom[Estart+i+4:Estart+i+8])[0]
#This is a bit idiotic but I do this so I don't have to
#create if statements for each specific render mode.
E.append([0,v])
E.append([0,q])
entry.append(E)
entry.append([[4,0]])
return [entry,starts]
def GetGroups(rom,start,Layout):
group = []
starts = []
for L in Layout:
if L[2][1][0]&0xFF000000 !=0x04000000:
continue
group.append([0,(L[2][1][0])])
starts.append(L[2][1][0])
group.append([4,0])
return [[group],starts]
def GetMicrocode(rom,start,EP,end,DLmembers):
f3d = []
starts = []
jumps = []
jumped = 0
for p in EP:
for s in p:
if s[0] == 4:
continue
#an entry point can have any number of DL members in it theoretically
for j in range(1,DLmembers+1,1):
ex2 = []
#I dynamically create new entry points to deal with jumps.
#This should deal with that error
if j>=len(s):
continue
if s[j]==0:
continue
Fstart = start + (s[j]&0xFFFFFF)
starts.append(s[j])
if Fstart>end:
break
endDL = 0xDF00000000000000
JumpEnd = 0xDE01000000000000
JUMP = 0xDE00000000000000
BZ = 0xE100000000000000
i=0
while(True):
f = struct.unpack(">Q",rom[Fstart+i:Fstart+i+8])
if f[0] >> 56 == 0x01:
symbols[f[0] & 0xFFFFFFFF] = "bank_%d_index_%d_vtx_%08X" % (globBank, globIndex, f[0] & 0xFFFFFFFF)
ex2.append(f)
if ((f[0] & 0xFF00000000000000)==JUMP) or ((f[0] & 0xFFFFFFFF00000000)==BZ):
if f[0]&0xFF000000==0x04000000:
newEP = (0x1,f[0]&0xFFFFFFFF)
if newEP not in jumps:
p.append(newEP)
jumps.append(newEP)
jumped = newEP
if f[0] == endDL or f[0]&0xFFFFFFFF00000000 == JumpEnd:
break
if Fstart+i>end:
break
i+=8
f3d.extend([ex2])
for p in EP:
for a in jumps:
if a in p:
p.remove(a)
return [f3d,starts]
#switched to dumping verts raw and have gotten better results. Easier to parse too.
def GetGeoVerticesOld(rom,start,VR):
Verts = []
starts = []
Vbufs = []
ranges = []
for ref in VR:
if ref[0] == 0:
break
Vstart = start + (ref[0]&0xFFFFFF)
G_VTX = struct.unpack(">2L",rom[Vstart:Vstart+8])
num = (G_VTX[0]&0x000FF000)>>12
VLoad = (G_VTX[1]&0x00FFFFFF)+start
#remove duplicate verts and clip buffers
if G_VTX[1] in starts:
#low hanging fruit
continue
skip=0
for v in Vbufs:
#skips
if VLoad<(v[0]+v[1]*16) and VLoad>v[0]:
skip=1
break
if not skip:
Vbufs.append([VLoad,num])
starts.append(G_VTX[1])
#Now I must sort the lists
starts.sort()
Vbufs.sort(key=lambda x: x[0])
for ref in Vbufs:
VB = []
for i in range(ref[1]):
Vert = []
for q in Geo_Vert.keys():
Vert.append([Geo_Vert.get(q)[1],struct.unpack(Geo_Vert.get(q)[0],rom[i*16+ref[0]+q:i*16+ref[0]+q+Geo_Vert.get(q)[2]])])
VB.append(Vert)
Verts.append(VB)
return [Verts,starts]
def GetGeoVertices(rom,start,starts):
startGV =start + 0x20
if not starts:
return None
q = starts.copy()
q.sort()
end = q[0]
GV = []
for i in range(startGV,(end&0xFFFFFF)+start,16):
V = []
for q in Geo_Vert.keys():
V.append([Geo_Vert.get(q)[1],struct.unpack(Geo_Vert.get(q)[0],rom[i+q:i+q+Geo_Vert.get(q)[2]])])
GV.append(V)
return GV
def GetTextureScrolls(rom,start,GH):
TS = GH[1][1][0]
ts = []
Unk = GH[6][1][0]
l = Unk-TS
if TS and Unk:
Hstart = start+(TS&0x00FFFFFF)
symbols[Hstart | 0x04000000] = "bank_%d_index_%d_texscroll_header_%08X" % (globBank, globIndex, Hstart | 0x04000000)
h = []
ptrs = []
i=0
k=0
while(True):
word = struct.unpack(">L",rom[Hstart+i*4:i*4+4+Hstart])
if word[0]==0x99999999:
h.append(word)
k=i*4+4
break
elif word[0]:
symbols[word[0]] = "bank_%d_index_%d_texture_scroll_subheader_%08X" % (globBank, globIndex, word[0])
ptrs.append(word)
h.append(word)
else:
h.append(word)
i+=1
Dptrs = []
Header2 = []
for p in ptrs:
Pstart = start+(p[0]&0x00FFFFFF)
i=0
L = []
while(True):
word = struct.unpack(">L",rom[Pstart+i*4:i*4+4+Pstart])
if word[0]==0x99999999:
L.append(word)
break
elif word[0]:
symbols[word[0]] = "bank_%d_index_%d_texture_scroll_%08X" % (globBank, globIndex, word[0])
Dptrs.append(word)
L.append(word)
else:
L.append(word)
i+=1
Header2.append([L,p[0]])
#Now Dptrs is a list of pointers to my 0x78 byte structs.
#Header 2 is a list of all the ptr headers that was inside the main header.
#The texture scroll order should be TSheader,padding,structs,Secondary Headers.
#I will check for padding, but seeing the address of the first thing inside Dptrs, and seeing if
#it matches with the end of the main header, aka variable k.
StructStart = start+(Dptrs[0][0]&0x00FFFFFF)
PadStart = Hstart+k
pad = []
padLen = StructStart-PadStart
for p in range(padLen)[::4]:
pad.append(struct.unpack(">L",rom[PadStart+p:PadStart+p+4]))
tHs = [*h]
tPad = [*pad]
#Now dumping TS structs.
prev = StructStart
TUnk = []
for D in Dptrs:
Dstart = start+(D[0]&0x00FFFFFF)
if (Dstart-prev)>0x78:
R = (Dstart-prev-0x78)//4
TUnk.append(struct.unpack(">%dL"%R,rom[prev+0x78:prev+0x78+R*4]))
else:
TUnk.append(())
prev = Dstart
scroll = []
for o,t in TextureScrollStruct.items():
scroll.append(struct.unpack(t[0],rom[Dstart+o:Dstart+o+t[2]]))
ts.append([scroll,D[0]])
return [tHs,ts,Header2,tPad,TUnk]
else:
return [None,None,None,None,None]
def GetUnknown2(rom,start,GH):
Unk = GH[6][1][0]
num = GH[5][1][0]
u = []
if Unk:
start = start+(Unk&0x00FFFFFF)
symbols[start | 0x04000000] = "bank_%d_index_%d_anims_%08X" % (globBank, globIndex, start | 0x04000000)
for b in range(num):
u.append(struct.unpack(">L",rom[start+4*b:start+4*b+4]))
return u
else:
return []
dlists = []
def GetGeoBlockData(rom,start,end):
GH = GetGeoHeader(rom,start)
[THS,TS,H2,tPad,tUnk] = GetTextureScrolls(rom,start,GH)
VR = GetGeoVertRefs(rom,start,GH)
IR = GetGeoImgRefs(rom,start,GH)
#Depending on whether the layout is 0x17 or 0x18 the seg ptrs are different
#In 5-4-7 and 5-4-8 a render mode of 0x1C is used which I have no idea about.
if GH[2][1][0] == 0x17:
[L,env] = GetLayout(rom,start,GH,end)
[SP,SPstart] = GetGroups(rom,start,L)
[f3d,starts] = GetMicrocode(rom,start,SP,end,1) #I get the end ptr here for while loop safety
SP = []
elif GH[2][1][0] == 0x18:
[L,env] = GetLayout(rom,start,GH,end)
[SP,SPstart] = GetEntryPoints(rom,start,L,1)
[f3d,starts] = GetMicrocode(rom,start,SP,end,1) #I get the end ptr here for while loop safety
elif GH[2][1][0] == 0x1C:
[L,env] = GetLayout(rom,start,GH,end)
#basically the same as 0x18, but entry points have two DL members.
[SP,SPstart] = GetEntryPoints(rom,start,L,2)
[f3d,starts] = GetMicrocode(rom,start,SP,end,2) #I get the end ptr here for while loop safety
elif GH[2][1][0] == 0x14:
L = []
env = []
[SP,SPstart] = GetEntryPoints14(rom,start,GH[0][1][0])
[f3d,starts] = GetMicrocode(rom,start,SP,end,1) #I get the end ptr here for while loop safety
elif GH[2][1][0] == 0x13:
L = []
env = []
SP = [[[0,GH[0][1][0]],[4,0]]]
SPstart = [GH[0][1][0]]
[f3d,starts] = GetMicrocode(rom,start,SP,end,1) #I get the end ptr here for while loop safety
elif GH[2][1][0] == 0x1B:
[L,env] = GetLayout(rom,start,GH,end)
[SP,SPstart] = GetEntryPoints1B(rom,start,L)
[f3d,starts] = GetMicrocode(rom,start,SP,end,1) #I get the end ptr here for while loop safety
else:
f3d = []
SP = []
starts = []
SPstart = []
L = []
env = []
for i in starts:
symbols[i] = "bank_%d_index_%d_dl_%08X" % (globBank, globIndex, i)
GV = GetGeoVertices(rom,start,starts)
#old cringe method which I'm now retiring. Caused me to parse entire DL
#too many times.
images = []
unk = GetUnknown2(rom,start,GH)
VBs = [] #old code
return [GH,GV,f3d,IR,VR,SP,L,TS,images,starts,SPstart,VBs,unk,env,THS,H2,tPad,tUnk]
def WriteGeoBlock(file,GeoBlock,rom):
RM = GeoBlock[0][2][1][0]
file.write(
"#include <ultra64.h>\n"
"#include \"geo_block_header.h\"\n"
"#include \"stages.h\"\n\n"
)
for ket in symbols:
if "subheader" in symbols[ket]:
file.write("extern struct TextureScroll *%s[];\n" % symbols[ket])
if "_dl_" in symbols[ket]:
file.write("extern Gfx %s[];\n" % symbols[ket])
file.write("\n")
WriteGeoHeader(file,GeoBlock[0])
WriteGeoVerts(file,GeoBlock[1],GeoBlock[11])
WriteGeoF3d2(file,GeoBlock[2],GeoBlock[9])
WriteImgRefs(file,GeoBlock[3])
WriteVertRefs(file,GeoBlock[4])
#deal with entry points to display lists differently
#depending on render mode.
if RM==0x18 or RM==0x17 or RM==0x14:
WriteEntryPoints(file,GeoBlock[5],GeoBlock[10])
elif RM==0x1B:
WriteDLPairs(file,GeoBlock[5],GeoBlock[10])
elif RM==0x1C:
WriteEntryPoints1C(file,GeoBlock[5],GeoBlock[10])
if RM!=0x13:
WriteLayout(file,GeoBlock[6],GeoBlock[13],GeoBlock[0])
else:
file.write("\n// No entry points in render mode 0x13\n")
file.write("\n// No layout in render mode 0x13\n")
WriteTS(file,GeoBlock[0],GeoBlock[7],GeoBlock[14],GeoBlock[15],GeoBlock[16],GeoBlock[17])
WriteUnk2(file,GeoBlock[0],GeoBlock[12])
file.close()
del file
def WriteGeoHeader(file,GH):
global globBank, globIndex
buf = ""
buf += "\nstruct GeoBlockHeader bank_%d_index_%d_geo_block_header = {\n" % (globBank, globIndex)
for h in zip(GH,Geo_Header.keys()):
if h[1] == 0x1c:
buf += " /*0x%02X*/ 0x%X,\n};\n\n"%(h[1],h[0][1][0])
elif h[1] == 0:
if h[0][1][0] == 0:
buf += " /*0x%02X*/ NULL,\n"%(h[1],h[0][1][0])
else:
file.write("extern struct Layout %s[];\n" % symbols[h[0][1][0]])
# buf += " /*0x%02X*/ (struct Layout *) 0x%08X,\n"%(h[1],h[0][1][0])
buf += " /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]])
elif h[1] == 4:
if h[0][1][0] == 0:
buf += " /*0x%02X*/ NULL,\n"%(h[1])
else:
file.write("extern struct TextureScroll **%s[];\n" % symbols[h[0][1][0]])
# buf += " /*0x%02X*/ (struct TextureScroll **) 0x%08X,\n"%(h[1],h[0][1][0])
buf += " /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]])
elif h[1] == 0xC:
if h[0][1][0] == 0:
buf += " /*0x%02X*/ NULL,\n"%(h[1])
else:
file.write("extern Gfx *%s[];\n" % symbols[h[0][1][0]])
buf += " /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]])
elif h[1] == 16:
if h[0][1][0] == 0:
buf += " /*0x%02X*/ NULL,\n"%(h[1])
else:
file.write("extern Gfx *%s[];\n" % symbols[h[0][1][0]])
buf += " /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]])
elif h[1] == 0x18:
if h[0][1][0] == 0:
buf += " /*0x%02X*/ NULL,\n"%(h[1])
else:
file.write("extern u32 %s[];\n" % symbols[h[0][1][0]])
buf += " /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]])
else:
buf += " /*0x%02X*/ 0x%X,\n"%(h[1],h[0][1][0])
file.write(buf)
def tc(a):
return struct.unpack('>h', bytes.fromhex(str(a)))[0]
import binascii
def WriteGeoVerts(file,GV,VBs):
global globBank, globIndex
if not GV:
return
# file.write("%s\n"%Geo_Vertices_Comment)
segAddr = 0x04000020
hits = 0
for j,v in enumerate(GV):
if segAddr in symbols:
if hits == 0:
file.write("Vtx bank_%d_index_%d_vtx_04000020[] = {\n" % (globBank, globIndex))
else:
file.write("};\n\nVtx bank_%d_index_%d_vtx_%08X[] = {\n" % (globBank, globIndex, segAddr))
hits+=1
file.write(" {{{"+"{:>6}, {:>7}, {:>7}".format(
v[0][1][0],
v[0][1][1],
v[0][1][2],
) + "}, " + "{}, ".format(v[1][1][0])+"{"+"{:>6}, {:>7}".format(
v[2][1][0],
v[2][1][1],
) + "}, {"+"0x{:02x}, 0x{:02x}, 0x{:02x}, 0x{:02x}".format(
int(v[3][1][0]),
int(v[3][1][1]),
int(v[3][1][2]),
int(v[3][1][3]),
)+"}}},\n"
)
segAddr += 16
file.write("};\n\n")
import subprocess
def WriteGeoF3d(file,f3d,starts):
global globBank, globIndex
n=0
#Sorting stuff when writing so its in the same order it is in the ROM
NewStarts = [[i,s] for i,s in enumerate(starts)]
NewStarts.sort(key= lambda x: x[1])
NewF3D = [f3d[i[0]] for i in NewStarts]
for j,l in enumerate(NewF3D):
file.write("Gfx bank_%d_index_%d_dl_%08X[] = {\n"%(globBank, globIndex, NewStarts[n][1]))
n+=1
for k,cmd in enumerate(l):
#idk why I built this to work off hex strings but now it
#fucks my ass and I have to do this dumb method.
hs = "%016X"%cmd[0]
# print(hs)
proc = subprocess.Popen(
"tools/gfxdis.f3dex2 -x -d " + str(hs)
,
shell=True,
stdout=subprocess.PIPE,
)
toReturn = proc.communicate()[0].decode("ascii")
toReturn = toReturn.split("\n")[1]
if "gsSPVertex" in toReturn:
tr2 = toReturn.replace(",", " ").replace("(", " ").replace(")"," ").split()
ad = int(tr2[1], 16)
if ad in symbols:
tr2[1] = "bank_%d_index_%d_vtx_%08X" % (globBank, globIndex, ad)
toReturn = " gsSPVertex(%s, %s, %s)," % (tr2[1], tr2[2], tr2[3])
if "gsSPDisplayList" in toReturn:
tr2 = toReturn.replace(",", " ").replace("(", " ").replace(")"," ").split()
ad = int(tr2[1], 16)
if ad in symbols:
tr2[1] = "bank_%d_index_%d_dl_%08X" % (globBank, globIndex, ad)
toReturn = " gsSPDisplayList(%s)," % (tr2[1])
file.write(str(toReturn) + "\n")
file.write("};\n\n")
# file.write("#DL map is nothing in the original game, its here for me\n")
# file.write("DLmap = [\n")
# for j,s in enumerate(NewStarts):
# file.write("%d,"%s[1])
# file.write("\n]\n")
def WriteGeoF3d2(file,f3d,starts):
global globBank, globIndex
n=0
#Sorting stuff when writing so its in the same order it is in the ROM
NewStarts = [[i,s] for i,s in enumerate(starts)]
NewStarts.sort(key= lambda x: x[1])
NewF3D = [f3d[i[0]] for i in NewStarts]
for j,l in enumerate(NewF3D):
file.write("Gfx bank_%d_index_%d_dl_%08X[] = {\n"%(globBank, globIndex, NewStarts[n][1]))
n+=1
dl_str = ""
for k,cmd in enumerate(l):
#idk why I built this to work off hex strings but now it
#fucks my ass and I have to do this dumb method.
dl_str += "%016X"%cmd[0]
# print(hs)
proc = subprocess.Popen(
"tools/gfxdis.f3dex2 -x -d " + str(dl_str)
,
shell=True,
stdout=subprocess.PIPE,
)
toReturn = proc.communicate()[0].decode("ascii")
tr = toReturn.split("\n")[1:-2]
for i in range(len(tr)):
tmp_line = tr[i]
if "gsSPVertex" in tmp_line:
tr2 = tmp_line.replace(",", " ").replace("(", " ").replace(")"," ").split()
ad = int(tr2[1], 16)
if ad in symbols:
tr2[1] = "bank_%d_index_%d_vtx_%08X" % (globBank, globIndex, ad)
tmp_line = " gsSPVertex(%s, %s, %s)," % (tr2[1], tr2[2], tr2[3])
if "gsSPDisplayList" in tmp_line:
tr2 = tmp_line.replace(",", " ").replace("(", " ").replace(")"," ").split()
ad = int(tr2[1], 16)
if ad in symbols:
tr2[1] = "bank_%d_index_%d_dl_%08X" % (globBank, globIndex, ad)
tmp_line = " gsSPDisplayList(%s)," % (tr2[1])
if "gsSPBranchLessZ" in tmp_line:
tr2 = tmp_line.replace(",", " ").replace("(", " ").replace(")"," ").split()
print(tr2)
ad = int(tr2[1], 16)
if ad in symbols:
tr2[1] = "bank_%d_index_%d_dl_%08X" % (globBank, globIndex, ad)
tmp_line = " gsSPBranchLessZ(%s, %s, %s, %s, %s, %s)," % (tr2[1], tr2[2], tr2[3], tr2[4], tr2[5], tr2[6])
tr[i] = tmp_line
file.write('\n'.join(tr) + "\n")
file.write("};\n\n")
def WriteLayout(file,L,env,GH):
global globBank, globIndex
if GH[2][1][0]==0x14:
file.write("// No layout in render mode 0x14\n")
return
# file.write("\n// Layouts Start at 0x%X\n"%GH[0][1][0])
file.write("\nstruct Layout bank_%d_index_%d_layout_%08X[] = {\n"%(globBank, globIndex, GH[0][1][0]))
for i,l in enumerate(L):
file.write(" {\n")
for h in zip(l,Layout.keys()):
if h[1] == 0x20:
file.write(" /*0x%02X*/ {%s},\n },\n"%(h[1],str(h[0][1])[1:-1]))
elif h[1]==4:
if h[0][1][0] == 0:
file.write(" /*0x%02X*/ NULL,\n"%h[1])
else:
if h[0][1][0] in symbols:
file.write(" /*0x%02X*/ %s,\n"%(h[1],symbols[h[0][1][0]]))
else:
file.write(" /*0x%02X*/ (struct EntryPoint *) 0x%08X,\n"%(h[1],h[0][1][0]))
elif h[1]<8:
file.write(" /*0x%02X*/ 0x%X,\n"%(h[1],h[0][1][0]))
else:
file.write(" /*0x%02X*/ {%s},\n"%(h[1],str(h[0][1])[1:-1]))
file.write("};\n")
#repeat for envfx, could do this smarter but I don't feel like it.
for i,e in enumerate(env):
file.write("\nEnvfx_%d = {\n"%i)
for h in zip(e,Layout.keys()):
if h[1] == 0x20:
file.write(" /*0x%02X*/ %s\n}\n"%(h[1],str(h[0][1])))
elif h[1]<8:
file.write(" /*0x%02X*/ 0x%X,\n"%(h[1],h[0][1][0]))
else:
file.write(" /*0x%02X*/ %s,\n"%(h[1],str(h[0][1])))
def getOffset(segAddr):
tmp = 0
fd = sorted([i for i in symbols])
for i in fd:
if segAddr < i:
break
tmp = i
return ("bank_%d_index_%d_dl_%08X" % (globBank, globIndex,tmp), int((segAddr - tmp) / 8))
def WriteImgRefs(file,IR):
global globBank, globIndex
file.write("\n// Img Load F3DEX2 cmd refs\nGfx *%s[] = {\n" % [symbols[i] for i in symbols if "img_refs" in symbols[i]][0])
for i,im in enumerate(IR):
if im[0] == 0:
file.write(" NULL,\n")
else:
file.write(" %s + 0x%X,\n"%getOffset(im[0]))
file.write("};\n")
def WriteVertRefs(file,VR):
global globBank, globIndex
file.write("\n// Vert Load F3DEX2 cmd refs\nGfx *%s[] = {\n" % [symbols[i] for i in symbols if "load_refs" in symbols[i]][0])
for i,v in enumerate(VR):
if v[0] == 0:
file.write(" NULL,\n")
else:
file.write(" %s + 0x%X,\n"%getOffset(v[0]))
file.write("};\n")
def WriteDLPairs(file,SP,starts):
for i,ep in enumerate(zip(SP,starts)):
file.write("\nGfx *bank_%d_index_%d_dl_pair_%08X[] = {\n"%(globBank, globIndex, ep[1]))
symbols[ep[1]] = "bank_%d_index_%d_dl_pair_%08X" % (globBank, globIndex, ep[1])
for p in ep[0]:
if p[1] in symbols:
file.write(" %s,\n"%symbols[p[1]])
else:
if p[1] == 0:
file.write(" NULL,\n")
else:
file.write(" 0x%08X,\n"%p[1])
file.write("};\n")
def WriteEntryPoints(file,SP,starts):
if len(SP) == 0:
file.write("// No Entry Points\n")
return
for i,ep in enumerate(zip(SP,starts)):
file.write("\nstruct EntryPoint bank_%d_index_%d_entry_point_%08X[] = {\n"%(globBank, globIndex, ep[1]))
for p in ep[0]:
if p[1] == 0:
file.write(" {0x%X, NULL},\n"%p[0])
else:
if p[1] in symbols:
file.write(" {0x%X, %s},\n"%(p[0],symbols[p[1]]))
else:
file.write(" {0x%X, (Gfx *) 0x%08X},\n"%(p[0],p[1]))
file.write("};\n")
def WriteEntryPoints1C(file,SP,starts):
global globBank, globIndex
#this is doodoo brain but don't want to rewrite all stuff
if len(SP) == 0:
file.write("// No Entry Points\n")
return
for i,ep in enumerate(zip(SP,starts)):
file.write("\n// Entry Point at 0x%X\nstruct EntryPoint bank_%d_index_%d_entry_point_%d[] = {\n"%(ep[1],globBank, globIndex,i))
for p in ep[0]:
if p[0] == 4:
file.write("{0x%X,0x%X,0x%X}"%(p[0],p[1],p[2]))
else:
file.write("{0x%X,0x%X,0x%X},"%(p[0],p[1],p[2]))
file.write("\n};\n")
def WriteUnk2(file,GH,unk):
if unk:
file.write("\nu32 bank_%d_index_%d_anims_%08X[] = {\n"%(globBank, globIndex, GH[6][1][0]))
for i,u in enumerate(unk):
# if i+1==len(unk):
# file.write(" 0x%X"%u + "\n")
# else:
file.write(" BANK_INDEX(%d, %d)"%(u[0] >> 16, u[0] & 0xFFFF) + ",\n")
file.write("};\n")
else:
file.write("\n// No Animations\n")
return
def WriteTS(file,GH,TS,THS,H2,tPad,tUnk):
global globBank, globIndex
if TS:
#Write Main TS Header
# file.write(TSComment)
ga = GH[1][1][0]
file.write("\nstruct TextureScroll **bank_%d_index_%d_texscroll_header_%08X[] = {\n"%(globBank, globIndex, GH[1][1][0]))
for j,v in enumerate(THS):
if v[0]==0:
file.write(" NULL,\n")
else:
if v[0] in symbols:
file.write(" %s"%symbols[v[0]] + ",\n")
else:
file.write(" (struct TextureScroll **) 0x%08X"%v + ",\n")
ga += 4
file.write("};\n")
#write padding
symbols[ga] = "bank_%d_index_%d_texture_ptr_%08X" % (globBank, globIndex, ga)
file.write("\n\nu32 bank_%d_index_%d_texture_ptr_%08X[] = {\n" % (globBank, globIndex, ga))
for j,v in enumerate(tPad):
# else:
if v[0] == 0x99999999:
file.write(" 0x%X"%v + ",\n")
if j + 1 != len(tPad):
file.write("u32 bank_%d_index_%d_texscroll_padding_%08X[] = {\n" % (globBank, globIndex, ga + 4))
symbols[ga + 4] = "bank_%d_index_%d_texscroll_padding_%08X" % (globBank, globIndex, ga + 4)
else:
if v[0] == 0:
file.write(" 0,\n")
else:
file.write(" BANK_INDEX(%d, %d)"%(v[0] >> 16, v[0] & 0xFFFF) + ",\n")
if j+1==len(tPad):
file.write("};\n\n")
ga += 4
# file.write("};\n\n")
#Write TS structs
for i,[t,u] in enumerate(zip(TS,tUnk)):
if u:
file.write("u32 bank_%d_index_%d_texture_ptr_%08X[] = {\n "%(globBank, globIndex, (t[1]-len(u)*4)))
symbols[t[1]-len(u)*4] = "bank_%d_index_%d_texture_ptr_%08X"%(globBank, globIndex,t[1]-len(u)*4)
for p in u:
if p == 0x99999999:
file.write(" 0x%08X,\n"%p)
elif p == 0:
file.write(" 0,\n")
else:
file.write(" BANK_INDEX(%d, %d),\n"%(p >> 16, p & 65535))
file.write("};\n\n")
if t[0]:
file.write("struct TextureScroll bank_%d_index_%d_texture_scroll_%08X = {\n"%(globBank, globIndex,t[1]))
for j,[v,[k,type]] in enumerate(zip(t[0],TextureScrollStruct.items())):
#why yes, I did learn code exclusively on w3schools
if type[0]==">f":
file.write(" /*0x%02X*/ "%k+"%f"%v + ",\n")
elif j == 0x3:
if v[0] == 0:
file.write(" /*0x%02X*/ "%k+"NULL,\n")
else:
file.write(" /*0x%02X*/ %s,\n" % (k, symbols[v[0]]))
# file.write(" /*0x%02X*/ "%k+"(u32 *) 0x%08X"%v + ",\n")
elif type[0]==">4B":
file.write(" /*0x%02X*/ {"%k+str(v)[1:-1] + "},\n")
elif j+1==len(t[0]):
file.write(" /*0x%02X*/ "%k+"0x%X"%v)
else:
file.write(" /*0x%02X*/ "%k+"0x%X"%v + ",\n")
file.write("\n};\n\n")
#Write subheaders
for j,v in enumerate(H2):
file.write("\nstruct TextureScroll *bank_%d_index_%d_texture_scroll_subheader_%08X[] = {\n"%(globBank, globIndex, v[1]))
for k,h in enumerate(v[0]):
if h[0] == 0:
file.write(" NULL" + ",\n")
else:
if h[0] in symbols:
file.write(" &%s,\n" % symbols[h[0]])
else:
file.write(" (struct TextureScroll *) 0x%08X"%h[0] + ",\n")
file.write("};\n")
else:
file.write("\n// No Texture Scroll section\n\n")
return
def GeometryBlock(stage,Kirb,start,end):
#Now Testing Formatting Geo Blocks
GB = GetGeoBlockData(Kirb,start,end)
WriteGeoBlock(stage,GB,Kirb)
return GB
import sys
def SingleGeo(Bank,Index):
global globBank, globIndex
globBank = Bank
globIndex = Index
#[start,end] = GetPointers(Bank,Index,"Geo_Block",Kirb)
name = ("Bank_%d_Index_%d_Geo"%(Bank,Index))
stage = open(sys.argv[2],'w')
Kirb=open(sys.argv[1],'rb')
Kirb=Kirb.read()
stage.write("// Bank " + str(Bank) + " ID " + str(Index) + "\n")
GeometryBlock(stage,Kirb,0,len(Kirb))
if __name__=='__main__':
toks = sys.argv[1].split("/")
b = int(toks[2].split("_")[1])
i = int(toks[3])
SingleGeo(b,i)

File diff suppressed because it is too large Load Diff

Binary file not shown.