diff --git a/Makefile.mak b/Makefile.mak index c473f3f2..d1491844 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -41,17 +41,17 @@ th05:: $(TH05:\=bin\th05\) bin\th01\zunsoft.com: th01\zunsoft.c $(CC) $(CFLAGS) -mt -lt -nbin\th01\ $** masters.lib -bin\th01\op.exe: bin\th01\op.obj th01\op_02.c th01\op_03.c th01\op_04.c th01\op_10.c th01\op_11.c th01\op_12.cpp +bin\th01\op.exe: bin\th01\op.obj th01\op_02.c th01\op_03.c th01\op_04.c th01\op_06.cpp th01\op_10.c th01\op_11.c th01\op_12.cpp $(CC) $(CFLAGS) -ml -3 -nbin\th01\ -eOP.EXE @&&| $** | -bin\th01\reiiden.exe: bin\th01\reiiden.obj th01\main_02.c th01\main_03.c th01\main_04.c th01\main_12.c th01\main_13.c th01\main_14.c th01\main_16.c +bin\th01\reiiden.exe: bin\th01\reiiden.obj th01\main_02.c th01\main_03.c th01\main_04.c th01\main_06.cpp th01\main_12.c th01\main_13.c th01\main_14.c th01\main_16.c $(CC) $(CFLAGS) -ml -3 -nbin\th01\ -eREIIDEN.EXE @&&| $** | -bin\th01\fuuin.exe: bin\th01\fuuin.obj th01\fuuin_05.c th01\fuuin_06.c th01\fuuin_11.c th01\fuuin_12.c th01\fuuin_13.c +bin\th01\fuuin.exe: bin\th01\fuuin.obj th01\fuuin_05.c th01\fuuin_06.c th01\fuuin_08.cpp th01\fuuin_11.c th01\fuuin_12.c th01\fuuin_13.c $(CC) $(CFLAGS) -ml -3 -nbin\th01\ -eFUUIN.EXE @&&| $** | diff --git a/Research/Borland C++ decompilation.md b/Research/Borland C++ decompilation.md index 57c10cee..14430f19 100644 --- a/Research/Borland C++ decompilation.md +++ b/Research/Borland C++ decompilation.md @@ -20,6 +20,7 @@ Example: | | | |-|-| | `MOV al, var`
`MOV ah, 0`| `var` is *unsigned char* | +| `MOV al, var`
`CBW` | `var` is *char*, `AX` is *int* | ## Arithmetic @@ -48,7 +49,18 @@ case it's part of an arithmetic expression that was promoted to `int`. * Multiple cases with the same offset in the table, to code that doesn't return? Code was compiled with `-O` -## Pushing byte arguments to functions +## Function calls + +### `NOP` insertion + +Happens for every `far` call to outside of the current translation unit, even +if both the caller and callee end up being linked into the same code segment. + +**Certainty:** Seems like there *might* be a way around that, apart from +temporarily spelling out these calls in ASM until both functions are compiled +as part of the same translation unit. Found nothing so far, though. + +### Pushing byte arguments to functions Borland C++ just pushes the entire word. Will cause IDA to mis-identify certain local variables as `word`s when they aren't. diff --git a/th01/fuuin_08.cpp b/th01/fuuin_08.cpp new file mode 100644 index 00000000..e1e3adcb --- /dev/null +++ b/th01/fuuin_08.cpp @@ -0,0 +1,6 @@ +/* ReC98 + * ----- + * Code segment #8 of TH01's FUUIN.EXE + */ + +#include "th01/hardware/respal.cpp" diff --git a/th01/hardware/palette.hpp b/th01/hardware/palette.hpp index 70288854..8dbbd361 100644 --- a/th01/hardware/palette.hpp +++ b/th01/hardware/palette.hpp @@ -12,3 +12,13 @@ void z_palette_black(void); // Sets all hardware colors to #FFF, without touching z_Palettes. void z_palette_white(void); + +/// Resident palette +/// ---------------- +// Copies the resident palette to z_Palettes and sets all hardware colors. +// Returns 1 on success, 0 on failure. +int z_respal_get_show(void); +// Copies z_Palettes to the resident palette. Returns 1 on success, 0 on +// failure. +int z_respal_set(void); +/// ---------------- diff --git a/th01/hardware/respal.cpp b/th01/hardware/respal.cpp new file mode 100644 index 00000000..794c0a76 --- /dev/null +++ b/th01/hardware/respal.cpp @@ -0,0 +1,135 @@ +#pragma option -Z + +extern "C" { +#include +#include "ReC98.h" +#include "th01/hardware/palette.hpp" + +// Resident palette +// ---------------- +#define RESPAL_ID "pal98 grb" +struct hack { char x[sizeof(RESPAL_ID)]; }; // XXX +extern const hack PAL98_GRB; + +#pragma option -a1 +// MASTER.MAN suggests that GBR ordering is some sort of standard on PC-98. +// It does match the order of the hardware's palette register ports, after +// all. (0AAh = green, 0ACh = red, 0AEh = blue) +struct grb_t { + uint4_t g, r, b; +}; + +struct respal_t { + char id[sizeof(RESPAL_ID)]; + unsigned char tone; + int8_t padding[5]; + grb_t pal[COLOR_COUNT]; +}; +// ---------------- + +// Memory Control Block +// Adapted from FreeDOS' kernel/hdr/mcb.h +// -------------------- +#define MCB_NORMAL 0x4d +#define MCB_LAST 0x5a + +struct mcb_t { + uint8_t m_type; // mcb type - chain or end + uint16_t __seg* m_psp; // owner id via psp segment + uint16_t m_size; // size of segment in paragraphs + uint8_t m_fill[3]; + uint8_t m_name[8]; +}; +#pragma option -a. + +respal_t __seg* z_respal_exist(void) +{ + union REGS regs; + struct SREGS sregs; + const hack ID = PAL98_GRB; + seg_t mcb; + int i; + +#define MCB reinterpret_cast(mcb) /* For easy derefencing */ +#define MCB_PARAS (sizeof(mcb_t) / 16) /* For segment pointer arithmetic */ + + // "Get list of lists" + segread(&sregs); + regs.h.ah = 0x52; + intdosx(®s, ®s, &sregs); + + mcb = *reinterpret_cast(MK_FP(sregs.es, regs.w.bx - 2)); + while(1) { + if(MCB->m_psp != 0) { + for(i = 0; i < sizeof(ID); i++) { + if(reinterpret_cast(MCB + 1)->id[i] != ID.x[i]) { + break; + } + } + if(i == sizeof(ID)) { + return reinterpret_cast(mcb + MCB_PARAS); + } + } + if(MCB->m_type != MCB_NORMAL) { + return 0; + } + mcb += MCB_PARAS + MCB->m_size; + }; + +#undef MCB_PARAS +#undef MCB +} + +int z_respal_get_show(void) +{ + int i; + respal_t __seg *respal_seg = z_respal_exist(); + if(respal_seg) { + grb_t *respal = respal_seg->pal; + for(i = 0; i < COLOR_COUNT; i++) { + /* TODO: Replace with the decompiled call + * z_palette_set_show(i, respal->r, respal->g, respal->b); + * once that function is part of this translation unit */ + __asm { + les bx, respal + mov al, es:[bx+2] + cbw + push ax + mov al, es:[bx+0] + cbw + push ax + mov al, es:[bx+1] + cbw + push ax + // Spelling out PUSH SI causes Turbo C++ to interpret SI as + // reserved, and it then moves [i] to DI rather than SI + db 0x56 + push cs + call near ptr z_palette_set_show + add sp, 8 + } + respal++; + } + return 0; + } + return 1; +} + +int z_respal_set(void) +{ + int i; + respal_t __seg *respal_seg = z_respal_exist(); + if(respal_seg) { + grb_t *respal = respal_seg->pal; + for(i = 0; i < COLOR_COUNT; i++) { + respal->g = z_Palettes.colors[i].c.g; + respal->r = z_Palettes.colors[i].c.r; + respal->b = z_Palettes.colors[i].c.b; + respal++; + } + return 0; + } + return 1; +} + +} diff --git a/th01/hardware/respal[data].asm b/th01/hardware/respal[data].asm new file mode 100644 index 00000000..9c2b735f --- /dev/null +++ b/th01/hardware/respal[data].asm @@ -0,0 +1,3 @@ +public _PAL98_GRB +_PAL98_GRB db 'pal98 grb',0 + even diff --git a/th01/main_06.cpp b/th01/main_06.cpp new file mode 100644 index 00000000..dfbb5434 --- /dev/null +++ b/th01/main_06.cpp @@ -0,0 +1,6 @@ +/* ReC98 + * ----- + * Code segment #6 of TH01's REIIDEN.EXE + */ + +#include "th01/hardware/respal.cpp" diff --git a/th01/op_06.cpp b/th01/op_06.cpp new file mode 100644 index 00000000..8911024f --- /dev/null +++ b/th01/op_06.cpp @@ -0,0 +1,6 @@ +/* ReC98 + * ----- + * Code segment #6 of TH01's OP.EXE + */ + +#include "th01/hardware/respal.cpp" diff --git a/th01_fuuin.asm b/th01_fuuin.asm index e6253800..2ecdd70d 100644 --- a/th01_fuuin.asm +++ b/th01_fuuin.asm @@ -5761,7 +5761,7 @@ game_init proc far call egc_start call graph_start call respal_create - call sub_E984 + call _z_respal_set call vram_planes_set @@ret: @@ -8887,211 +8887,7 @@ loc_E89E: retf sub_E722 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_E8A9 proc far - -inregs = REGS ptr -22h -var_12 = byte ptr -12h -segp = SREGS ptr -8 - - enter 22h, 0 - push si - push di - lea ax, [bp+var_12] - push ss - push ax - push ds - push offset aPal98Grb ; "pal98 grb" - mov cx, 0Ah - call SCOPY@ - push ss - lea ax, [bp+segp] - push ax ; segp - call _segread - add sp, 4 - mov byte ptr [bp+inregs+1], 52h ; 'R' - push ss - lea ax, [bp+segp] - push ax ; segregs - push ss - lea ax, [bp+inregs] - push ax ; outregs - push ss - push ax ; inregs - call _intdosx - add sp, 0Ch - mov bx, word ptr [bp+inregs+2] - sub bx, 2 - mov es, [bp+segp+SREGS._es] - mov si, es:[bx] - -loc_E8F1: - mov es, si - cmp word ptr es:1, 0 - jz short loc_E91A - xor di, di - jmp short loc_E90B -; --------------------------------------------------------------------------- - -loc_E8FF: - mov es, si - mov al, es:[di+10h] - cmp al, [bp+di+var_12] - jnz short loc_E910 - inc di - -loc_E90B: - cmp di, 0Ah - jl short loc_E8FF - -loc_E910: - cmp di, 0Ah - jnz short loc_E91A - lea ax, [si+1] - jmp short loc_E933 -; --------------------------------------------------------------------------- - -loc_E91A: - mov es, si - cmp byte ptr es:0, 4Dh ; 'M' - jz short loc_E928 - xor ax, ax - jmp short loc_E933 -; --------------------------------------------------------------------------- - -loc_E928: - mov es, si - mov ax, es:3 - inc ax - add si, ax - jmp short loc_E8F1 -; --------------------------------------------------------------------------- - -loc_E933: - pop di - pop si - leave - retf -sub_E8A9 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_E937 proc far - -var_4 = dword ptr -4 - - enter 4, 0 - push si - push di - call sub_E8A9 - mov di, ax - or di, di - jz short loc_E97D - mov word ptr [bp+var_4+2], di - mov word ptr [bp+var_4], 10h - xor si, si - jmp short loc_E974 -; --------------------------------------------------------------------------- - -loc_E953: - les bx, [bp+var_4] - mov al, es:[bx+2] - cbw - push ax - mov al, es:[bx] - cbw - push ax - mov al, es:[bx+1] - cbw - push ax - push si - call _z_palette_set_show - add sp, 8 - add word ptr [bp+var_4], 3 - inc si - -loc_E974: - cmp si, COLOR_COUNT - jl short loc_E953 - xor ax, ax - jmp short loc_E980 -; --------------------------------------------------------------------------- - -loc_E97D: - mov ax, 1 - -loc_E980: - pop di - pop si - leave - retf -sub_E937 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_E984 proc far - -var_4 = dword ptr -4 - - enter 4, 0 - push si - push di - call sub_E8A9 - mov di, ax - or di, di - jz short loc_E9DD - mov word ptr [bp+var_4+2], di - mov word ptr [bp+var_4], 10h - xor si, si - jmp short loc_E9D4 -; --------------------------------------------------------------------------- - -loc_E9A0: - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].g - les bx, [bp+var_4] - mov es:[bx], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].r - mov bx, word ptr [bp+var_4] - mov es:[bx+1], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].b - mov bx, word ptr [bp+var_4] - mov es:[bx+2], al - add word ptr [bp+var_4], 3 - inc si - -loc_E9D4: - cmp si, 10h - jl short loc_E9A0 - xor ax, ax - jmp short loc_E9E0 -; --------------------------------------------------------------------------- - -loc_E9DD: - mov ax, 1 - -loc_E9E0: - pop di - pop si - leave - retf -sub_E984 endp - + extern _z_respal_set:proc fuuin_08_TEXT ends ; =========================================================================== @@ -9824,8 +9620,7 @@ _game_initialized db 0 include th01/hardware/palette[data].asm byte_134EA db 0 word_134EB dw 80h -aPal98Grb db 'pal98 grb',0 - db 0 +include th01/hardware/respal[data].asm word_134F8 dw 1 word_134FA dw 1 dd 0 diff --git a/th01_op.asm b/th01_op.asm index 2620fbac..497ce43c 100644 --- a/th01_op.asm +++ b/th01_op.asm @@ -2184,7 +2184,7 @@ game_init proc far call egc_start call graph_start call respal_create - call sub_D1C0 + call _z_respal_set call vram_planes_set @@ret: @@ -5107,200 +5107,7 @@ loc_D0DA: leave retf -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_D0E5 proc far - -inregs = REGS ptr -22h -var_12 = byte ptr -12h -segp = SREGS ptr -8 - - enter 22h, 0 - push si - push di - lea ax, [bp+var_12] - push ss - push ax - push ds - push offset aPal98Grb ; "pal98 grb" - mov cx, 0Ah - call SCOPY@ - push ss - lea ax, [bp+segp] - push ax ; segp - call _segread - add sp, 4 - mov byte ptr [bp+inregs+1], 52h ; 'R' - push ss - lea ax, [bp+segp] - push ax ; segregs - push ss - lea ax, [bp+inregs] - push ax ; outregs - push ss - push ax ; inregs - call _intdosx - add sp, 0Ch - mov bx, word ptr [bp+inregs+2] - sub bx, 2 - mov es, [bp+segp+SREGS._es] - mov si, es:[bx] - -loc_D12D: - mov es, si - cmp word ptr es:1, 0 - jz short loc_D156 - xor di, di - jmp short loc_D147 -; --------------------------------------------------------------------------- - -loc_D13B: - mov es, si - mov al, es:[di+10h] - cmp al, [bp+di+var_12] - jnz short loc_D14C - inc di - -loc_D147: - cmp di, 0Ah - jl short loc_D13B - -loc_D14C: - cmp di, 0Ah - jnz short loc_D156 - lea ax, [si+1] - jmp short loc_D16F -; --------------------------------------------------------------------------- - -loc_D156: - mov es, si - cmp byte ptr es:0, 4Dh ; 'M' - jz short loc_D164 - xor ax, ax - jmp short loc_D16F -; --------------------------------------------------------------------------- - -loc_D164: - mov es, si - mov ax, es:3 - inc ax - add si, ax - jmp short loc_D12D -; --------------------------------------------------------------------------- - -loc_D16F: - pop di - pop si - leave - retf -sub_D0E5 endp - -; --------------------------------------------------------------------------- - enter 4, 0 - push si - push di - call sub_D0E5 - mov di, ax - or di, di - jz short loc_D1B9 - mov [bp-2], di - mov word ptr [bp-4], 10h - xor si, si - jmp short loc_D1B0 -; --------------------------------------------------------------------------- - -loc_D18F: - les bx, [bp-4] - mov al, es:[bx+2] - cbw - push ax - mov al, es:[bx] - cbw - push ax - mov al, es:[bx+1] - cbw - push ax - push si - call _z_palette_set_show - add sp, 8 - add word ptr [bp-4], 3 - inc si - -loc_D1B0: - cmp si, COLOR_COUNT - jl short loc_D18F - xor ax, ax - jmp short loc_D1BC -; --------------------------------------------------------------------------- - -loc_D1B9: - mov ax, 1 - -loc_D1BC: - pop di - pop si - leave - retf - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_D1C0 proc far - -var_4 = dword ptr -4 - - enter 4, 0 - push si - push di - call sub_D0E5 - mov di, ax - or di, di - jz short loc_D219 - mov word ptr [bp+var_4+2], di - mov word ptr [bp+var_4], 10h - xor si, si - jmp short loc_D210 -; --------------------------------------------------------------------------- - -loc_D1DC: - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].g - les bx, [bp+var_4] - mov es:[bx], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].r - mov bx, word ptr [bp+var_4] - mov es:[bx+1], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].b - mov bx, word ptr [bp+var_4] - mov es:[bx+2], al - add word ptr [bp+var_4], 3 - inc si - -loc_D210: - cmp si, 10h - jl short loc_D1DC - xor ax, ax - jmp short loc_D21C -; --------------------------------------------------------------------------- - -loc_D219: - mov ax, 1 - -loc_D21C: - pop di - pop si - leave - retf -sub_D1C0 endp - + extern _z_respal_set:proc op_06_TEXT ends ; --------------------------------------------------------------------------- @@ -7528,8 +7335,7 @@ _game_initialized db 0 include th01/hardware/palette[data].asm byte_129AA db 0 word_129AB dw 80h -aPal98Grb db 'pal98 grb',0 - db 0 +include th01/hardware/respal[data].asm word_129B8 dw 1 word_129BA dw 1 dd 0 diff --git a/th01_reiiden.asm b/th01_reiiden.asm index b1c91aa0..4cd33366 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -5349,7 +5349,7 @@ game_init proc far call egc_start call graph_start call respal_create - call sub_102BB + call _z_respal_set call vram_planes_set loc_E835: @@ -8481,213 +8481,7 @@ loc_101D5: retf sub_10059 endp - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_101E0 proc far - -inregs = REGS ptr -22h -var_12 = byte ptr -12h -segp = SREGS ptr -8 - - enter 22h, 0 - push si - push di - lea ax, [bp+var_12] - push ss - push ax - push ds - push offset aPal98Grb ; "pal98 grb" - mov cx, 0Ah - call SCOPY@ - push ss - lea ax, [bp+segp] - push ax ; segp - call _segread - add sp, 4 - mov byte ptr [bp+inregs+1], 52h ; 'R' - push ss - lea ax, [bp+segp] - push ax ; segregs - push ss - lea ax, [bp+inregs] - push ax ; outregs - push ss - push ax ; inregs - call _intdosx - add sp, 0Ch - mov bx, word ptr [bp+inregs+2] - sub bx, 2 - mov es, [bp+segp+SREGS._es] - mov si, es:[bx] - -loc_10228: - mov es, si - cmp word ptr es:1, 0 - jz short loc_10251 - xor di, di - jmp short loc_10242 -; --------------------------------------------------------------------------- - -loc_10236: - mov es, si - mov al, es:[di+10h] - cmp al, [bp+di+var_12] - jnz short loc_10247 - inc di - -loc_10242: - cmp di, 0Ah - jl short loc_10236 - -loc_10247: - cmp di, 0Ah - jnz short loc_10251 - lea ax, [si+1] - jmp short loc_1026A -; --------------------------------------------------------------------------- - -loc_10251: - mov es, si - cmp byte ptr es:0, 4Dh ; 'M' - jz short loc_1025F - xor ax, ax - jmp short loc_1026A -; --------------------------------------------------------------------------- - -loc_1025F: - mov es, si - mov ax, es:3 - inc ax - add si, ax - jmp short loc_10228 -; --------------------------------------------------------------------------- - -loc_1026A: - pop di - pop si - leave - retf -sub_101E0 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_1026E proc far - -var_4 = dword ptr -4 - - enter 4, 0 - push si - push di - call sub_101E0 - mov di, ax - or di, di - jz short loc_102B4 - mov word ptr [bp+var_4+2], di - mov word ptr [bp+var_4], 10h - xor si, si - jmp short loc_102AB -; --------------------------------------------------------------------------- - -loc_1028A: - les bx, [bp+var_4] - mov al, es:[bx+2] - cbw - push ax - mov al, es:[bx] - cbw - push ax - mov al, es:[bx+1] - cbw - push ax - push si - call _z_palette_set_show - add sp, 8 - add word ptr [bp+var_4], 3 - inc si - -loc_102AB: - cmp si, COLOR_COUNT - jl short loc_1028A - xor ax, ax - jmp short loc_102B7 -; --------------------------------------------------------------------------- - -loc_102B4: - mov ax, 1 - -loc_102B7: - pop di - pop si - leave - retf -sub_1026E endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_102BB proc far - -var_4 = dword ptr -4 - - enter 4, 0 - push si - push di - call sub_101E0 - mov di, ax - or di, di - jz short loc_10314 - mov word ptr [bp+var_4+2], di - mov word ptr [bp+var_4], 10h - xor si, si - jmp short loc_1030B -; --------------------------------------------------------------------------- - -loc_102D7: - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].g - les bx, [bp+var_4] - mov es:[bx], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].r - mov bx, word ptr [bp+var_4] - mov es:[bx+1], al - mov bx, si - imul bx, 3 - mov al, _z_Palettes[bx].b - mov bx, word ptr [bp+var_4] - mov es:[bx+2], al - add word ptr [bp+var_4], 3 - inc si - -loc_1030B: - cmp si, 10h - jl short loc_102D7 - -loc_10310: - xor ax, ax - jmp short loc_10317 -; --------------------------------------------------------------------------- - -loc_10314: - mov ax, 1 - -loc_10317: - pop di - pop si - leave - retf -sub_102BB endp - + extern _z_respal_set:proc main_06_TEXT ends ; =========================================================================== @@ -28892,8 +28686,7 @@ _game_initialized db 0 include th01/hardware/palette[data].asm byte_350C0 db 0 word_350C1 dw 80h -aPal98Grb db 'pal98 grb',0 - db 0 +include th01/hardware/respal[data].asm word_350CE dw 1 word_350D0 dw 1 dd 0