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