OBJNAM CHGMEM.LIT ; Created 8-May-87, edited 8-May-87
; by Irv Bromberg, Medic/OS Consultants, Toronto, Canada
; Allows the size of any module in user's MEM: area to be changed relatively
; or absolutely.
RADIX 10
VMAJOR=1
VMINOR=1
VEDIT=2

SEARCH SYS
SEARCH SYSSYM

if eq,1
Syntax examples:

CHGMEM MODULE.DAT 10    ; increase size of MODULE.DAT by 10 bytes
CHGMEM MODULE.DAT +10   ; plus sign allowed, same effect
CHGMEM MODULE.DAT,10    ; comma separator allowed, same effect
CHGMEM MODULE.DAT +11   ; increase size of MODULE.DAT by 12 bytes (odd sizes
                       ; are rounded up to even size)
CHGMEM MODULE.DAT 10K   ; increase size of MODULE.DAT by 10 kilobytes
CHGMEM MODULE.DAT -10   ; decrease size of MODULE.DAT by 10 bytes
CHGMEM MODULE.DAT -11   ; decrease size of MODULE.DAT by 10 bytes (odd negative
                       ; sizes are rounded down to even negative size)
CHGMEM MODULE.DAT=100   ; force MODULE.DAT to absolute size = 100 bytes
CHGMEM MODULE.DAT=101   ; force MODULE.DAT to absolute size = 102 bytes (odd
                       ; sizes are rounded up to even size)
CHGMEM MODULE.DAT=0     ; make MODULE.DAT empty (warning will be issued)
CHGMEM MODULE.DAT -500K ; unless it was >500K MODULE.DAT is now empty

Of course any valid filename name may be substituted for MODULE.DAT (the
default extension for the module name is ".DAT").

When the specified change results in no change then there is no change
and no error message is displayed.  Thus there is no harm in specifying
no change except for the computer's wasted effort in figuring out
that nothing should happen.

Be very careful when reducing the size of a module because crucial
information may be lost from the high end, depending on the module
contents.  Also take care when there are additional modules at addresses
beyond the one being changed - these will be moved (either up or down,
depending on the relative change in size) and this may disturb software
contained within or operating upon those modules.  In other words
the CHGMEM command is intended for advanced applications only, to be
used by programmers who know what they are doing!

Possible messages:

%Warning - MEM:filnam.ext is now empty
?Cannot find MEM:filnam.ext
?Memory allocation failed
?NULL relative size change

CHGMEM.LIT is re-entrant and re-useable.

endc

JCB=A0
Buffer=A2
Name=A3
Module=A5

Size=D0
Char=D1
Number=D1
Flags=D2
 Minus=0       ; set if input number was preceeded by "-" (relative mode)
 Abs=1         ; set if absolute size was specified (preceeded by "=")

       PHDR    -1,0,PH$REE!PH$REU

       CLR     Flags                   ; pre-clear all flags

       MOV     JOBCUR,JCB              ; use JOBRBK as work area
       LEA     Name,JOBRBK(JCB)
       CLR     @Name                   ; pre-clear filename in case
       CLR     4(Name)                 ; of invalid entry
       FILNAM  @Name,DAT

Search: SRCH    @Name,Module,F.USR      ; module already in MEM:?
       BEQ     GetSiz
       TYPE    <?Cannot find MEM:>
       PRNAM   @Name
       CRLF
       EXIT

GetSiz: BYP                             ; allow blank or tab separators
       MOVB    @Buffer,Char            ; check for absolute specifier "="
       CMPB    Char,#'=
       BNE     ChkComma
       BSET    #Abs,Flags              ; remember we got absolute signal
       BR      SkipIt                  ; no sign possible

ChkComma:CMPB   Char,#',                ; allow comma
       BNE     ChkNeg
       INCW    Buffer                  ; skip comma
       BYP                             ; bypass possibly more whitespace

ChkNeg: CMPB    @Buffer,#'-             ; minus sign present?
       BNE     ChkPlus
       BSET    #Minus,Flags            ; remember it's negative
       BR      SkipIt

ChkPlus:CMPB    @Buffer,#'+             ; plus sign present?
       BNE     GetNum
SkipIt: INCW    Buffer                  ; skip sign
       BYP                             ; skip possibly more whitespace

GetNum: GTDEC
       MOV     Number,Size
       BNE     Kilo
       BTST    #Abs,Flags              ; was it absolute size?
       BNE     Change                  ; OK, let him do it (hope he's right)
       TYPECR  <?NULL relative size change>
       EXIT

Kilo:   CMPB    @Buffer,#'K             ; kilobytes?
       BNE     FixSiz
       MUL     Size,#1024              ; yes, convert to KB

FixSiz: LSR     Size                    ; check if odd
       BCC     10$
       INC     Size                    ; yes, make it even
       BTST    #Minus,Flags            ; but if it was negative
       BEQ     10$
       SUB     #2,Size                 ; undo and make it less negative
10$:    LSL     Size                    ; restore value
       BTST    #Minus,Flags            ; also if it was negative
       BEQ     Change
       NEG     Size                    ; convert to negative value

Change: BTST    #Abs,Flags              ; is it absolute size?
       BNE     DoIt
       ADD     -12(Module),Size        ; add existing module size
       SUB     #12,Size                ; deduct housekeeping words
       BPL     DoIt                    ; if now negative, convert to 0
       CLR     Size                    ; so empty module remains

DoIt:   PUSH    Size
       PUSH    Module
       CHGMEM  @SP
       BNE     Done                    ; NE=failed, errmsg on screen

ChkSiz: TST     Size                    ; it size = 0?
       BNE     Done                    ; no, all done
       TYPE    <%Warning - MEM:>       ; yes, warn user it's empty
       PRNAM   @Name
       TYPECR  < is now empty>

Done:   EXIT

       END