mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th04/th05] EGC-powered page 1→0 rectangle blitting
Actually fairly average, as far as unreasonable decompilations are
concerned. No `goto`, at least! Another place that would benefit from
EGC raster op documentation, though.
Also, got one more padding byte in TH05's MAINE.EXE correct. 🙂
Part of P0126, funded by [Anonymous] and Blue Bolt.
This commit is contained in:
parent
b504d72301
commit
baac3f7682
4
decomp.h
4
decomp.h
|
@ -10,6 +10,7 @@
|
|||
// these assemble into the single given instruction. Apply the ! operator to
|
||||
// get the N versions.
|
||||
#define FLAGS_ZERO (_FLAGS & 0x40) /* JZ */
|
||||
#define FLAGS_SIGN (_FLAGS & 0x80) /* JS */
|
||||
// ----------------
|
||||
|
||||
// Alternate version that doesn't spill the port number to DX
|
||||
|
@ -24,3 +25,6 @@
|
|||
mov dx, port; \
|
||||
out dx, ax; \
|
||||
}
|
||||
|
||||
// Versions that actually inline with pseudoregisters
|
||||
#define pokew(sgm, off, val) { *(uint16_t far *)(MK_FP(sgm, off)) = val; }
|
||||
|
|
|
@ -32,10 +32,13 @@
|
|||
outport2(EGC_ADDRRESSREG, 0); \
|
||||
outport2(EGC_BITLENGTHREG, 0xF);
|
||||
|
||||
// Blits the rectangle from (⌊x/16⌋*16, y) to (⌈((x + w)/16)*16⌉, (y + h))
|
||||
// Blits the rectangle from
|
||||
// (⌊left/16⌋*16, top)
|
||||
// to
|
||||
// (⌈((left + w)/16)*16⌉, (top + h))
|
||||
// from VRAM page 1 to the same position on VRAM page 0.
|
||||
void DEFCONV egc_copy_rect_1_to_0_16(
|
||||
screen_x_t x, vram_y_t y, pixel_t w, pixel_t h
|
||||
screen_x_t left, vram_y_t top, pixel_t w, pixel_t h
|
||||
);
|
||||
|
||||
// Blits [h] rows starting at [top] from VRAM page 1 to the same position on
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "th04/hardware/egcrect.cpp"
|
|
@ -1,2 +0,0 @@
|
|||
public _egccopyr_width_words
|
||||
_egccopyr_width_words dw ?
|
|
@ -1,3 +1,4 @@
|
|||
; (TH04 version only, until that one gets linked in)
|
||||
public EGC_COPY_RECT_1_TO_0_16
|
||||
egc_copy_rect_1_to_0_16 proc far
|
||||
|
||||
|
@ -12,9 +13,7 @@ egc_copy_rect_1_to_0_16 proc far
|
|||
push bp
|
||||
mov bp, sp
|
||||
push di
|
||||
if GAME eq 4
|
||||
cld
|
||||
endif
|
||||
call egc_start_copy
|
||||
outw EGC_MODE_ROP_REG, EGC_COMPAREREAD or EGC_WS_ROP or EGC_RL_MEMREAD or 0F0h
|
||||
mov ax, @@x
|
||||
|
@ -36,7 +35,7 @@ endif
|
|||
inc ax
|
||||
|
||||
@@x_on_word_boundary:
|
||||
mov _egccopyr_width_words, ax
|
||||
mov _egcrect_w, ax
|
||||
mov cx, (ROW_SIZE / 2)
|
||||
sub cx, ax
|
||||
shl cx, 1
|
||||
|
@ -47,29 +46,16 @@ endif
|
|||
assume es:nothing
|
||||
|
||||
@@next_row:
|
||||
mov cx, _egccopyr_width_words
|
||||
mov cx, _egcrect_w
|
||||
|
||||
@@next_word:
|
||||
if GAME eq 5
|
||||
or di, di
|
||||
js short @@skip
|
||||
cmp di, PLANE_SIZE
|
||||
jnb short @@skip
|
||||
endif
|
||||
mov al, 1
|
||||
out 0A6h, al
|
||||
mov dx, es:[di]
|
||||
xor ax, ax
|
||||
out 0A6h, al
|
||||
if GAME eq 5
|
||||
mov es:[di], dx
|
||||
|
||||
@@skip:
|
||||
add di, 2
|
||||
else
|
||||
mov ax, dx
|
||||
stosw
|
||||
endif
|
||||
loop @@next_word
|
||||
add di, @@stride
|
||||
dec @@row
|
||||
|
@ -104,3 +90,4 @@ egc_start_copy proc near
|
|||
outw EGC_BITLENGTHREG, 0Fh
|
||||
retn
|
||||
egc_start_copy endp
|
||||
even
|
|
@ -0,0 +1,128 @@
|
|||
#pragma codeseg SHARED_
|
||||
|
||||
extern "C" {
|
||||
#include <dos.h>
|
||||
#include "platform.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "decomp.h"
|
||||
#include "master.hpp"
|
||||
#include "th01/hardware/egc.h"
|
||||
|
||||
#define graph_accesspage_1() \
|
||||
outportb2(0xA6, 1);
|
||||
|
||||
#define graph_accesspage_0() \
|
||||
_AX ^= _AX; \
|
||||
__asm out 0xA6, al;
|
||||
|
||||
extern vram_word_amount_t egcrect_w;
|
||||
|
||||
static void near egc_start_copy(void);
|
||||
|
||||
void DEFCONV egc_copy_rect_1_to_0_16(
|
||||
screen_x_t left, vram_y_t top, pixel_t w, pixel_t h
|
||||
)
|
||||
{
|
||||
#define vo_tmp _BX // vram_offset_t
|
||||
#define first_bit _CX
|
||||
#define stride static_cast<vram_byte_amount_t>(_BP)
|
||||
#define w_tmp static_cast<vram_word_amount_t>(_AX)
|
||||
#define rows_remaining static_cast<pixel_t>(_BX)
|
||||
#define dots static_cast<dots16_t>(_DX)
|
||||
|
||||
#if (GAME == 4)
|
||||
// TH04 wants to blit using a forward STOSW (DF = 0)
|
||||
__asm { cld; }
|
||||
#endif
|
||||
egc_start_copy();
|
||||
egc_setrop(EGC_COMPAREREAD | EGC_WS_ROP | EGC_RL_MEMREAD | 0xF0);
|
||||
|
||||
// Using inline assembly rather than register pseudovariables to prevent
|
||||
// parameters from being moved to the SI register
|
||||
__asm mov ax, left;
|
||||
__asm mov dx, top;
|
||||
|
||||
vo_tmp = _AX;
|
||||
static_cast<vram_offset_t>(vo_tmp) >>= 4;
|
||||
__asm shl bx, 1;
|
||||
_DX <<= 6;
|
||||
vo_tmp += _DX;
|
||||
_DX >>= 2;
|
||||
vo_tmp += _DX;
|
||||
|
||||
_DI = vo_tmp;
|
||||
_AX &= ((BYTE_DOTS * 2) - 1);
|
||||
first_bit = _AX;
|
||||
|
||||
w_tmp = ((_AX + w) >> 4);
|
||||
if(first_bit) {
|
||||
w_tmp++;
|
||||
}
|
||||
egcrect_w = w_tmp;
|
||||
|
||||
_CX = (ROW_SIZE / 2);
|
||||
_CX -= w_tmp;
|
||||
__asm shl cx, 1;
|
||||
rows_remaining = h;
|
||||
stride = _CX;
|
||||
_ES = SEG_PLANE_B;
|
||||
|
||||
do {
|
||||
_CX = egcrect_w;
|
||||
put_loop: {
|
||||
#if (GAME == 5)
|
||||
_DI |= _DI;
|
||||
if((!FLAGS_SIGN) && (_DI < PLANE_SIZE)) {
|
||||
graph_accesspage_1(); dots = peek(_ES, _DI);
|
||||
graph_accesspage_0(); pokew(_ES, _DI, dots);
|
||||
}
|
||||
_DI += 2;
|
||||
#else
|
||||
graph_accesspage_1(); dots = peek(_ES, _DI);
|
||||
graph_accesspage_0(); _AX = dots; __asm { stosw; }
|
||||
#endif
|
||||
__asm { loop put_loop; }
|
||||
}
|
||||
_DI += stride;
|
||||
rows_remaining--;
|
||||
} while(!FLAGS_SIGN);
|
||||
egc_off();
|
||||
}
|
||||
|
||||
#pragma codestring "\x90"
|
||||
#pragma option -k-
|
||||
|
||||
static void near egc_start_copy(void)
|
||||
{
|
||||
__asm {
|
||||
push es
|
||||
push 0
|
||||
pop es
|
||||
pushf
|
||||
cli
|
||||
|
||||
// The EGC does in fact require an active GRCG in TDW mode.
|
||||
// (See PC-9801 Programmers' Bible, p. 456)
|
||||
mov al, GC_TDW
|
||||
out 0x7C, al // grcg_setmode()
|
||||
|
||||
// According to MEMSYS.TXT, GRCG mode changes should always be
|
||||
// reflected in this memory location, for compatibility with interrupt
|
||||
// routines?
|
||||
mov byte ptr es:[0x495], al
|
||||
popf
|
||||
pop es
|
||||
}
|
||||
graph_egc_on();
|
||||
outport(EGC_ACTIVEPLANEREG, 0xFFF0);
|
||||
egc_selectpat();
|
||||
outport(EGC_MASKREG, 0xFFFF);
|
||||
_DX = EGC_ADDRRESSREG;
|
||||
outport(_DX, (_AX - _AX)); // :zunpet:
|
||||
outport(EGC_BITLENGTHREG, 0xF);
|
||||
}
|
||||
|
||||
#pragma codestring "\x90"
|
||||
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
public _egcrect_w
|
||||
_egcrect_w dw ?
|
|
@ -2664,8 +2664,7 @@ include th02/initop.asm
|
|||
include th04/formats/cdg_put_noalpha.asm
|
||||
include th04/hardware/input_sense.asm
|
||||
include th04/snd/se.asm
|
||||
include th04/hardware/egccopyr.asm
|
||||
even
|
||||
include th04/hardware/egcrect.asm
|
||||
include th04/bgimage.asm
|
||||
include th04/bgimage_put_rect.asm
|
||||
include th04/formats/cdg_load.asm
|
||||
|
@ -2933,7 +2932,7 @@ include libs/master.lib/bgm[bss].asm
|
|||
include th02/snd/load[bss].asm
|
||||
include th04/mem[bss].asm
|
||||
include th04/hardware/input[bss].asm
|
||||
include th04/hardware/egccopyr[bss].asm
|
||||
include th04/hardware/egcrect[bss].asm
|
||||
include th04/formats/cdg[bss].asm
|
||||
include th04/setup[bss].asm
|
||||
include th04/zunsoft[bss].asm
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
#include "th04/hardware/egcrect.cpp"
|
|
@ -7554,7 +7554,7 @@ include th05/snd/delaymea.asm
|
|||
include th05/hardware/frame_delay.asm
|
||||
db 0
|
||||
include th04/formats/cdg_load.asm
|
||||
include th04/hardware/egccopyr.asm
|
||||
extern EGC_COPY_RECT_1_TO_0_16:proc
|
||||
SHARED_ ends
|
||||
|
||||
.data
|
||||
|
@ -7887,7 +7887,7 @@ include th05/formats/pi_headers[bss].asm
|
|||
include th04/hardware/input[bss].asm
|
||||
include th04/formats/cdg[bss].asm
|
||||
include libs/master.lib/pfint21[bss].asm
|
||||
include th04/hardware/egccopyr[bss].asm
|
||||
include th04/hardware/egcrect[bss].asm
|
||||
include th04/end/cutscene_script[bss].asm
|
||||
db 4 dup(?)
|
||||
byte_14F8E db ?
|
||||
|
|
|
@ -2562,8 +2562,7 @@ include th04/formats/cdg_put_nocolors.asm
|
|||
include th05/hardware/frame_delay.asm
|
||||
db 0
|
||||
include th04/formats/cdg_load.asm
|
||||
include th04/hardware/egccopyr.asm
|
||||
even
|
||||
extern EGC_COPY_RECT_1_TO_0_16:proc
|
||||
SHARED_ ends
|
||||
|
||||
.data
|
||||
|
@ -3260,7 +3259,7 @@ include th05/formats/pi_headers[bss].asm
|
|||
include th04/hardware/input[bss].asm
|
||||
include th04/formats/cdg[bss].asm
|
||||
include libs/master.lib/pfint21[bss].asm
|
||||
include th04/hardware/egccopyr[bss].asm
|
||||
include th04/hardware/egcrect[bss].asm
|
||||
include th04/setup[bss].asm
|
||||
include th04/zunsoft[bss].asm
|
||||
db 104 dup(?)
|
||||
|
|
Loading…
Reference in New Issue