Auf RAM im unreal-Mode zugreifen

Diskussion zum Thema Programmierung unter DOS (Intel x86)
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

DOSferatu hat geschrieben:
freecrac hat geschrieben:Da ich immer wußte wie viel Speicher ich eingebaut habe, deswegen war ich bisher noch zu faul es softwareseitig zu ermitteln. Und da ich oft auch eine RAM-Disk von 64 MiB für XMS-Speicher(Himem.sys) verwende, deswegen habe ich einfach den Speicher ab dem 65. MiB von bis zu knapp 1 Gib für meine Daten benutzt.
@freecrac: Bedeutet das, daß Deine Programme nur laufen, wenn mehr Speicher als 64 MB vorhanden sind?
Nur jene Programme von mir die ab dem 65 Megabyte Daten in den Speicher schreiben. Diese Programme brauchen dann auf jeden Fall mehr als 64 MB physikalisch vorhandenen Speicher.
Ohne die Ramdisk könnte man aber auch nur bis 64 MiB an Speicher für eigene Daten verwenden.

Jedoch können Bilddaten sehr viel Platz beanspruchen (zur Zeit verwende ich eine Auflösung von 1920x1200x32). Wenn Manipulationen des Bildschirm-Inhaltes vorgenommen werden sollen, dann ist es sinnvoll die neuen Bilddaten in einem anderen Speicherbereich erstmal aufzubreiten und erst wenn dieser Vorgang beendet ist, dann kopiert man alles zusammen in einem Rutsch in den Bldschirmspeicher. Das Lesen des Bildschirmspeicher-Inhaltes sollte man auf jeden Fall vermeiden, da dieser Vorgang um einiges langsamer ist als Schreibzugriffe dorthin. Wenn also der Inahlt des Bildspeichers benötigt wird, um mit diesen Daten Berechnungen anstellen zu können, dann nimmt man dafür besser eine Kopie des Bildschirminhaltes welche sich im Ram befindet.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

wobo hat geschrieben:
DOSferatu hat geschrieben:
freecrac hat geschrieben:Da ich immer wußte wie viel Speicher ich eingebaut habe, deswegen war ich bisher noch zu faul es softwareseitig zu ermitteln. Und da ich oft auch eine RAM-Disk von 64 MiB für XMS-Speicher(Himem.sys) verwende, deswegen habe ich einfach den Speicher ab dem 65. MiB von bis zu knapp 1 Gib für meine Daten benutzt.
@freecrac: Bedeutet das, daß Deine Programme nur laufen, wenn mehr Speicher als 64 MB vorhanden sind?
Ja. Aber ich glaube, seine Programme brauchen so oder so immer knapp 1 GB Minimum (hat er mal geschrieben).
Es kommt immer ganz darauf an was ich programmiere.

