3.12.5 Memory-Management

Nur 60KB RAM der von PV-Programmen können normal genutzt werden und sind folgendermaßen aufgeteilt: Die Stack/near Abgrenzung existiert eher im Modell, man kann also den Stackspeicher auch teilweise für lokale Variablen verwenden - ohne etwas tun zu müssen, da der Stack und der near Speicher sozusagen aufeinanader zu arbeiten.

Man kann sich daß etwa so vorstellen: In einem Bücherregal fängt der near Speicher links oben (oberstes Brett) an und sortiert seine Bücher (Daten) von links nach rechts, von oben nach unten ein, dann startet das Programm das den Stack vergrößert/verkleinert - wobei der Stack rechts unten anfängt und seine "Bücher" zuerst rechts unten einsortiert und sich erst nach links und dann nach oben vorarbeitet... Irgendwann treffen sich dann Stack und near Speicher und der Stack schmeißt die Bücher des near Speichers raus und stellt die eigenen rein... Die Daten des near Speichers werden also überschrieben - genauso wirft dann der near Speicher die "Stackbücher" raus, wenn er eigentlich ein near-gespeichertes Buch durch ein neues ersetzen will oder liest im Stackbuch Daten
=> kurz: Stack und near Speicher benutzen dann den selben Speicher und überschreiben sich gegenseitig. Dadurch kommt es sehr schnell zu einem Absturz, da im Stack auch Rücksprungadressen bei Funktionsaufrufen gespeichert werden. Wenn die überschrieben werden, dann springt der Prozessor am Ende der Funktion im Programmcode "irgendwohin", aber sehr wahrscheinlich dorthin, wo er nicht soll...

ACHTUNG:

Der Compiler gibt keine Fehlermeldung aus, wenn beispielweise die near Daten 29Kb belegen...
=> folgender Code läßt den PV abstürzen, ohne daß Compiler oder Simulator was dran zu mäkeln haben:
#include <stdrom.h>

char test[28000];

void main() 
{
  LibJumpMenu();
}
Die RAM-Benutzung ist folgendermaßen (laut MEMMAP.TXT vom Simulator) dokumentiert:
=> alle Adressen sind Physikalische Adressen, dazu später mehr <=
1KB (00000h-003FFh) => Interruptvektoren
3KB (00400h-00FFFh) => Systemreserve #1
3200B(01000h-01C7Fh) => Bildspeicher (Zwischenspeicher vom Betriebssystem)
24,9K(01C80h-07FFFh) => Systemreserver #1 (Rest davon...)
32KB (08000h-0FFFFh) => far Daten-"Segment" für PV-Addins
33KB (10000h-183FFh) => Systemreserve #2
3KB (18400h-18FFFh) => "System Holds" für PV-Addins
20KB (19000h-1DFFFh) => near Daten-"Segment" für PV-Addins
8KB (1E000h-1FFFFh) => Stack-"Segment"
64KB (80000h-8FFFFh) => 1. 64KB Segment für PV-Addin-Programmcode/Static far Vars (Flash-ROM)
64KB (90000h-9FFFFh) => 2. 64KB Segment für PV-Addin-Programmcode/Static far Vars (Flash-ROM)
3200 Bytes (F0100h-F0D80h) => Bildspeicher (Hardware)

Interruptvektoren:


Hier werden für alle 256 Interrupts (von 0 bis 256) die Adressen gespeichert, die angesprungen werden, wenn diese ausgelöst wurden. Dabei werden 4 Bytes pro Adresse gespeichtert (1. Word: Offset, 2. Word: Segment). Die Adresse, wo eine Adresse für den jeweiligen Interrupt steht, errechnet sich einfach durch 4*InterruptNummer...

Systemreserve #1:


Hier speichert das PV-Betriebssystem Daten, wie die aktuelle Uhrzeit und soetwas...

far Daten-"Segment":


Hier werden als "far" deklarierte globale variablen gespeichert, die nicht als "static" deklariert sind.

Also beispielsweise:

int far test;
char far map[32][32];
Aber nicht:
static int far blah=293;
static int far foo=815;

static int far graphic[]= {
0xFF, 0xAA, 0xDD, 0x00, 0x00
.
.
.
0x00, 0x01, 0xBC, 0xDA, 0x00
}

Systemreserve #2:


Fragt mich nicht, was hier gespeichert wird, guckt mit dem Simulator, was passiert...

"System Holds" für Addins:


Keine Ahnung, aber hier werden wohl irgendwelche Sachen gespeichert, die das Betriebssystem zum Ausführen des Addins benötigt...

near Daten-"Segment" für PV-Addins:


Hier werden die globalen variablen abgelegt, die nicht als "far" (also "near") deklariert sind...

Z.B.:

int test;
char test2[32];
int dummy[7][7][7];

Stack-"Segment":


Hier werden die lokalen Variablen abgelegt, sowie Rücksprungadressen bei Funktionsaufrufen gespeichert...

z.B.:

void main() {
int test1;
char c;
.
.
.
}

Bildspeicher (Hardware/Betriebssystem):


Jedes Pixel belegt 1 Bit. Ein Byte speichert so 8 Pixel. 0 ist weiß, 1 ist schwarz... Das höchstwertigste Bit (welches den Wert 128 repräsentiert), ist das am weitesten linke auf dem Display. Die Bytes repräsentieren nacheinander je 8 Pixel einer Zeile von links nach rechts (20 Bytes je Zeile) und dann von oben nach unten...
Also: 160 Zeilen á 20 Bytes (mit 8 Pixel drin) = 3200 Bytes

Das Betriebssystem speichert seine Bilder erst in einem "Zwischenpuffer" bevor dieser dann mit "LibPutDisp();" in den "Hardwarespeicher" kopiert wird, von wo er dann wirklich angezeigt wird - damit wird verhindert, daß der evtl. langsame Bildaufbau zu sehen ist.

1./2. 64KB Segment für PV-Addin-Programmcode/Static far Vars (Flash-ROM):


Je nachdem, wie groß ein Programm ist, benutzt es 1 oder 2 64KB-Blöcke des Flash-Speichers der an diesen Adressen eingeblendet wird. Der Inhalt hat laut Doku folgende Reihenfolge:

<=64KB - Programme (S Model)
---------------------------
TEXT
_GHOST_DATA
_x_n_DATA
FAR_DATA

>64KB - Programme (P Model)
---------------------------
TEXT
_GHOST_DATA
<<<---------- Segmentgrenze
x_TEXT
_x_n_DATA
FAR_DATA
"TEXT" meint hier wohl "Programmcode"
"FAR_DATA" sind die Inhalte der als "static far" definierten Variablen, z.B. so:
static char far grafik[]= {
0x00, 0x10, 0xFF,
.
.
.
0x00, 0x10, 0xFF
}

Für Ergänzungen wenden Sie sich bitte an: Jürgen Wagner