back : next : content =


3               System


3.1                   Memory

The system provides several means of memory management and control, depending on the actual memory area and usage.

Any sorts of memory allocations have one thing in common: Their address is not pre determinable. Which results to the requirement of fully relocatable program codes, and position independent memory addressing.

The SBasic interpreter is an example which uses a wide variety of those techniques. The program can be moved while it is running, the only stable reference remaining the relative positions with regard to the base register, A6.

For multitasking shared code "re-entrancy" as another requirement has to be met..

3.1.1   *       Memory map

General memory usage is explained in the user manual as follows:
SV_RESPR : Resident Procedure Area, rpa
 SV_TRNSP : Transient Program Area, tpa
 SV_BASIC : SuperBASIC Area, sba
 SV_FREE : Free (for system use only)  memory area
 SV_CHEAP : Common Heap, System Heap, User Heap
SV_BASE : Base of System variables.

3.1.2   *       Memory Management

The RAM is a most important resource, supplying the computers workspace, where the active programs and any immediately accessible data reside.

Differently to other computer systems the system itself takes over all memory management, allocating as efficiently as possible, moving around, cacheing disc data, etc. with no direct user (or programmers) interference. Any freely useable area should be requested from the system (MT_ALCHP, etc.) before reliably being available for whatever purpose.

Depending on the allocation type/area the system acts differently, and different allocation procedures are valid: - Resident (S*Basic) Procedures

                (SV.RESPR(sb) to SV.RAMT(sb)-1)

This area is falsely maintained by SMSxx (SV.RESPR set equal to SV.RAMT)!

A user memory area protected against interference by the system. Code loaded here can thus safely modify the system, itself, and store protected user data.
It is the area where S*Basic extensions will be stored to, regularly.
It is extendable only if no transient job exists (re below).

The manager traps MT.ALRES (1/22) and MT.RERES (1/23) allocate and de-allocate resident memory. MT.RERES is non-functional in the genuine QL-ROMs, not implemented in SMSxx. It is properly implemented in the MINERVA systems, only. - Transient Programs (QDOS-Jobs)

(SV.TRNSP(sb) to SV.RESPR(sb)-1)
This area expands from SV.RESPR, by moving the SBasic area (re below) into "free" memory to lower addresses, according to de-/allocations by MT.ALCHP rsp MT.RECHP (1/24, 25), and with de-/installation of QDOS jobs by MT.CJOB (1/1), and MT.RJOB (1/4) or MT.FRJOB (1/5).
MT.FREE (1/16) returns the size of the greatest consecutively free - allocatible - area. - Basic

                (SV.BASIC(sb) to SV.TRNSP(sb)-1)

The (first) S*Basic command interpreter job resides in this changeable(!) area, being installed at system start-up, automatically by QDOS.
The S*Basic jobs are movable and re-sizeable, at any time, by their own and other jobs memory requirements, by the means of MT.ALBAS (1/22) and MT.REBAS (1/23).

Provided sufficient understanding of the S*Basic jobs structures those traps could be used for any other sort of movable and re-sizeable jobs, in non SMSxx systems. Sadly, those traps are falsely  implemented (buggy!) and access to the relating QDOS vectors "protected" in quite a silly manner against that sort of useage (thus disrupting the development of a truely multitasking shell program of my own, and other programs).
Recent SMSxx specifications do not explain the above traps, any more. - Heap Areae

                (SV.HEAP(sb) to SV.BASIC(sb)-1)

Heap Management {1}, "heap fragmentation" example:

For instance, starting with an empty (transient) heap memory a first job, 'A', was executed, allocating some space at "area A":

- free -
 area A

Another job, 'B', executes, allocating some workspace at "area B", and the next at "area C":

- free -
area C
area B
 area A

After 'B' was done, and removed from memory, the system deallocates its memory, relinking it to the list of available heap memory:

- free -
area C
- free -
 area A

Another job, 'D', executes, with a very modest memory allocation which fits into the empty space left by 'B':

- free -
area C
- free -
 area A

The next job, 'E', need a huge area, allocated at "area E":

area E
area C
- free -
 area A

Now 'A' allocates some additiona space, filling up the gap left from 'B':

area E
area C
more A
 area A

The "heap fragmentation" now comes to effect if job 'A' terminates:

area E
- free -
- free -

Another job of about the same size as 'E' would fit into the remaining memory if its requirements could have been splitted  into two pieces. - Which QDOS does not permit, thus inhibiting that jobs invocation.

Without the further allocation for some system program, 'S', maybe a new device definition, or just the maintanance memory blocks allocated by a directory device handler when accessing an until then unused drive, the consecutive space would have been restored after removal of job 'D'.

This is the situation commonly known as "heap fragmentation", which by normal means is not recoverable (only "DEL_DEFB" of TK2 would help, in the above eample).
The system itself does not provide any means of control over the heap fragmentation.

Only the user has some limited control by allocating memory areae and executing jobs in a carefully selected manner. Further, the device tables can be put together at low memory by calling, for instance, a procedure which reads the directories of the devices which are planned to be used most frequently, as one of the very first actions immediately after the systems startup.         *       Queue

A queue, allocated with MT.ALCHP (1/24), is an area of memory, with some rudimentary management of data i/o, initiated with the QDOS-vector IO.QSET ($DC).

eoff |     nextq     
0 = base addres 4:end ptr 8:write ptr 12:read ptr 16+: dataspace...

The queue structure leads to the first QDOS device definition:

The simplest QDOS device is the PIPE, giving orderly acces to a queue via trap #3 calls, as a uni-directional data transfer memory device. A second queue can be linked into the device definition, providing for the opposite directional data transfer.
Also, the same address can be entered to the input and output queue pointer, forming a bi-directional PIPE (several S.Basic extensions provide the appropriate procedures).

  top : back : next : content