FreeDOS/test/lmacros/lmacros3.mac

140 lines
3.3 KiB
Plaintext
Raw Normal View History

[list -]
%if 0
Extensions to NASM macro collection
Public Domain by C. Masloch, 2019
Intended for 86 Mode programs.
%endif
%ifndef __lMACROS3_MAC__
%assign __lMACROS3_MAC__ 1
%include "lmacros2.mac"
[list -]
; This macro is used to generate byte or word access to specific
; bits of a dword variable.
; %1 = token: if "~", bit value will be negated after checking
; %2 = instruction
; %3 = variable, in the form "[address]" without size specification
; %4 = bit value(s) to access
; %5 = bool: disable word access warning, defaults to 0
; If the value in %4 has bits set in different bytes so that
; a single 8- or 16-bit instruction cannot access all the bits,
; an error is displayed. This insures that the macro only has
; to generate one instruction, as a 32-bit access on 16-bit
; CPUs requires multiple instructions. This workaround code
; needs to be written specifically then, or the flags have to
; be re-ordered to allow the access.
%macro _opt 4-5.nolist 0
%push
%defstr %$adr %3
%strlen %$len %$adr
%substr %$tf %$adr 1
%substr %$tb %$adr %$len
%substr %$adr %$adr 2,-2
%deftok %$adr %$adr
%%num: equ %4
%assign %$num %%num
%ifnidn %$tf,"["
%error Invalid memory access syntax
%elifnidn %$tb,"]"
%error Invalid memory access syntax
%elifn %$num
%error Bit value is zero! Check code.
%elifn (%$num) & ~0FFh
%2 byte [%$adr], %1(%$num)
%elifn (%$num) & ~0FF00h
%2 byte [%$adr+1], %1((%$num)>>8)
%elifn (%$num) & ~0FF0000h
%2 byte [%$adr+2], %1((%$num)>>16)
%elifn (%$num) & ~0FF000000h
%2 byte [%$adr+3], %1((%$num)>>24)
%elifn (%$num) & ~0FFFFh
%ifn %5
%warning Macro generated word access
%endif
%2 word [%$adr], %1(%$num)
%elifn (%$num) & ~0FFFF00h
%ifn %5
%warning Macro generated word access
%endif
%2 word [%$adr+1], %1((%$num)>>8)
%elifn (%$num) & ~0FFFF0000h
%ifn %5
%warning Macro generated word access
%endif
%2 word [%$adr+2], %1((%$num)>>16)
%else
%error Unsupported macro usage, requires dword:
%ifempty %1
%error %2 dword [%$adr], %$num
%else
%error %2 dword [%$adr], %1(%$num)
%endif
%endif
%pop
%endmacro
; User forms for above macro.
; %1 = variable, in the form "[address]" without size specification
; %2 = bit value(s) to access
; %3 = bool: disable word access warning, defaults to 0
; testopt tests the specified bits (using a "test" instruction) and
; leaves a meaningful result in ZF, as well as NC.
; clropt clears the specified bits (using an "and" instruction with
; the negated value) and leaves NC, but a random ZF.
; setopt sets the specified bits (using an "or" instruction) and
; leaves NC, NZ.
; xoropt toggles the specified bits (using a "xor" instruction) and
; leaves NC, but a random ZF.
%idefine testopt _opt ,test,
%idefine clropt _opt ~,and,
%idefine setopt _opt ,or,
%idefine xoropt _opt ,xor,
%imacro addsection 1-2.nolist
%ifdef _SECTION_ADDED_%1
%error Section %1 already added
%endif
section %1 %2
%define _SECTION_ADDED_%1 1
usesection %1
%endmacro
%imacro usesection 1-2.nolist 0
%ifndef _SECTION_ADDED_%1
%error Section %1 not yet added
%endif
%if %2
%define _CURRENT_SECTION
[section %1]
%else
%xdefine _CURRENT_SECTION %1
section %1
%endif
%endmacro
%macro subcpu 1.nolist
%push SUBCPU
%xdefine %$CPU_PREV __CPU__
cpu %1
%endmacro
%macro subcpureset 0.nolist
%ifnctx SUBCPU
%error Wrong context
%endif
%xdefine __CPU__ %$CPU_PREV
%pop
__CPU__
%endmacro
%endif
[list +]