From 84d4914a3b124b6cb1ecaa638d71226f1671c753 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Thu, 28 Jan 2021 20:43:49 +0100 Subject: [PATCH] [Separate translation units] [th02] snd_mmd_resident() (undecompilable) Reason: Wants to be word-aligned, and the previous version in OP.EXE, game_exit(), is not, despite having an even length :( Oh well, at least I'm confident enough about it by now to document it. And out of all decompilations to be thrown away, this is a pretty dispensable one. Part of P0133, funded by [Anonymous]. --- Makefile.mak | 6 +++--- Research/Borland C++ decompilation.md | 13 +++++++++++++ Tupfile | 1 + Tupfile.bat | 1 + th02/main02_2.cpp | 3 --- th02/maine022.cpp | 3 --- th02/op_02_2.cpp | 6 ------ th02/snd/mmd_res.asm | 6 +++--- th02/snd/mmd_res.c | 23 ----------------------- th02/snd/snd.h | 6 ++++-- th02/snd_mmdr.asm | 16 ++++++++++++++++ 11 files changed, 41 insertions(+), 43 deletions(-) delete mode 100644 th02/snd/mmd_res.c create mode 100644 th02/snd_mmdr.asm diff --git a/Makefile.mak b/Makefile.mak index e8bd8e5e..3471ba5f 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -78,17 +78,17 @@ bin\th02\zun_res.com: th02\zun_res1.c th02\zun_res2.c th02\zun_res3.c $** | masters.lib -bin\th02\op.exe: th02\op_01.cpp bin\exit_dos.obj bin\th02\zunerror.obj bin\th02\grppsafx.obj bin\th02\op.obj th02\op_02_1.cpp bin\th02\pi_load.obj bin\th02\grp_rect.obj bin\frmdely2.obj th02\op_02_2.cpp bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_load.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj th02\op_02_3.cpp bin\th02\snd_se.obj bin\frmdely1.obj th02\op_03.cpp th02\op_04.cpp th02\op_05.cpp th02\op_06.cpp +bin\th02\op.exe: th02\op_01.cpp bin\exit_dos.obj bin\th02\zunerror.obj bin\th02\grppsafx.obj bin\th02\op.obj th02\op_02_1.cpp bin\th02\pi_load.obj bin\th02\grp_rect.obj bin\frmdely2.obj th02\op_02_2.cpp bin\th02\snd_mmdr.obj bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_load.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj th02\op_02_3.cpp bin\th02\snd_se.obj bin\frmdely1.obj th02\op_03.cpp th02\op_04.cpp th02\op_05.cpp th02\op_06.cpp $(CC) $(CFLAGS) -ml -Z -DGAME=2 -nbin\th02\ -eOP.EXE @&&| $** | -bin\th02\main.exe: bin\th02\main.obj bin\th02\zunerror.obj th02\main02_1.cpp bin\th02\pi_load.obj bin\th02\vector.obj bin\frmdely1.obj th02\main02_2.cpp bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_dlyv.obj bin\th02\snd_load.obj th02\mptn_i.cpp bin\th02\initmain.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj bin\th02\snd_dlym.obj bin\th02\snd_se.obj th02\main_03.cpp +bin\th02\main.exe: bin\th02\main.obj bin\th02\zunerror.obj th02\main02_1.cpp bin\th02\pi_load.obj bin\th02\vector.obj bin\frmdely1.obj th02\main02_2.cpp bin\th02\snd_mmdr.obj bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_dlyv.obj bin\th02\snd_load.obj th02\mptn_i.cpp bin\th02\initmain.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj bin\th02\snd_dlym.obj bin\th02\snd_se.obj th02\main_03.cpp $(CC) $(CFLAGS) -ml -Z -DGAME=2 -nbin\th02\ -eMAIN.EXE @&&| $** | -bin\th02\maine.exe: bin\th02\maine.obj bin\th02\grppsafx.obj th02\maine021.cpp bin\th02\pi_load.obj bin\frmdely1.obj th02\maine022.cpp bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_load.obj bin\th02\initmain.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj bin\th02\snd_dlym.obj th02\maine_03.c th02\maine_04.cpp th02\maine_05.cpp +bin\th02\maine.exe: bin\th02\maine.obj bin\th02\grppsafx.obj th02\maine021.cpp bin\th02\pi_load.obj bin\frmdely1.obj th02\maine022.cpp bin\th02\snd_mmdr.obj bin\th02\snd_mode.obj bin\th02\snd_pmdr.obj bin\th02\snd_load.obj bin\th02\initmain.obj bin\th02\pi_put.obj bin\th02\snd_kaja.obj bin\th02\snd_dlym.obj th02\maine_03.c th02\maine_04.cpp th02\maine_05.cpp $(CC) $(CFLAGS) -ml -3 -Z -DGAME=2 -nbin\th02\ -eMAINE.EXE @&&| $** | diff --git a/Research/Borland C++ decompilation.md b/Research/Borland C++ decompilation.md index 747d9c70..82356814 100644 --- a/Research/Borland C++ decompilation.md +++ b/Research/Borland C++ decompilation.md @@ -368,6 +368,19 @@ static_storage db 2, 0, 6 @_STCON_$qv endp ``` + +## Padding bytes in code segments + +- `0x00` is only emitted to word-align `switch` jump tables with `-a2`. + Anywhere else, it indicates the start or end of a word-aligned `SEGMENT` + compiled from assembly. Borland C++ never adds padding between functions or + segments. + + **Certainty**: Would love to find a proper compiler or linker setting for + this, but it doesn't seem to exist. The `#pragma codestring \x00` workaround + doesn't respect different alignment requirements of surrounding translation + units, after all. + ## C++ In C++ mode, the value of a `const` scalar-type variable declared at global diff --git a/Tupfile b/Tupfile index c7e1709a..2ec35c01 100644 --- a/Tupfile +++ b/Tupfile @@ -68,6 +68,7 @@ BMP2ARR = bin\\Pipeline\\bmp2arr.exe : th02_zuninit.asm |> !as |> bin\\th02\\zuninit.obj : th02\\snd_se.asm |> !as2 |> +: th02\\snd_mmdr.asm |> !as2 |> : th02_op.asm |> !as |> bin\\th02\\op.obj : th02_main.asm | \ th02/sprites/pellet.asp \ diff --git a/Tupfile.bat b/Tupfile.bat index f7ef3817..e9e9d93a 100644 --- a/Tupfile.bat +++ b/Tupfile.bat @@ -25,6 +25,7 @@ tasm32 /m /mx /kh32768 /t th01_reiiden.asm bin\th01\reiiden.obj tasm32 /m /mx /kh32768 /t th01_fuuin.asm bin\th01\fuuin.obj tasm32 /m /mx /kh32768 /t th02_zuninit.asm bin\th02\zuninit.obj tasm32 /m /mx /kh32768 /t /dGAME=2 th02\snd_se.asm bin\th02\snd_se.obj +tasm32 /m /mx /kh32768 /t /dGAME=2 th02\snd_mmdr.asm bin\th02\snd_mmdr.obj tasm32 /m /mx /kh32768 /t th02_op.asm bin\th02\op.obj tasm32 /m /mx /kh32768 /t th02_main.asm bin\th02\main.obj tasm32 /m /mx /kh32768 /t th02_maine.asm bin\th02\maine.obj diff --git a/th02/main02_2.cpp b/th02/main02_2.cpp index 0fdce99d..8bce44c1 100644 --- a/th02/main02_2.cpp +++ b/th02/main02_2.cpp @@ -8,14 +8,11 @@ extern "C" { #include -#include "libs/kaja/kaja.h" #include "th02/th02.h" #include "master.hpp" #include "th02/hardware/frmdelay.h" #include "th02/hardware/input.hpp" -#include "th02/snd/snd.h" #include "th02/hardware/input.c" #include "th02/exit.c" -#include "th02/snd/mmd_res.c" } diff --git a/th02/maine022.cpp b/th02/maine022.cpp index dd3afe0f..840867a1 100644 --- a/th02/maine022.cpp +++ b/th02/maine022.cpp @@ -7,12 +7,10 @@ extern "C" { #include -#include "libs/kaja/kaja.h" #include "th02/th02.h" #include "master.hpp" #include "th02/hardware/frmdelay.h" #include "th02/hardware/input.hpp" -#include "th02/snd/snd.h" #include "th02/formats/pf.hpp" #include "th02/snd/data.c" @@ -20,5 +18,4 @@ extern const char pf_fn[] = PF_FN; #include "th02/hardware/input.c" #include "th02/exit.c" -#include "th02/snd/mmd_res.c" } diff --git a/th02/op_02_2.cpp b/th02/op_02_2.cpp index 0ff73369..01eee85d 100644 --- a/th02/op_02_2.cpp +++ b/th02/op_02_2.cpp @@ -8,12 +8,10 @@ extern "C" { #include -#include "libs/kaja/kaja.h" #include "th02/th02.h" #include "master.hpp" #include "th02/mem.h" #include "th02/core/initexit.h" -#include "th02/snd/snd.h" #include "th02/formats/pf.hpp" #include "th02/hardware/frmdelay.h" #include "th02/hardware/input.hpp" @@ -25,8 +23,4 @@ const char pf_fn[] = PF_FN; #include "th02/hardware/input.c" #include "th02/core/initop.cpp" #include "th02/exit.c" - -#pragma codestring "\x00" - -#include "th02/snd/mmd_res.c" } diff --git a/th02/snd/mmd_res.asm b/th02/snd/mmd_res.asm index 520a4f0d..1188fdaf 100644 --- a/th02/snd/mmd_res.asm +++ b/th02/snd/mmd_res.asm @@ -2,7 +2,7 @@ public _snd_mmd_resident _snd_mmd_resident proc xor ax, ax mov es, ax - les bx, dword ptr es:[61h * 4] + les bx, dword ptr es:[MMD * 4] assume es:nothing cmp byte ptr es:[bx+2], 'M' jnz short @@nope @@ -10,7 +10,7 @@ _snd_mmd_resident proc jnz short @@nope cmp byte ptr es:[bx+4], 'D' jnz short @@nope - mov _snd_interrupt_if_midi, 61h + mov _snd_interrupt_if_midi, MMD if GAME le 3 mov _snd_midi_active, 1 endif @@ -25,4 +25,4 @@ endif xor ax, ax ret _snd_mmd_resident endp - nop ; word alignment + even diff --git a/th02/snd/mmd_res.c b/th02/snd/mmd_res.c deleted file mode 100644 index 3ad1693e..00000000 --- a/th02/snd/mmd_res.c +++ /dev/null @@ -1,23 +0,0 @@ -#pragma option -k- - -int snd_mmd_resident(void) -{ - _AX = 0; - __asm mov es, ax; - __asm les bx, dword ptr es:[MMD * 4]; - __asm cmp byte ptr es:[bx+2], 'M'; - __asm jnz nope; - __asm cmp byte ptr es:[bx+3], 'M'; - __asm jnz nope; - __asm cmp byte ptr es:[bx+4], 'D'; - __asm jnz nope; - snd_interrupt_if_midi = MMD; - snd_midi_active = 1; - snd_midi_possible = 1; - return 1; -nope: - snd_midi_possible = 0; - return 0; -} - -#pragma codestring "\x90" diff --git a/th02/snd/snd.h b/th02/snd/snd.h index b1c525f8..4410569f 100644 --- a/th02/snd/snd.h +++ b/th02/snd/snd.h @@ -27,8 +27,10 @@ extern bool snd_midi_possible; // check for an actual installed FM sound source is done by // snd_determine_mode(). bool16 snd_pmd_resident(void); -#if GAME != 3 - int snd_mmd_resident(void); +#if (GAME != 3) + // Returns whether the MMD driver is resident at its interrupt. If it is, + // ≤TH03 sets [snd_midi_active] to true. + bool16 snd_mmd_resident(void); #endif // Checks whether an FM sound source is active, and sets [snd_fm_possible] diff --git a/th02/snd_mmdr.asm b/th02/snd_mmdr.asm new file mode 100644 index 00000000..d0ba259c --- /dev/null +++ b/th02/snd_mmdr.asm @@ -0,0 +1,16 @@ + .386 + .model large SHARED + locals + +include libs/kaja/kaja.inc + + extrn _snd_interrupt_if_midi:byte + extrn _snd_midi_active:byte + extrn _snd_midi_possible:byte + +SHARED segment word public 'CODE' use16 + assume cs:SHARED +include th02/snd/mmd_res.asm +SHARED ends + + end