mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th05] pi_put_8(), pi_put_quarter_8()
> assigning to the DI register immediately before a CALL Yeah, no amount of comma operator trickery can get *that* out of this compiler. Also, these TH05 .PI functions are the only place in PC-98 Touhou with a `IMUL DI, imm8` instruction, which is impossible to get out of Turbo C++'s built-in assembler. Well, at least the `if` branches decompile somewhat nicely. Part of P0134, funded by [Anonymous].
This commit is contained in:
parent
25d26824a1
commit
ffcc46d32f
|
@ -150,7 +150,7 @@ bin\th05\res_kso.com: th05\res_kso.cpp
|
|||
$**
|
||||
| masters.lib
|
||||
|
||||
bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
$(CC) $(CFLAGS) -ml -DGAME=5 -DBINARY='O' -3 -Z -nbin\th05\ -eOP.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
@ -160,7 +160,7 @@ bin\th05\main.exe: bin\th05\main.obj th05\main010.cpp th05\main011.cpp th05\p_co
|
|||
$**
|
||||
|
|
||||
|
||||
bin\th05\maine.exe: bin\th05\maine.obj th05\maine011.cpp th05\regist.cpp th05\staff.cpp bin\th05\pi_asm_2.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
bin\th05\maine.exe: bin\th05\maine.obj th05\maine011.cpp th05\regist.cpp th05\staff.cpp bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj
|
||||
$(CC) $(CFLAGS) -ml -DGAME=5 -DBINARY='E' -Z -nbin\th05\ -eMAINE.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
|
|
@ -7,6 +7,8 @@ include libs/master.lib/macros.inc
|
|||
|
||||
GAIJI_PUTSA procdesc pascal far \
|
||||
x:word, y:word, strp_seg:word, strp_off:word, atrb:word
|
||||
GRAPH_PACK_PUT_8_NOCLIP procdesc pascal far \
|
||||
left:word, top:word, linepat_sgm:word, linepat_off:word, len:word
|
||||
GRAPH_PI_FREE procdesc pascal far \
|
||||
header:far ptr, image:far ptr
|
||||
PALETTE_SHOW procdesc pascal far
|
||||
|
|
|
@ -460,6 +460,11 @@ void MASTER_RET palette_white_out(unsigned speed);
|
|||
void MASTER_RET graph_pack_put_8(
|
||||
int x, int y, const void far *linepat, int len
|
||||
);
|
||||
// Copy of graph_pack_put_8() that does not clip the Y coordinate to
|
||||
// the vertical grc_setclip() coordinates.
|
||||
void MASTER_RET graph_pack_put_8_noclip(
|
||||
screen_x_t left, screen_y_t top, const void far *linepat, pixel_t len
|
||||
);
|
||||
#endif
|
||||
// ---
|
||||
|
||||
|
|
|
@ -16,6 +16,43 @@ include th03/arg_bx.inc
|
|||
SHARED_ segment word public 'CODE' use16
|
||||
assume cs:SHARED_
|
||||
|
||||
public PI_PUT_8_ROWLOOP
|
||||
pi_put_8_rowloop proc pascal near
|
||||
; Can't use ARG, because the function doesn't `PUSH BP`!
|
||||
@@stride_packed = word ptr [bp+2]
|
||||
@@w = word ptr [bp+4]
|
||||
@@top = word ptr [bp+6]
|
||||
@@left = word ptr [bp+8]
|
||||
@@h equ di
|
||||
|
||||
mov bp, sp
|
||||
|
||||
@@put_row:
|
||||
push es
|
||||
call graph_pack_put_8_noclip pascal, @@left, @@top, es, si, @@w
|
||||
pop es
|
||||
inc @@top
|
||||
cmp @@top, RES_Y
|
||||
jb short @@next_row
|
||||
sub @@top, RES_Y
|
||||
|
||||
@@next_row:
|
||||
add si, @@stride_packed
|
||||
|
||||
; .PI pointer normalization, see pi_buffer_p_normalize()
|
||||
mov ax, si
|
||||
shr ax, 4
|
||||
mov dx, es
|
||||
add dx, ax
|
||||
mov es, dx
|
||||
and si, 0Fh
|
||||
|
||||
dec @@h
|
||||
jnz short @@put_row
|
||||
retn 8
|
||||
pi_put_8_rowloop endp
|
||||
|
||||
|
||||
public PI_PALETTE_APPLY
|
||||
func pi_palette_apply
|
||||
arg_bx far, @slot:word
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
// Second TH05 .PI C++ translation unit.
|
||||
|
||||
#pragma codeseg SHARED_
|
||||
|
||||
extern "C" {
|
||||
#include <stddef.h>
|
||||
#include "platform.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "master.hpp"
|
||||
#include "th05/formats/pi.h"
|
||||
#include "th05/formats/pi_impl.hpp"
|
||||
|
||||
// Additionally takes:
|
||||
// • `void far *pi_buf` in ES:SI
|
||||
// • `pixel_t h` in DI
|
||||
void pascal near pi_put_8_rowloop(
|
||||
screen_x_t left, vram_y_t top, pixel_t w, size_t stride_packed
|
||||
);
|
||||
|
||||
void DEFCONV pi_put_8(screen_x_t left, vram_y_t top, int slot)
|
||||
{
|
||||
#define rowloop_func __asm { \
|
||||
push left; /* left */ \
|
||||
push top; /* top */ \
|
||||
mov ax, word ptr pi_headers[di].xsize; \
|
||||
push ax; /* w */ \
|
||||
shr ax, 1; \
|
||||
push ax; /* stride_packed */ \
|
||||
mov di, word ptr pi_headers[di].ysize; \
|
||||
call near ptr pi_put_8_rowloop; \
|
||||
}
|
||||
pi_put_impl(left, top, slot, rowloop_func);
|
||||
#undef rowloop_func
|
||||
}
|
||||
|
||||
#pragma codestring "\x90"
|
||||
|
||||
void pascal pi_put_quarter_8(
|
||||
screen_x_t left, vram_y_t top, int slot, int quarter
|
||||
)
|
||||
{
|
||||
#define rowloop_func __asm { \
|
||||
push left; \
|
||||
push top; \
|
||||
push PI_QUARTER_W; \
|
||||
push (PI_W / 2); \
|
||||
mov di, PI_QUARTER_H; \
|
||||
call near ptr pi_put_8_rowloop; \
|
||||
}
|
||||
pi_put_quarter_impl(left, top, slot, quarter, rowloop_func);
|
||||
#undef rowloop_func
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
// Shared parts of the pi_put_*() functions.
|
||||
|
||||
#include "decomp.h"
|
||||
|
||||
inline void imul_di(int8_t factor) {
|
||||
__emit__(0x6B, 0xFF, factor);
|
||||
}
|
||||
|
||||
#define pi_put_impl(left, top, slot, rowloop_func) \
|
||||
_SI = slot; \
|
||||
_DI = _SI; \
|
||||
_SI <<= 2; /* *= sizeof(void far *) */ \
|
||||
__asm { les si, pi_buffers[si]; } \
|
||||
imul_di(sizeof(PiHeader)); \
|
||||
rowloop_func
|
||||
|
||||
#define buffer_offset_off _AX
|
||||
#define buffer_offset_sgm _DX
|
||||
#define quarter_local _CL
|
||||
|
||||
#define pi_put_quarter_impl(left, top, slot, quarter, rowloop_func) \
|
||||
buffer_offset_off = 0; \
|
||||
buffer_offset_sgm = 0; \
|
||||
_SI = slot; \
|
||||
\
|
||||
quarter_local = quarter; \
|
||||
if(quarter_local & 1) { \
|
||||
buffer_offset_off = (PI_QUARTER_W / 2); \
|
||||
} \
|
||||
if(quarter_local & 2) { \
|
||||
/* Careful! Parenthesizing this naively leads to overflows, since */ \
|
||||
/* (PI_QUARTER * PI_W) doesn't fit into 16 bits. */\
|
||||
buffer_offset_sgm = ((PI_QUARTER_H / 2) * (PI_W / 16)); \
|
||||
} \
|
||||
_SI <<= 2; /* *= sizeof(void far *) */ \
|
||||
__asm { les si, pi_buffers[si]; } \
|
||||
_SI += buffer_offset_off; \
|
||||
_ES += buffer_offset_sgm; \
|
||||
rowloop_func
|
|
@ -1,109 +0,0 @@
|
|||
public PI_PUT_8
|
||||
pi_put_8 proc
|
||||
; (PASCAL calling convention, parameter list needs to be reversed here)
|
||||
arg @@slot:word, @@top:word, @@left:word
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
mov si, @@slot
|
||||
mov di, si
|
||||
shl si, 2
|
||||
les si, _pi_buffers[si]
|
||||
imul di, size PiHeader
|
||||
push @@left
|
||||
push @@top
|
||||
mov ax, _pi_headers.PiHeader._xsize[di]
|
||||
push ax
|
||||
shr ax, 1
|
||||
push ax
|
||||
mov di, _pi_headers.PiHeader._ysize[di]
|
||||
call pi_put_8_rowloop
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret 6
|
||||
pi_put_8 endp
|
||||
align 2
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
public PI_PUT_QUARTER_8
|
||||
pi_put_quarter_8 proc
|
||||
; (PASCAL calling convention, parameter list needs to be reversed here)
|
||||
arg @@quarter:byte, @@slot:word, @@top:word, @@left:word
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
push si
|
||||
push di
|
||||
xor ax, ax
|
||||
xor dx, dx
|
||||
mov si, @@slot
|
||||
mov cl, @@quarter
|
||||
test cl, 1
|
||||
jz short @@bottom_quarter?
|
||||
mov ax, 160
|
||||
|
||||
@@bottom_quarter?:
|
||||
test cl, 2
|
||||
jz short @@put
|
||||
mov dx, ((640 * 200) / 2) / 16
|
||||
|
||||
@@put:
|
||||
shl si, 2
|
||||
les si, _pi_buffers[si]
|
||||
add si, ax
|
||||
mov ax, es
|
||||
add ax, dx
|
||||
mov es, ax
|
||||
push @@left
|
||||
push @@top
|
||||
push 320
|
||||
push 320
|
||||
mov di, 200
|
||||
call pi_put_8_rowloop
|
||||
pop di
|
||||
pop si
|
||||
pop bp
|
||||
ret 8
|
||||
pi_put_quarter_8 endp
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
; void pascal pi_put_8_rowloop(
|
||||
; void far *pi_buf<es:si>,
|
||||
; pixel_t h<di>,
|
||||
; screen_x_t x, vram_y_t y, pixel_t w, size_t stride_packed
|
||||
; );
|
||||
pi_put_8_rowloop proc near
|
||||
@@stride_packed = word ptr [bp+2]
|
||||
@@w = word ptr [bp+4]
|
||||
@@top = word ptr [bp+6]
|
||||
@@left = word ptr [bp+8]
|
||||
@@h equ di
|
||||
|
||||
mov bp, sp
|
||||
|
||||
@@put_row:
|
||||
push es
|
||||
call graph_pack_put_8_noclip pascal, @@left, @@top, es, si, @@w
|
||||
pop es
|
||||
inc @@top
|
||||
cmp @@top, RES_Y
|
||||
jb short @@next_row
|
||||
sub @@top, RES_Y
|
||||
|
||||
@@next_row:
|
||||
add si, @@stride_packed
|
||||
mov ax, si
|
||||
shr ax, 4
|
||||
mov dx, es
|
||||
add dx, ax
|
||||
mov es, dx
|
||||
and si, 0Fh
|
||||
dec @@h
|
||||
jnz short @@put_row
|
||||
retn 8
|
||||
pi_put_8_rowloop endp
|
|
@ -0,0 +1 @@
|
|||
#include "th05/formats/pi_cpp_2.cpp"
|
|
@ -7540,7 +7540,8 @@ include th05/snd/load.asm
|
|||
include th05/snd/kajaint.asm
|
||||
include th05/formats/pi_put_masked.asm
|
||||
include th05/formats/pi_load.asm
|
||||
include th05/formats/pi_put.asm
|
||||
extern PI_PUT_8:proc
|
||||
extern PI_PUT_QUARTER_8:proc
|
||||
extern PI_PALETTE_APPLY:proc
|
||||
extern PI_FREE:proc
|
||||
extern GAME_INIT_MAIN:proc
|
||||
|
|
|
@ -2545,7 +2545,7 @@ include th05/snd/load.asm
|
|||
include th05/snd/kajaint.asm
|
||||
include th05/formats/pi_put_masked.asm
|
||||
include th05/formats/pi_load.asm
|
||||
include th05/formats/pi_put.asm
|
||||
extern PI_PUT_8:proc
|
||||
extern PI_PALETTE_APPLY:proc
|
||||
extern PI_FREE:proc
|
||||
extern _game_init_op:proc
|
||||
|
|
Loading…
Reference in New Issue