*
*    These macros are a subset of the macros included in the AsMac_02.zoo
*    file.
*
*____________________________________________________________________________
*
*    When writing a program using these macros, the following rules apply:
*
*         - Must include the file called CoreMacros.i . This file contains
*            the following macros:
*
*                 DefineSections           CallLib
*                 OpenLib                  CloseLib
*                 DefDS                    DS_BSS
*                 OnReEntrant              OffReEntrant
*
*         - Other macros must be included individually if they are used.
*
*         - Must do the DefineSections macro at the start of the program.
*            The other macros depend on this.
*
*         - These macros must only be invoked from the CODE section.
*
*

*****************************************************************************
*
*    DefineSections           MACRO                           25 Dec 88
*
*    NAME:
*         DefineSections  - Defines the DATA, BSS and CODE program sections.
*
*    SYNOPSIS:
*         DefineSections [<ProgramName>]
*
*    FUNCTION:
*         This macro defines the DATA, BSS and CODE program sections. This
*          is required for the other macros to work correctly.
*
*         If <ProgramName> is specified, the program unit will be given
*          this name.
*


DefineSections MACRO
*-------------------------------;    Start of DefineSections macro.
               NOLIST
               IFEQ NARG-1
               LIST
               IDNT "\1"
               NOLIST
               ENDC
               IFND ReEntrant
ReEntrant      SET 0
               ENDC
               IFND CAPE
               LIST
MetacomcoFix:  SECTION   "",CODE             ; This un-named code section
               JMP CodeStart                 ;  is needed to fix a bug in
                                             ;  the MetaComCo assembler.
               NOLIST
               ENDC
               LIST
DefDSPointer   SET 0
CurrentLibID   SET 0
               SECTION   CodeSection,CODE    ; Relocatable code section
CodeStart:
               SECTION   DataSection,DATA    ; Initialized data section
DataStart:
               SECTION   BSS_Section,BSS     ; Un-initialized data section
BSS_Start:
               SECTION   CodeSection,CODE    ; Relocatable code section
*-------------------------------;    End of DefineSections macro.
               ENDM

*****************************************************************************
*
*    DefDS                    MACRO                           26 Dec 88
*
*    NAME:
*         DefDS - Define an offset to a location in the RAM block used for
*                  un-initialized data storage.
*
*    SYNOPSIS:
*         DefDS <label>,<size>
*
*    FUNCTION:
*         This macro defines an offset to a location in the RAM block used
*          for un-initialized data storage. The <label> is equated to this
*          offset value. The data storage size will be <size> long words.
*          This macro is used when the reentrant macro expansion feature is
*          turned on.
*
*         See also AllocUDS.
*

DefDS          MACRO
               NOLIST
               IFND \1
\1             EQU DefDSPointer
DefDSPointer   SET DefDSPointer+(4*\2)
               ENDC
               LIST
               ENDM

*****************************************************************************

*****************************************************************************
*
*    DS_BSS                   MACRO                           13 Sept 88
*
*    NAME:
*         DS_BSS - Define data storage in a BSS section.
*
*    SYNOPSIS:
*         DS_BSS <label>,<size>,.B|.W|.L
*
*    FUNCTION:
*         This macro defines data storage in a BSS section. The <label> is
*          equated to this value. The third argument tells whether the units
*          of <size> are byte, word, or long.
*

DS_BSS    MACRO
          NOLIST
          IFND \1
          SECTION BSS_Section,BSS
          IFC "\3",".W"
          CNOP 0,2
          ENDC
          IFC "\3",".L"
          CNOP 0,4
          ENDC
\1:
          DS\3 \2
          SECTION CodeSection,CODE
          ENDC
          LIST
          ENDM

*****************************************************************************
*
*    OnReEntrant, OffReEntrant          MACRO                 13 Sept 88
*
*    FUNCTION:
*         These macros turn the reentrant macro expansion feature on or off.
*
*         When the reentrant macro expansion feature is turned on, all
*          BSS-type data space is in a block of RAM pointed to by A5.
*
*         See also AllocUDS.
*

OnReEntrant    MACRO
               NOLIST
ReEntrant      SET 1
               LIST
               ENDM

