OBJNAM FREESP.SBR ; Created 3-Nov-85, Last modified 2-Jan-86
; Subroutine to free up freespace reserved by FREESP command
; by Irv Bromberg, Medic/OS Consultants, Toronto, CANADA
RADIX 10
VEDIT=7
VMINOR=0
VMAJOR=2
VSUB=0

IF EQ,1

Calling syntax: XCALL FREESP {,Bytes}

Assembled under AMOS/L 1.3 FREESP.SBR version 2.0(7) size=138 bytes,
hash=477-617-264-136.

Frees up the freespace reserved by FREESP command used to invoke the
calling BASIC program.  Optionally returns the number of free bytes to
floating variable.  Method used:  If the user's partition contains a
command file and the pending line contains only "!" followed by line
terminator then the command  file and terminal status words are saved,
silence (NO trace) mode and line input mode are set, a KBD monitor call
is executed to flush the FREESP command file, and then the command file
and terminal status words are restored.  Otherwise no action is taken
except to optionally return the number of free bytes.

The freespace remains free (and its contents unmodified) even when you
chain from one compiled BASIC program to another.  This allows you to
create a common data module in the freespace and chain to another
program which will have access to the common data.

To return the freespace or reserve even more your program must return to
monitor level.  At this time any files or programs which were LOADed
will slide down to the base of the user's memory partition.

SCALE is supported (scaled floating values) so that the bytes count
floating parameter returned to BASIC is properly scaled.

Edit history:
1-Jan-86  1.2(5)  Put back flushed line if it's not empty; removed
                 conditional assembly of SCALE, always supported.
2-Jan-86  1.3(6)  Simplify & improve.  Always try to get more freespace
                 unless no CMD file pending -- if flushed line is not
                 "!<cr>" then put it back.
2-Jan-86  2.0(7)  Simplify further.  Don't flush line if it is not "!", thus
                 avoiding the need to be prepared to put it back.
ENDC

SEARCH SYS
SEARCH SYSSYM
SEARCH TRM

Impure=A0
JCB=A1
Buffer=A2
ArgBas=A3
Worksp=A4
Stack=A5
TCB=A5
Atemp=A6

Free=D1
Number=D1
Length=D4
Dtemp=D6

SCALE=128       ; =offset to SCALE value in BASIC impure area

       PHDR    -1,0,PH$REE!PH$REU      ; re-entrant & re-usable

       jobidx  JCB
       tstw    JOBCMZ(JCB)             ; command file pending?
       beq     NoMore                  ; no, can't clear any more
       mov     JOBBAS(JCB),Buffer      ; find beginning of current cmd file
       add     JOBSIZ(JCB),Buffer
       subw    JOBCMZ(JCB),Buffer      ; now pointing to next byte
       cmpb    (Buffer)+,#'!           ; must be exclamation here
       bne     NoMore                  ; else can't flush for freespace
       lin                             ; must be followed by line terminator
       bne     NoMore
       pushw   JOBCMS(JCB)             ; save command file status
       movw    #c.sil,JOBCMS(JCB)      ; silence mode (suppress !<cr><lf>)
       mov     JOBTRM(JCB),TCB         ; yes, flush first line of command file
       pushw   T.STS(TCB)              ; save terminal status word
       andw    #^c<T$IMI!T$DAT>,T.STS(TCB) ; force line input mode
       kbd                             ; flush FREESP cmd file
       popw    Dtemp                   ; recall saved terminal status word
       andw    #^c<T$OIP>,Dtemp        ; clear old OIP bit
       orw     Dtemp,T.STS(TCB)        ; restore T.STS bits originally set
       popw    JOBCMS(JCB)             ; restore command file status

NoMore: tstw    @ArgBas                 ; parameter passed?
       beq     Done                    ; no, done
       cmpb    2(ArgBas),#4            ; floating?
       bne     Done                    ; no, ignore it
       usrend  Free                    ; get new user end
       usrfre  Atemp
       sub     Atemp,Free
       add     #4,Free                 ; because USRFRE goes 1 LWORD beyond
       sub     #8,sp                   ; get some workspace on user stack
       mov     sp,Worksp
       fltof   Free,@Worksp
       mov     Scale(Impure),D7        ; SCALE factor in use?
       beq     10$                     ; 0=no SCALE factor in use
       fpwr    @Worksp,D7              ; yes, scale the number
10$:    mov     4(ArgBas),Atemp
       movb    (Worksp)+,(Atemp)+      ; move byte-by-byte in case on
       movb    (Worksp)+,(Atemp)+      ; odd memory address
       movb    (Worksp)+,(Atemp)+
       movb    (Worksp)+,(Atemp)+
       movb    (Worksp)+,(Atemp)+
       movb    (Worksp)+,(Atemp)+
       add     #8,sp                   ; restore SP
Done:   RTN                             ; return to BASIC
       END