Mein Demo für die Verwendung vom "VESA hardware triple buffering" verwendet den Unrealmode nur, um in den LFB schreiben zu können.
Die "Neutrip.exe" belegt dabei selber nur 63480 Bytes im unteren 1 MiB-Speicherbereich.
http://www.alice-dsl.net/freecracmaps//Tool/Neutrip.zip
Dieses Programm benötigt einen CRT-Monitor mit mindestens 96 khz( wie es viele 19"-CRTs unterstützen), damit 100 hz in 1024x768x32 angeschaltet werden kann.
Und dieses Programm benötigt eine MMX-CPU, weil ich die 64Bit-MMX-Register zum Löschen von Bildbereichen verwende anstelle von nur 32 Bit-Register.
Die MMX-Befehle könnte man aber durch 32Bit-Befehle ersetzen, wobei ich aber Zweifel daran habe, dass ältere CPUs ohne MMX schnell genug für dieses Demo sind.
Geschrieben habe ich das Programm auf einen Rechner mit AMD Athlon Palomino(Sockel A(462)) 1800+ mit 1533 Mhz und einer Geforce 4 Ti 4200 (AGPx4 mit 64 MiB) von MSI.
(Eine GF4 von ASUS ist meinem Bruder schon vor Jahren kaputt gegangen. Meine GF4 von MSI läuft immer noch fehlerfrei obwohl ich diese Karte lange Zeit sogar übertaktet betrieben habe.)
Auch sollte es möglich sein die EDID des Monitors zu holen, weil dessen Kapazität überprüft wird um dort Schäden zu vermeiden, falls der Monitor nicht mit einer "Out of Sync"-Meldung selber abschaltet sollte, wenn dessen Kapazität nicht dafür ausreicht.
(5pol. BNC-Monitorkabel haben keinen Display-Data-Channel(DDC) und können deswegen nicht verwendet werden, um die EDID zu holen.)
Da ist es dann wurscht, wenn er die ersten 64 MB verschwendet.
Stimmt, mit einem GiB Speicher oder noch mehr braucht man nicht wirklich die ersten 64 MiB.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

DOSferatu hat geschrieben:Boah, was schreibt der denn fürn Zeug?! Ich wüßte gar nicht, womit ich EIN GIGABYTE vollkriegen soll...
Mit Bilddaten für hohe Bildmodi kann man ganz schnell 1 GiB an Speicher voll bekommen.

Auch schon für ein paar Sekunden Film-Daten mit sehr geringer Auflösung beispielweise von "Groby aus der Sesamstrasse" aufgenommen mit einer TV-Karte kommen schon ein paar Megabyte zusammen.
Dieses animated Gif von wenigen Sekunden Bildmaterial (besteht aus 130 Bildsequenzen) hat schon über 6 MiB an Grösse (danach wird es von vorne beginnend erneut zur Anzeige gebracht=looping):
Bild
Wegen der Grösse und auch wegen nicht vorhandenen Verwertungsrechten werde ich dieses Bild allerdings auch bald wieder von meiner Homepage löschen und auch aus diesem Beitrag entfernen.
Es soll hier nur mal als Beispiel dienen und aufzeigen, wie schnell sich ein Gigabyte mit Bildaten füllen lassen.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

TomCat hat geschrieben:hier die Routine(vereinfacht)

mov ax,data1
mov ds,ax
assume ds:data1
mov eax,0
mov fs,eax
Segmentregister sind nur 16 Bit gross und dürfen deswegen nur mit einem 16 Bit-Wert gefüllt werden:
mov fs, ax
mov Counter,0
Ohne Angabe auf wieviele Bytes hierbei zugegriffen werden sollen weiss der Assembler wohl nicht so genau was er tun soll.
So ist es sinnvoll es im Befehl mit anzugeben ob hier nur auf eine Byte, auf ein Word, oder auf ein Double-Word zugegriffen werden soll.

Bei NASM:
mov BYTE[Counter], 0
mov WORD[Counter], 0
mov DWORD[Counter], 0

Bei MASM:
mov BYTE PTR[Counter], 0
mov WORD PTR[Counter], 0
mov DWORD PTR[Counter], 0

mov edi,200000000 ;200 Millionen = Startadresse
Kurz mal nachrechen wo das eigentlich genau liegt.
Das erste Megabyte beginnt bei der linearen Adresse dezimal 1.048.576 entspricht hex 00100000h.
Dezimal 200.000.000 entspricht = 0BEBC200 hexadezimal = 190. Megabyte
mov esi,edi ;sichern der Startadresse

mov eax,0
mov ecx,10000000 ;10 millionen dwords werden geschrieben
40.000.000 dez = 02625A00 hex
+ 0BEBC200
= 0E4E1C00 ...Endet also knapp vor dem 229 Megabyte.
Das erste GiB endet bei 3FFFFFFF hex

Ich hoffe es hat sich kein Rechenfehler eingeschlichen.
;fuellen des speichers mit 32-bit werten.
loop1: mov fs:[edi],eax
add edi,4
inc eax
dec ecx
jnz loop1

;auslesen des speichers

mov edi,esi ;startadresse restaurieren
mov eax,0

mov ecx,10000000 ;10 mio

loop2: mov ebx,fs:[edi]
cmp ebx,eax
jne label_fehler
inc counter
add edi,4
inc eax
dec ecx
jnz loop2

label_fehler:
-----------------------------------------------------------------------

erklaerung: der counter zeigt mir an, wie lange die schleife laeuft, bis ein fehler aufgetreten ist. in abhaengigkeit des speicherbereichs oftmals 0 manchmel sogar ca. 100.000 durchlaeufe

und nein, ich verwende Ga20 nicht.
Mein RAM ist 1GB groß.
Huch ohne die 21. Adressleitung anzuschalten kann das nütrlich nicht gehen.

Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

Hier die Sub-Routine die ich benutze, um in den 16 Bit-Unrealmode zu schalten und ein kurzes Beipiel wie man darüber etwas in den Speicherbereich oberhalb des ersten MiB schreiben kann.
Hinweis: Es wird nur DS auf 4 GiB erweitert, wenn andere Segmentregister(ES, FS, oder GS) erweitert werden sollen, dann kann die betreffende Zeilen ggf. unten vom Semikolon befreit werden.
(Mit DS braucht man nicht in jedem Fall Segment-Overide-Prefixe, sondern nur wenn man (E)BP, oder (E)SP als Adressregister verwenden möchte und trotzdem über DS adressieren möchte, oder wenn man über andere Segmentregister etwas adressieren möchte.)
Am Ende befindet sich die Routine zum Freischalten der 21. Adressleitung. Auf meinen Rechnern funktionierte diese Routine bisher immer. Es gibt aber auch noch andere Methoden, falls es damit nicht funktionieren sollte.

Code: Alles auswählen

       NMI_Port = 70h

START:


;--------------------------------
	  cli                           ; Software-Interrupts ausschalten
	  in       al, NMI_Port         ; Über CMOS-Baustein auch
	  or       al, 80h              ; die NMIS abschalten
	  out      NMI_Port, al

	  call ESEG                     ; Segmente erweitern auf 32 Bit

	  in       al, NMI_Port         ; NMIs wieder einschalten
	  and      al, 7Fh
	  out      NMI_Port, al
	  sti                           ; Software-Interrupts einschalten

;--------------------------------
; Beispiel:
;--------------------------------
          xor     eax, eax
          mov     ax, DATEN       ; Die genau Adresse unseres Datensegments wird vom Assembler eingetragen
          mov     ds, ax
          shl     eax, 4
          mov     edi,  lineare 32 Bit Adresse oberhalb des ersten MiB
          sub     edi, eax
          mov     si, OFFSET TABELLE
          mov     eax, [si]        ; Wir holen aus einer Tabelle im Datensegment ein DWORD über DS:SI
          mov     [edi], eax       ;   und schreiben es über DS:EDI zu einer Adresse oberhalb des ersten MiB.
;         .....



;────────────────────────────────────────────────────────────────────────────
;                     GDT für den Protected Mode
;────────────────────────────────────────────────────────────────────────────
 org START + ((($-START)/64)*64)+64     ; Code-Ausrichtung
;----------------------------------------------------------------------------
GDTZEIGER DW ?      ; Länge der GDT
	  DW ?      ; Adresse low -Word:SEGMENTE
	  DW ?      ; Adresse high-Word:SEGMENTE
	  DW 0      ; reserviert

SEGMENTE  DW 0      ; Bits: 0-15 Seg.länge(Bit0-15)
	  DW 0      ; Bits: 0-15 Basis-Adresse Deskriptor-Table
	  DB 0      ; Bits:16-23 Basis-Adresse Deskriptor-Table
	  DB 0      ; Bits: 0- 7 Zugriffsrechte
	  DB 0      ; Bits: 0- 3 Seg.länge(Bit16-19)/Bit7:1=4KByte/0=1Byte
	  DB 0      ; Bits:24-31 Basis-Adresse Deskriptor-Table

;-------------------------------------------- Selektor    Segmente
       DW 0FFFFh ; Segmentlänge   Bits: 0-15  ┬──────┬  ┬─────────┬
       DW 0      ; Adresse low    Bits: 0-15  │ 08h  │  │Code (CS)│
       DB 0      ; Adresse high   Bits:16-23  └──────┘  └─────────┘
       DB 9Ah    ; Zugriffsrechte
       DB 0      ; Seg.Länge Bits:16-19 im Bit0-3 /Bit7:1=4KByte/0=1Byte
       DB 0      ; Seg.Adresse    Bits:24-31
;--------------------------------------------------- Selektor    Segmente
       DW 0FFFFh ; Segmentlänge   Bits: 0-15  ┬──────┬  ┬──────────┬
       DW 0      ; Adresse low    Bits: 0-15  │ 10h  │  │Stack (SS)│
       DB 0      ; Adresse high   Bits:16-23  └──────┘  └──────────┘
       DB 92h    ; Zugriffsrechte
       DB 0      ; Seg.Länge Bits:16-19 im Bit0-3 /Bit7:1=4KByte/0=1Byte
       DB 0      ; Seg.Adresse    Bits:24-31
;--------------------------------------------------- Selektor    Segmente
       DW 0FFFFh ; Segmentlänge   Bits: 0-15  ┬──────┬ ┬─────────────┬
       DW 0      ; Seg.Adresse    Bits: 0-15  │  18h │ │(DS,ES,FS,GS)│
       DB 0      ; Seg.Adresse    Bits:16-23  └──────┘ └─────────────┘
       DB 92h    ; Zugriffsrechte
       DB 0FFh   ; Seg.Länge Bits:16-19 im Bit0-3//Bit7:1=4KByte/0=1Byte
       DB 0FFh   ; Seg.Adresse    Bits:24-31
;---------------------------------------------------
	SEGMENTE_END label WORD
	Gdt_Groesse equ (OFFSET SEGMENTE_END - SEGMENTE -1)
;────────────────────────────────────────────────────────────────────────────
; Setzt für das DS,ES,FS,GS-Register eine neue Segmentlänge von 00FFFFFFh.
; Dazu wird in den Protected Mode umgeschaltet.
;────────────────────────────────────────────────────────────────────────────
 org START + ((($-START)/32)*32)+32              ; Code-Ausrichtung
;----------------------------------------------------------------------------
ESEG:     xor      eax, eax
	  mov      ax, cs
	  mov      ds, ax
	  shl      eax, 4                        ; EAX ist nun physikalische
	  mov      ebx, eax                      ; Segmentstartadresse
	  mov     WORD PTR[SEGMENTE+0Ah], ax     ; in den Deskriptoren
	  mov     WORD PTR[SEGMENTE+12h], ax     ; für CS
	  ror      eax, 10h                      ; und SS in der
	  mov     BYTE PTR[SEGMENTE+0Ch], al     ; GDT abspeichern
	  mov     BYTE PTR[SEGMENTE+14h], al
	  xor      eax, eax                      ; EAX auf null
	  mov      ax, OFFSET SEGMENTE           ; 16-Bit-Offset
	  add      ebx, eax                      ; GDT-Adresse im
	  mov     WORD PTR[GDTZEIGER], Gdt_Groesse ; GDT-Deskriptor
	  mov     DWORD PTR[GDTZEIGER+2], ebx

	  pushf                                  ; Flags retten
	  lgdt    FWORD PTR[GDTZEIGER]           ; GDT laden
	  mov      dx, ss                        ; SS retten
	  mov      eax, cr0                      ; Steuerwort 0 nach EAX
	  or       al, 1                         ; Protected Mode ein
	  mov      cr0, eax                      ; im Steuerwort
						 ; Prefetch-Puffer löschen
	  DB  0EAh                               ; die folgenden Zeilen
	  DW  (OFFSET PMODE)                     ; erzeugen:
	  DW  8                                  ; JMP FAR CS:PMODE
;------------------------------------------------
 org START + ((($-START)/32)*32)+32              ; Code-Ausrichtung
;------------------------------------------------
PMODE:    mov      ax, 10h                       ; SS-Selektor auf 64
	  mov      ss, ax                        ; KByte begrenzen
	  mov      ax, 18h
	  mov      ds, ax                        ; DS,ES,FS,GS-Selektoren
;          mov      es, ax                        ; auf 16 MByte erweitern
;          mov      fs, ax
;          mov      gs, ax

	  mov      eax, cr0                      ; Steuerwort 0 nach EAX
	  and      eax, not 1                    ; Protected Mode aus
	  mov      cr0, eax                      ; im Steuerwort
						 ; Prefetch-Puffer löschen
	  DB  0EAh                               ; Die folgenden Zeilen er-
	  DW  (OFFSET RMODE)                     ; zeugen das Kommando
AKTSEG    DW  (SEG RMODE)                        ; JMP FAR CS:RMODE
;------------------------------------------------
 org START + ((($-START)/32)*32)+32              ; Code-Ausrichtung
;------------------------------------------------
RMODE:    mov      ss, dx                        ; SS zurueck
	  popf                                   ; Flags holen
;----------------------------------------------------------------------------
;           Schaltet   das   21. Adreßbit   des   Prozessors   ein.
;----------------------------------------------------------------------------
BIT_FREI: call W_8042        ;   Warte auf 8042
	       jnz BACK 
	       mov      al, 0D1h  ;  Kommando schreiben
     	  out      64h, al 
	       call W_8042        ;  fertig zum Emnpfang ?
	       jnz BACK 
	       mov      al, 0DFh  ;  ja,Leitung 20 freischalten
	       out      60h, al
;------------------------------------------------------------
;           Wartet   darauf,  bis  der  8042 bereit  ist.
;------------------------------------------------------------
W_8042:   xor      cx, cx    ;   CX=0
STATUS:   in       al, 64h   ;  Status lesen
	       and      al, 2     ; Puffer voll ?
	       loopnz STATUS      ; bis nein oder Timeout
BACK:     ret 
Dirk
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von TomCat »

Also bin auf was Interessantes gestossen. Wenn ich vorher den interruptvektor vom Timer lese (ax=3508h; int 21h), kann ich nachher problemlos auf den Ram zugreifen. Wenn nicht funktioniert es nicht einwandfrei. Hat da evtl. jemand eine Erklärung dafür?
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von TomCat »

freecrac hat geschrieben:
DOSferatu hat geschrieben:
freecrac hat geschrieben: Jedoch können Bilddaten sehr viel Platz beanspruchen (zur Zeit verwende ich eine Auflösung von 1920x1200x32). Dirk
Sag mal wie stellst du diese Auflösung ein??
Mit VESA ist mir max. 1600x1200x32 bekannt.

TomCat
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

TomCat hat geschrieben:
freecrac hat geschrieben: Jedoch können Bilddaten sehr viel Platz beanspruchen (zur Zeit verwende ich eine Auflösung von 1920x1200x32). Dirk
Sag mal wie stellst du diese Auflösung ein??
Mit VESA ist mir max. 1600x1200x32 bekannt.

TomCat
Neuere GraKas wie meine GTX 295 (von Colorfull) unterstützen auch Vesamodi für widescreen-Auflösungen.
Es soll sogar welche geben die eine Auflösung von 2560x1536 über das VBE-Bios unterstüzen.

Hier ist eine Mail-Antwort von "Dan Hudgins" vom 14.04.2010 auf eine diesbezügliche Anfrage von mir:
Hi Dirk,

The PNY GeForce 6200 256MB works in linear memory mode at 2048x1536x32bit (24+8) under VBE 2.0 and probably VBE 3.0.

Some of the lower modes are not there thhough, but 2048x1526x32 is!

For 1920x1440 and all the other modes the SIS cards are better.

If you find a board that works over the full screen in banked modem VBE 1.2, please let me know as that would be a big help to me!

IBM made a LCD monitor 2048x1536 with analog input that might work with the GeForce but it costs like $3000 used!

So I use a CRT monitor at the 2048x1536 resolution for my Digital Cinema programs...

Thank you,

Dan Hudgins
tempnulbox@yahoo.com
http://www.DANCAD3D.com
San Francisco, CA USA
Und hier ist die Vesa-Modeliste aus dem VBE-3-Bios meiner GTX 295 vom Kartenhersteller "Colorfull":

Code: Alles auswählen

Vesamode,XRes,YRes,Bits per Pixel,Adresse des Framebuffer
0100 640x400x8 01080000 
0101 640x480x8 01080000 
0102 800x600x4 
0103 800x600x8 01080000 
0104 1024x768x4 
0105 1024x768x8 01080000 
0106 1280x1024x4 
0107 1280x1024x8 01080000 
010E 320x200x16 01080000 
010F 320x200x32 01080000 
0111 640x480x16 01080000 
0112 640x480x32 01080000 
0114 800x600x16 01080000 
0115 800x600x32 01080000 
0117 1024x768x16 01080000 
0118 1024x768x32 01080000 
011A 1280x1024x16 01080000 
011B 1280x1024x32 01080000 
0130 320x200x8 01080000 
0131 320x400x8 01080000 
0132 320x400x16 01080000 
0133 320x400x32 01080000 
0134 320x240x8 01080000 
0135 320x240x16 01080000 
0136 320x240x32 01080000 
013D 640x400x16 01080000 
013E 640x400x32 01080000 
0145 1600x1200x8 01080000 
0146 1600x1200x16 01080000 
014A 1600x1200x32 01080000 
0160 1280x800x8 01080000 
0161 1280x800x32 01080000 
0162 768x480x8 01080000 
0166 1600x900x16 01080000 
0167 1600x900x32 01080000 
0170 1600x900x8 01080000 
017B 1280x720x32 01080000 
017C 1920x1200x8 01080000 
017D 1920x1200x32 01080000 
Dirk
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

TomCat hat geschrieben:Also bin auf was Interessantes gestossen. Wenn ich vorher den interruptvektor vom Timer lese (ax=3508h; int 21h), kann ich nachher problemlos auf den Ram zugreifen. Wenn nicht funktioniert es nicht einwandfrei. Hat da evtl. jemand eine Erklärung dafür?
Das kann ich mir gar nicht erklären.
Mit welchem DOS geht das so und wurde vorher ein Memmorymanager wie Himem.sys, oder Emm386.exe gestartet?

Dirk
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von TomCat »

freecrac hat geschrieben:
TomCat hat geschrieben:Also bin auf was Interessantes gestossen. Wenn ich vorher den interruptvektor vom Timer lese (ax=3508h; int 21h), kann ich nachher problemlos auf den Ram zugreifen. Wenn nicht funktioniert es nicht einwandfrei. Hat da evtl. jemand eine Erklärung dafür?
Das kann ich mir gar nicht erklären.
Mit welchem DOS geht das so und wurde vorher ein Memmorymanager wie Himem.sys, oder Emm386.exe gestartet?

Dirk
Arbeite mit DOS 6.22. Ich habe nur einen Ram-Drive mit 64MB am Laufen. hat aber scheinbar damit nichts zu tun. Ich habe in meinem Code alles rausgeworfen um festzustellen welche Funktion mir anscheinend den Gate öffnet. Und es ist eindeutig dieses Lesen des Interruptvektors des Timers. Was noch sehr interessant ist, ich muss sogar jedesmal beim Programmstart den UNreal-Mode neu initialisieren, d.h. er bleibt nicht erhalten und ich kann nicht mal mehr den Grafik-Flat-Memory benutzen. Auch etwas dass ich nicht verstehe. Hat jemand eine Erfklärung dafür

TomCat
wobo
DOS-Guru
Beiträge: 614
Registriert: So 17. Okt 2010, 14:40

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von wobo »

Den unreal/16bit initialisiere ich auch immer bei jedem Programmstart. Ich weiß ja nicht, was ein ggf. zwischenzeitlich gestartetes Programm mit den Segmentdeskriptoren macht. Unreal bei jedem Programmstart zu initialisieren ist m.E. Standard.

Du hast ja eine RAM-Disk in den ersten 64 MB, d.h. diese greift auf jeden Fall auf den XMS zu. Was diese RAM-Disk dabei macht, weißt Du ja nicht. Wenn Sie den Zugriff auf das XMS mittels himem.sys macht, dann schaltet himem.sys meinen Tests nach selbst in den unreal (für die REgister ds und es, nicht aber für fs und gs), sobald das erste Mal eine XMS-Kopierroutine aufgerufen wird. Nach Beendigung der XMS-Kopierroutine schaltet bei mir himem.sys die Register ds und es jedenfalls nicht zurück auf 16bit-Segmente. Es könnte aber sein, dass himem.sys in anderen Situationen die 16bit-Segmente wieder zurücksetzt.

Warum das Lesen der IntVec-Tabelle das Gate A20 öffnet, kann ich mir auch nicht erklären. Wenn Du es weißt, lass es uns ruhig wissen ;-) Hast Du in DOS mit DOS=HIGH hochgeladen, so dass es den ersten 64k-Abschnitt nach der 1-MB-Grenze nutzt? Dann müßte Dos ja natürlich auch irgendwann das Gate A20 öffnen, wobei ich eigentlich davon ausging, dass das ganz am Anfang (nämlich beim Hochladen) bereits passiert...
TomCat
MemMaker-Benutzer
Beiträge: 87
Registriert: Do 1. Dez 2011, 17:16

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von TomCat »

