Author Topic: NEC DSP UPD77016 Disassembler - Help? Anyone?!  (Read 1108 times)

0 Members and 1 Guest are viewing this topic.

Offline pcbbcTopic starter

  • Newbie
  • Posts: 4
  • Country: gb
NEC DSP UPD77016 Disassembler - Help? Anyone?!
« on: October 26, 2021, 02:31:43 pm »
Hi All,

Okay, I'm attempting to disassemble some code for a NEC UPD77115A.
Datasheet
Instruction Reference Manual

I can't find a disassembler, so I'm writing my own.  Here's the output I have so far...
Code: [Select]
0200: 2C002000 jmp 0x0240
0201: 00000000 nop
0202: 00000000 nop
0203: 00000000 nop
0204: 00000000 nop
0205: 26000000 iret
0206: 00000000 nop
0207: 00000000 nop
0208: 00000000 nop
0209: 26000000 iret
020A: 00000000 nop
020B: 00000000 nop
020C: 00000000 nop
020D: 26000000 iret
020E: 00000000 nop
020F: 00000000 nop
0210: 00000000 nop
0211: 26000000 iret
0212: 00000000 nop
0213: 00000000 nop
0214: 00000000 nop
0215: 26000000 iret
0216: 00000000 nop
0217: 00000000 nop
0218: 00000000 nop
0219: 26000000 iret
021A: 00000000 nop
021B: 00000000 nop
021C: 2C036000 jmp 0x08DC
021D: 26000000 iret
021E: 00000000 nop
021F: 00000000 nop
0220: 2C032100 jmp 0x0862
0221: 26000000 iret
0222: 00000000 nop
0223: 00000000 nop
0224: 2C031F00 jmp 0x0862
0225: 26000000 iret
0226: 00000000 nop
0227: 00000000 nop
0228: 2C032D00 jmp 0x0882
0229: 26000000 iret
022A: 00000000 nop
022B: 00000000 nop
022C: 2C034780 jmp 0x08BB
022D: 26000000 iret
022E: 00000000 nop
022F: 00000000 nop
0230: 2C00ED00 jmp 0x040A
0231: 26000000 iret
0232: 00000000 nop
0233: 00000000 nop
0234: 2C00FD80 jmp 0x042F
0235: 26000000 iret
0236: 00000000 nop
0237: 00000000 nop
0238: 2C034A00 jmp 0x08CC
0239: 26000000 iret
023A: 00000000 nop
023B: 00000000 nop
023C: 2C030900 jmp 0x084E
023D: 26000000 iret
023E: 00000000 nop
023F: 00000000 nop
0240: 61000000 clr(r0)
0241: 38013007 r0l = 0x3007
0242: 48103805 X[0x3805] = r0h
0243: 38010004 r0l = 0x0004
0244: 48103804 X[0x3804] = r0h

So, what looks like a fairly sensible 64 word vector area (see datasheet page 21/22), and the reset vector @ 0x0200 jumps to address 0x0240 where there's also some sensible looking initialisation code.

However here's where I'm running into problems.  The code clears r0 (40 bits), then sets the low 16 bits to immediate value 0x3007.
Then we have instruction 0x48103805 which decodes to X[0x3805] = r0h, at least as far as I can tell from the Instruction Reference Manual.
Surely that should be X[0x3805] = r0l as we've justed loaded the low 16 bits?
Even more so since we go on to load the 16 bit immediate value 0x0004 to r0l (thus overwriting the previous value without apparently using it).
Similarly for the subsequent initialisation of address X[0x3804].

The confussion for me is in reading the instruction table in Fig A-4 (Load/Store Instruction Format 2/2) on page 128 of the Instruction Reference Manual.
0x48103805 decodes as...
010010b reg=000b suf=001b xy=0b 00b d=0b direct=0x3805

But how to interpret the suf+d column?  And what is the meaning of "d"?  Direction???
I has assumed rows of the table are for increassing suf vales 0..7 (as for example how reg bits are presumably encoded).  So suf=001b decodes as *dp = regh.

But that doesn't seem right, because as discussed above we might be expecting *dp = regl, which should perhaps be encoded as suf=000b.

Similar problems exist for interpreting many other instruction formats, since there's no indication of the individual field bit codings.

Have I missed something?  Clues anyone?  Things that would help...
  • Better instruction reference manual
  • Existing disassembler
  • Existing assembler

Hoping there's someone who's woroked with this flavour of DSP chip in the past and can offer some insight.   ^-^

Cheers, Stuart.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 823
  • Country: es
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #1 on: October 26, 2021, 08:33:28 pm »
Just a guess: a register of this CPU consists of 3 parts (e, h, l), so each bit of 3-bit suf could be a direct enable signal for one part (i.e. 001 - l, 010 - h, 100 - e, so eh would be 110 and full reg - 111). From the hw designer’s point - why encode something into sequential numbers if there are enough bits to be used directly?
 

Offline pcbbcTopic starter

  • Newbie
  • Posts: 4
  • Country: gb
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #2 on: October 26, 2021, 11:23:25 pm »
Just a guess: a register of this CPU consists of 3 parts (e, h, l), so each bit of 3-bit suf could be a direct enable signal for one part (i.e. 001 - l, 010 - h, 100 - e, so eh would be 110 and full reg - 111). From the hw designer’s point - why encode something into sequential numbers if there are enough bits to be used directly?
Good suggestion, but the 3 suf bits code need to code for all of the following...
*dp = regl
*dp = regh
*dp = rege
regl = *dp
regh = *dp
rege = *dp
regeh = *dp
reg = *dp

