One of the 3 first game on the console.
The game seems very basic and I am very surprised that this game would use a custom microcode.
I would believe that it would use a early version of the fast3d.
in HLE

in LLE

May this game has an issue with emulating the lines on the board or the polygon of the pawns.
@gonetz
Do you have just a very vague idea on where the plugin fails?
I am still surprised it would be customed ucode. Most gfx works.
I haven't chance to investigate it.
I got some time to dumped the ucode and noticed that the MoveWord command is a bit different:
Kuiki Uhabi Suigo ucode:
case_G_MOVEWORD:
lbu target, (0-6)(dinp) # index to address
lbu offset, (0-5)(dinp) # offset from address
lh outptr,(MOVEWORD_TBL)(target) # actual address
add outptr,outptr,offset # ...plus offset
j GfxDone #
sw gfx1, 0(outptr) # store @ addr + off
.end case_G_MOVEWORD
Fast3d ucode:
case_G_MOVEWORD:
lbu target, (0-5)(dinp) # index to address
lhu offset, (0-7)(dinp) # offset from address
lh outptr,(MOVEWORD_TBL)(target) # actual address
add outptr,outptr,offset # ...plus offset
j GfxDone #
sw gfx1, 0(outptr) # store @ addr + off
.end case_G_MOVEWORD
dinp points to the next DL command.
So the following shifts in F3D_MoveWord are wrong for this game:
-_SHIFTR( w0, 0, 8 ) should be _SHIFTR( w0, 8, 8 )
-_SHIFTR( w0, 8, 16 ) should be _SHIFTR( w0, 0, 8 )
Unfortunately this is not fixing the issue.
woa still very interesting!
Is it the only difference in the ucode?
May be this little change has other impacts in the gliden64 HLE code.
I noticed another difference, the ucode actually has an additional command to normalize the perspective projection, additionally to the move word command.
Here's the mapping of the commands in the ucode:
#define F3D_PERSPNORM 0xB4
#define F3D_RDPHALF_1 0xB3
#define F3D_RDPHALF_2 0xB2
#define F3D_RDPHALF_CONT 0xB1
This command is called while rendering the above scene.
@gonetz the gSPPerspNormalize function is not implemented right now, do you think it might be the cause of this issue?
There's no other diff with the Fast3d ucode.
Woa that is nice discovery!
G_PERSPNORMALIZE is mentionned in some "docs" as an immediate command indeed.

"This command sets a normalizing factor which can increase the precision of the perspective divide. The data is a 16 bit unsigned integer and should be the value returned by the guPerspective() routine. When using an orthographic (or other non-perspective) projection this value should be set to 0xffff."
I guess this command was change to a flag in Moveword command as there is no mention of G_MW_PERSPNORM in this "doc".
By the way, I think that you also solved another mystery: RDPHALF_1, F3D_RDPHALF_2 and F3D_RDPHALF_CONT are respectively in 0xB3, 0xB2 and 0xB1 in your mapping.
In the "normal" (or let's say more mature version of fast3D ucode), RDPHALF_1 is not 0xB3, but 0xB2, RDPHALF21 is not 0xB2 but 0xB3, F3D_RDPHALF_CONT is not 0xB1 but 0xB4. In the normal microcode 0xB1 is G_LINE3D_LINE.
I guess it explains why some early games (but not all) may have the command at the "wrong" place. It is for instance the case of Super Mario 64 :)
Edit: You can find in GlideN64, F3D.CCP
void F3D_MoveWord( u32 w0, u32 w1 )
....
case G_MW_PERSPNORM:
gSPPerspNormalize( w1 );
break
We are obvioulsy around something!!!
Very, very mysterious ucode.
I made new ucode according to Gillou68310 notices about MoveWord and
I have doubts that this
So the following shifts in F3D_MoveWord are wrong for this game:
-_SHIFTR( w0, 0, 8 ) should be _SHIFTR( w0, 8, 8 )
-_SHIFTR( w0, 8, 16 ) should be _SHIFTR( w0, 0, 8 )
is true, because in that case G_MW_SEGMENT never hit, which is hardly possible for any game.
Or MOVEWORD command is not 0xBC.
But this is not the main problem. In HLE mode my code detects type of Texrect command (0xE4) as gdpTexRect (see _getTexRectParams). In LLE mode there are no Texrects! Really, texrect never called, only gDPTriShadeTxtr. Thus, 0xE4, which is texrect for all ucodes, is not texrect for this ucode. I can't understand how this is possible.
Another notice: When I use PJ64 RSP plugin 1.7.013, it silently switches to LLE mode even when Graphics HLE is set, and game starts to work.
Indeed PJ64 2.xxx switch automatically in LLE mode for games with non standard ucode. It is set in the RDB (sort of ini). Nothing mysterious here :)
I did not know that.
HLE mode of this game is real mystery.
@Gillou68310: if you check the GIMM.S file (file containing the source code of the immediate command) and not GRUCODE.pdf, you can notice this:
case_G_MOVEWORD:
# lbu target, (0-6)(dinp) # index to address
# lbu offset, (0-5)(dinp) # offset from address
lbu target, (0-5)(dinp) # index to address
lhu offset, (0-7)(dinp) # offset from address
lh outptr,(MOVEWORD_TBL)(target) # actual address
add outptr,outptr,offset # ...plus offset
j GfxDone #
sw gfx1, 0(outptr) # store @ addr + off
.end case_G_MOVEWORD
in bold it is exactly what you found out but it is with a #, so it is only a comment. Why so, that is unclear to me. I think however that your analysis can be correct on this command.
Woa that is getting quite odd this ucode.
@gonetz: even if LLE may not using E4 (omg !!!!), the display list uses it and shows correct graphics thanks to it (in example the clocks on the left and right).
What is missing are the lines (are they lines or texture by the way? because if 0xB1 is not G_LINE3D_LINE, that may be an issue!) with and the pawns, which does not uses texrec i guess.
Was is the outcome of the implementation of the suggestions of Gillou68310?
even if LLE may not using E4 (omg !!!!), the display list uses it and shows correct graphics thanks to it (in example the clocks on the left and right).
Everything is rendered by textured LLE triangles, not by texrects.
Was is the outcome of the implementation of the suggestions of Gillou68310?
Modifications in MoveWord gave nothing. PERSPNORM command really called, but I don't see how it should affect rendering. The game looks the same with all my modifications.
My hypotheses is that 0xBC is not MoveWord here. Each HLE display list started with MoveWord Segement. This game never call it.
Ok I double checked what I mentioned in my previous posts and everything is correct. However I missed something, all case value in F3D_MoveWord are wrong for this ucode, here's the mapping:
#define G_MW_NUMLIGHT 0x00
#define G_MW_CLIP 0x02
#define G_MW_SEGMENT 0x04
#define G_MW_FOG 0x06
#define G_MW_LIGHTCOL 0x08
G_MW_MATRIX, G_MW_POINTS and G_MW_PERSPNORM are non existent in this ucode.
This seems to be the last piece of the puzzle, Kuiki Uhabi Suigo welcome to HLE!!!!

