Ok this is going to be fun.
BTW in case you wonder why I have time and state of mind to write this long post, see here :-(.
So all you have so far is two contradicting claims coming from me and KS, and you cannot be sure which of us is right.
Let us rectify that. I attach the spreadsheet I used to calculate the bitrate values - you will need to keep it open in Excel because otherwise you will not be able to properly follow the rest of my post. NB. you will need Excel 2013 or later because it uses some Excel functions that were unavailable before Excel 2013.
I also attach a print screen for those of you who would rather not download it and instead look at a picture :-), or do not have Excel 2013.
Unfortunately the machine I am writing this from does not have Excel 2013 either so I cannot plug in the 40Mbit value - but you will see that the spreadsheet calculation gives the exact value I used and KS quoted - see cell E48 (If you want, tonight I will post an updated picture).
BTW if you have not heard of hexadecimal (base 16) numbering which is used in computing because it is easier :-) just remember that instead of numbers containing 0-9 you will see in the spreadsheet many numbers using 0-9 and A-F (coz base 16). If you are unfamiliar with this, do not be discouraged - I will not ask you to make any calculations.
So, if you are ready to invest 10 minutes in understanding where do the rates come from, here we go:
When I looked into the newly broken-in NX500 it was obvious that the di-camera-app was the program to look into - the name makes it so. So my initial objective was to see where the bitrates are set - well, to cut a long story short, I identified the place in a certain function call, and I saw that the bitrates were loaded into a CPU register via a couple of ARM instructions (different for each bitrate slot).
These instructions are called mov.w and movt. The end result of running them one after the other is that a 32-bit value is loaded into a target CPU register. For the bitrates, the target register needs to be R3 (except for nx500 pro bitrates which need to be put in R0 - note that KS did not say what is the cause of this exception).
Now we go in really deep.
Basically we need to re-encode these instructions such that instead of loading into R3 whatever bit rates Samsung marketing decided, they should load whatever __I__ wanted.
From now on I will start each paragraph with the cell you need to look at.
Cell D9 - So let us pick the target value - in this case 85Mbps. Cell D10 - to keep things easy let us convert it in a 32-bit hexadecimal Cell D11 - let us not forget the target register (for nx500 pro bitrates we would change this to r0)
Cell H5 After thoroughly reading the relevant section of the ARMv7 reference manual, I built the tables H5-AM9 and B13-AM23. Let us discuss then a bit.
The two ARM instructions I am trying to assemble are each 4 bytes = 32 bits. Since this is little-endian ARM, the values are stored in memory as shown in table H5-AM9. that is, a bit scrambled :-). If you read the ARM reference manual, you will see that these two instructions are very similar, the only difference is that one loads a 16-bit value in the lower half of the target register (mow.w) and the other of into the upper half of the target register (movt). They are encoded with some fixed bits (background white in the tables) and some variable bits which contain the 16 bits that make up the value to be uploaded into the register (yellow background).
So now all we have to do is split the 32 bits of the target value into two sets of 16 bits, and spread these 16 bits into the dedicated yellow spaces reserved for them.
Cell B13 Let us start with mov.w (cell B13). The mov.w neds to contain the lower 16 bits of the target value - see cells E14 and E15. These 16 bits I then manually (ok through formulae) sprinkle into the proper yellow places in the encoded ARM instruction.
I then do the same for the movt instruction. The upper 16 bits from the target bitrate I "sprinkle" into the necessary places within the encoded instruction - see cells B19-AM23.
So now we have the ARM instructions codes, exactly how they look if we dump the memory: see cells AB16 and AB22.
BUT, since I am going to use gdb to patch the memory, they are inconvenient, because gdb would require four set statements if I tried to patch byte by byte the memory. So what I decided was to make out of these 4 bytes an integer (which can be patched with one gdb set statement). How to do it? Well, because ARM is little-endian, I needed to reverse the memory byte order to arrive to an integer that gdb will use for patching. Hence cells AB17 and AB23 - notice that the bytes are in reverse order compared to what you see in the memory. This is because gdb, when putting an integer into memory, will know ARM stores them in reverse order and therefore will do the same. The net result is that we end up with the proper value in the memory.
Finally, again to make my gdb task easier, I decided to concatenate these two ARM instructions together so I do not mismatch them and because they are easily split again in gdb. I did that in cell AD25.
So now all we need is to add the surrounding text to make it simply a copy/paste in the gdb script and thus avoid re-typing errors. This I did in cell Q27.
But this calculates only ONE bitrate value, and I am lazy so how can I force Excel to calculate all of them without me having to replace each value in cell D9? Well, Microsoft was kind enough to provide for array operations (I think they are called so) and I took advantage by telling Excel to basically replace D9, successively, with the values I wanted, and store the result in a table. You will find the table in cells D46 to G82.
From there I simply copied the result into the gdb script I publicly released.
Now if you have gdb, go to the memory addresses that change the bitrates and compare my spreadsheet results with the original SAMSUNG values, you will see that they match perfectly: the instructions generated by my spreadsheet are CORRECT - every instance of original Samsung bitrate set instructions, read from memory, matches the corresponding value calculated by my spreadsheet. This proves that the elaborate construction I put together in this spreadsheet is correct.
Finally, for those who open the file, there's a second section of the worksheet that I did not discuss, and which is basically the development of the algorithm used by my current nx-patch and which calculates on the fly the bitrate allowing you to set it to whatever value you want. This development I integrated ad-literam in my nx-patch - see bitRateOpCodes function in nx-patch.cpp.
NB. This is a very very short explanation of my thought process how I went from zero ARM assembly knowledge to encoding these instructions, by using the ARM reference manual.
I hope this post will clear any lingering doubts about the correctness of my calculations.
NX wip v18.xlsx