wobo hat geschrieben:Den unreal/16bit initialisiere ich auch immer bei jedem Programmstart. Ich weiß ja nicht, was ein ggf. zwischenzeitlich gestartetes Programm mit den Segmentdeskriptoren macht. Unreal bei jedem Programmstart zu initialisieren ist m.E. Standard.

Du hast ja eine RAM-Disk in den ersten 64 MB, d.h. diese greift auf jeden Fall auf den XMS zu. Was diese RAM-Disk dabei macht, weißt Du ja nicht. Wenn Sie den Zugriff auf das XMS mittels himem.sys macht, dann schaltet himem.sys meinen Tests nach selbst in den unreal (für die REgister ds und es, nicht aber für fs und gs), sobald das erste Mal eine XMS-Kopierroutine aufgerufen wird. Nach Beendigung der XMS-Kopierroutine schaltet bei mir himem.sys die Register ds und es jedenfalls nicht zurück auf 16bit-Segmente. Es könnte aber sein, dass himem.sys in anderen Situationen die 16bit-Segmente wieder zurücksetzt.

Warum das Lesen der IntVec-Tabelle das Gate A20 öffnet, kann ich mir auch nicht erklären. Wenn Du es weißt, lass es uns ruhig wissen ;-) Hast Du in DOS mit DOS=HIGH hochgeladen, so dass es den ersten 64k-Abschnitt nach der 1-MB-Grenze nutzt? Dann müßte Dos ja natürlich auch irgendwann das Gate A20 öffnen, wobei ich eigentlich davon ausging, dass das ganz am Anfang (nämlich beim Hochladen) bereits passiert...
ich schmeisse mal den Ram-Drive raus und teste noch mal alles durch. Mal sehen was dann alles Sache ist...