OffReEntrant   MACRO
               NOLIST
ReEntrant      SET 0
               LIST
               ENDM

*****************************************************************************

*****************************************************************************
*
*    CallLib                  MACRO                            9 Feb 89
*
*    NAME:
*         CallLib  - Call a subroutine of a library.
*
*    SYNOPSIS:
*         CallLib <SubroutineName>,<libname>
*
*    FUNCTION:
*         This macro calls a subroutine of a library. The library must
*          have been previously opened, and the library pointer must be
*          at <libname>.library.ptr .
*
*         See also OpenLib.
*

CallLib   MACRO
     NOLIST
     IFND _LVO\1.Ref
_LVO\1.Ref SET 1
     LIST
        XREF _LVO\1
     NOLIST
     ENDC
     IFEQ ReEntrant-1
     LIST
        MOVE.L \2.library.ptr(A5),A6
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
        MOVE.L \2.library.ptr,A6
     NOLIST
     ENDC
     LIST
        JSR _LVO\1(A6)
     ENDM

*****************************************************************************

*****************************************************************************
*
*    OpenLib                  MACRO                          25 Dec 88
*
*    NAME:
*         OpenLib  - Open a library.
*
*    SYNOPSIS:
*         OpenLib <libname>
*
*                  Returns:  pointer to the library at <libname>.ptr
*
*                            Z-flag = 1 if fail
*
*    FUNCTION:
*         This macro returns a pointer to a library that was previously
*          installed into the system. If it is not successful, it will return
*          a library pointer of zero and set the zero flag.
*
*         See also CloseLib.
*
*    INPUTS:
*         <libname>   - Typed in as the first argument of the macro.
*
*    RESULTS:
*         pointer to library - Returned in memory at the address labeled
*                               "<libname>.ptr".
*
*         fail               - Zero flag = true if failed, false if o.k.
*

OpenLib   MACRO
*------------------------------; Start of OpenLib macro.
     NOLIST
                               ; Define _AbsExecBase and _LVOOpenLibrary if
     IFND _AbsExecBase         ;  they have not yet been defined.
     LIST
     XREF _AbsExecBase
     NOLIST
     ENDC
     IFND _LVOOpenLibrary
     LIST
     XREF _LVOOpenLibrary
     NOLIST
     ENDC
     LIST
     MOVE.L _AbsExecBase,A6    ; Do set-up for _LVOOpenLibrary.
     CLR.L D0
     MOVE.L #\1.str,A1
     SECTION DataSection,DATA  ; This is the <libname> ASCII string.
\1.str:
     DC.B '\1',0
     CNOP 0,2
     SECTION CodeSection,CODE
     JSR _LVOOpenLibrary(A6)   ; Call OpenLibrary to open <libname>.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     DefDS \1.ptr,1
     MOVE.L D0,\1.ptr(A5)
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L D0,\1.ptr
     DS_BSS \1.ptr,1,.L
     NOLIST
     ENDC
     LIST
     TST.L D0                  ; Make the zero flag indicate failure.
*------------------------------; End of OpenLib macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    CloseLib               exec.library  MACRO        Rev: 13 Sept 88
*
*    NAME:
*         CloseLib  - Close a library.
*
*    SYNOPSIS:
*         CloseLib <libname>
*
*                  Returns:  Nothing.
*
*    FUNCTION:
*         This macro tells the library manager that there is one fewer task
*          currently using the specified library. This allows the operating
*          system to purge the library from RAM if the extra RAM space is
*          needed and no task is using it. Since this macro invokes the exec
*          library (exec.library), the exec library should be closed last.
*
*         See also OpenLib.
*
*    INPUTS:
*         <libname>       - Typed in as the first argument of the macro.
*                            "<libname>.ptr" must have been created by the
*                            OpenLib macro.
*
*         exec.library.ptr - Since this macro invokes the exec library, the
*                            exec library must have been opened previously
*                            by invoking the "OpenLib exec.library"
*                            macro command.
*


CloseLib       MACRO
*------------------------------; Start of CloseLib macro.
                               ; Put the library pointer in A1.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     MOVE.L \1.ptr(A5),A1
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L \1.ptr,A1
     NOLIST
     ENDC
     LIST
     CallLib CloseLibrary,exec ; Call CloseLibrary.
*------------------------------; End of CloseLib macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    Close                  dos.library  MACRO                13 Sept 88
*
*    NAME:
*         Close  - Close a directory or file.
*
*    SYNOPSIS:
*         Close <FileHandleName>
*
*                  Returns:  Nothing.
*
*    FUNCTION:
*         This macro closes a directory or file.
*
*         See also Open.
*
*    INPUTS:
*         <FileHandleName> - The name of the file to be removed.
*
*         dos.library.LP   - Must have been defined by invoking the
*                             "OpenLib dos.library" macro command.
*


Close          MACRO
*------------------------------; Start of Close macro.
                               ; Put the file handle in D1.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     MOVE.L \1(A5),D1
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L \1,D1
     NOLIST
     ENDC
     LIST
     CallLib Close,dos         ; Call Close to remove the file.
*------------------------------; End of Close macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    Disable                  MACRO                            9 Feb 89
*
*    NAME:
*         Disable - Disable all interrupts.
*
*    SYNOPSIS:
*         Disable
*
*    FUNCTION:
*         This macro disables all interrupts. It may be unsafe to leave
*          interrupts disabled for more than 250 microseconds.
*
*         See also Enable.
*

Disable   MACRO
*------------------------------; Start of Disable macro.
     NOLIST
     IFND _intena
     LIST
     XREF _intena
     NOLIST
     ENDC
     IFEQ ReEntrant-1
     LIST
        MOVE.L exec.library.ptr(A5),A6
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
        MOVE.L exec.library.ptr,A6
     NOLIST
     ENDC
     LIST
     MOVE.W #$4000,_intena
     ADDQ.B #1,$126(A6)        ; Increment IDNestCnt.
*------------------------------; End of Disable macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    Enable                   MACRO                            9 Feb 89
*
*    NAME:
*         Enable - Enable interrupts.
*
*    SYNOPSIS:
*         Enable
*
*    FUNCTION:
*         This macro enables interrupts.
*
*         See also Disable.
*

Enable    MACRO
*------------------------------; Start of Enable macro.
     NOLIST
     IFEQ ReEntrant-1
     LIST
        MOVE.L exec.library.ptr(A5),A6
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
        MOVE.L exec.library.ptr,A6
     NOLIST
     ENDC
     LIST
     SUBQ.B #1,$126(A6)        ; Decrement IDNestCnt.
     BGE.S 5$
     MOVE.W #$C000,_intena
5$:
*------------------------------; End of Enable macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    GetStdOut           dos.library  MACRO                   14 Sept 88
*
*    NAME:
*         GetStdOut - Get a file handle for the program's initial output.
*
*    SYNOPSIS:
*         GetStdOut
*                  Returns:  File handle in D0 and at StdOut.
*
*    FUNCTION:
*         This macro returns a file handle for the program's initial output.
*          This file handle will usually be associated with the CLI window,
*          unless output was redirected from the command line.
*
*    INPUTS:
*         dos.library.LP  - Must have been defined by invoking the
*                             "OpenLib dos.library" macro command.
*
*    RESULTS:
*         file handle - Returned in D0 and in memory at the address
*                        labeled "StdOut".
*
*


GetStdOut   MACRO
*------------------------------; Start of GetStdOut macro.
     CallLib Output,dos        ; Call Output.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     DefDS StdOut,1
     MOVE.L D0,StdOut(A5)      ; Save the file handle at StdOut.
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     DS_BSS StdOut,1,.L
     MOVE.L D0,StdOut          ; Save the file handle at StdOut.
     NOLIST
     ENDC
     LIST
*------------------------------; End of GetStdOut macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    Open                dos.library  MACRO                 19 Dec 88
*
*    NAME:
*         Open  - Open a file.
*
*    SYNOPSIS:
*         Open D,<FileName>,<FileHandleName> [,new | read | r/w]
*                                            [or with D0 = 0 if new]
*
*         Open I,<PointerToFileName>,<FileHandleName> [,new | read | r/w]
*                                                     [or with D0 = 0 if new]
*
*         Open R,D1,<FileHandleName> [,new | read | r/w]
*                                    [or with D0 = 0 if new]
*
*                  Returns:  File handle in D0 and at <FileHandleName>.
*                            Z-flag = 1 if fail.
*
*    FUNCTION:
*         This macro returns a file handle for a file.  The file name is
*          either specified directly as <FileName>, or indirectly as a string
*          pointed to by D1 or by <PointerToFileName>.
*
*         If it is not successful, it will return a file handle of zero and
*          set the zero flag.
*
*         See also Close.
*
*    INPUTS:
*         "D","I" or "R"      - Indicates "direct", "indirect", or "register"
*                                mode for the second argument.
*
*         <PointerToFileName> - Pointer to a null-terminated file name string
*         or <FileName>          or the FileName itself.
*
*         <FileHandleName> - The name you want the file handle to be called.
*
*         new | read | r/w - Specifys whether a new file should be created or
*                             an existing file should be used. For existing
*                             files, "read" indicates that a shared read lock
*                             is needed, "r/w" indicates that an exclusive
*                             lock is needed. Must be lower case.
*
*         D0 = 0 if new    - If new, read, or r/w is not specified, D0 tells
*                             the macro whether the file to be opened is a
*                             new file (D0 = 0) or existing r/w (D0 not 0).
*                             Use the Lock macro to establish D0.
*
*         dos.library.LP   - Must have been defined by invoking the
*                             "OpenLib dos.library" macro command.
*
*    RESULTS:
*         file handle - Returned in D0 and in memory at the address
*                        labeled "<FileHandleName>".
*
*         fail        - Zero flag = true if failed, false if o.k.
*


Open        MACRO
*------------------------------; Start of Open macro.
     NOLIST
     IFEQ NARG-4               ; If new, read, or r/w is specified, make D2
                               ;  indicate the accessMode accordingly.
     IFC '\4','new'
     LIST
     MOVE.L #1006,D2           ; Make D2 indicate "new" access mode.
     NOLIST
     ENDC
     IFC '\4','read'
     LIST
     MOVE.L #1005,D2           ; Make D2 indicate "read" access mode.
     NOLIST
     ENDC
     IFC '\4','r/w'
     LIST
     MOVE.L #1004,D2           ; Make D2 indicate "r/w" access mode.
     NOLIST
     ENDC
     ENDC
     IFEQ NARG-3               ; If new, read, or r/w is not specified,
     LIST
     MOVE.L #1005,D2           ; Make D2 indicate the old/new accessMode
     TST D0                    ;  based on D0.
     BNE 5$
     SUBQ #1,D2
5$:
     NOLIST
     ENDC
     IFC '\1','I'              ; If <PointerToFileName> is specified, then
     LIST
                               ; Put <PointerToFileName> in D1.
     MOVE.L #\2,D1
     NOLIST
     IFEQ ReEntrant-1
     LIST
     ADD.L A5,D1
     NOLIST
     ENDC
     ENDC
     IFC '\1','D'              ; If <FileName> is specified, then
     LIST
                               ; Make D1 point to the file name string.
     MOVE.L #\2.str,D1
     NOLIST
     IFND \2.str               ; Unless it was previously defined,
     LIST
     SECTION DataSection,DATA  ; The ASCII <FileName> string goes here.
\2.str:
     DC.B '\2',0
     CNOP 0,2
     SECTION CodeSection,CODE
     NOLIST
     ENDC
     ENDC
     LIST
     CallLib Open,dos          ; Call Open to open <FileName>.
                               ; Put the file handle at <FileHandleName>.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     DefDS \3,1
     MOVE.L D0,\3(A5)
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     DS_BSS \3,1,.L
     MOVE.L D0,\3
     NOLIST
     ENDC
     LIST
     TST.L D0                  ; Make the zero flag indicate failure.
*------------------------------; End of Open macro.
     ENDM

*****************************************************************************

*****************************************************************************
*
*    Write               dos.library  MACRO                      21 Dec 88
*
*    NAME:
*         Write - Write to a file from a buffer.
*
*    SYNOPSIS:
*         Write D,<BufferStartAddr>,<FileHandleName>
*         Write D,<BufferStartAddr>,<FileHandleName>,D3
*         Write D,<BufferStartAddr>,<FileHandleName>,<BufferSize>
*
*         Write R,D2,<FileHandleName>,D3
*         Write R,D2,<FileHandleName>,<BufferSize>
*
*         Write I,<MemBlockName>,<FileHandleName>
*         Write I,<MemBlockName>,<FileHandleName>,D3
*         Write I,<MemBlockName>,<FileHandleName>,<BufferSize>
*
*                  Returns:  Actual length of bytes written in D0.
*                            Z-flag = 1 if fail.
*
*    FUNCTION:
*         This macro writes bytes from a buffer to an opened file. The buffer
*          is either specified by a vector located at <MemBlockName>.Adr or
*          by <BufferStartAddr>.
*
*         If no fourth argument is given, and <BufferStartAddr> is
*          specified, the label "<BufferStartAddr>End" must exist one byte
*          past the end of the buffer.
*
*         If no fourth argument is given, and <MemBlockName> is specified,
*          the buffer size must be specified in <MemBlockName>.Size .
*
*         D3 may be used to specify the buffer size, or the buffer size may
*          be specified directly as <BufferSize>.
*
*         If it is not successful, it will set the zero flag.
*
*    INPUTS:
*         "D","I" or "R"      - Indicates "direct", "indirect", or "register"
*                                mode for the second argument.
*
*         <FileHandleName>   - Typed in as the third argument of the macro.
*                               Use the Open macro to create this.
*
*         <BufferStartAddr>  - Defined for the start of the buffer.
*
*         <MemBlockName>     - This is the same <MemBlockName> argument which
*                               was used for the AllocMem macro.
*
*         buffer size        - Specified in D3, or as <BufferSize>, or at
*                               <MemBlockName>.Size, or as
*                               <BufferStartAddr>End minus <BufferStartAddr>.
*
*         dos.library.LP     - Must have been defined by invoking the
*                               "OpenLib dos.library" macro command.
*
*    RESULTS:
*         actual length - Returns actual length of bytes written in D0.
*
*         fail          - Zero flag = true if failed, false if o.k.
*


Write       MACRO
*------------------------------; Start of Write macro.
                               ; Put the file handle in D1.
     NOLIST
     IFEQ ReEntrant-1
     LIST
     MOVE.L \3(A5),D1
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L \3,D1
     NOLIST
     ENDC
     LIST
                               ; Make D2 point to the start of the buffer.
     NOLIST
     IFC '\1','D'
     LIST
     MOVE.L #\2,D2
     NOLIST
     ENDC
     IFC '\1','I'
     IFEQ ReEntrant-1
     LIST
     MOVE.L \2.Adr(A5),D2
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L \2.Adr,D2
     NOLIST
     ENDC
     ENDC
     IFEQ NARG-3               ; If there is no fourth argument, and
     IFC '\1','D'              ;  <BufferStartAddr> is specified, then
     LIST
                               ; Calculate the buffer size as
                               ;  <BufferStartAddr>End minus
                               ;  <BufferStartAddr>. Put it in D3.
     MOVE.L #\2End-\2,D3
     NOLIST
     ENDC
     IFC '\1','I'              ; If <MemBlockName> is specified, then
     LIST
                               ; Get the buffer size from <MemBlockName>.Size
     NOLIST
     IFEQ ReEntrant-1
     LIST
     MOVE.L \2.Size(A5),D3
     NOLIST
     ENDC
     IFNE ReEntrant-1
     LIST
     MOVE.L \2.Size,D3
     NOLIST
     ENDC
     ENDC
     ENDC
     IFEQ NARG-4               ; If the fourth argument exists,
     IFNC '\4','D3'            ;  and it is not "D3", then
     LIST
                               ; Use the buffer size of the fourth argument.
     MOVE.L #\4,D3
     NOLIST
     ENDC
     ENDC
     LIST
     CallLib Write,dos         ; Call Write.
     CMPI.L #-1,D0             ; Make the zero flag indicate failure.
*------------------------------; End of Write macro.
     ENDM

*****************************************************************************

