161 lines
3.9 KiB
PHP
161 lines
3.9 KiB
PHP
; Copyright (C) 2025 Elaina Claus
|
|
;
|
|
; This program is free software: you can redistribute it and/or modify
|
|
; it under the terms of the GNU General Public License as published by
|
|
; the Free Software Foundation, either version 3 of the License, or
|
|
; (at your option) any later version.
|
|
;
|
|
; This program is distributed in the hope that it will be useful,
|
|
; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
; GNU General Public License for more details.
|
|
;
|
|
; You should have received a copy of the GNU General Public License
|
|
; along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
%ifnmacro __CDECL16_PROC_ENTRY
|
|
%macro __CDECL16_PROC_ENTRY 0-1
|
|
push bp
|
|
mov bp, sp
|
|
|
|
push si
|
|
push di
|
|
push bx
|
|
|
|
%if %0 = 1
|
|
sub sp, %1 ; reserve locals only when needed
|
|
%endif
|
|
%endmacro
|
|
%endif
|
|
|
|
%ifnmacro __CDECL16_PROC_EXIT
|
|
%macro __CDECL16_PROC_EXIT 0
|
|
pop bx
|
|
pop di
|
|
pop si
|
|
|
|
mov sp, bp
|
|
pop bp
|
|
%endmacro
|
|
%endif
|
|
|
|
; __CDECL16_PROC_ARGS nargs
|
|
; Creates %$arg1 .. %$argN as [bp+4], [bp+6], ...
|
|
; for use inside of function bodies
|
|
%ifnmacro __CDECL16_PROC_ARGS
|
|
%macro __CDECL16_PROC_ARGS 1
|
|
%push __CDECL16_PROC_ARGS
|
|
%assign %$__i 1
|
|
%rep %1
|
|
%xdefine %$arg%$__i [bp + 4 + 2*(%$__i-1)]
|
|
%assign %$__i %$__i + 1
|
|
%endrep
|
|
%pop
|
|
%endmacro
|
|
%endif
|
|
|
|
; __CDECL16_CALL_ARGS a,b,c ==> push c / push b / push a
|
|
; handles pushing values to the stack in the correct order
|
|
%ifnmacro __CDECL16_CALL_ARGS
|
|
%macro __CDECL16_CALL_ARGS 1-*
|
|
%rep %0
|
|
%rotate -1 ; move the last argument into %1
|
|
push %1 ; push last, then next-to-last, ...
|
|
%endrep
|
|
%endmacro
|
|
%endif
|
|
|
|
; __CDECL16_CALL func, nargs ; adds sp by nargs*2 after call
|
|
; adds up word pushes to restore stack frame
|
|
; WARNING: if you push a dword it will only count 2, use __CDECL16_CALL_ARGS_SIZED
|
|
%ifnmacro __CDECL16_CALL
|
|
%macro __CDECL16_CALL 2
|
|
call %1
|
|
add sp, %2*2
|
|
%endmacro
|
|
%endif
|
|
|
|
; __CDECL16_CALL_ARGS_SIZED func, size1[, size2 ...] ; sizes in BYTES
|
|
; if you *need* to pass dword sized args in 16-bit mode, use this to properly
|
|
; count the stack frame to restore later!
|
|
%ifnmacro __CDECL16_CALL_ARGS_SIZED
|
|
%macro __CDECL16_CALL_ARGS_SIZED 2-*
|
|
%push __CDECL16_CALL_ARGS_SIZED
|
|
call %1
|
|
%assign %$__sum 0
|
|
%assign %$__i 2
|
|
%rep %0-1
|
|
%assign %$__sum %$__sum + %[%$__i] ; sizes may be expressions
|
|
%assign %$__i %$__i + 1
|
|
%endrep
|
|
%if %$__sum & 1
|
|
%error "__CDECL16_CALL_ARGS_SIZED: total size is odd; pushes must sum to whole bytes actually pushed (usually even)."
|
|
%endif
|
|
add sp, %$__sum
|
|
%pop
|
|
%endmacro
|
|
%endif
|
|
|
|
|
|
; __CDECL16_INVOKE func, arg1[, arg2 ...]
|
|
; pushes args right-to-left, calls, then add sp by (#args)*2
|
|
; !!! warning for word sized args only !!!
|
|
%ifnmacro __CDECL16_INVOKE
|
|
%macro __CDECL16_INVOKE 1-*
|
|
%push __CDECL16_INVOKE
|
|
%define %$fn %1
|
|
%assign %$argc %0-1
|
|
%rotate -1 ; drop function name; %1.. are args
|
|
%rep %$argc
|
|
%rotate -1
|
|
push %1
|
|
%endrep
|
|
call %$fn
|
|
%if %$argc
|
|
add sp, %$argc*2
|
|
%endif
|
|
%pop
|
|
%endmacro
|
|
%endif
|
|
|
|
%ifnmacro __CDECL16_CLOB
|
|
; Save registers in the order listed. Supports "flags" as a pseudo-reg.
|
|
%macro __CDECL16_CLOB 1-*
|
|
%rep %0
|
|
%ifidni %1, flags
|
|
pushf
|
|
%else
|
|
push %1
|
|
%endif
|
|
%rotate 1
|
|
%endrep
|
|
%endmacro
|
|
%endif
|
|
|
|
%ifnmacro __CDECL16_UNCLOB
|
|
; Restore in reverse order of CLOB. Supports "flags".
|
|
%macro __CDECL16_UNCLOB 1-*
|
|
%rep %0
|
|
%rotate -1
|
|
%ifidni %1, flags
|
|
popf
|
|
%else
|
|
pop %1
|
|
%endif
|
|
%endrep
|
|
%endmacro
|
|
%endif
|
|
|
|
%ifnmacro __FASTCALL16_ENTRY
|
|
%macro __FASTCALL16_ENTRY 0
|
|
push bp
|
|
mov bp, sp
|
|
%endmacro
|
|
%endif
|
|
|
|
%ifnmacro __FASTCALL16_EXIT
|
|
%macro __FASTCALL16_EXIT 0
|
|
mov sp, bp
|
|
pop bp
|
|
%endmacro
|
|
%endif |