OBJNAM FREESP.LIT ; Created 29-Oct-85, Last modified 3-Apr-86
; by Irv Bromberg, Medic/OS Consultants, Toronto, CANADA
RADIX 10
VEDIT=18
VMINOR=2
VMAJOR=2
VSUB=0
IF EQ,1
Assembled under AMOS/L 1.3 FREESP.LIT version 2.2(18) size=364 bytes,
hash=332-014-453-455.
Syntax: FREESP bytes{K}{/I} command
Reserves free space at the top of the user's partition prior to
execution of a the specified command. This free space is made available
the next time the user's job executes a KBD monitor call with his
terminal in LINE INPUT MODE. The Bytes count is specified as a base-10
number and can optionally be followed by a "K" for kilobytes. The
command can be any monitor-level command at all. The maximum is 32K.
The space reserved is in addition to any that would become free from
processing of any pending CMD file already at the top of the user's
partition (total limit 32K bytes).
The /I switch causes the command to be immediately executed using an
AMOS monitor call instead of the normal mode where an EXIT monitor
call is allowed to invoke the command indirectly. The Immediate mode
is intended to be used only when debugging using SuperFIX -- it uses
slightly more partition space (occupied by FREESP.LIT module) and the
command being invoked MUST NOT be a CMD or DO file.
Here are some example of use with AlphaBASIC:
.freesp 8k basic ; reserves 8K bytes, goes into Interactive BASIC,
AlphaBASIC Version 1.3(196)
READY (Notice the exclamation from the FREESP memory cmd file
! displays immediately, 8K bytes immediately free)
xcall freesp,free (AlphaBASIC always leaves 8 bytes free at the
print "Free=";free top of the user's partition, this is in addition
Free= 8204 to the amount reserved by FREESP, therefore we
get 8K+8 =8*1024+8 =8192+8 =8204 bytes free here)
Also note that for efficiency FREESP always rounds up the Number specified
so that the number of bytes to be nulled is divisible by 4, allowing a
longword at a time to be cleared.
.freesp 8k run prog ; reserves 8K bytes
To free up the space reserved by the above command the program can do any of
the following:
-- invoke a dummy string INPUT or INPUT LINE statement, this will return
"!" as the input (will also echo !<cr><lf> on the user's screen) and
will flush away the FREESP cmd file, freeing up the reserved space.
-- XCALL FREESP,Free ! frees up the freespace and returns how much to
the floating variable, Free. Can be used anytime to return total free.
-- XCALL AMOS (the Medic/OS AMOS.SBR checks for the FREESP cmd file and
automatically flushes it to free up the reserved freespace).
-- invoke any other XCALL subroutine which executes a KBD monitor call in
line input mode.
Both the Medic/OS FREESP.SBR and AMOS.SBR prevent the !<cr><lf> from
echoing to the user's screen when flushing the FREESP cmd file.
Edit history:
2-Jan-86 2.0(16) Major rewrite: mark reserved space with "!" so FREESP.SBR
can check for it; Number adjusted for CRLF ! CRLF,
length of command and current CMD file size; Max total
CMD file size is 32K - check adjusted Number for this.
2-Jan-86 2.1(17) correct the longword Number rounding routine
3-Apr-86 2.2(18) add /I switch to use AMOS call to Immediately execute cmd
ENDC
GetNUM: GTDEC ; get the number of bytes to reserve
JMI Syntax
TST Number
JEQ Syntax
CMPB (Buffer)+,#'K ; kilobytes?
BNE ChkEND
MUL Number,#1024 ; yes, x1024
ChkEND: USRFRE UFRE
MOV JOBBAS(JCB),UEND ; calculate USREND addr
ADD JOBSIZ(JCB),UEND
SUBW JOBCMZ(JCB),UEND ; pointing at next command file char
CLR CMDSIZ ; pre-clear
MOV UEND,Dtemp ; test if odd address
LSR Dtemp
BCC ChkSW ; carry clear if already even
CLRB -(UEND) ; make it even
INCW CMDSIZ ; remember we did so
ChkSW: BYP
CMPB @Buffer,#'/ ; switch present?
BNE ChkLEN
INCW Buffer
CMPB (Buffer)+,#'I ; is it /I switch?
BEQ 10$
TYPECR <?Illegal switch> ; no, illegal
EXIT
10$: BYP ; and skip next whitespace
; when /I is specified we don't copy command line to FREESP cmd file
CLR Length ; use 0 as flag that /I was specified
BR ChkLN2
ChkLEN: MOV Buffer,SavBuf
10$: LIN ; determine length of remaining
BEQ 20$ ; command line
INC Buffer
BR 10$
20$: MOV Buffer,Length ; make sure there will be room to also
SUB SavBuf,Length ; put the cmd line at beginning
ADD Length,CMDSIZ ; add length of command line
ADD #2,CMDSIZ ; +2 for CRLF after cmd
ChkLN2: ADD #3,CMDSIZ ; +3 for ! CRLF
SUB #3,Number ; adjust Number for ! CRLF only
Round: INC Number ; round up to even longword quantity
LSR Number
INC Number
LSR Number
LSL Number,#2
ADD Number,CMDSIZ ; now we can add Number into total
CLR Dtemp ; pre-clear for word move
MOVW JOBCMZ(JCB),Dtemp ; get current command file size
ADD Dtemp,CMDSIZ
CMP CMDSIZ,#32768 ; must be less than 32K
BLO ChkFRE
TYPECR <?Memory command file size would exceed 32K bytes>
EXIT
ChkFRE: MOV UEND,Free
SUB UFRE,Free ; calculated #bytes free
SUB #4,Free ; allow for 0 to end module chain
MOV Length,Dtemp ; length of command to execute
BEQ 10$ ; 0=immediate execute mode
ADD #2,Dtemp ; for CRLF
10$: ADD #3,Dtemp ; for ! CRLF
ADD Number,Dtemp
CMP Dtemp,Free ; are we asking for too much?
BLO Clear ; no, we can do it!
TYPECR <?Not enough free memory>
EXIT
Clear: LSR Number,#2 ; /4 for longword clear
BR LpDBF ; enter at end of DBF loop
Loop: CLR -(UEND)
LpDBF: DBF Number,Loop
TSTW JOBCMZ(JCB) ; command file already being processed?
BNE 5$ ; yes
ANDW #^C<C.TRC>,JOBCMS(JCB) ; no, turn off trace mode
5$: MOVW CMDSIZ,JOBCMZ(JCB) ; fool OS into thinking there is a
; NULL command file at the top
MOVB #LF,-(UEND) ; First CRLF needed to terminate the
MOVB #CR,-(UEND) ; command we're invoking.
MOVB #'!,-(UEND) ; "!" is checked for by FREESP.SBR
TST Length ; =0 if immediate exec mode
BEQ Immed
MOVB #LF,-(UEND) ; CRLF needed to hold the NULLs in the
MOVB #CR,-(UEND) ; freespace until the command runs.
BR 20$ ; enter at end of DBF loop
10$: MOVB -(Buffer),-(UEND) ; copy remainder of cmd line
20$: DBF Length,10$
EXIT ; let the monitor execute it...
Immed: AMOS ; immediately execute the command
EXIT