home *** CD-ROM | disk | FTP | other *** search
- ; ==================================================================
- ; Dieses Programm schaltet über die Funktion 89h des Interrupts 15h
- ; in den Protected-Modus, gibt einen Ton aus und kehrt
- ; über einen Reset in den Real-Modus zurück.
- ; ==================================================================
-
- .MODEL SMALL,C
- .286 ; Befehle der 80286-CPU zulassen
- .STACK
-
- GDT_SIZE = 8 ; Anzahl der Deskriptoren in der GDT
- IDT_SIZE = 14 ; Anzahl der Deskriptoren in der IDT
- CODE_DESCRIPT = 48 ; Deskriptor-Index für Codesegment
-
- IDT_DESCRIPT MACRO LIMIT,BASE_LOW,BASE_HIGH,ACCESS
- DW LIMIT
- DW BASE_LOW
- DB BASE_HIGH
- DB ACCESS
- DW 0
- ENDM
-
- 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>
-
- ; ---------------------------------------------------------
- ; Vierzehn Interrupt Deskriptoren definieren
- ; ---------------------------------------------------------
-
- IDT_START LABEL WORD
- IDT_DESCRIPT FAULT00,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT01,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT02,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT03,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT04,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT05,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT06,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT07,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT08,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT09,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT10,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT11,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT12,CODE_DESCRIPT,0,86h
- IDT_DESCRIPT FAULT13,CODE_DESCRIPT,0,86h
-
- .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
-
- ; ---------------------------------------------------------
- ; Hier beginnen die Interrupt-Routinen 0-13
- ; ---------------------------------------------------------
-
- FAULT13:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- LOOP @B
- FAULT12:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- LOOP @B
- FAULT11:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT10:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT09:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT08:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT07:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT06:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT05:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT04:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT03:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT02:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT01:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
- FAULT00:
- PUSH 1000
- CALL BEEP
- MOV CX,0FFFFh
- @@:
- NOP
- NOP
- NOP
- LOOP @B
-
- POP BX
- POP BX
- POP BX
- POP BX
-
- ; ---------------------------------------------------------
- ; Durchführen eines Reset
- ; ---------------------------------------------------------
-
- MOV AL,0FEh
- OUT 64h,AL
- HLT
-
- ; ---------------------------------------------------------
- ; Hier wird nach einem Reset der Real-Modus wieder 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 2
- PUSH DS
- PUSH OFFSET IDT_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 DATABOX.ASM -----------------
-