Even if you say d is for direction (so there are duplicates listed for regl, regh and rege) there's still the unidirectional regeh and reg flavours to code for.  So at least 5 codings required in total.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 823
  • Country: es
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #3 on: October 27, 2021, 08:56:51 am »
Yes, d clearly looks like direction. Check other transfer instructions (Inter-Register Transfer, Immediate Value Set) - this bit is shown with a fixed value there and the value matches direction.
That 8-case table is labeled suf+d, so it should look like this actually:
d = 0d = 1
*dp = reglregl = *dp
*dp = reghregh = *dp
*dp = regerege = *dp
- regeh = *dp
- reg = *dp
And, if my "lane enable" guess is correct, first three rows will correspond to a single 1 bit in suf each (not sure about the order, but your example suggests l is lsb), regeh row will have two bits set (those for rege and regh - enabling both lanes), and the reg row will be suf=111 - enabling all 3 lanes.
So the full table could look like this:
sufd = 0d = 1
001*dp = reglregl = *dp
010*dp = reghregh = *dp
100*dp = regerege = *dp
110 - regeh = *dp
111 - reg = *dp
 

Offline pcbbcTopic starter

  • Newbie
  • Posts: 4
  • Country: gb
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #4 on: October 27, 2021, 01:42:24 pm »
Of course, makes perfect sense.  I should have got the full implication of what you meant from your first post.  Thanks for taking the time to explain more fully.
After I'd posted I'd already concluded that suf=010b most likely coresponded to regh.  It should have twigged...

Okay, having implemented this in the disassembler I find the code is using all of the suf combinations as you presented in your table...
sufd = 0d = 1
001*dp = reglregl = *dp
010*dp = reghregh = *dp
100*dp = regerege = *dp
110 - regeh = *dp
111 - reg = *dp
...and more importantly none of the blank ones.  I think you've certainly cracked it.  8)

Unfortunately now there are similar problems with other instruction formats...
Format A-2 page 124. 4 bits but only 14 intructions listed.
Format A-3 page 125.  4 bits but only 8 instructions listed.

It's interesting that format A-10 page 137 has a blank row, so they actually got that layout correct such that you could imply the coding by order!  Here the low order bit of the condition code indicates the negation of the test, so cond=0001b would be NEVER (esentially a NOP), as it's the negation of the EVER with cond=0000b.

Anyway, I feel I've already taken up enough of your time.  I'll try and work through the remaining by looking for any orthogonality with the other instructions, which are actually used in the code, and if they make any sense (or not).
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 823
  • Country: es
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #5 on: October 27, 2021, 04:50:55 pm »
Great! I enjoy such riddles, post more samples if you need any help :)
Note that A-3 op table (that one with just 8 ops for 4 bits) looks similar to the second half of A-1's op table, the encoding could be the same.
A-2 - try gathering statistics of real code to see which two combinations are never used. Perhaps the table is ordered correctly and you just need to find where to insert two blank rows there.

BTW, are you developing a standalone tool or a plugin to some "big" disassembler (IDA Pro, Ghidra etc)? For any serious disasm having the power of one of those tools is a game changer. IDA could be a bit pricy depending on the project scale, but Ghidra is free.
« Last Edit: October 27, 2021, 05:11:49 pm by abyrvalg »
 

Offline pcbbcTopic starter

  • Newbie
  • Posts: 4
  • Country: gb
Re: NEC DSP UPD77016 Disassembler - Help? Anyone?!
« Reply #6 on: October 27, 2021, 11:27:16 pm »
Thanks. Yes me too, although a processor instruction manual really shouldn’t have such riddles…

I’ve a feeling marketing got their hands on the spec after tech wrote it and were like “All these blank lines in tables? Tush, tush! I can fix that so it looks real nice!”.

Enjoyable, but as a friend of mine once said, “Enjoyable like banging your head against a brick wall”!  That is to say, enjoyable when it stops (i.e. you solved the riddle)!

Already ahead of you on that one. Yes, A3 doesn’t use any of the codes 0000b through 0111b. So all 8 in the “top” half. They do appear to be in order from what I can tell. A2 is missing 0000b, 1010b and 1011b codings. The code seems to do all its compares with r = r’ - r’’ and then checking using some conditional of r with zero. I’m assuming that LT is coded for with 0000b but just not used by the code I’m analysing, that 1010b and 1011b are unused, and that everything else is in order as presented.

This code provides MP3 decode and an SD card interface for a car nav and entertainment system.  Specifically the first generation of an Audi RNSE. The second generation unit got a faster more capable main CPU and onboarded these functions, thus doing away with the DSP.

I already have a home developed emulator for the system (both generations), but for the first generation unit I’m unable to emulate MP3 playback or SD card access. Trying to reverse engineer what the main CPU is expecting back from the DSP chip host interface, without any knowledge of the DSP code, is beyond hard.

Did contemplate writing a Ghidra plugin, but with only a few K words of code I think hand commenting is probably manageable. I think next step might be to emulate the DSP (actually 2 of them, one for each SD card slot) as a subsystem to the main emulator.

Again I have to thank you for your insight and willingness to help. I’ll be sure to post back, if only as an update on progress.
« Last Edit: October 27, 2021, 11:28:58 pm by pcbbc »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf