;**************************************************************************
;*                      MemWarn by Mike Fuller                            *
;*                      Completed 6-Jan-1991                              *
;*                                                                        *
;*  MemWarn is a very small assembly language program for use in batch    *
;*  files, such as the startup-sequence.  It accepts one argument when    *
;*  called, the memory requirements in kilobytes, and returns a WARN if   *
;*  the available total system memory at that time is greater.            *
;*  To keep it as small as possible, no error checking is done apart      *
;*  from returning a FAIL if no numerical argument is given.              *
;*                                                                        *
;*   Algorithm:                                                           *
;*               clear buffer                                             *
;*               while not linefeed                                       *
;*                   get ASCII character from argument                    *
;*                   if ASCII digit                                       *
;*                       convert to number                                *
;*                       shift decimal point in buffer                    *
;*                       add number to buffer                             *
;*                                                                        *
;*               if zero in buffer                                        *
;*                   set FAIL                                             *
;*               else                                                     *
;*                   convert buffer to bytes                              *
;*                   get system memory                                    *
;*                   if system mem > buffer                               *
;*                       set WARN                                         *
;*                   else                                                 *
;*                       set zero                                         *
;*                                                                        *
;*               return                                                   *
;*                                                                        *
;*   Notes:                                                               *
;*         1.  After calling a program, register A0 contains a pointer to *
;*           the string entered after the call, and D0 contains the       *
;*           number of characters. So, if no argument was given, A0 would *
;*           point to a linefeed character and D0 would contain 1.        *
;*         2.  AvailMem requires the Exec library pointer in A6, and the  *
;*           type of memory (1 for public, 2 for chip, 4 for fast) in D1. *
;*           The available memory is returned in D0.                      *
;*         3.  The value in register D0 when the program returns to the   *
;*           CLI determines the level of CLI function.                    *
;*           (0 - nothing, 5 - WARN, 10 - ERROR, 20 - FAIL).              *
;*                                                                        *
;**************************************************************************

        xref    _LVOAvailMem    ;external reference to exec function


        Section "MemWarn",Code

;************************* Constants **************************************

SYSBASE equ     4               ;pointer to address of exec library
LF      equ     $A              ;linefeed character
PUBLICMEM equ   1               ;public memory mask
DECFAC  equ     10              ;factor for shifting decimal point
KBFAC   equ     1000            ;factor for conversion to number of bytes

;************************* Main Program **********************************

;   clear buffers

        moveq   #0,d1           ;clear register - holds single character
        moveq   #0,d2           ;clear buffer 2 - holds total number

;   get characters and convert to number

Getchr:
        move.b  (a0)+,d1        ;get character
        cmpi.b  #LF,d1          ;is character a linefeed?
        beq     Cmpmem          ;if yes, compare memory
        cmpi.b  #'0',d1         ;is char < 0?
        blt     Enget           ;if yes, ignore
        cmpi.b  #'9',d1         ;is char > 9?
        bgt     Enget           ;if yes, ignore
        subi.b  #'0',d1         ;else, convert to decimal number
        mulu    #DECFAC,d2      ;factorise buffer
        add.l   d1,d2           ;add number to buffer
Enget:
        bra     Getchr          ;get next character

;   Compare memory with user requirements and set appropriate level

Cmpmem:
        tst.l   d2              ;check amount given
        beq     Setfail         ;if 0, return a FAIL
        mulu    #KBFAC,d2       ;adjust for kilobytes
        movea.l SYSBASE,a6      ;get exec library address
        moveq   #PUBLICMEM,d1   ;type of memory required
        jsr     _LVOAvailMem(a6)    ;get total memory available
        cmp.l   d2,d0           ;is available memory less than user needs?
        blt     Setzero         ;if so, don't return a WARN
        moveq   #5,d0           ;else, return a WARN
        bra     Finish          ;and finish
Setfail:
        moveq   #20,d0          ;return a FAIL
        bra     Finish          ;and finish
Setzero:
        clr.l   d0              ;no WARN

Finish:
        rts                     ;return to CLI or Shell

        END
