Metropoli BBS
VIEWER: frmi.inc MODE: TEXT (CP437)
──────────────────────────────────────────────────────────────────────────────

 FALSE EQU 0
 TRUE  EQU NOT FALSE

 CPU_8086   = 0
 CPU_80286  = 2
 CPU_80386  = 3
 CPU_80386p = 4

 MAX_EMB    = 32                   ; HIMEM.SYS supports a maximum of 32 EMB

──────────────────────────────────────────────────────────────────────────────

 ENUM PM           PM_NA=0FFh, PM_OK=0, PM_V86, PM_DPMS, PM_PHAR_LAP, PM_DOS4GW, PM_DOSX, PM_DPMI
 ENUM XMS_INIT_ERR XMS_NOT_INSTALLED=1, XMS_BAD_VERSION, XMS_BAD_A20
 ENUM GET_RAM_ERR  NO_FREE_RAM=0, NO_FREE_EMB, CANT_LOCK_XMS

──────────────────────────────────────────────────────────────────────────────

 GLOBAL CPU:BYTE

──────────────────────────────────────────────────────────────────────────────

 GLOBAL FRMI_START:PROC
 GLOBAL TEST_CPU:PROC
 GLOBAL XMS_INIT:PROC
 GLOBAL XMS_LOCAL_ENABLE_A20:PROC
 GLOBAL XMS_QUERY_FREE:PROC
 GLOBAL XMS_ALLOC:PROC
 GLOBAL XMS_FREE:PROC
 GLOBAL XMS_LOCK:PROC
 GLOBAL XMS_UNLOCK:PROC
 GLOBAL XMS_REALLOC:PROC
 GLOBAL QUERY_FREE_RAM:PROC
 GLOBAL GET_RAM:PROC
 GLOBAL FREE_RAM:PROC

──────────────────────────────────────────────────────────────────────────────

MACRO   @XMS_CALL  Func, D         ; Macro to call XMS driver
   Mov   AH, Func
   
   IFNB  <D>
      Mov   DX, D
   ENDIF

   CALL  [CS:XMS_DRIVER_ADDRESS]
ENDM

MACRO @SEG2LIN Reg, Segt, Offs     ; Macro to convert a segmented address into
   LOCAL @@RegIsExt, @@16_Reg      ; a 32 bit linear address

   MACRO @@Check_Ext_Reg Register
      @@RegIsExt = 0

      IRP Ext_Reg, <EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP>
         IFIDNI <Register>, <&Ext_Reg&>
            @@RegIsExt = 1
            EXITM
         ENDIF
      ENDM
   ENDM


   IFB <Reg>
      ERR "Must pass destination Register (1st parameter) to @SEG2LIN"
   ELSE
      IFB <Segt>
         ERR "Must pass Segment (2nd parameter) to @SEG2LIN"
      ELSE
         IFB <Reg>
            ERR "Must pass Offset (3rd parameter) to @SEG2LIN"
         ELSE
            @@Check_Ext_Reg <Reg>

            IFE @@RegIsExt
               ERR "Must pass an Extended Register (ie EAX, EBX, etc. as 1st parameter) to @SEG2LIN">
               EXITM
            ENDIF

            IRP Ext_Reg, <EAX, EBX, ECX, EDX, ESI, EDI, EBP, ESP>
               IFDIFI <&Ext_Reg&>, <Reg>
                  Push  &Ext_Reg&
   
                  Xor   &Ext_Reg&, &Ext_Reg&
                  Mov   Reg, &Ext_Reg&
                  
                  @@16_Reg SUBSTR <&Ext_Reg&>, 2, 2
                  Mov   @@16_Reg, Segt

                  Shl   &Ext_Reg&, 4
              
                  @@16_Reg SUBSTR <Reg>, 2, 2
                  Mov   @@16_Reg, Offs
                  Add   Reg, &Ext_Reg&
   
                  Pop   &Ext_Reg&
               
                  EXITM
               END
            ENDM
         ENDIF
      ENDIF
   ENDIF
ENDM


MACRO LOOPX   Offs     ; Macro to use ECX in LOOP instruction
   DB 67h
   LOOP   Offs
ENDM


MACRO LOOPXNZ Offs     ; Macro to use ECX in LOOPNZ instruction
   DB 67h
   LOOPNZ Offs
ENDM

MACRO LOOPXNE Offs     ; Same as above but just for different syntax
   DB 67h
   LOOPNE Offs
ENDM


MACRO LOOPXZ  Offs     ; Macro to use ECX in LOOPZ instruction
   DB 67h
   LOOPZ  Offs
ENDM

MACRO LOOPXE  Offs     ; Same as above but just for different syntax
   DB 67h
   LOOPE  Offs
ENDM

──────────────────────────────────────────────────────────────────────────────
[ RETURN TO DIRECTORY ]