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_RAMTOP : Ram Top
- $0020(sb) top of available memory
The 1st address which is NOT available in the physical RAM area.
SQ: Falsely set equal to SV_RESPR.
SV_RESPR : Resident Procedure Area, rpa
- $001C(sb)
Permanently allocated memory area. Cannot be de-allocated. A user memory area, (fairly) safely protected against unwanted modifications by the system.
This area is NOT meant to be write protected! It is just some safe user memory, taken off from the QDOS memory management, for that purpose (re above, SMSQ & RAMTOP).
SV_TRNSP : Transient Program Area, tpa
- $0014(sb)
This is where executable programs ("jobs") will be allocated.
SV_BASIC : SuperBASIC Area, sba
- $0010(sb) The SBasic Interpreter
A movable and resizeable(!) memory area, preferably for the SBasic job(s).
SQ: No chance for user defined programs, any more, because of different (incompatible, apparently by purpose) management!
SV_FREE : Free (for system use only) memory area
- $000C(sb)
Everything not explicitly allocated to any job, task, device, data management is the "free memory" - managed by the system, and not freely accessible by an application.
SV_CHEAP : Common Heap, System Heap, User Heap
- $0004(sb)
Allocation area for devices, channels and other system tables.
SV_BASE : Base of System variables.
- $0000(sb)
Beginning at address $28000 in standard systems, only. Can be allocated anywhere in memory, the actual address will be found with the QDOS trap MT.INF (0/1).
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:
3.1.2.1 - 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.
3.1.2.2 - Transient Programs (QDOS-Jobs)
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).(SV.TRNSP(sb) to SV.RESPR(sb)-1)
MT.FREE (1/16) returns the size of the greatest consecutively free - allocatible - area.
3.1.2.3 - 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.
3.1.2.4 - Heap Areae
(SV.HEAP(sb) to SV.BASIC(sb)-1)
- Common Heap: for programs and (user) data.
- System Heap: system tables, device definition data, channel description tables, system workspace.
- User Heap: separately maintained sub-areae of and within previously allocated common heap blocks.
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 - D area A
The next job, 'E', need a huge area, allocated at "area E":
area E area C - free - D area A Now 'A' allocates some additiona space, filling up the gap left from 'B':
area E area C more A D area A
The "heap fragmentation" now comes to effect if job 'A' terminates:
area E - free - S D - 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.
3.1.2.5 * 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 end nextin nextout queue 0 = base addres 4:end ptr 8:write ptr 12:read ptr 16+: dataspace...
- Q.EOFF
Bit#7 at the queue base address, if set, serves as the EOF flag.- Q.NEXTQ
user definable, can point to a follow-up queue, or to some other system address.- Q.END
points to the addres AFTER the last byte of the queues dataspace.
SQ: in CON-channel-queues address of the last byte WITHIN the queue.- Q.NEXTIN
points to where the next input byte will be written to.- Q.NEXTOUT
points to where the next output byte will be fetched from.- Q.QUEUE
1st byte of the data storage area.
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).