home *** CD-ROM | disk | FTP | other *** search
- ; Dieses Programm initialisiert das Cache-Segmentregister des
- ; FS-Registers, so daß auch im Real-Modus ein Adreßraum von
- ; 4 GByte zur Verfügung steht.
- ; Wichtig: Da die A20-Leitung über die Funktionen von HIMEM.SYS
- ; ein- und ausgeschaltet wird, muß dieser Treiber vorhanden sein!
-
- .386P ; Assembler soll 80386-Protected-Modusbefehle assemblieren
-
- STACK SEGMENT STACK ; Ein Stacksegment wird für den XMS-Treiber benötigt
- DW 100h DUP (?)
- STACK ENDS
-
- DESCRIPTOR STRUC ; Strukturtyp für den Deskriptor
- LIMIT0_15 DW ? ; Segmentgröße 0-15
- BASIS0_15 DW ? ; Basisadresse 0-15
- BASIS16_23 DB ? ; Basisadresse 16-23
- ZUGRIFF DB ? ; Zugriffsrechte
- EXTRA DB ? ; Zusätzliche Segmentinfo
- BASIS24_31 DB ? ; Basisadresse 24-31
- DESCRIPTOR ENDS
-
- CODE SEGMENT USE16 ; Hier beginnt das Codesegment
- ASSUME CS:CODE,DS:CODE
-
- GDT_ADR LABEL FWORD ; Adresse und Größe der GDT
- DW 24 ; Größe der GDT
- DD ? ; Startadresse der GDT
-
- GDT_START LABEL DWORD ; Hier beginnt die GDT
- D0 DESCRIPTOR <0,0,0,0,0,0> ; Offset 0 - Dummy-Deskriptor
- D1 DESCRIPTOR <0FFFFh,0,0,92h,8Fh,0> ; Offset 8 - Deskriptor für FS
-
- XMSControl DD 0 ; Adresse des XMS-Handlers
- ADRESSE_32BIT DD 8388568 ; Adresse im Extended-Memory
-
- ERROR_TEXT1 DB 'HIMEM.SYS nicht gefunden!',07,10,13,'$'
- ERROR_TEXT2 DB 'Problem mit der A20-Leitung!',07,10,13,'$'
- OLD_BUF DB 10,13,'Dieser Text war im Extended-Memory!','$'
- STRING_LEN = $ - OLD_BUF
-
- NEW_BUF DB (STRING_LEN - 1) DUP (32)
- DB '$'
-
- SETUP_PMODE PROC ; Setzt Segmentgröße für FS auf 4 GByte
-
- MOV AX,CS ; Startadresse der GDT in 20-Bit-Format berechnen
- AND EAX,0FFFFh
- SHL EAX,4
- ADD EAX,OFFSET GDT_START
- MOV DWORD PTR GDT_ADR+2,EAX
- LGDT GDT_ADR ; LGDT-Register bereits im Real-Modus laden
-
- MOV EAX,CR0 ; PE-Bit im CR0-Register setzen
- OR EAX,1
- MOV CR0,EAX
- JMP SHORT NEXT_BYTE ; Warteschlange leeren
- NEXT_BYTE:
- MOV BX,8 ; 1. Deskriptor in FS-Cache laden
- MOV FS,BX
- AND AL,0FEh ; Zurück in den Real-Modus
- MOV CR0,EAX
- RET
- SETUP_PMODE ENDP
-
- ADRESSE EQU [BP+04]
- WERT EQU [BP+08]
-
- READ_BYTE PROC ; Ein Byte aus Extended-Memory lesen
- PUSH BP ; Stackrahmen aufbauen
- MOV BP,SP
- XOR BX,BX
- MOV FS,BX
- MOV EAX,ADRESSE
- MOV AL,FS:[EAX] ; Byte nach AL lesen
- XOR AH,AH
- POP BP
- RET
- READ_BYTE ENDP
-
- WRITE_BYTE PROC ; Byte in Extended-Memory schreiben
- PUSH BP
- MOV BP,SP
- XOR BX,BX
- MOV FS,BX
- MOV EAX,ADRESSE
- MOV BX,WERT
- MOV FS:[EAX],BL
- POP BP
- RET
- WRITE_BYTE ENDP
-
- NO_NMI MACRO ; NMI-Verarbeitung abschalten
- IN AL,07Fh
- OR AL,80h
- OUT 07Fh,AL
- ENDM
-
- YES_NMI MACRO ; NMI wieder erlaubt
- IN AL,07Fh
- AND AL,07Fh
- OUT 07Fh,AL
- ENDM
-
- ON = 1
- OFF = 0
-
- SET_A20 MACRO ZUSTAND ; A20-Leitung ein-/ausschalten
- IF ZUSTAND EQ OFF
- MOV AH,06h
- ELSE
- MOV AH,05h
- ENDIF
- CALL XMSControl
- ENDM
-
- START:
- PUSH CS ; DS mit CS laden
- POP DS
-
- MOV AX,4300h ; Ist HIMEM.SYS da?
- INT 2Fh
-
- CMP AL,80h
- JNE NoXMS ; Nein, dann Abbruch
- MOV AX,4310h ; Adresse des XMS-Treibers ermitteln
- INT 2Fh ; und abspeichern
- MOV WORD PTR [XMSControl],BX
- MOV WORD PTR [XMSControl+2],ES
-
- CLI ; Kein Interrupts bitte
- NO_NMI ; Und keinen NMI
-
- SET_A20 ON ; A20-Leitung frei
- CMP AX,1 ; Operation geglückt?
- JNE A20_PROBLEM ; Nein, dann Abbruch
-
- CALL SETUP_PMODE ; Segmentgröße von FS auf 4 GByte setzen
-
- STI ; Interrupts wieder zulassen
- YES_NMI
-
- ; ---------------------------------------------------------
- ; Ein String wird in das Extended-Memory geschrieben
- ; ---------------------------------------------------------
-
- LEA DI,OLD_BUF ; Adresse des alten Puffers laden
- MOV CX,STRING_LEN+1 ; Länge des Strings
- MOV EAX,ADRESSE_32BIT ; Beliebige 32-Bit-Adresse
- M1:
- XOR BH,BH ; Puffer in das Extended-Memory an eine
- MOV BL,[DI] ; beliebige Adresse schreiben
- PUSH BX
- PUSH EAX
- CALL WRITE_BYTE
- ADD SP,6
- INC EAX
- INC DI
- LOOP M1
-
- ; ---------------------------------------------------------
- ; Ein String wird aus dem Extended-Memory gelesen
- ; ---------------------------------------------------------
-
- LEA DI,NEW_BUF ; Adresse des neuen Puffers laden
- MOV CX,STRING_LEN+1 ; Länge des Strings
- MOV EAX,ADRESSE_32BIT ; 32-Bit-Adresse
- M2:
- PUSH EAX ; Abgespeicherten String aus Extended-Memory
- CALL READ_BYTE ; wieder in einen anderen Puffer laden
- MOV [DI],AL
- INC DI
- POP EAX
- INC EAX
- LOOP M2
-
- MOV DX,OFFSET NEW_BUF ; Neuen Pufferinhalt ausgeben
- MOV AH,09
- INT 21h
-
- SET_A20 OFF ; A20-Leitung wieder sperren
- CMP AX,1 ; Alles klar?
- JNE A20_PROBLEM ; Nein, dann kurze Mitteilung
- ENDE:
- MOV AH,4Ch ; Das ist das Ende
- INT 21h
-
- NoXMS: ; Fehlermeldung ausgeben
- MOV DX,OFFSET ERROR_TEXT1
- MOV AH,09
- INT 21h
- JMP ENDE
- A20_PROBLEM: ; Fehlermeldung ausgeben
- MOV DX,OFFSET ERROR_TEXT2
- MOV AH,09
- INT 21h
- JMP ENDE
- CODE ENDS
- END START
-
-
-
-