G_MW_SEGMENT never hit, which is hardly possible for any game.
Thanks for the hint @gonetz, this definitely led me to the right direction.
Great! It really works. Thanks!
I put my implementation of this ucode to https://github.com/gonetz/GLideN64/tree/f3dswd branch
I don't know how to name that ucode. I named it F3DSWD because it is modification of Fast3D and olivieryuyu said that in some games that ucode is named as RSP SW Version: 2.0D
@Gillou68310 how you obtained information about MoveWord work and its parameters?
From disassembly :-)
Cool!
case_G_MOVEWORD:
lbu target, (0-6)(dinp) # index to address
lbu offset, (0-5)(dinp) # offset from address
lh outptr,(MOVEWORD_TBL)(target) # actual address
add outptr,outptr,offset # ...plus offset
j GfxDone #
sw gfx1, 0(outptr) # store @ addr + off
.end case_G_MOVEWORD
MOVEWORD_TBL points to a table of addresses in DMEM, here's the table structure for the Fast3d ucode:
MOVEWORD_TBL:
.half RSP_CURR_MPMTX_OFFSET # matrix IMPORTANT! Must be first! (for movemem)
.half RSP_L_NUM # number of active lights * RSP_L_LEN
.half CLIP_SELECT # clip lookup table
.half RSP_SEG_OFFSET # segment table
.half RSP_FOG_FACTOR # fog multipliers
.half RSP_LIGHT_COL # light colors
.half RSP_POINTS_OFFSET # points buffer
.half RSP_STATEP_PERSPNORM_H # perspnorm factor
I compared addresses from this table between both Fast3d and Kuiki Uhabi Suigo ucodes, that's how I managed to make the link.
BTW I noticed that G_MW_POINTS and G_MW_PERSPNORM in Fast3d are respectively 0x0C and 0x0E in your code or in the ucode they are respectively 0x0B and 0x0C.
Wonderful!!!!!!!!!!!!!!!!!!!!!!!!! Super great job Gilles!!!! A never emulated game in HLE now in HLE. It is great!!! Merci t'est un chef!!!
:-)
Great, now how about deciphering uCodes for battle for naboo and indiana jones?
@Gillou68310
BTW I noticed that G_MW_POINTS and G_MW_PERSPNORM in Fast3d are respectively 0x0C and 0x0E in your code or in the ucode they are respectively 0x0B and 0x0C.
I do not understand: do you want to say that G_MW_POINTS and G_MW_PERSPNORM constants in my code are wrong and that actual values are 0x0B and 0x0C?
Cite GBI.h:
@olivieryuyu How to name that ucode? Is it used by any other game?
I guess gbi.h changed with ucode update. I will check in the Fast3d ucode from n64sdk just to be sure.
@Frank-74 that's going to be a much more harder task, I'd rather focus on easier task for now to get familiar with different ucodes.
Thank you for the RE work! Progress in this department is why I donated to gonetz' project.
Finally. People are collaborating on an opensource graphics plugin and ucodes that have been stale for more than a decade are getting fixed and their unknowns RE'd.
@gonetz: though question!!! There is no string in this game, it does not state RSP SW Version: 2.0D. Some games published by SETA does not show a string by the way. Some acts very weirdly, even though they were always more or less emulated. Only Kuiki Uhabi Suigo one was till today completely unplayable.
For me either Kuiki Uhabi Suigo is a early version of the fast3d or a custom ucode based on fast3d. It does not have a official name so. Fast3D_SETA or FAST3D_ALPHA could be a name so.
Here the game that could use this microcode if we consider that the publisher SETA would have use again the same microcode:
Eik艒 no Saint Andrews: see issue #161 and #6
pachinko nichi 365: #6
However those games can have completely different issues than the one of Kuiki Uhabi Suigo and be a normal microcode actually.
@Gillou68310: even in my old version of GBI.h, I have:
Where 0x0B and 0x0C are come from then?
I'd rather focus on easier task for now to get familiar with different ucodes.
I have two candidates:
Yep, they are indeed nice candidates.
I reopened #848 for the branch Z issue- full explanation can be found there.
The light issue and some information can be found in #778
Where 0x0B and 0x0C are come from then?
Nevermind I was wrong. I was looking at the wrong table.
i am closing this ticket. 20 years to HLEzied this game :)
It is great from all of you, thanks!!!!
Most helpful comment
I have two candidates: