randrew / uxn32

Uxn emulator for Windows and Wine
175 stars 7 forks source link

"Beetbug" debugger assigns opcodes the wrong instructions #7

Closed dheadshot closed 1 year ago

dheadshot commented 2 years ago

I don't know if this is just in the debugger, but 0x00 (BRK) is called LIT, 0x80 (LIT) is called LITk and more importantly, 0x06 (DUP) and 0x07 (OVR) are swapped over. BRK and LIT still function correctly with the wrong names, but I'm not sure about DUP and OVR as my test program doesn't seem to work either way?

randrew commented 2 years ago

Thanks for finding the problem with OVR and DUP being swapped. That mistake was added back a few months ago, when the numeric values of Uxn's opcodes were shuffled around. I've fixed it now, in the source. The next release will include the fix, or you can build it yourself right away.

BRK and LIT thing is more complicated. Instructions in Uxn are 8 bits. The top 3 bits are for the modifiers 2, k, and r. The bottom 5 bits are the opcode (the general operation to perform.) BRK and LIT both share the same bottom 5 bits, 0 0 0 0 0. For most opcodes, the mnemonic is something like OVR and then the additional 2, k, and r modifiers:

static LPCSTR const uxn_op_names =
TEXT("LITINCPOPNIPSWPROTDUPOVREQUNEQGTHLTHJMPJCNJSRSTHLDZSTZLDRSTRLDASTADEIDEOADDSUBMULDIVANDORAEORSFT");

static int InstructionToMnemonic(TCHAR *out, BYTE instr)
{
    int n = 3;
    CopyMemory(out, uxn_op_names + (instr & 0x1F) * 3, 3 * sizeof(TCHAR));
    if (instr & 0x20) out[n++] = '2';
    if (instr & 0x80) out[n++] = 'k';
    if (instr & 0x40) out[n++] = 'r';
    out[n] = 0;
    return n;
}

For the instruction 0b00000000, it's treated as a break instruction. For 0b10000000, it's treated as LIT, because the top bit is set. This means its mnemonic, if you apply the same consistent rules as the other opcodes, will be LITk. And BRK the same as a LIT opcode with none of the upper 3 bits set.

Uxn32 just does the 'dumb' thing and always calls it LIT instead of BRK. I could add special cases for BRK and LIT, but it would make the code a little bit longer. If you think that's something you would like, I can do it.

neauoire commented 2 years ago

It might be worth cleaning it up to hide the k mode in LIT opcodes, I remember being faced with the same challenge when implementing the disassembler in Dexe. Alternatively, you could do something like this, where the opcodes are displayed as the actual literal instead of an opcode and blank lines for the body of the LIT.

ss

randrew commented 2 years ago

OK. I did all of this in commit 463799dae3b372499651656744d31be438e28d00. It's on the master branch, so if you pull and build, you should be able to try it out. Let me know if it's OK.

randrew commented 2 years ago

@dheadshot have you had a chance to try this?

dheadshot commented 2 years ago

Looks like in order to get it to compile with MinGW, you have to define WIN32 and _WIN32_IE=0x1100, which isn't mentioned anywhere.

From the looks of it, DUP and OVR are the right way around now and BRK and LIT display correctly (though 0x40 still shows up as LITr, instead of being an unknown instruction, though that probably doesn't matter).

Interestingly, the commandline window shows up in the background in this version but not on the released one, presumably meaning FreeConsole() was called before but not now?

randrew commented 2 years ago

Regarding the MinGW thing, that's weird. It compiles for me without needing to define that. What versions of MinGW and which compilers, etc. are you using? I've tested it in a bunch of versions.

I don't think the LITr thing matters.

Uxn32 doesn't use FreeConsole(). FreeConsole() is for cmd.exe style Windows consoles, which Uxn32 doesn't use at all. The console in Uxn32 handled internally.

dheadshot commented 2 years ago

I was using MinGW32, with gcc version 6.3.0.1.

The commandline window that shows up in the background is a cmd.exe console and it just does nothing but sit there. If you don't want it to show up, you have to use FreeConsole() to get rid of it! See screenshot: image

randrew commented 2 years ago

No, that's not how it works here. Uxn32 does not create a Windows cmd.exe console window. I think you are building Uxn32 as a console application instead of as a GUI application.

dheadshot commented 2 years ago

I didn't realise there was the option to do that - I've just been freeing the console all these years! gcc [...] -Wl,--subsystem,windows was what I needed!

randrew commented 1 year ago

Released in 1.8.