TomCat
Brueggi

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von Brueggi »

Sorry, wenn ich da kurz etwas einschiebe. Gibts irgendwo ein gutes Tutorial zum 32-Bit-Protected-Mode? Konkret: Was muss ich einrichten, bevor ich den PM nutzen kann, wie kann ich wieder zum RM wechseln usw. Ich will ja so langsam aber sicher mal zu BDOS/386 wechseln - wobei der Unreal-Mode jetzt grundsätzlich gut ist, aber wohl eher nur eine Art RAM-Disk ist - wenn, dann soll man auch Programme in Speicher > 1 MB laden können.

Und noch eine Frage: Kann es sein, das die Bios-Routinen in Int $15 immer A20 deaktivieren? Ich hab bei meinem 486 schon alles versucht - sobald ich BIOS-Routinen verwende, um Speicher zu transfierieren, scheint danach jedes mal A20 aus zu sein, und lässt sich auch nicht wieder anschalten (z. B. über den Tastatur-Controller). Das Ergebnis ist immer ein Freeze :-(
freecrac
DOS-Guru
Beiträge: 861
Registriert: Mi 21. Apr 2010, 11:44
Wohnort: Hamburg Horn

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von freecrac »

Brueggi hat geschrieben:Sorry, wenn ich da kurz etwas einschiebe. Gibts irgendwo ein gutes Tutorial zum 32-Bit-Protected-Mode? Konkret: Was muss ich einrichten, bevor ich den PM nutzen kann, wie kann ich wieder zum RM wechseln usw. Ich will ja so langsam aber sicher mal zu BDOS/386 wechseln - wobei der Unreal-Mode jetzt grundsätzlich gut ist, aber wohl eher nur eine Art RAM-Disk ist - wenn, dann soll man auch Programme in Speicher > 1 MB laden können.
Für den 32 Bit PM gibt es eine Menge Dinge zu beachten. Um in den RM zurücktzkommen muss man unterscheidliche Dinge beachten, beispielsweise ob man Paging aktiviert hat.
Um in den 32 Bit-Mode zu kommen ist das D-Flag zu setzen.
http://www.lowlevel.eu/wiki/Protected_Mode
D-Bit
Dieses Bit gibt an, ob es sich um ein Segment für den 286 (Datensegment max. 64 kB, Code = 16 Bit, Stack = 16 Bit) oder ein Segment für den 386 (Datensegment max. 4 GB, Code = 32 Bit, Stack = 32 Bit) handelt.
Der Code wird damit als 32 Bit-Code ausgeführt. Das bedeutet das ohne die Verwendung von Registersize/Adresssize/Operandsize-Prefixe die benutzten Adressen/Operanden/Register eines Befehls als 32 Register/Adressen interpretiert und ausgeführt werden. So wird der verwendete Code in der Regel kürzer. Wenn jedoch nur die unteren 16 Bit einer Adresse/Operanden/Registers verwendet werden sollen, dann muss jeweils ein Prefix verwendet werden.
Die Bedeutung der Prefixe kehrt sich um je nachdem ob das D-Bit gesetzt ist. Mit den Einträgen für die Segmentgröße im GDT oder LDT ob nun auf 64 KB, oder auf 4 GiB eingestellt, hat das aber eigentlich nur wenig zu tun. Denn auch im 16 Bit PM kann man auf einem 80386+ die Segmentgrösse auf 4 GiB einstellen und darauf zugreifen. Die Gleichung 16 Bit = max. 64 KiB Segmentgrösse ist nur für 16 Bit-CPUs gültig, bei denen ein D-Bit gar nicht vorhanden ist. :???:

Assembler-Directive:
http://courses.engr.illinois.edu/ece390 ... ctive.html
When NASM is in BITS 16 state, instructions which use 32-bit data are prefixed with an 0x66 byte, and those referring to 32-bit addresses have an 0x67 prefix. In BITS 32 state, the reverse is true: 32-bit instructions require no prefixes, whereas instructions using 16-bit data need an 0x66 and those working in 16-bit addresses need an 0x67.
http://webster.cs.ucr.edu/Page_TechDocs ... hap_13.htm
http://www.arl.wustl.edu/~lockwood/clas ... H08-3.html

Ein kurzer Überblick:
http://www.tecchannel.de/server/prozess ... en_teil_4/
Und noch eine Frage: Kann es sein, das die Bios-Routinen in Int $15 immer A20 deaktivieren? Ich hab bei meinem 486 schon alles versucht - sobald ich BIOS-Routinen verwende, um Speicher zu transfierieren, scheint danach jedes mal A20 aus zu sein, und lässt sich auch nicht wieder anschalten (z. B. über den Tastatur-Controller). Das Ergebnis ist immer ein Freeze :-(
Vieleicht hat dieser Schalter da etwas mit zu tun?
http://www.msdosbefehle.de/himemsys-ms- ... -t250.html
/a20controhonloff

Bezeichnet, ob HIMEM.SYS die Steuerung der A20-Leitung auch dann übernehmen soll, wenn A20 beim Laden von HIMEM.SYS aktiviert war.

Falls Sie /a20controhoff angeben, übernimmt HIMEM.SYS die Steuerung der A20-Leitung nur dann, wenn A20 beim Laden von HIMEM.SYS deaktiviert war. Standardmäßig ist /a20control:on gesetzt.
Dirk
Brueggi

Re: Auf RAM im unreal-Mode zugreifen

Beitrag von Brueggi »

Huii :-) Danke für die ausführliche Antwort.
Das arbeite ich mal in Ruhe durch :-)

Das A20-Problem übrigens besteht auch, wenn kein Himem oder gleichwertiger Treiber geladen wurde.
Antworten