Version 2.0 Aktualisiert: 30.03.04

Handle: Gerät: Bezeichnung: 1 Bildschirm Standart-Ausgabe (STDOUT,CON) 2 Bildschirm Standart-Fehlerausgabe (STDERR) 3 Serielle Schnitstelle Hilfsein-/ausgabe (STDAUX,AUX,COM) 4 Drucker/Parallele Schnitst. Standart-Drucker (STDPRN,PRN,LPT)Wenn man die Datei erst erstellen muss, dann benutzt man DOS-Funktion 3Ch. Man erhält dann ebenfalls eine Handle in AX. Der Dateiname muss über DS:DX angegeben werden. Für beide Fälle (öffnen/erstellen) gilt: Der Dateiname muss so: Lbl DB "Dateiname.ext",0 beendet werden also durch das ASCII Zeichen 00h. Mit der Funktion 3Fh kann man dann aus der Datei (bzw. dem Gerät) lesen, mit Funktion 40h kann man schreiben. Das Handle muss diesen Funktionen immer in BX übergeben werden, die Anzahl der zu lesenden/schreibenden Bytes muss in CX übergeben werden. Die gelesenden/zu schreibenden Daten kommen/stehen in den/im Puffer, der über DS:DX adressiert wird. Wenn man Fertig ist, muss die Datei mit Funktion 3Eh geschlossen werden, das Handle muss wieder in BX stehen. Bei allen Handle-Funktionen gilt: Wird nach der Funktion das Carry-Flag gesetzt, dann ist ein Fehler aufgetreten. Dies kann mit JC überprüft werden.
Zusammenfassung:
1. Öffnen einer Datei:
Interrupt 21h Funktion 3Dh.
Eingabe:
AH = 3Dh
AL = Zugriffsmodus (00h = Nur lesen, 01h = Nur schreiben, 02h = Lesen und schreiben)
DS = Segmentadresse des Dateinamens
DX = Offsetadresse des Dateinamens
Ausgabe:
Carry Flag = 0 --> Ok
AX = Handle der Datei
Ist ein Fehler aufgetreten dann Carry Flag = 1 und Fehlercode in AX:
AX = 1 = Datei schon geöffnet
AX = 2 = Datei nicht gefunden
AX = 3 = Pfad nicht gefunden
AX = 4 = Kein freies Handle
AX = 5 = Zugriff verweigert
2. Datei erstellen:
Interrupt 21 Funktion 3Ch
Eingabe:
AH = 3Ch
DS = Segmentadresse des Dateinamens
DX = Offsetadresse des Dateinamens
CX = Dateiattribut (00h = Normal, 01h = Schreibschutz, 02h = Versteckt, 04h = System)
Ausgabe:
Carry Flag = 0 --> OK
AX = Handle der Datei -->D.h. die Datei braucht nicht noch extra geöffnet werden!
Ist ein Fehler aufgetreten dann Carry Flag = 1 und Fehlercode in AX:
AX = 1 = Pfad nicht gefunden
AX = 4 = Kein freies Handle
AX = 5 = Zugriff verweigert
--> Falls die angegebene Datei bereits existiert, wird sie ohne Warnung überschrieben.
3. Datei schliessen:
Interrupt 21 Funktion 3Eh
Eingabe:
AH = 3Eh
BX = Handle der Datei
Ausgabe:
Carry Flag = 0 --> OK
Carry Flag = 1 --> Fehler u. Fehlercode in AX (AX = 6 = Ungültiges Handle)
4. Datei lesen:
Interrupt 21h Funktion 3Fh
Eingabe:
AH = 3Fh
BX = Handle der Datei/des Geräts
CX = Anzahl der zu lesenden Bytes
DS = Segmentadresse des Puffers
DX = Offsetadresse des Puffers
Ausgabe:
Carry Flag = 0 --> OK und AX = Anzahl der gelesenen Bytes
Carry Flag = 1 --> Fehler u. Fehlercode in AX:
AX = 5 = Zugriff verweigert
AX = 6 = Ungültiges Handle
--> Der "Zeiger" innerhalb der zu lesenden Datei wird automatisch um den Wert in CX erhöht, so
dass der nächste Lesevorgang wieder neue Daten einliest.
5. Datei schreiben:
Interrupt 21h Funktion 40h
Eingabe:
AH = 40h
BX = Handle der Datei/des Geräts
CX = Anzahl der zu schreibenden Bytes
DS = Segmentadresse des Puffers
DX = Offsetadresse des Puffers
Ausgabe:
Carry Flag = 0 --> Ok und AX = Anzahl der geschriebenen Bytes
Carry Flag = 1 --> Fehler u. Fehlercode in AX:
AX = 5 = Zugriff verweigert
AX = 6 = Ungültiges Handle
--> Auch bei dieser Funktion wird der Zeiger innerhalb der Datei automatisch um den Wert in CX
erhöht, so dass der nächste Schreibvorgang hinter dem zuletzt geschriebenen Byte erfolgt.
Und hier das Programm zum sichern der CMOS-RAM Daten:
.MODEL SMALL
.STACK 100h
.DATA
Dateinamen DB "CMOS.DAT",0 ;In diese Datei kommen die Daten. Die 0 zeigt das Ende an
Puffer DB ?
FehlerMeld DB "Fehler beim erstellen/schreiben/schliessen der Datei CMOS.DAT !$"
Msg1 DB "CMOS RAM Sicherungsprogramm Version 1.03",13,10,"$"
.CODE
cli ;extern maskierbare Interrupts sperren
mov ax,@data
mov ds,ax
mov dx,OFFSET Msg1
mov ah,09h
int 21h
mov dx,OFFSET Dateinamen
xor cx,cx ;cx=0 -->Dateiattribut Normal.
mov ah,3Ch ;DOS Funktion: Create File with Handle
int 21h ;Datei Erstellen. Ist eine gleichnamige Datei bereits
;vorhanden, dann wird diese ueberschrieben.
;*******************************
jc Fehler ;Springe wenn Fehler
xchg bx,ax ;Handle sichern. Das Handle dient als eine Art Kennung der
;Datei, wenn auf diese zugegriffen wird.
;*******************************
mov cx,80h ;CMOS Maximaladdresse in cx
;Das CMOS-RAM ist bei neueren Computern 128 Bytes gross (80h)
xor ah,ah ;ah Zeigt auf tatsaechliche CMOS-RAM Addresse
Schleife:
mov al,ah
out 70h,al ;In diesen Port kommt die Offsetadresse im CMOS-RAM rein
jmp $+2 ;Der Befehl soll nur Zeit verbrauchen.
;Das $ wird hier vom Assembler als die aktuelle Position
;im Code interpretiert. Gesprungen wird also direkt zum
;naechsten Befehl (in al,71h)
in al,71h ;CMOS Daten aus Port einlesen aus oben eingegebener Adresse.
mov Puffer,al ;In den Puffer!
;*******************************
push cx ;Schleifenzaehler cx auf Stack
push ax ;Addresszaehler ax bzw ah auf Stack
mov ah,40h ;DOS-Funktion: Write file or Device
mov cx,01h ;Laenge der zu Speichernden Daten
mov dx,OFFSET Puffer ;Puffer von dem Geschrieben wird
int 21h ;Puffer in Datei Schreiben
jc Fehler
pop ax ;ax vom Stack
pop cx ;cx vom Stack
inc ah ;ah Erhoehen!
Loop Schleife
;*******************************
mov ah,3Eh ;Datei schliessen
int 21h
jnc Ende
Fehler: mov dx,OFFSET FehlerMeld
mov ah,09h
int 21h ;Fehlerbehandlung fuer Arme
;*******************************
Ende: sti ;Extern maskierbare Interrupts zulassen
mov ah,4Ch
int 21h ;Und Tschuess
END
;-->Dieses Programm speichert also die CMOS-RAM Daten in der Datei Cmos-dat, welche ins selbe
; Verzeichnis kommt.
Und hier das Programm zum wiederherstellen der CMOS-RAM Daten:
.MODEL SMALL
.STACK 100h
.DATA
Dateiname DB "CMOS.DAT",0
Puffer DB ?
FehlerMeld DB 10,13,"Fehler beim oeffnen/lesen/schliessen der Datei!"
DB "Datei CMOS.DAT vorhanden?$" ;<-- Fortsetzung von oben
Copyright DB "CMOS RAM Wiederherstellung Version 1.01$"
Frage DB 10,13,"CMOS RAM Wiederherstellen (y/n) ? $"
.CODE
cli
mov ax,@DATA
mov ds,ax
mov dx,OFFSET Copyright
mov ah,09h
int 21h
mov dx,OFFSET Frage
int 21h
mov ah,08h ;DOS-Funktion:Zeichen von der Tastatur lesen. Ausgabe in AL
int 21h
cmp al,'y'
je Weiter
call Beenden ;Prozedur zum beenden des Programms aufrufen
Weiter: mov dx,OFFSET Dateiname
xor al,al
mov ah,3Dh ;DOS-Funktion: Datei oeffnen
int 21h
jc Fehler
mov bx,ax ;Handle sichern
mov cx,80h ;Max. Adresse
xor ax,ax ;Ax=0
Schleife:
push cx
push ax
mov ah,3Fh ;DOS-Funktion: Datei lesen.
mov dx,OFFSET Puffer
mov cx,01h
int 21h
jc Fehler
;***********************
pop ax
pop cx
mov al,ah
out 70h,al ;Adresse im CMOS-RAM hier rein
jmp $+2 ;Delay-Befehl
mov al,Puffer
out 71h,al ;Inhalt des Puffers hier rein
inc ah
Loop Schleife
;***********************
mov ah,3Eh ;Datei schliessen
int 21h
jnc Ende
Fehler: mov dx,OFFSET FehlerMeld
mov ah,09h
int 21h
Ende: sti
;Die Beenden Prozedur muss nicht extra aufgerufen werden
Beenden PROC NEAR ;denn hier kommt sie ja sowieso
mov ah,4Ch
int 21h
Beenden ENDP
END
;--> Zur Wiederherstellung muss sich die Datei Cmos.dat im selben Verzeichnis befinden (vorher
;mit dem Sicherungsprogramm erstellt)
Schlussbemerkung: