I’ve made some significant progress on REing Discworld Noir BMV.
First, I put opcodes meaning into table (it’s probably the only case when I had to use spreadsheet for REing) to figure out the meaning.
Normal mode of operation have these opcodes:
00**00*0
— perform extra-long copy;00**00*1
— perform extra-long invoking of pixel functions;00**xxx0
— copyxxx-1
pixels;00**xxx1
— invoke pixel functionxxx-1
times;xxxx000y
— copyxxxx+3+y
pixels;xxxx001y
— invoke pixel functionxxxx+3+y
times;<xxx0yyy0
— copyyyy-1
pixels and then invoke pixel functionxxx-3
times;xxx0yyy1
— invoke pixel functionyyy-1
times and then repeat last valuexxx-3
times;xxx1yyy0
— copyyyy-1
pixels and then repeat last valuexxx-3
times;xxx1yyy1
— invoke pixel functionyyy-1
times and then copyxxx-3
pixels.
Then depending on last operation performed mode is changed to: something special for 00******
opcodes, no change for repeat, “after copy mode” and “after pixel func mode” for obvious cases.
After copy mode opcodes:
xxxxxxx0
— invoke normal mode opcodexxxxxxx1
;00**00**
— extended repeat;00**xxx1
— repeat last valuexxx-1
times;xxxx00y1
— repeat last valuexxxx+3+y
times;xxx0yyy0
— repeat last valueyyy-1
times and copyxxxx-3
pixels;xxx0yyy1
— repeat last valueyyy-1
times and copyxxxx-3
pixels;xxx1yyy1
— repeat last valueyyy-1
times and invoke pixels functionxxxx-3
times.
After pixel function mode is simple: xxxxxxx0
opcode is after copy mode xxxxxxx1
opcode and xxxxxxx1
opcode is normal mode xxxxxxx0
opcode.
The special modes may have secondary opcodes that usually boil down to the same thing: either do some more of the same and proceed normally or calculate next opcode instead of reading it from the stream.
And now the second thing: I’ve managed to rip the relevant code from the disassembly, fix it for NASM to handle plus added some fixed to make it possible to invoke externally and linked it against my own small program that parses BMV file, decodes the first video frame and dumps it into file. That approach works so I have something to test my new implementation against. Also since NASM makes all labels visible it’s easy to make debugger report each opcode as it gets called.
To summarise, I have good understanding of the algorithm and I have a working binary specification. This should be enough to finish it soon (unless I get distracted by something else of course).
You ripped disasembly? Excellent skills!
That’s trivial especially if you use something more advanced than
objdump
to produce disassembly. It just took time to figure out what arguments are passed to the function (in register) and what they mean and to augment the assembly to take them from the stack instead. Plus correcting some instructions that NASM treats differently. Anybody with ~15 minutes in assembly could do that.And don’t forget that the function is more or less self-contained. You call the setup function to initialise frame buffer pointers and then pass frame data to the decoder function. And it simply reads it and writes to the known location without any other calls.