[Decompilation] [th01] Background + foreground VRAM blit functions

Yes, functions! Those would have been nice earlier!
Also documented another overly specific Borland C++ code generation
quirk with regard to assigning expression results to elements of 16-bit
arrays…

Part of P0107, funded by Yanga.
This commit is contained in:
nmlgc 2020-08-06 20:23:52 +02:00
parent 34a5f4d183
commit 816ba8342c
3 changed files with 81 additions and 158 deletions

View File

@ -88,6 +88,33 @@ case it's part of an arithmetic expression that was promoted to `int`.
ret = (3.14 > f); // FLD 3.14, FCOMP f + 4
```
## Assignments
* When assigning to a array element at a variable or non-0 index, the array
element address is typically evaluated before the expression to be assigned.
But when assigning
* the result of any arithmetic expression of a *16-bit type*
* to an element of a `far` array of a *16-bit type*,
the expression will be evaluated first, if its signedness differs from that
of the array:
```c
int far *s;
unsigned int far *u;
int s1, s2;
unsigned int u1, u2;
s[1] = (s1 | s2); // LES BX, [s]; MOV AX, s1; OR AX, s2; MOV ES:[BX+2], AX
s[1] = (s1 | u2); // MOV AX, s1; OR AX, u2; LES BX, [s]; MOV ES:[BX+2], AX
s[1] = (u1 | u2); // MOV AX, u1; OR AX, u2; LES BX, [s]; MOV ES:[BX+2], AX
u[1] = (s1 | s2); // MOV AX, s1; OR AX, s2; LES BX, [u]; MOV ES:[BX+2], AX
u[1] = (s1 | u2); // LES BX, [u]; MOV AX, s1; OR AX, u2; MOV ES:[BX+2], AX
u[1] = (u1 | u2); // LES BX, [u]; MOV AX, u1; OR AX, u2; MOV ES:[BX+2], AX
```
## `switch` statements
* Sequence of the individual cases is identical in both C and ASM

View File

@ -192,4 +192,29 @@ void CBossEntity::put_1line(int left, int y, int image, int row) const
bos_p++;
}
}
void pascal near vram_snap_masked(
dots16_t &dst, dots8_t plane[], uint16_t vram_offset, dots16_t mask
)
{
dst = (reinterpret_cast<dots16_t &>(plane[vram_offset]) & mask);
}
void pascal near vram_put_bg_fg(
sdots16_t fg, dots8_t plane[], uint16_t vram_offset, sdots16_t bg_masked
)
{
reinterpret_cast<dots16_t &>(plane[vram_offset]) = (fg | bg_masked);
}
void pascal near vram_put_unaligned_bg_fg(
sdots16_t fg,
dots8_t plane[],
uint16_t vram_offset,
uint16_t bg_masked,
char first_bit
)
{
sdots16_t fg_shifted = (fg >> first_bit) + (fg << (16 - first_bit));
reinterpret_cast<dots16_t &>(plane[vram_offset]) = (fg_shifted | bg_masked);
}
/// --------

View File

@ -8877,6 +8877,11 @@ main_21_TEXT segment byte public 'CODE' use16
extern @CBossEntity@bos_metadata_get$xqmimuct1t1:proc
extern @CBossEntity@put_8$xqiii:proc
extern @CBossEntity@put_1line$xqiiii:proc
VRAM_SNAP_MASKED procdesc pascal near
VRAM_PUT_BG_FG procdesc pascal near \
fg:word, plane:dword, vram_offset:word, bg_masked:word
VRAM_PUT_UNALIGNED_BG_FG procdesc pascal near \
fg:word, plane:dword, vram_offset:word, bg_masked:word, first_bit:byte
main_21_TEXT ends
main_21__TEXT segment byte public 'CODE' use16
@ -8884,88 +8889,6 @@ main_21__TEXT segment byte public 'CODE' use16
;org 4
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_15C80 proc near
arg_0 = word ptr 4
arg_2 = word ptr 6
arg_4 = dword ptr 8
arg_8 = dword ptr 0Ch
push bp
mov bp, sp
les bx, [bp+arg_4]
add bx, [bp+arg_2]
mov ax, es:[bx]
and ax, [bp+arg_0]
les bx, [bp+arg_8]
mov es:[bx], ax
pop bp
retn 0Ch
sub_15C80 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_15C99 proc near
arg_0 = word ptr 4
arg_2 = word ptr 6
arg_4 = dword ptr 8
arg_8 = word ptr 0Ch
push bp
mov bp, sp
mov ax, [bp+arg_8]
or ax, [bp+arg_0]
les bx, [bp+arg_4]
add bx, [bp+arg_2]
mov es:[bx], ax
pop bp
retn 0Ah
sub_15C99 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_15CAF proc near
var_2 = word ptr -2
arg_0 = byte ptr 4
arg_2 = word ptr 6
arg_4 = word ptr 8
arg_6 = dword ptr 0Ah
arg_A = word ptr 0Eh
enter 2, 0
push si
mov si, [bp+arg_A]
mov ax, si
mov cl, [bp+arg_0]
sar ax, cl
mov cl, 10h
sub cl, [bp+arg_0]
mov dx, si
shl dx, cl
add ax, dx
mov [bp+var_2], ax
les bx, [bp+arg_6]
add bx, [bp+arg_4]
or ax, [bp+arg_2]
mov es:[bx], ax
pop si
leave
retn 0Ch
sub_15CAF endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -9107,51 +9030,35 @@ loc_15D71:
pushd [_VRAM_PLANE_B]
push si
push [bp+var_20]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_E]
push ax
pushd [_VRAM_PLANE_R]
push si
push [bp+var_20]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_C]
push ax
pushd [_VRAM_PLANE_G]
push si
push [bp+var_20]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_A]
push ax
pushd [_VRAM_PLANE_E]
push si
push [bp+var_20]
call sub_15C80
call vram_snap_masked
push 0
call _graph_accesspage_func
add sp, 4
push [bp+var_1E]
pushd [_VRAM_PLANE_B]
push si
push [bp+var_10]
call sub_15C99
push [bp+var_1C]
pushd [_VRAM_PLANE_R]
push si
push [bp+var_E]
call sub_15C99
push [bp+var_1A]
pushd [_VRAM_PLANE_G]
push si
push [bp+var_C]
call sub_15C99
push [bp+var_18]
pushd [_VRAM_PLANE_E]
push si
push [bp+var_A]
call sub_15C99
call vram_put_bg_fg pascal, [bp+var_1E], large [_VRAM_PLANE_B], si, [bp+var_10]
call vram_put_bg_fg pascal, [bp+var_1C], large [_VRAM_PLANE_R], si, [bp+var_E]
call vram_put_bg_fg pascal, [bp+var_1A], large [_VRAM_PLANE_G], si, [bp+var_C]
call vram_put_bg_fg pascal, [bp+var_18], large [_VRAM_PLANE_E], si, [bp+var_A]
jmp loc_15F2C
; ---------------------------------------------------------------------------
@ -9172,55 +9079,35 @@ loc_15E7A:
pushd [_VRAM_PLANE_B]
push si
push [bp+var_12]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_E]
push ax
pushd [_VRAM_PLANE_R]
push si
push [bp+var_12]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_C]
push ax
pushd [_VRAM_PLANE_G]
push si
push [bp+var_12]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_A]
push ax
pushd [_VRAM_PLANE_E]
push si
push [bp+var_12]
call sub_15C80
call vram_snap_masked
push 0
call _graph_accesspage_func
add sp, 4
push [bp+var_1E]
pushd [_VRAM_PLANE_B]
push si
push [bp+var_10]
push [bp+var_7]
call sub_15CAF
push [bp+var_1C]
pushd [_VRAM_PLANE_R]
push si
push [bp+var_E]
push [bp+var_7]
call sub_15CAF
push [bp+var_1A]
pushd [_VRAM_PLANE_G]
push si
push [bp+var_C]
push [bp+var_7]
call sub_15CAF
push [bp+var_18]
pushd [_VRAM_PLANE_E]
push si
push [bp+var_A]
push [bp+var_7]
call sub_15CAF
call vram_put_unaligned_bg_fg pascal, [bp+var_1E], large [_VRAM_PLANE_B], si, [bp+var_10], [bp+var_7]
call vram_put_unaligned_bg_fg pascal, [bp+var_1C], large [_VRAM_PLANE_R], si, [bp+var_E], [bp+var_7]
call vram_put_unaligned_bg_fg pascal, [bp+var_1A], large [_VRAM_PLANE_G], si, [bp+var_C], [bp+var_7]
call vram_put_unaligned_bg_fg pascal, [bp+var_18], large [_VRAM_PLANE_E], si, [bp+var_A], [bp+var_7]
loc_15F2C:
add si, 2
@ -10059,7 +9946,7 @@ loc_16596:
add ax, ax
add bx, ax
push word ptr es:[bx]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_E]
push ax
@ -10071,7 +9958,7 @@ loc_16596:
add ax, ax
add bx, ax
push word ptr es:[bx]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_C]
push ax
@ -10083,7 +9970,7 @@ loc_16596:
add ax, ax
add bx, ax
push word ptr es:[bx]
call sub_15C80
call vram_snap_masked
push ss
lea ax, [bp+var_A]
push ax
@ -10095,7 +9982,7 @@ loc_16596:
add ax, ax
add bx, ax
push word ptr es:[bx]
call sub_15C80
call vram_snap_masked
push 0
call _graph_accesspage_func
add sp, 4
@ -10104,41 +9991,25 @@ loc_16596:
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx+bos_image_t.BOS_B]
pushd [_VRAM_PLANE_B]
push si
push [bp+var_10]
call sub_15C99
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_B], si, [bp+var_10]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_R]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
pushd [_VRAM_PLANE_R]
push si
push [bp+var_E]
call sub_15C99
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_R], si, [bp+var_E]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_G]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
pushd [_VRAM_PLANE_G]
push si
push [bp+var_C]
call sub_15C99
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_G], si, [bp+var_C]
les bx, [bp+@@bos]
les bx, es:[bx+bos_image_t.BOS_E]
mov ax, di
add ax, ax
add bx, ax
push word ptr es:[bx]
pushd [_VRAM_PLANE_E]
push si
push [bp+var_A]
call sub_15C99
call vram_put_bg_fg pascal, word ptr es:[bx], large [_VRAM_PLANE_E], si, [bp+var_A]
add si, 2
loc_166AA: