; $Id: bootsector2-template-header.mac $
;; @file
; bootsector2 header for multi-mode code templates.
;

;
; Copyright (C) 2007-2023 Oracle and/or its affiliates.
;
; This file is part of VirtualBox base platform packages, as
; available from https://www.virtualbox.org.
;
; 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, in version 3 of the
; License.
;
; 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>.
;
; The contents of this file may alternatively be used under the terms
; of the Common Development and Distribution License Version 1.0
; (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
; in the VirtualBox distribution, in which case the provisions of the
; CDDL are applicable instead of those of the GPL.
;
; You may elect to license modified versions of this file under the
; terms and conditions of either the GPL or the CDDL or both.
;
; SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
;

;
; Check and expand the mode defines.
; One of the following must be defined:
;       - TMPL_RM    - real mode.
;       - TMPL_PE16  - 16-bit protected mode, unpaged.
;       - TMPL_PE32  - 32-bit protected mode, unpaged.
;       - TMPL_PEV86 - virtual 8086 mode under protected mode, unpaged.
;       - TMPL_PP16  - 16-bit protected mode, paged.
;       - TMPL_PP32  - 32-bit protected mode, paged.
;       - TMPL_PPV86 - virtual 8086 mode under protected mode, paged.
;       - TMPL_PAE16 - 16-bit protected mode with PAE (paged).
;       - TMPL_PAE32 - 16-bit protected mode with PAE (paged).
;       - TMPL_PAEV86- virtual 8086 mode under protected mode with PAE (paged).
;       - TMPL_LM16  - 16-bit long mode (paged).
;       - TMPL_LM32  - 32-bit long mode (paged).
;       - TMPL_LM64  - 64-bit long mode (paged).
;
; Derived indicators:
;       - TMPL_CMN_PE  = TMPL_PE16  | TMPL_PE32  | TMPL_PEV86
;       - TMPL_CMN_PP  = TMPL_PP16  | TMPL_PP32  | TMPL_PPV86
;       - TMPL_CMN_PAE = TMPL_PAE16 | TMPL_PAE32 | TMPL_PAEV86
;       - TMPL_CMN_LM  = TMPL_LM16  | TMPL_LM32  | TMPL_LM64
;       - TMPL_CMN_V86 = TMPL_PEV86 | TMPL_PPV86 | TMPL_PAEV86
;       - TMPL_CMN_R86 = TMPL_CMN_V86 | TMPL_RM
;
%ifdef TMPL_RM
 %ifdef TMPL_PE16
  %error "Both 'TMPL_RM' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_RM' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_RM' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_RM' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_RM' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_RM' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_RM' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_RM' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_RM' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_RM' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_RM' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_RM' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _rm
 %define TMPL_NM_CMN(Name)      Name %+ _r86
 %define TMPL_MODE_STR          'real mode'
 %define TMPL_HAVE_BIOS
 %define TMPL_CMN_R86
%endif

%ifdef TMPL_PE16
 %ifdef TMPL_RM
  %error "Both 'TMPL_PE16' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PE16' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_RM' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PE16' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PE16' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PE16' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PE16' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PE16' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PE32' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PE16' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PE16' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PE16' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PE
 %define TMPL_CMN_P16
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _pe16
 %define TMPL_NM_CMN(Name)      Name %+ _p16
 %define TMPL_MODE_STR          '16-bit unpaged protected mode'
%endif

%ifdef TMPL_PE32
 %ifdef TMPL_RM
  %error "Both 'TMPL_PE32' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PE32' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PE32' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PE32' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PE32' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PE32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PE32' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PE32' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAE86
  %error "Both 'TMPL_PE32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PE32' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PE32' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PE32' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PE
 %define TMPL_CMN_P32
 %define TMPL_32BIT
 %define TMPL_BITS              32
 %define TMPL_PTR_DEF           dd
 %define TMPL_NM(Name)          Name %+ _pe32
 %define TMPL_NM_CMN(Name)      Name %+ _p32
 %define TMPL_MODE_STR          '32-bit unpaged protected mode'
%endif

%ifdef TMPL_PEV86
 %ifdef TMPL_RM
  %error "Both 'TMPL_PEV86' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PEV86' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PEV86' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PEV86' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PEV86' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PEV86' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PEV86' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PEV86' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAE86
  %error "Both 'TMPL_PEV86' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PEV86' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PEV86' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PEV86' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PE
 %define TMPL_CMN_V86
 %define TMPL_CMN_R86
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _pev86
 %define TMPL_NM_CMN(Name)      Name %+ _r86
 %define TMPL_MODE_STR          'v8086 unpaged protected mode'
%endif

%ifdef TMPL_PP16
 %ifdef TMPL_RM
  %error "Both 'TMPL_PP16' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PP16' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PP16' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PP16' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PP16' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PP32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PP16' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PP16' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PP16' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PP16' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PP16' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PP16' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PP
 %define TMPL_CMN_P16
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _pp16
 %define TMPL_NM_CMN(Name)      Name %+ _p16
 %define TMPL_MODE_STR          '16-bit paged protected mode'
%endif

%ifdef TMPL_PP32
 %ifdef TMPL_RM
  %error "Both 'TMPL_PP32' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PP32' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PP32' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PP32' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PP32' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PP32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PP32' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PP32' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PP32' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PP32' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PP32' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PP32' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PP
 %define TMPL_CMN_P32
 %define TMPL_32BIT
 %define TMPL_BITS              32
 %define TMPL_PTR_DEF           dd
 %define TMPL_NM(Name)          Name %+ _pp32
 %define TMPL_NM_CMN(Name)      Name %+ _p32
 %define TMPL_MODE_STR          '32-bit paged protected mode'
%endif

%ifdef TMPL_PPV86
 %ifdef TMPL_RM
  %error "Both 'TMPL_PPV86' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PPV86' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PPV86' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PPV86' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PPV86' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PPV86' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PPV86' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PPV86' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PPV86' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PPV86' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PPV86' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PPV86' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PP
 %define TMPL_CMN_V86
 %define TMPL_CMN_R86
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _ppv86
 %define TMPL_NM_CMN(Name)      Name %+ _r86
 %define TMPL_MODE_STR          'v8086 paged protected mode'
%endif

%ifdef TMPL_PAE16
 %ifdef TMPL_RM
  %error "Both 'TMPL_PAE16' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PAE16' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PAE16' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PAE16' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PAE16' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PAE16' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PAE16' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_PAE16' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PAE16' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PAE16' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PAE16' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PAE16' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PAE
 %define TMPL_16BIT
 %define TMPL_CMN_P16
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _pae16
 %define TMPL_NM_CMN(Name)      Name %+ _p16
 %define TMPL_MODE_STR          '16-bit pae protected mode'
%endif

%ifdef TMPL_PAE32
 %ifdef TMPL_RM
  %error "Both 'TMPL_PAE32' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PAE32' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PAE32' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PAE32' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PAE32' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PAE32' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PAE32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PAE32' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PAE32' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PAE32' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PAE32' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PAE32' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PAE
 %define TMPL_CMN_P32
 %define TMPL_32BIT
 %define TMPL_BITS              32
 %define TMPL_PTR_DEF           dd
 %define TMPL_NM(Name)          Name %+ _pae32
 %define TMPL_NM_CMN(Name)      Name %+ _p32
 %define TMPL_MODE_STR          '32-bit pae protected mode'
%endif

%ifdef TMPL_PAEV86
 %ifdef TMPL_RM
  %error "Both 'TMPL_PAEV86' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_PAEV86' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_PAEV86' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_PAEV86' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_PAEV86' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_PAEV86' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_PAEV86' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_PAEV86' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_PAEV86' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_PAEV86' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_PAEV86' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_PAEV86' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_PAE
 %define TMPL_CMN_V86
 %define TMPL_CMN_R86
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _paev86
 %define TMPL_NM_CMN(Name)      Name %+ _r86
 %define TMPL_MODE_STR          'v8086 pae protected mode'
%endif

%ifdef TMPL_LM16
 %ifdef TMPL_RM
  %error "Both 'TMPL_LM16' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_LM16' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_LM16' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_LM16' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_LM16' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_LM16' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_LM16' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_LM16' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_LM16' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_LM16' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_LM16' and 'TMPL_LM32' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_LM16' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_LM
 %define TMPL_CMN_P16
 %define TMPL_16BIT
 %define TMPL_BITS              16
 %define TMPL_PTR_DEF           dw
 %define TMPL_NM(Name)          Name %+ _lm16
 %define TMPL_NM_CMN(Name)      Name %+ _p16
 %define TMPL_MODE_STR          '16-bit long mode'
%endif

%ifdef TMPL_LM32
 %ifdef TMPL_RM
  %error "Both 'TMPL_LM32' and 'TMPL_RM' are defined."
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_LM32' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_LM32' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_LM32' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_LM32' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_LM32' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_LM32' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_LM32' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_LM32' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_LM32' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_LM32' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM64
  %error "Both 'TMPL_LM32' and 'TMPL_LM64' are defined."
 %endif
 %define TMPL_CMN_LM
 %define TMPL_CMN_P32
 %define TMPL_32BIT
 %define TMPL_BITS              32
 %define TMPL_PTR_DEF           dd
 %define TMPL_NM(Name)          Name %+ _lm32
 %define TMPL_NM_CMN(Name)      Name %+ _p32
 %define TMPL_MODE_STR          '32-bit long mode'
%endif

%ifdef TMPL_LM64
 %ifdef TMPL_RM
  %error ""Both 'TMPL_LM64' and 'TMPL_RM' are defined.""
 %endif
 %ifdef TMPL_PE16
  %error "Both 'TMPL_LM64' and 'TMPL_PE16' are defined."
 %endif
 %ifdef TMPL_PE32
  %error "Both 'TMPL_LM64' and 'TMPL_PE32' are defined."
 %endif
 %ifdef TMPL_PEV86
  %error "Both 'TMPL_LM64' and 'TMPL_PEV86' are defined."
 %endif
 %ifdef TMPL_PP16
  %error "Both 'TMPL_LM64' and 'TMPL_PP16' are defined."
 %endif
 %ifdef TMPL_PP32
  %error "Both 'TMPL_LM64' and 'TMPL_PP32' are defined."
 %endif
 %ifdef TMPL_PPV86
  %error "Both 'TMPL_LM64' and 'TMPL_PPV86' are defined."
 %endif
 %ifdef TMPL_PAE16
  %error "Both 'TMPL_LM64' and 'TMPL_PAE16' are defined."
 %endif
 %ifdef TMPL_PAE32
  %error "Both 'TMPL_LM64' and 'TMPL_PAE32' are defined."
 %endif
 %ifdef TMPL_PAEV86
  %error "Both 'TMPL_LM64' and 'TMPL_PAEV86' are defined."
 %endif
 %ifdef TMPL_LM16
  %error "Both 'TMPL_LM64' and 'TMPL_LM16' are defined."
 %endif
 %ifdef TMPL_LM32
  %error "Both 'TMPL_LM64' and 'TMPL_LM32' are defined."
 %endif
 %define TMPL_CMN_LM
 %define TMPL_CMN_P64
 %define TMPL_64BIT
 %define TMPL_BITS              64
 %define TMPL_PTR_DEF           dq
 %define TMPL_NM(Name)          Name %+ _lm64
 %define TMPL_NM_CMN(Name)      Name %+ _p64
 %define TMPL_MODE_STR          '64-bit long mode'
%endif

%ifndef TMPL_MODE_STR
 %error "internal error"
%endif


;
; Register aliases.
;
%ifdef TMPL_64BIT
 %define xCB  8
 %define xDEF dq
 %define xRES resq
 %define xPRE qword
 %define xSP  rsp
 %define xBP  rbp
 %define xAX  rax
 %define xBX  rbx
 %define xCX  rcx
 %define xDX  rdx
 %define xDI  rdi
 %define xSI  rsi
 %define xWrtRIP wrt rip
 %define xPUSHF pushq
 %define xPOPF  popfq
%else
 %ifdef TMPL_32BIT
  %define xCB  4
  %define xDEF dd
  %define xRES resd
  %define xPRE dword
  %define xSP  esp
  %define xBP  ebp
  %define xAX  eax
  %define xBX  ebx
  %define xCX  ecx
  %define xDX  edx
  %define xDI  edi
  %define xSI  esi
  %define xWrtRIP
  %define xPUSHF pushfd
  %define xPOPF  popfd
 %else
  %ifndef TMPL_16BIT
   %error "TMPL_XXBIT is not defined."
  %endif
  %define xCB  2
  %define xDEF dw
  %define xRES resw
  %define xPRE word
  %define xSP  sp
  %define xBP  bp
  %define xAX  ax
  %define xBX  bx
  %define xCX  cx
  %define xDX  dx
  %define xDI  di
  %define xSI  si
  %define xWrtRIP
  %define xPUSHF pushf
  %define xPOPF  popf
 %endif
%endif

;
; Register names corresponding to the max size for pop/push <reg>.
;
; 16-bit can push both 32-bit and 16-bit registers.  This 's' prefixed variant
; is used when 16-bit should use the 32-bit register.
;
%ifdef TMPL_64BIT
 %define sCB  8
 %define sDEF dq
 %define sRES resq
 %define sPRE qword
 %define sSP  rsp
 %define sBP  rbp
 %define sAX  rax
 %define sBX  rbx
 %define sCX  rcx
 %define sDX  rdx
 %define sDI  rdi
 %define sSI  rsi
 %define sPUSHF pushfq
 %define sPOPF  popfq
%else
 %define sCB  4
 %define sDEF dd
 %define sRES resd
 %define sPRE dword
 %define sSP  esp
 %define sBP  ebp
 %define sAX  eax
 %define sBX  ebx
 %define sCX  ecx
 %define sDX  edx
 %define sDI  edi
 %define sSI  esi
 %define sPUSHF pushfd
 %define sPOPF  popfd
%endif

;
; Default code segment.
;
%ifdef TMPL_64BIT
 %define TMPL_BEGINCODE BEGINCODEHIGH
%elifdef TMPL_32BIT
 %define TMPL_BEGINCODE BEGINCODEHIGH
%elifdef TMPL_16BIT
 %define TMPL_BEGINCODE BEGINCODELOW
%else
 %error "Missing TMPL_xxBIT!"
%endif
TMPL_BEGINCODE

;
; Change the bitness.
;
%ifdef TMPL_64BIT
BITS 64
%else
 %ifdef TMPL_32BIT
BITS 32
 %else
BITS 16
 %endif
%endif