home *** CD-ROM | disk | FTP | other *** search
- ; =========================================================
- ; Programm schaltet über die Funktion 89h des Int. 15h
- ; in den Protected-Modus, gibt einen Ton aus und kehrt
- ; über einen Reset in den Real-Modus zurück.
- ; (c) 1991 Peter Monadjemi & toolbox
- ; =========================================================
- .MODEL SMALL,C
- .286 ; Befehle der 80286-CPU zulassen
- .STACK
-
- GDT_SIZE = 8 ; Anzahl der Deskriptoren in der GDT
- IDT_SIZE = 0 ; Anzahl der Deskriptoren in der IDT
- CODE_DESCRIPT = 48 ; Deskriptor-Index für Codesegment
-
- DESCRIPTOR STRUC
- LIMIT DW ?
- BASE_LOW DW ?
- BASE_HIGH DB ?
- ZUGRIFF DB ?
- DUMMY DW 0
- DESCRIPTOR ENDS
-
- .DATA
- MASK1_8259A DB ?
- MASK2_8259A DB ?
-
- ; ---------------------------------------------------------
- ; Sieben Deskriptoren für die GDT definieren
- ; ---------------------------------------------------------
- GDT_START LABEL WORD
- DESCRIPTOR <0,0,0,0>
- DESCRIPTOR <GDT_SIZE * 8,,,92h>
- DESCRIPTOR <IDT_SIZE * 8,,,92h>
- DESCRIPTOR <0FFFFh,,,92h>
- DESCRIPTOR <0FFFFh,,,92h>
- DESCRIPTOR <0FFFFh,,,92h>
- DESCRIPTOR <0FFFFh,,,9Ah>
- .CODE
- DS_SAVE DW ?
- ES_SAVE DW ?
- SS_SAVE DW ?
-
- BEEP PROC FREQUENZ:WORD
- MOV DI,FREQUENZ ; Frequenz des Tones
- MOV BX,10 ; Dauer des Tones in 0.2 Sek.
- MOV AL,182 ; Timer initialisieren
- OUT 43H,AL
- MOV DX,12H ; Zeitschleife festlegen
- MOV AX,34DCh ; Frequenz umrechnen
- DIV DI
- OUT 42H,AL ; Umgerechnete Frequenz an den
- MOV AL,AH ; Timer schicken
- OUT 42H,AL
- IN AL,61H ; Inhalt des Ports 61h retten
- MOV AH,AL
- OR AL,3 ; Lautsprecher einschalten
- OUT 61H,AL
- WARTE:
- MOV CX,0DAD4h ; Zeitschleife ca. 200 Millisekunden
- @@:
- LOOP @B
- DEC BX ; Zähler erniedrigen
- JNZ WARTE ; Ausschalten ?
- MOV AL,AH ; Port 61h wieder herstellen
- OUT 61H,AL ; das heißt Lautsprecher aus
- RET
- BEEP ENDP
-
- ; ----------------------------------------------------------
- ; Rechnet eine Segment:Offset-Adresse in eine 24-Bit-Adresse
- ; um, die in der GDT abgelegt wird.
- ; ----------------------------------------------------------
-
- SET_GDT_BASE PROC BASE_OFF:WORD,BASE_SEG:WORD,GDT_NR:WORD
- PUSH AX
- PUSH CX
- PUSH DX
- PUSH DI
- MOV AX,BASE_SEG
- MOV DX,16
- MUL DX
- ADD AX,BASE_OFF
- ADC DL,0
- MOV DI,GDT_NR
- MOV CL,3
- SHL DI,CL
- ADD DI,2
- MOV GDT_START[DI],AX
- ADD DI,2
- MOV BYTE PTR GDT_START[DI],DL
- POP DI
- POP DX
- POP CX
- POP AX
- RET
-
- SET_GDT_BASE ENDP
- ; ---------------------------------------------------------
- ; Durchführen eines Reset
- ; ---------------------------------------------------------
- MOV AL,0FEh
- OUT 64h,AL
- HLT
- ; ---------------------------------------------------------
- ; Hier wird nach einem Reset der Real-Modus eingeleitet.
- ; ---------------------------------------------------------
-
- PROC_MODE_EXIT:
- MOV AX,CS:DS_SAVE
- MOV DS,AX
- MOV AX,CS:ES_SAVE
- MOV ES,AX
- MOV AX,CS:SS_SAVE
- MOV SS,AX
- MOV AL,MASK1_8259A
- OUT 021h,AL
- MOV AL,MASK2_8259A
- OUT 0A1h,AL
- JMP ENDE
- ; ---------------------------------------------------------
- ; Hier beginnt das Programm
- ; ---------------------------------------------------------
- START:
- ; ---------------------------------------------------------
- ; Initialisierung
- ; ---------------------------------------------------------
- MOV DX,@DATA
- MOV DS,DX
- ; ---------------------------------------------------------
- ; Die Basisadresse für die globalen Deskriptoren definieren
- ; ---------------------------------------------------------
- PUSH 1
- PUSH DS
- PUSH OFFSET GDT_START
- CALL SET_GDT_BASE
- ADD SP,6
- PUSH 3
- PUSH DS
- PUSH 0
- CALL SET_GDT_BASE
- ADD SP,6
- PUSH 4
- PUSH DS
- PUSH 0
- CALL SET_GDT_BASE
- ADD SP,6
- PUSH 5
- PUSH SS
- PUSH 0
- CALL SET_GDT_BASE
- ADD SP,6
- PUSH 6
- PUSH CS
- PUSH 0
- CALL SET_GDT_BASE
- ADD SP,6
- ; ---------------------------------------------------------
- ; Segmentregister für den Real-Modus retten
- ; ---------------------------------------------------------
- MOV AX,DS
- MOV CS:DS_SAVE,AX
- MOV AX,ES
- MOV CS:ES_SAVE,AX
- MOV AX,SS
- MOV CS:SS_SAVE,AX
- ; ---------------------------------------------------------
- ; 8259A-Register retten
- ; ---------------------------------------------------------
- IN AL,021h
- MOV MASK1_8259A,AL
- IN AL,0A1h
- MOV MASK2_8259A,AL
- ; ---------------------------------------------------------
- ; CMOS für Neustart markieren, damit kein Warmstart erfolgt
- ; ---------------------------------------------------------
- MOV AL,0Fh
- OUT 70h,AL
- MOV AL,05h
- OUT 71h,AL
- ; ---------------------------------------------------------
- ; Sprungvektor für Neustart setzen
- ; ---------------------------------------------------------
- PUSH DS
- MOV DX,0040h
- MOV DS,DX
- MOV DI,067h
- MOV DX,OFFSET PROC_MODE_EXIT
- MOV [DI],DX
- ADD DI,2
- MOV DX,CS
- MOV [DI],DX
- POP DS
- ; ---------------------------------------------------------
- ; In den Protected-Modus schalten
- ; ---------------------------------------------------------
- MOV DX,DS
- MOV ES,DX
- LEA SI,GDT_START
- MOV BH,00
- MOV BL,08
- MOV AH,89h
- MOV CX,0FFFFh ; Zeitschleife
- @@:
- LOOP @B
- INT 15h
- PUSH 440
- CALL BEEP
- MOV AL,0FEh ; Reset durchführen
- OUT 064h,AL
- HLT
- ENDE:
- MOV AH,01 ; Warten auf Tastendruck
- INT 21h
- MOV AH,4Ch ; Zurück zu DOS
- INT 21h
- END START
- ; =========================================================
- ; = Ende von REALPRO.ASM =
-