Nicht behebbarer Prozessorfehler beim Wechsel in P-Mode



  • Ohjee..

    Eigentlich hatte ich nicht vor das Forum mit Beiträgen zu füllen aber ich komme wieder mal nicht weiter.

    Ich versuche vom Dos aus in den P-Mode zu schalten und direkt wieder zurück in den R-Mode.

    Dazu habe ich mir die drei GDT-Einträge von Herrn Henkes zur Hilfe genommen.
    Das A20 Gate wir über eine Prozedur von LowLeval angeschaltet.

    Da ich keine Bootloader habe sondern von DOS starte, lade ich die ersten beiden Byte der Segment Basis Adresse erst im Programm.

    CS nach AX * 16 = Basis des Segments.

    Ansonsten habe ich alles so gemacht wie Herr Henkes in seinem Projekt.

    Hier mal der Code der den Prozessor lahmlegt.

    org 100h
    
    	xor eax, eax
    	xor ebx, ebx
    	xor ecx, ecx
    	xor edx, edx
    
    	mov ax, cs
    	mov word [segm], ax
    
    	mov cl, 4d
    	shl eax, cl
    	mov word [sbase1], ax
    	mov word [dbase1], ax
    
    a1:
        	in 	al, 0x64      	;Tastatur-Controller-Statusbyte lesen
         	test 	al, 00000010b 	;Ist Bit 1 gesetzt?
         	jnz 	a1            		;Wenn ja, dann wiederhole
    
         	mov   al, 0xD0 		;Befehl zum Lesen des Output-Port-Statusbytes in AL speichern
         	out   0x64, al 		;Befehl an 
    
    a2:
         	in    al, 0x64       		;Tastatur-Controller-Statusbyte lesen
         	test  al, 00000001b  	;Bit 0 testen, ob es gesetzt ist
        	jz    a2 
    
         	in    al, 0x60       		;Output-Port-Statusbyte von Tastatur-Chip lesen
         	or    al, 00000010b  	;Bit 1 auf 1 setzen (A20Gate-Enable-Bit)
         	push  eax            
    
    a3:
         	in    al, 0x64       		;Tastatur-Controller-Statusbyte lesen
         	test  al, 00000010b  	;Ist das Bit 1 gesetzt?
         	jnz   a3
    
         	mov   al, 0xD1  		;Befehl zum Schreiben des Statusbytes des Output-Ports in AL schreiben
         	out   0x64, al 
    
    a4:
         	in    al, 0x64       		;Tastatur-Controller-Statusbyte lesen
         	test  al, 00000010b  	;Ist das Bit 1 gesetzt?
        	jnz   a4   
    
         	pop   eax       		;Statusbyte vom Stack holen
         	out   0x60, al  
    
    	cli
    	lgdt [gdtr]      		;Laden der GDT via GDTR 
    
    	mov eax, cr0      	;Springe zum P-Mode
        	or  eax, 1        		; setze Bit 0 auf 1
        	mov cr0, eax      	; 
    
        	jmp 0x8:pmode 
    
    pmode:
    	mov    ax, 0x10
        	mov    ds, ax      		; GDT'S zuordnen
        	mov    ss, ax             
       	mov    es, ax
        	mov    fs, ax
        	mov    gs, ax
    
        	mov eax, cr0      	; Umschalten zum Real Mode
        	xor eax, eax		; Bit 0 löschen
        	mov cr0, eax      	;
    
    	jmp rmode
    
    rmode:
    	mov ax, word [segm]
    	mov cs, ax
    	mov ds, ax
    	sti
    
    pende:
    	;call modus3			;Videomodus 3 einstellen
    	mov eax, 4C00h
    	int 21h				;programm beenden
    
    ;### Variablen
    
    NULL_Desc:
        dd    0
        dd    0
    
    CODE_Desc:
        dw    0xFFFF        		; segment length  bits 0-15 ("limit")    
    sbase1 dw    0             		; segment base    byte 0,1
        db    0             			; segment base    byte 2    
        db    10011010b     		; access rights
        db    11001111b     		; bit 7-4: 4 flag bits:  granularity, default operation size bit, 
                            			; 2 bits available for OS
                            			; bit 3-0: segment length bits 16-19 
        db    0             			; segment base    byte 3    
    
    DATA_Desc:
        dw    0xFFFF        		; segment length  bits 0-15
    dbase1 dw    0             		; segment base    byte 0,1
        db    0             			; segment base    byte 2
        db    10010010b     		; access rights
        db    11001111b     		; bit 7-4: 4 flag bits:  granularity, 
                            			; big bit (0=USE16-Segm., 1=USE32-Segm.), 2 bits avail.
                            			; bit 3-0: segment length bits 16-19
        db    0             			; segment base    byte 3       
    
    gdtr:
    Limit    dw 24          		; length of GDT
    Base     dd NULL_Desc   	; base of GDT ( linear address: RM Offset + Seg<<4 )
    
    segm dw 0
    

    Für Tipps zur Prozessorrettung bin ich wie immer dankbar.

    Gruß, Nicky



  • Sieht bei mir so aus:

    Prot:   xor eax,eax
            mov ax,cs               ;eax = Adresse dieses Code-Segments
            shl eax,4               ;eax=eax*16
            lea ebx,[eax]           ;ebx = lineare Adressse dieses Segments
            mov [Sel01+2],bx        
            mov [Sel02+2],bx
            shr ebx,16
            mov [Sel01+4],bl        ;
            mov [Sel02+4],bl
            mov [Sel01+7],bh        ;
            mov [Sel02+7],bh
            mov [Base],ebx
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;       gdtr und idtr setzen
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
            lea ebx,[eax+gdt]       ;ebx = lineare Adresse der gdt
            mov [gdtr+2],ebx
            lea ebx,[eax+idt]       ;ebx = lineare Adresse der idt
            mov [idtr+2],ebx
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;       Jetzt in den Protect Mode
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
            cli
            lgdt [gdtr]
            lidt [idtr]
    
            mov eax,cr0
            or al,1
            mov cr0,eax
    
            jmp  Selektor01:Go
    
    .....
    
    ;Parameter der Globalen Deskriptor Table
    
    gdtr:   dw      gdt_ende-gdt-1  ;Die GrӇe der gdt
            dd      gdt             ;Die Adresse der gdt
    
    ;Parameter der Interrupt Deskriptor Table
    idtr:   dw      idt_ende-idt-1  ;Die GrӇe der idt
            dd      idt             ;Die Adresse der idt
    
    ;Hilfstabelle fr die Selektoren
    
    gdt:
    
    Sel00:  dw 0            ;Der Null Deskriptor
            dw 0
            db 0
            db 0
            db 0
            db 0
    
    Sel01:  dw 0xffff       ;Fr das DS  (Protect Mode)
            dw 0            ;Wird beim Start Up gesetzt
            db 0            ;auch
            db 0x9a         ;Present,Ring 0,Code,Non-Conforming,Readable
            db 0xcf         ;Page-Granular,32-Bit
            db 0
    
    Sel02:  dw 0xffff       ;Fr das CS  (Protect Mode)
            dw 0            ;Wird beim Start Up gesetzt
            db 0            ;auch
            db 0x92         ;Present,Ring 0,Data,Expant Up,Writeble
            db 0xcf         ;Page-Granular,32-Bit
            db 0
    
    Sel03:  dw 0xffff       ;Fr das DS  (Protect Mode) Linear Modus
            dw 0            ;
            db 0            ;
            db 0x92         ;Present,Ring 0,Data,Expant Up,Writeble
            db 0xcf         ;Page-Granular,32-Bit
            db 0
    
    Sel04:  dw 0xfff        ;Fr das DS  (Real Mode)
            dw 0            ;
            db 0            ;
            db 0x92         ;Present,Ring 0,Data,Expant Up,Writeble
            db 0xcf         ;Byte-Granular,16-Bit
            db 0
    
    Sel05:  dw 0xffff       ;Fr das CS  (Real Mode)
            dw 0            ;Wird beim Start Up gesetzt
            db 0            ;auch
            db 0x9a         ;Present,Ring 0,Code,Non-Conforming,Writeble
            db 0xcf         ;Byte-Granular,16-Bit
            db 0
    
    Sel06:  ;dw s_tss_e-s_tss_a   ;Der Selektor fr das TSS
            dw 0            ;Wird beim Start Up gesetzt
            db 0            ;auch
            db 0xe9         ;present, ring 3,32 Bit,avilable TSS
            db 0
            db 0
    
    gdt_ende:
    
    ;Hilfstabelle fr die Selektoren
    
    Selektor00 equ Sel00-gdt
    Selektor01 equ Sel01-gdt
    Selektor02 equ Sel02-gdt
    Selektor03 equ Sel03-gdt
    Selektor04 equ Sel04-gdt
    Selektor05 equ Sel05-gdt
    Selektor06 equ Sel06-gdt
    

    Ich benutzt nur die PM-Selektoren -> Die RM Selektoren müssen noch richtig gesetzt werden (Am Anfang)



  • Hallo,

    Fehlermeldung ist weg.. aber er bleibt mit blinkendem Cursor stehen.

    Eine Sache noch..

    mov ax, cs
    shl eax, 4
    lea ebx, [eax]
    

    Wenn ich den Wert von EAX nach dem shl mit dem Wert von EBX nach dem LEA Befehl
    vergleiche, erhalte ich die selben Werte (bei mir 65024 = FE00h).
    Aber ohne den LEA Befehl gehts auch nicht... Ich dachte immer CS * 16 währe schon
    die physikalische Adresse (Start des Segments)?
    Welche Aufgabe hat LEA hierbei?

    Gruß und Danke schonmal

    Nicky



  • Ist lea ebx, [eax] nicht gleichbedeutend mit mov ebx, eax? Geht es so schneller?

    Ich würde zumindest mit letzerem 1 Byte sparen.



  • Ich weis es auch nicht genau.

    Es funktioniert, gut ist.



  • Vieleicht solltest du das CR0 nicht löschen.



  • supernicky schrieb:

    Hallo,

    Fehlermeldung ist weg.. aber er bleibt mit blinkendem Cursor stehen.

    Eine Sache noch..

    mov ax, cs
    shl eax, 4
    lea ebx, [eax]
    

    Wenn ich den Wert von EAX nach dem shl mit dem Wert von EBX nach dem LEA Befehl
    vergleiche, erhalte ich die selben Werte (bei mir 65024 = FE00h).
    Aber ohne den LEA Befehl gehts auch nicht... Ich dachte immer CS * 16 währe schon
    die physikalische Adresse (Start des Segments)?
    Welche Aufgabe hat LEA hierbei?

    Gruß und Danke schonmal

    Nicky

    Mit LEA witd die effektive Adresse geholt/berechnet.
    Bei "lea ebx, [eax]" wird die Adresse nur geholt wie bei "mov ebx, eax"

    Berechnungen über LEA werden schneller und von anderen CPU-Einheiten ausgeführt, als andere Integer-Operationen.

    lea eax, [eax+1] ; kann man als Ersatz nehmen anstelle für "inc eax"

    lea ebx, [eax+ecx*4+22224444h] ; Ersatz für 1 mul-Befehl und 3 add-Behehle

    Dirk



  • Hallo und Guten Abend..

    Das umschalten in den PMode und das beschreiben des Videospeichers klappt schon ganz gut...

    mein letztes Problem ist das zurückschalten in den RMode.
    Herr Meßmer und Herr Tischer schreiben daß das Löschen des Bit 0 von CR0 dafür reicht. Ich habe dazu auch am Anfang CS gesichert und nach dem löschen von CR0 wieder geladen. Außer einem blinkenden Courser erhalte ich aber keine Reaktion mehr vom System. (Aber auch keinen Prozessorfehler :-))

    Wie komme ich "sauber" zurück?
    Mein Programmcode ist im ersten Posting.

    Nicky



  • mov eax, cr0          ; Umschalten zum Real Mode
    xor eax, eax        ; Bit 0 löschen
    mov cr0, eax          ;
    

    Warum speicherst du cr0 im Register eax, das du dann ohnehin leerst?



  • Die erste Zeile könnte ich weglassen.. stimmt..

    Hab noch kein Programm geschrieben das größer als 4Kb ist.. an einer Zeile mehr stör ich mich erstmal nicht so 🙂

    Gruß, Nicky



  • Mit oder ohne Zeile heißt das allerdings, dass cr0 id. 0 ist. Wenn du nur das erste Bit löschen willst:

    mov eax, cr0
    xor eax, 1
    mov cr0, eax
    

    Edit: Oder noch schneller mit

    mov eax, cr0
    dec al
    mov cr0, eax
    

    unter der Annahme, dass es vorher 1 war.



  • Ich hab mich damit nochnicht rum geärgert.
    Würde aber als LeadIn zumindest ein Pusha spendieren.
    Ev. noch das SS extra speichern.
    Entsprechend als LeaOut SS zurück und Popa



  • Ich habe mir das Listing nun mal etwas näher angeschaut.
    Dort wird ja gar nicht der NMI deaktiviert.

    Routine zum Wechseln vom RM in den 16 Bit-Unrealmode(MASM-Syntax):

    START:
    
    	  cli                           ; Software-Interrupts ausschalten
    	  in       al, 70h              ; Über CMOS-Baustein auch
    	  or       al, 80h              ; die NMIS abschalten
    	  out      70h, al
    
    	  call ESEG                     ; Segmente erweitern auf 32 Bit
    
    	  in       al, 70h              ; NMIs wieder einschalten
    	  and      al, 7Fh
    	  out      70h, al
    	  sti                           ; Software-Interrupts einschalten
    
    ;----------------------------------------------------------------------------
    ;                     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 (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
    ;          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
    	  jnz BACK
    	  mov      al, 0D1h
    	  out      64h, al
    	  call W_8042
    	  jnz BACK
    	  mov      al, 0DFh
    	  out      60h, al
    ;-----------------------------------------------------------
    ;           Wartet darauf, bis der 8042 bereit ist.
    ;------------------------------------------------------------
    W_8042:   xor      cx, cx
    STATUS:   in       al, 64h
    	  and      al, 2
    	  loopnz STATUS
    BACK:     ret
    


  • Das mit dem NMI hab ich auch nicht.
    Bringt aber anscheinend kein Problem.
    Ich hatte da bisher keine Sorgen wegen.

    Ausserdem gebe ich zu bedenken das NMI ja Nicht Maskierbarer Interrupt heist. 😮



  • Hallo zusammen,

    ich habe den Fehler gefunden.

    Hier der alte Code:

    cli 
        lgdt [gdtr]              ;Laden der GDT via GDTR 
    
        mov eax, cr0          ;Springe zum P-Mode 
            or  eax, 1                ; setze Bit 0 auf 1 
            mov cr0, eax          ; 
    
            jmp 0x8:pmode 
    
    pmode: 
        mov    ax, 0x10 
            mov    ds, ax              ; GDT'S zuordnen 
            mov    ss, ax             
           mov    es, ax 
            mov    fs, ax 
            mov    gs, ax 
    
            mov eax, cr0          ; Umschalten zum Real Mode 
            xor eax, eax        ; Bit 0 löschen 
            mov cr0, eax          ; 
    
        jmp rmode 
    
    rmode: 
        mov ax, word [segm] 
        mov cs, ax 
        mov ds, ax 
        sti
    

    und hier mein neuer

    push ds
    
    	cli
    	lgdt [gdtr]      		;Laden der GDT via GDTR 
    
    	mov eax, cr0      	;Springe zum P-Mode
        	or  eax, 1        		; setze Bit 0 auf 1
        	mov cr0, eax      	; 
    
        	jmp 0x8:pmode 
    
    pmode:	
    
        	mov    ax, 18h     ; GDT'S zuordnen          
       	mov    es, ax
        	mov    fs, ax
        	mov    gs, ax
    
    	xor eax, eax
    
        	xor eax, eax
        	mov eax, cr0      	; Umschalten zum Real Mode
        	and al, 11111110b		; Bit 0 löschen
        	mov cr0, eax      	;
    
        	jmp rmode
    
    rmode:	
    
        	pop ds
    
    	sti
    

    Im Grunde brauche ich ja nur die Segmentregister ES, FS und GS auf 32Bit zu erweitern. DS und CS bleiben unverändert.
    So funktioniert es jetzt bei mir.

    Ich probier dann mal weiter.

    Gruß und Danke

    Nicky



  • gargyle schrieb:

    Das mit dem NMI hab ich auch nicht.
    Bringt aber anscheinend kein Problem.
    Ich hatte da bisher keine Sorgen wegen.

    Aha. Ist wohl auch nur wenn ein Speicherfehler auftritt?

    Ausserdem gebe ich zu bedenken das NMI ja Nicht Maskierbarer Interrupt heist. 😮

    Nicht Maskierbar bedeutet aber nur, dass der NMI sich weder über den PIC1(PORT 20h-003Fh), oder PIC2(Port 00A0h-00AFh) selektiv maskieren läßt, noch durch die cli/sti-Befelhle beeinflusst wird, die sonst alle maskierbaren Interrupts generell sperren/freigeben, aber nicht den NMI.

    - Generelle Interrupt-Maskierung betrifft alle maskierbaren Interrupts
    - Selektive Interrupt-Maskierung betrifft nur den gewählten Interrupt
    - Maskenbits (je Interrupt) werden üblicherweise zu Maskenregistern zusammengefasst
    - Neben der Interrupt-Maskierung werden üblicherweise auch Interrupt-Prioritäten verwaltet (konfigurierbar)

    Bitfields for PIC output control word OCW1:
    Bit(s)	Description	(Table P0014)
     7	disable IRQ7 (parallel printer interrupt)
     6	disable IRQ6 (diskette interrupt)
     5	disable IRQ5 (fixed disk interrupt)
     4	disable IRQ4 (serial port 1 interrupt)
     3	disable IRQ3 (serial port 2 interrupt)
     2	disable IRQ2 (video interrupt)
     1	disable IRQ1 (keyboard, mouse, RTC interrupt)
     0	disable IRQ0 (timer interrupt)
    SeeAlso: #P0015,#P0016,#P0418
    
    Bitfields for PIC2 output control word OCW1:
    Bit(s)	Description	(Table P0418)
     7	disable IRQ15 (reserved)
     6	disable IRQ14 (fixed disk interrupt)
     5	disable IRQ13 (coprocessor exception interrupt)
     4	disable IRQ12 (mouse interrupt)
     3	disable IRQ11 (reserved)
     2	disable IRQ10 (reserved)
     1	disable IRQ9  (redirect cascade)
     0	disable IRQ8  (real-time clock interrupt)
    SeeAlso: #P0014
    
    0070  -W  CMOS RAM index register port (ISA, EISA)
    		 bit 7	= 1  NMI disabled from reaching CPU
    			      = 0  NMI enabled
    
    Note:	any write to PORT 0070h should be followed by an action to
    		  PORT 0071h or the RTC wil be left in an unknown state.
    

    Bei mir ist auch noch nie ein unbekannter Zustand im RTC vorgekommen.
    Für diesen Fall wäre es dann wohl besser einen Zugriff auf Port 71h zu machen:

    cli                           ; Software-Interrupts ausschalten
          in       al, 70h              ; Über CMOS-Baustein auch
          or       al, 80h              ; die NMIS abschalten
          out      70h, al
          [b]in al, 71h[/b]
    
          call ESEG                     ; Segmente erweitern auf 32 Bit
    
          in       al, 70h              ; NMIs wieder einschalten
          and      al, 7Fh
          out      70h, al
          [b]in al, 71h[/b]
          sti                           ; Software-Interrupts einschalten
    

    Dirk



  • supernicky schrieb:

    Hallo zusammen,

    ich habe den Fehler gefunden.

    Prima.

    Im Grunde brauche ich ja nur die Segmentregister ES, FS und GS auf 32Bit zu erweitern. DS und CS bleiben unverändert.
    So funktioniert es jetzt bei mir.

    Ich probier dann mal weiter.

    Gruß und Danke

    Nicky

    Ich erweitere meistens nur DS, weil dann seltener Segment-Override Prefixe benötigt werden.
    (Ausnahme: Wenn (E)BP oder (E)SP als Adressregister verwendet wird, dann wird ggf. ein Segment-Override Prefix mit DS nötig, wenn darüber adressiert werden soll.
    Das läßt sich aber oft vermeiden, wenn man diese beiden Offsetregister nicht zum Adressieren verwendet, wenn man über DS adressieren möchte.)

    Um über FS und GS zu adressieren braucht man aber immer ein Segment-Override Prefix.

    Wenn DS erweitert wurde, dann kann DS auch weiterhin auf unseren Datenbereich zeigen und alle linearen Adressen lassen sich relativ dazu berechnen und darauf anpassen.

    Dirk


Anmelden zum Antworten