ReC98/th03/arg_bx.inc

56 lines
2.0 KiB
PHP
Raw Normal View History

; Reimplementation of TASM's ARG directive for those weirdly micro-optimized
; ASM functions that keep their base pointer in BX. The ENTER instruction of
; the original ARG directive is replaced with ´MOV BX, SP`. Afterwards, use
; `ret_bx` to emit the correct `RET` instruction for the given number of
; parameters.
; [distance] must be either NEAR or FAR, matching the function this macro is
; used in.
;
; [params] uses the same colon-separated `name:type` syntax as the original
; ARG directive. Since all of those functions (thankfully) use the Pascal
; calling convention, they need to be declared in reverse order, compared to
; the C declaration.
; Unfortunately, the names can't be prefixed with @@, as that would make them
; local to the macro. Hacking around this with NOLOCALS, PUSHSTATE, and
; POPSTATE would break local labels for the usage code. So, just use a single
; @ instead... or a clean namespace.
;
; MODDERS: Replace with the regular ARG and RET directives in the usage code,
; and delete this file.
arg_bx macro distance:req, params:vararg
; Expanding a text macro on the left side of `=` only seems to work in
; QUIRKS mode?!
PUSHSTATE
QUIRKS
@bp = ((-distance and 0FFFFh) * word)
@sp = @bp
for @@param, params
@@colon_pos instr <@@param>, <:>
@@name substr <@@param>, 1, (@@colon_pos - 1)
@@type substr <@@param>, (@@colon_pos + 1)
@@local_err substr <@@param>, 1, 2
errifidn @@local_err, <@@> "arg_bx: @@ in parameter names is not supported"
; % at the beginning of the line (!) forces expansion of the text
; macro @@name... in QUIRKS mode.
% @@name = @@type ptr ss:[bx+@sp]
; The stack is word-aligned...
@sp = (@sp + ((@@type + 1) and (not 1)))
endm
ret_bx macro
ret (@sp - @bp)
endm
POPSTATE
; This allows `ret_bx` to be used in functions with no parameters as well,
; e.g. if parameters were removed between games. Simply don't pass any
; [params], and this macro will turn itself to a no-op, with `ret_bx` not
; clearing any parameters either.
if (@sp ne @bp)
mov bx, sp
endif
endm