diff --git a/decomp.h b/decomp.h index 0fc3819f..773c3559 100644 --- a/decomp.h +++ b/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; } diff --git a/th01/hardware/egc.h b/th01/hardware/egc.h index 8e7baa40..44621f1a 100644 --- a/th01/hardware/egc.h +++ b/th01/hardware/egc.h @@ -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 diff --git a/th04/egcrect.cpp b/th04/egcrect.cpp new file mode 100644 index 00000000..9ad6cd82 --- /dev/null +++ b/th04/egcrect.cpp @@ -0,0 +1 @@ +#include "th04/hardware/egcrect.cpp" diff --git a/th04/hardware/egccopyr[bss].asm b/th04/hardware/egccopyr[bss].asm deleted file mode 100644 index efc9291f..00000000 --- a/th04/hardware/egccopyr[bss].asm +++ /dev/null @@ -1,2 +0,0 @@ -public _egccopyr_width_words -_egccopyr_width_words dw ? diff --git a/th04/hardware/egccopyr.asm b/th04/hardware/egcrect.asm similarity index 85% rename from th04/hardware/egccopyr.asm rename to th04/hardware/egcrect.asm index c2503c16..c3190c1e 100644 --- a/th04/hardware/egccopyr.asm +++ b/th04/hardware/egcrect.asm @@ -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 diff --git a/th04/hardware/egcrect.cpp b/th04/hardware/egcrect.cpp new file mode 100644 index 00000000..cad1aa9a --- /dev/null +++ b/th04/hardware/egcrect.cpp @@ -0,0 +1,128 @@ +#pragma codeseg SHARED_ + +extern "C" { +#include +#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(_BP) + #define w_tmp static_cast(_AX) + #define rows_remaining static_cast(_BX) + #define dots static_cast(_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(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" + +} diff --git a/th04/hardware/egcrect[bss].asm b/th04/hardware/egcrect[bss].asm new file mode 100644 index 00000000..1cdcb3fb --- /dev/null +++ b/th04/hardware/egcrect[bss].asm @@ -0,0 +1,2 @@ +public _egcrect_w +_egcrect_w dw ? diff --git a/th04_op.asm b/th04_op.asm index 2ab4ec46..eeb09010 100644 --- a/th04_op.asm +++ b/th04_op.asm @@ -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 diff --git a/th05/egcrect.cpp b/th05/egcrect.cpp new file mode 100644 index 00000000..9ad6cd82 --- /dev/null +++ b/th05/egcrect.cpp @@ -0,0 +1 @@ +#include "th04/hardware/egcrect.cpp" diff --git a/th05_maine.asm b/th05_maine.asm index a7974296..c53ff77f 100644 --- a/th05_maine.asm +++ b/th05_maine.asm @@ -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 ? diff --git a/th05_op.asm b/th05_op.asm index d90e9898..41784ffc 100644 --- a/th05_op.asm +++ b/th05_op.asm @@ -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(?)