home *** CD-ROM | disk | FTP | other *** search
- ;//////////////////////////////////////////////////////
- ;/ /
- ;/ Run-time Library für Borland Pascal 7.0 unter OS/2 /
- ;/ Routinen für Text-Dateien. /
- ;/ /
- ;/ 1993 Matthias Withopf / c't /
- ;/ Originalversion (c) 1988,92 Borland International /
- ;/ /
- ;//////////////////////////////////////////////////////
-
- .286p
-
- _NOMACROS_ = 1 ; keine Macros definieren
- INCLUDE SE.ASM
- INCLUDE OS2.ASM
-
- DATA SEGMENT WORD PUBLIC
- EXTRN FileMode:WORD,InOutRes:WORD
- DATA ENDS
-
- CODE SEGMENT BYTE PUBLIC
- ASSUME CS:CODE,DS:DATA
-
- EXTRN ConvErrCode:NEAR
-
- ;
- ; Assign(Var f;Name : PChar);
- ;
-
- PUBLIC AssignTextC
- AssignTextC PROC PASCAL FAR
- MOV DL,1 ; setze Flag für PChar-Argument
- JMP SHORT Assign
- AssignTextC ENDP
-
- ;
- ; Assign(Var f;Name : String);
- ;
-
- PUBLIC AssignText
- AssignText PROC PASCAL FAR
- XOR DX,DX ; lösche Flag für PChar-Argument
- AssignText ENDP
-
- ;
- ; Allgemeine Assign-Prozedur.
- ;
-
- Assign PROC PASCAL FAR
- ARG A_File : DWORD, \
- A_Name : DWORD
- PUSH DS ; rette Datensegment
- LES DI,A_File ; lese Zeiger auf TextRec
- LDS SI,A_Name ; lese Zeiger auf Namen
- MOV ES:[DI].fHandle,0 ; markiere Handle als ungültig
- MOV ES:[DI].fMode,fmClosed ; Datei ist geschlossen
- MOV ES:[DI].fBufSize,128 ; setze Standardgröße des Buffers
- MOV ES:[DI].fPrivate,0 ; init. private Daten
- MOV ES:[DI].fBufPos,0 ; lösche den
- MOV ES:[DI].fBufEnd,0 ; Datei-Buffer
- LEA AX,[DI].fBuffer ; initialisiere Zeiger
- MOV ES:[DI].fBufPtr.offs,AX ; auf Buffer innerhalb
- MOV ES:[DI].fBufPtr.segm,ES ; TextRec
- MOV ES:[DI].fOpenProc.offs,OFFSET FileOpen ; definiere die
- MOV ES:[DI].fOpenProc.segm,CS ; Open-Funktion
- XOR AX,AX ; lösche die
- MOV CX,(fName-fInOutProc)/2 ; restlichen
- ADD DI,fInOutProc ; Funktionszeiger
- CLD ; und
- REP STOSW ; UserData
- MOV CX,79 ; lese max. Länge des Dateinamens
- OR DX,DX ; ist es PChar-Routine ?
- JNE @@CopyNameLoop ; ja -> weiter
- LODSB ; lese Längenbyte des Namens
- CMP CL,AL ; ist max. Länge überschritten ?
- JBE @@CopyNameLoop ; nein -> ok, weiter
- MOV CL,AL ; schneide Namen ab
- JCXZ @@CopyNameEnd ; falls Namen Leerstring -> weiter
- @@CopyNameLoop: LODSB ; lese Zeichen aus angegebenem Dateinamen
- OR AL,AL ; Ende erreicht (bei PChar-Routine) ?
- JE @@CopyNameEnd ; ja -> Kopieren des Namens beenden
- STOSB ; speichere Zeichen in TextRec
- LOOP @@CopyNameLoop ; gesamten Namen kopieren
- @@CopyNameEnd: XOR AL,AL ; schließe Namen in TextRec
- STOSB ; mit Nullbyte ab
- POP DS ; stelle Datensegment wieder her
- RET
- Assign ENDP
-
- ;
- ; Procedure SetTextBuf(var F : Text;Var Buf;Size : Word);
- ;
-
- PUBLIC BufferText
- BufferText PROC PASCAL FAR
- ARG A_File : DWORD, \
- A_Buf : DWORD, \
- A_Size : WORD
- LES DI,A_File ; lese Zeiger auf TextRec
- MOV AX,A_Size ; setze neue
- MOV ES:[DI].fBufSize,AX ; Buffer-Größe
- MOV AX,A_Buf.offs ; setze
- MOV ES:[DI].fBufPtr.offs,AX ; neuen
- MOV AX,A_Buf.segm ; Zeiger
- MOV ES:[DI].fBufPtr.segm,AX ; auf Buffer
- XOR AX,AX ; lösche
- MOV ES:[DI].fBufPos,AX ; den
- MOV ES:[DI].fBufEnd,AX ; Datei-Buffer
- RET
- BufferText ENDP
-
- ;
- ; Procedure Reset(Var f : Text);
- ;
-
- PUBLIC ResetText
- ResetText PROC PASCAL FAR
- MOV DX,fmInput ; lese Dateimodus für Eingabe
- mov cx,OPEN_ACCESS_READONLY ;{CT} allow read only file access
- JMP SHORT OpenText
- ResetText ENDP
-
- ;
- ; Procedure Rewrite(Var f : Text);
- ;
-
- PUBLIC RewriteText
- RewriteText PROC PASCAL FAR
- MOV DX,fmOutput ; lese Dateimodus für Ausgabe
- MOV CX,OPEN_ACCESS_WRITEONLY ;{CT} Allow readonly File Access
- JMP SHORT OpenText
- RewriteText ENDP
-
- ;
- ; Procedure Append(Var f : Text);
- ;
-
- PUBLIC AppendText
- AppendText PROC PASCAL FAR
- MOV DX,fmInOut ; lese Dateimodus für wahlfreien Zugriff
- MOV CX,OPEN_ACCESS_READWRITE ;{CT} Allow read only file access
- AppendText ENDP
-
- ;
- ; Öffne Datei oder lege Datei neu an.
- ; In DX wird der Dateimodus übergeben.
- ;
-
- PUBLIC OpenText
- OpenText PROC PASCAL FAR
- ARG A_File : DWORD
- LES DI,A_File ; lese Zeiger auf TextRec
- MOV AX,ES:[DI].fMode ; lese aktuellen Modus der Datei
- CMP AX,fmInput ; ist die Datei zum Lesen geöffnet ?
- JE @@CloseFirst ; ja -> zuerst schließen
- CMP AX,fmOutput ; ist die Datei zum Schreiben geöffnet ?
- JE @@CloseFirst ; ja -> zuerst schließen
- CMP AX,fmClosed ; ist die Datei geschlossen ?
- JE @@Open ; ja -> ok, öffnen
- MOV InOutRes,102 ; sonst Fehler: 'File not assigned'
- JMP SHORT @@End ; -> Ende
-
- @@CloseFirst: PUSH DX ; rette neuen Dateimodus
- PUSH ES ;{CT} Save es
- PUSH DI ;{CT} Save DI
- PUSH ES ; übergebe den Zeiger
- PUSH DI ; auf TextRec
- PUSH CS ; schließe die Datei,
- CALL NEAR PTR CloseText ; bevor sie neu geöffnet wird
- POP DI ;{CT} recover DI
- POP ES ;{CT} RECOVER ES
- POP DX ; hole neuen Dateimodus zurück
- @@Open: MOV ES:[DI].fMode,DX ; speichere neuen Dateimodus
- MOV ES:[Di].Fprivate,CX ;{CT} Allow REadonly
- XOR AX,AX ; lösche den
- MOV ES:[DI].fBufPos,AX ; Buffer
- MOV ES:[DI].fBufEnd,AX ; der Textdatei
- MOV BX,fOpenProc ; rufe Funktion
- CALL DoFunction ; zum Öffnen auf
- JE @@End ; falls kein Fehler -> ok, weiter
- MOV ES:[DI].fMode,fmClosed ; bei Fehler: setze Dateimodus auf geschlossen
- @@End: RET
- OpenText ENDP
-
- ;
- ; Procedure Flush(Var f : Text);
- ;
-
- PUBLIC FlushText
- FlushText PROC PASCAL FAR
- XOR AL,AL ; lösche Flag für "Schließen"
- JMP SHORT FlushClose
- FlushText ENDP
-
- ;
- ; Procedure Close(Var f);
- ;
-
- PUBLIC CloseText
- CloseText PROC PASCAL FAR
- MOV AL,1 ; setze Flag für "Schließen"
- CloseText ENDP
-
- ;
- ; Flush/Close.
- ;
-
- PUBLIC FlushClose
- FlushClose PROC PASCAL FAR
- ARG A_File : DWORD
- LES DI,A_File ; lese Zeiger auf TextRec
- CMP ES:[DI].fMode,fmInput ; ist Datei als Eingabe geöffnet ?
- JE @@DontFlush ; ja -> kein Flush nötig
- CMP ES:[DI].fMode,fmOutput ; ist Datei als Ausgabe geöffnet ?
- JE @@DoFlush ; ja -> Flush
- MOV InOutRes,103 ; sonst Fehler: 'File not open'
- JMP SHORT @@DontClose ; -> Ende
-
- @@DoFlush: PUSH AX ; rette Flag für "Schließen"
- MOV BX,fInOutProc ; gebe den restlichen
- CALL DoFunction ; Buffer-Inhalt aus
- POP AX ; hole Flag für "Schließen" zurück
- @@DontFlush: OR AL,AL ; ist Flag für "Schließen" gesetzt ?
- JE @@DontClose ; nein -> weiter, nicht schließen
- MOV BX,fCloseProc ; schließe
- CALL DoFunction ; die Datei
- MOV ES:[DI].fMode,fmClosed ; setze Dateimodus auf 'geschlossen'
- @@DontClose: RET
- FlushClose ENDP
-
- ;
- ; Führe eine Funktion eines Textdatei-Gerätetreibers
- ; aus. Der Offset der Funktion innerhalb des
- ; TextRecs wird in BX übergeben.
- ;
-
- DoFunction PROC NEAR
- PUSH ES ; rette Zeiger
- PUSH DI ; auf TextRec
- PUSH ES ; übergebe den Zeiger
- PUSH DI ; auf TextRec als Argument
- CALL DWORD PTR ES:[DI+BX] ; rufe die gewünschte Funktion auf
- OR AX,AX ; ist Fehler aufgetreten ?
- JE @@NoErr ; nein -> weiter
- MOV InOutRes,AX ; speichere Fehlercode
- @@NoErr: POP DI ; hole Zeiger
- POP ES ; auf TextRec zurück
- RET
- DoFunction ENDP
-
- ;
- ; Read-Funktion des Standard-Text-Gerätetreibers.
- ;
-
- PUBLIC FileRead
- FileRead PROC PASCAL FAR
- ARG A_File : DWORD
- LOCAL L_ReadCnt : WORD
- PUSH DS ; rette Datensegment
- LES DI,A_File ; lese Zeiger auf TextRec
- PUSH ES:[DI].fHandle ; übergebe FileHandle
- LDS BX,ES:[DI].fBufPtr ; übergebe Zeiger
- PUSH DS ; auf den
- PUSH BX ; Datei-Buffer
- PUSH ES:[DI].fBufSize ; übergebe Buffer-Größe
- LEA BX,L_ReadCnt ; übergebe Zeiger auf Word,
- PUSH SS ; in dem die tatsächliche Anzahl
- PUSH BX ; gelesener Bytes gespeichert wird
- CALL DosRead ; lese Block aus Datei
- OR AX,AX ; ist Fehler beim Lesen aufgetreten ?
- JNZ @@Error ; ja -> Fehler
- MOV AX,L_ReadCnt ; lese Anzahl gelesener Bytes
- LES DI,A_File ; lese Zeiger auf TextRec
- MOV ES:[DI].fBufEnd,AX ; speichere neues Buffer-Ende
- XOR AX,AX ; lösche Fehlercode
- @@End: MOV ES:[DI].fBufPos,0 ; setze Position des Zeigers auf Datei-Buffers zurück
- POP DS ; hole Datensegment zurück
- RET
-
- @@Error: MOV ES:[DI].fBufEnd,0 ; lösche den Datei-Buffer
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- JMP SHORT @@End ; -> Ende
- FileRead ENDP
-
- ;
- ; Write-Funktion des Standard-Text-Gerätetreibers.
- ;
-
- PUBLIC FileWrite
- FileWrite PROC PASCAL FAR
- ARG A_File : DWORD
- LOCAL L_WriteCnt : WORD
- PUSH DS ; rette Datensegment
- LES DI,A_File ; lese Zeiger auf TextRec
- PUSH ES:[DI].fHandle ; übergebe FileHandle
- LDS BX,ES:[DI].fBufPtr ; übergebe
- PUSH DS ; Zeiger auf
- PUSH BX ; den Datei-Buffer
- XOR CX,CX ; übergebe aktuelle
- XCHG CX,ES:[DI].fBufPos ; Größe des Datei-Buffers
- PUSH CX ; und setze sie zurück
- LEA BX,L_WriteCnt ; übergebe Zeiger auf Word,
- PUSH SS ; in dem die tatsächliche Anzahl
- PUSH BX ; geschriebener Bytes gespeichert wird
- CALL DosWrite ; schreibe Block in Datei
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- OR AX,AX ; ist Fehler aufgetreten ?
- JNZ @@Exit ; ja -> Ende
- MOV AX,L_WriteCnt ; lese Anzahl geschriebener Bytes
- SUB AX,CX ; konnten alle Bytes geschrieben werden ?
- JE @@Exit ; ja -> ok, weiter
- MOV AX,101 ; sonst Fehler: 'Disk write error'
- @@Exit: POP DS ; hole Datensegment zurück
- RET
- FileWrite ENDP
-
- ;
- ; Write-Funktion des Standard-Text-Gerätetreibers
- ; für Device-Dateien.
- ;
-
- PUBLIC FileWrDev
- FileWrDev PROC PASCAL FAR
- ARG A_File : DWORD
- LOCAL L_WriteCnt : WORD
- PUSH DS ; rette Datensegment
- LES DI,A_File ; lese Zeiger auf TextRec
- PUSH ES:[DI].fHandle ; übergebe FileHandle
- LDS BX,ES:[DI].fBufPtr ; übergebe
- PUSH DS ; Zeiger auf
- PUSH BX ; den Datei-Buffer
- XOR CX,CX ; übergebe aktuelle
- XCHG CX,ES:[DI].fBufPos ; Größe des Datei-Buffers
- PUSH CX ; und setze sie zurück
- LEA BX,L_WriteCnt ; übergebe Zeiger auf Word,
- PUSH SS ; in dem die tatsächliche Anzahl
- PUSH BX ; geschriebener Bytes gespeichert wird
- CALL DosWrite ; sende Block an Device
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- POP DS ; hole Datensegment zurück
- RET
- FileWrDev ENDP
-
- ;
- ; Close-Funktion des Standard-Text-Gerätetreibers.
- ;
-
- PUBLIC FileClose
- FileClose PROC PASCAL FAR
- ARG A_File : DWORD
- LES DI,A_File ; lese Zeiger auf TextRec
- MOV BX,ES:[DI].fHandle ; lese FileHandle
- XOR AX,AX ; lösche Fehlercode
- CMP BX,2 ; ist es Handle für Standard-I/O ?
- JBE @@Exit ; ja -> nicht schließen
- PUSH BX ; übergebe FileHandle
- CALL DosClose ; schließe Datei
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- @@Exit: RET
- FileClose ENDP
-
- ;
- ; Open-Funktion des Standard-Text-Gerätetreibers.
- ;
- ; {CT} 11/11/93
- ; BUG: Could not use a TEXTREC Created on heap,
- ; FIX: change use of DS to ES.
- ; DESCRIPTION:
- ; Procedure origional used DS as segment for access
- ; to TEXTREC, in doing so, it destroyed the DS segment
- ; for access to FILEMODE and INOUTRES.
- ; I change PROC to use ES Segment for access to TEXTREC.
- ; This fixed the problem.
- ;
-
- FileOpen PROC PASCAL FAR
- ARG A_File : DWORD
- LOCAL L_Handle : WORD, \
- L_Action : WORD, \
- L_FileSize : DWORD, \
- L_FilePtr : DWORD, \
- L_Count : WORD, \
- L_HandleType : WORD, \
- L_DevAttr : WORD
- PUSH DS ; rette Datensegment
- ; LDS DI,A_File ; lese Zeiger auf TextRec
- les di,a_file ;{CT} Load ES:DI to point to TextREC
- ; MOV [DI].fHandle,0 ; Handle für Standardeingabe = 0
- MOV es:[DI].fHandle,0 ;{CT} init file handle = 0
- MOV AX,FILE_OPEN ; lese Flags für
- ; MOV CX,OPEN_ACCESS_READONLY ; Reset()
- MOV CX,es:[di].fprivate ;{CT} Allow readonly access
- ; CMP [DI].fMode,fmInput ; wird Datei zum Lesen geöffnet ?
- CMP es:[DI].fMode,fmInput ;{CT}
- JE @@ModeOk ; ja -> ok, weiter
- ; MOV CX,OPEN_ACCESS_READWRITE; lese Flags für Append()
- ; INC [DI].fHandle ; Handle für Standardausgabe = 1
- INC ES:[DI].fHandle ;{CT}
- ; CMP [DI].fMode,fmInOut ; wird Datei wahlfrei geöffnet ?
- CMP ES:[DI].fMode,fmInOut ; {CT}
- JE @@ModeOk ; ja -> ok, weiter
- MOV AX,FILE_CREATE OR FILE_OPEN; lese Flags für ReWrite()
- ;@@ModeOk: CMP [DI].fName,0 ; ist Standardein-/ausgabe gemeint ?
- @@ModeOk: CMP es:[DI].fName,0 ;{CT}
- JE @@AlreadyOpen ; ja -> Datei nicht öffnen
- LEA DX,[DI].fName ; lese Zeiger auf
- ; PUSH DS ; den Dateinamen
- PUSH ES ; {CT}
- PUSH DX ; und übergebe ihn als Argument
- LEA BX,L_Handle ; übergebe Zeiger auf
- PUSH SS ; Speicherbereich, wo
- PUSH BX ; DateiHandle abgelegt wird
- LEA BX,L_Action ; übergebe Zeiger auf
- PUSH SS ; Speicherbereich, wo
- PUSH BX ; ausgeführte Aktion abgelegt wird
- XOR BX,BX ; übergebe
- PUSH BX ; Größe
- PUSH BX ; von 0
- PUSH FILE_NORMAL ; Flag für normale Datei
- PUSH AX ; übergebe Open Flags
- mov ax,filemode ;{CT} Allow readonly file access
- and ax,0FFFCh; ;{CT} mask off OPEN_ACCESS flags;
- OR Cx,Ax ;{CT} or with shareing ...
- ; OR CX,FileMode ; setze Share-Mode
- PUSH CX ; übergebe Open Mode
- PUSH BX ; übergebe 0L
- PUSH BX ; (reserviert)
- CALL DosOpen ; öffne Datei
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- OR AX,AX ; Fehler aufgetreten ?
- JNZ @@OpenError ; ja -> Ende
- MOV AX,L_Handle ; lese neues DateiHandle
- ; MOV [DI].fHandle,AX ; speichern in TextRec
- MOV ES:[DI].fHandle,AX ;{CT}
- @@AlreadyOpen: MOV AX,OFFSET FileRead ; lese Zeiger auf Read-Funktion
- MOV DX,CS ; in DX:AX
- XOR CX,CX ; keine Flush-Funktion
- XOR BX,BX ; für Eingabedatei verfügbar
- ; CMP [DI].fMode,fmInput ; ist Dateimodus Eingabe ?
- CMP ES:[DI].fMode,fmInput ;{CT}
- JE @@SetTextFuncs ; ja -> weiter
- ; PUSH [DI].fHandle ; teste, ob Datei zu einem Device führt
- PUSH ES:[DI].fHandle ;{CT}
- LEA BX,L_HandleType ; übergebe Zeiger auf Word,
- PUSH SS ; in dem der Handle-Typ
- PUSH BX ; gespeichert wird
- LEA BX,L_DevAttr ; übergebe Zeiger auf Word,
- PUSH SS ; in dem die Device-Attribute
- PUSH BX ; gespeichert werden
- CALL DosQHandType ; erfrage Typ des FileHandles
- OR AX,AX ; ist Fehler aufgetreten ?
- MOV DX,0 ; Datei ist kein Device
- JNZ @@NoDevice ; Fehler -> weiter
- MOV AX,L_HandleType ; lese Typ des FileHandles
- AND AX,NOT HANDTYPE_NETWORK ; maskiere Network-Flag aus
- CMP AL,HANDTYPE_DEVICE ; ist es Device ?
- JNZ @@NoDevice ; ja -> weiter
- INC DX ; setze Flag für "kein Device"
- @@NoDevice:
- OR DX,DX ; ist es Device?
- MOV AX,OFFSET FileWrDev ; lese Zeiger auf Write-Funktion
- MOV DX,CS ; für Devices in DX:AX
- MOV CX,AX ; lese Zeiger auf Flush-Funktion
- MOV BX,DX ; für Devices in BX:CX
- JNE @@IsDevice ; falls Device -> weiter
- ; CMP [DI].fMode,fmInOut ; ist es Datei mit wahlfreiem Zugriff ?
- CMP ES:[DI].fMode,fmInOut ;{CT}
- JNE @@NoAppend ; nein -> weiter
- CALL FileAppend ; bereite Datei-Anfügung vor
- @@NoAppend: MOV AX,OFFSET FileWrite ; lese Zeiger auf Write-Funktion
- MOV DX,CS ; für Devices in DX:AX
- XOR CX,CX ; keine Flush-Funktion
- XOR BX,BX ; verfügbar
- ;@@IsDevice: MOV [DI].fMode,fmOutput ; setze Dateimodus für Ausgabe
- ;@@SetTextFuncs: MOV [DI].fInOutProc.offs,AX ; speichere Zeiger auf
- ; MOV [DI].fInOutProc.segm,DX ; Ein-/Ausgabe-Funktion
- ; MOV [DI].fFlushProc.offs,CX ; speichere Zeiger auf
- ; MOV [DI].fFlushProc.segm,BX ; Flush-Funktion
- ; MOV [DI].fCloseProc.offs,OFFSET FileClose ; speichere Zeiger
- ; MOV [DI].fCloseProc.segm,CS ; auf Close-Funktion
- @@IsDevice: MOV ES:[DI].fMode,fmOutput ;{CT} initialize TEXTREC
- @@SetTextFuncs: MOV ES:[DI].fInOutProc.offs,AX ;{CT} ofs address for inoutproc
- MOV ES:[DI].fInOutProc.segm,DX ;{CT} seg address for inoutproc
- MOV ES:[DI].fFlushProc.offs,CX ;{CT} ofs address for flushproc
- MOV ES:[DI].fFlushProc.segm,BX ;{CT} seg address for flushproc
- MOV ES:[DI].fCloseProc.offs,OFFSET FileClose ;{CT} closeproc
- MOV ES:[DI].fCloseProc.segm,CS ;{CT} closeproc
- XOR AX,AX ; lösche Fehlercode
- @@OpenError: POP DS ;{CT} change destinatin of jump to
- ;{CT} restore ds befor return
- RET ;{CT}
-
- ;
- ; Bereite Datei-Anfügung vor, indem der Datei-Zeiger an
- ; das Ende der Datei bewegt wird und der letzte 128-Byte-
- ; Block der Datei in den Date-Buffer eingelesen wird.
- ;
-
- FileAppend PROC NEAR
-
- ; Bestimme Länge der Datei.
-
- ; PUSH [DI].fHandle ; bestimme aktuelle Position
- PUSH ES:[DI].fHandle ;{CT} push correct handle
- XOR AX,AX ; übergebe 0
- PUSH AX ; als
- PUSH AX ; Positionsangabe
- PUSH FILE_END ; vom Dateiende aus
- LEA BX,L_FileSize ; lese Zeiger auf Word, in dem
- PUSH SS ; die Dateigröße
- PUSH BX ; gespeichert wird
- CALL DosChgFilePtr ; erfrage Länge der Datei
- OR AX,AX ; ist Fehler aufgetreten ?
- JNZ @@GetSizeError ; ja -> Dateilänge := 0
- MOV AX,L_FileSize.offs ; lese Länge
- MOV DX,L_FileSize.segm ; der Datei
- SUB AX,128 ; berechne Position
- SBB DX,0 ; des letzten 128-Byte-Blocks
- JNC @@Seek ; falls Datei nicht zu kurz -> weiter
- @@GetSizeError: XOR AX,AX ; bei Fehler
- XOR DX,DX ; -> Datelänge := 0
-
- ; Bewege Datei-Zeiger auf 128 Bytes vor Dateiende.
-
- ;@@Seek: PUSH [DI].fHandle ; übergebe FileHandle
- @@Seek: PUSH ES:[DI].fHandle ;{CT} push correct handle
- PUSH DX ; übergebe neue Position
- PUSH AX ; des Datei-Zeigers (128 Bytes vor Dateiende)
- PUSH FILE_BEGIN ; vom Dateianfang aus
- LEA BX,L_FilePtr ; lese Zeiger auf Word, in dem
- PUSH SS ; die neue Position des
- PUSH BX ; Datei-Zeigers gespeichert wird
- CALL DosChgFilePtr ; setze Datei-Zeiger
-
- ; Lese die letzten 128 Byte aus der Datei.
-
- ; PUSH [DI].fHandle ; übergebe FileHandle
- PUSH ES:[DI].fHandle ;{CT} push correct handle
- LEA BX,[DI].fBuffer ; übergebe Zeiger
- PUSH SS ; auf den
- PUSH BX ; Datei-Buffer
- PUSH 128 ; Länge := 128 Bytes
- LEA BX,L_Count ; übergebe Zeiger auf Word,
- PUSH SS ; in dem die Anzahl der gelesenen
- PUSH BX ; Bytes gespeichert wird
- CALL DosRead ; lese 128 Bytes aus Datei
- OR AX,AX ; ist Lesefehler aufgetreten ?
- MOV AX,0 ; für diesen Fall: 0 Bytes gelesen
- JNZ @@ReadError ; Fehler -> weiter
- MOV AX,L_Count ; lese Anzahl tatsächlich gelesener Bytes
- @@ReadError: XOR BX,BX ; init. Index auf Datei-Buffer
- @@ChkEofLoop: CMP BX,AX ; Ende des Buffers erreicht ?
- JE @@End ; ja -> Ende
- ; CMP [DI].fBuffer[BX],eof ; ist EOF-Zeichen im Buffer ?
- CMP ES:[DI].fBuffer[BX],eof ;{CT} set correct entry in buffer
- JE @@Truncate ; ja -> schneide Datei ab
- INC BX ; nächstes Byte im Buffer
- JMP @@ChkEofLoop ; auf EOF testen
-
- ; Schneide Datei am EOF-Zeichen ab, alle weiteren
- ; Bytes hinter (logischem) Dateiende werden gelöscht.
-
- @@Truncate: SUB BX,AX ; berechne
- MOV AX,L_FileSize.offs ; Position
- MOV DX,L_FileSize.segm ; zum
- ADD AX,BX ; Abschneiden
- ADC DX,0 ; der Datei
- ; PUSH [DI].fHandle ; übergebe FileHandle
- PUSH ES:[DI].fHandle ;{CT} push correct handle
- PUSH DX ; übergebe neue Länge
- PUSH AX ; der Datei
- CALL DosNewSize ; schneide Datei ab
- CALL ConvErrCode ; konvertiere Fehlercode nach OS/2-Code
- @@End: RET
- FileAppend ENDP
- FileOpen ENDP
-
- CODE ENDS
-
- END
-