home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / bpos2-v2.zip / RTL-FIX1.ZIP / TCTL.ASM < prev   
Assembly Source File  |  1993-11-19  |  32KB  |  581 lines

  1. ;//////////////////////////////////////////////////////
  2. ;/                                                    /
  3. ;/ Run-time Library für Borland Pascal 7.0 unter OS/2 /
  4. ;/ Routinen für Text-Dateien.                         /
  5. ;/                                                    /
  6. ;/ 1993 Matthias Withopf / c't                        /
  7. ;/ Originalversion (c) 1988,92 Borland International  /
  8. ;/                                                    /
  9. ;//////////////////////////////////////////////////////
  10.  
  11.                 .286p                                         
  12.  
  13.                 _NOMACROS_ = 1                  ; keine Macros definieren
  14.                 INCLUDE SE.ASM
  15.                 INCLUDE OS2.ASM
  16.  
  17. DATA            SEGMENT WORD PUBLIC
  18.                 EXTRN   FileMode:WORD,InOutRes:WORD
  19. DATA            ENDS
  20.  
  21. CODE            SEGMENT BYTE PUBLIC
  22.                 ASSUME  CS:CODE,DS:DATA
  23.  
  24.                 EXTRN   ConvErrCode:NEAR
  25.  
  26.                 ;
  27.                 ; Assign(Var f;Name : PChar);
  28.                 ;
  29.  
  30.                 PUBLIC  AssignTextC
  31. AssignTextC     PROC    PASCAL FAR
  32.                 MOV     DL,1                    ; setze Flag für PChar-Argument
  33.                 JMP     SHORT Assign
  34. AssignTextC     ENDP
  35.  
  36.                 ;        
  37.                 ; Assign(Var f;Name : String);
  38.                 ;
  39.  
  40.                 PUBLIC  AssignText
  41. AssignText      PROC    PASCAL FAR
  42.                 XOR     DX,DX                   ; lösche Flag für PChar-Argument
  43. AssignText      ENDP
  44.  
  45.                 ;
  46.                 ; Allgemeine Assign-Prozedur.
  47.                 ;
  48.  
  49. Assign          PROC    PASCAL FAR 
  50.                 ARG     A_File : DWORD,  \
  51.                         A_Name : DWORD
  52.                 PUSH    DS                      ; rette Datensegment
  53.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  54.                 LDS     SI,A_Name               ; lese Zeiger auf Namen
  55.                 MOV     ES:[DI].fHandle,0       ; markiere Handle als ungültig
  56.                 MOV     ES:[DI].fMode,fmClosed  ; Datei ist geschlossen
  57.                 MOV     ES:[DI].fBufSize,128    ; setze Standardgröße des Buffers
  58.                 MOV     ES:[DI].fPrivate,0      ; init. private Daten
  59.                 MOV     ES:[DI].fBufPos,0       ; lösche den
  60.                 MOV     ES:[DI].fBufEnd,0       ; Datei-Buffer
  61.                 LEA     AX,[DI].fBuffer         ; initialisiere Zeiger
  62.                 MOV     ES:[DI].fBufPtr.offs,AX ; auf Buffer innerhalb
  63.                 MOV     ES:[DI].fBufPtr.segm,ES ; TextRec
  64.                 MOV     ES:[DI].fOpenProc.offs,OFFSET FileOpen ; definiere die
  65.                 MOV     ES:[DI].fOpenProc.segm,CS              ; Open-Funktion
  66.                 XOR     AX,AX                   ; lösche die 
  67.                 MOV     CX,(fName-fInOutProc)/2 ; restlichen 
  68.                 ADD     DI,fInOutProc           ; Funktionszeiger
  69.                 CLD                             ; und
  70.                 REP     STOSW                   ; UserData
  71.                 MOV     CX,79                   ; lese max. Länge des Dateinamens
  72.                 OR      DX,DX                   ; ist es PChar-Routine ?
  73.                 JNE     @@CopyNameLoop          ; ja -> weiter
  74.                 LODSB                           ; lese Längenbyte des Namens
  75.                 CMP     CL,AL                   ; ist max. Länge überschritten ?
  76.                 JBE     @@CopyNameLoop          ; nein -> ok, weiter
  77.                 MOV     CL,AL                   ; schneide Namen ab
  78.                 JCXZ    @@CopyNameEnd           ; falls Namen Leerstring -> weiter
  79. @@CopyNameLoop: LODSB                           ; lese Zeichen aus angegebenem Dateinamen
  80.                 OR      AL,AL                   ; Ende erreicht (bei PChar-Routine) ?
  81.                 JE      @@CopyNameEnd           ; ja -> Kopieren des Namens beenden
  82.                 STOSB                           ; speichere Zeichen in TextRec
  83.                 LOOP    @@CopyNameLoop          ; gesamten Namen kopieren
  84. @@CopyNameEnd:  XOR     AL,AL                   ; schließe Namen in TextRec
  85.                 STOSB                           ; mit Nullbyte ab
  86.                 POP     DS                      ; stelle Datensegment wieder her
  87.                 RET     
  88. Assign          ENDP
  89.  
  90.                 ;        
  91.                 ; Procedure SetTextBuf(var F : Text;Var Buf;Size : Word);
  92.                 ;
  93.  
  94.                 PUBLIC  BufferText
  95. BufferText      PROC    PASCAL FAR
  96.                 ARG     A_File : DWORD,    \
  97.                         A_Buf  : DWORD,    \
  98.                         A_Size : WORD
  99.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  100.                 MOV     AX,A_Size               ; setze neue 
  101.                 MOV     ES:[DI].fBufSize,AX     ; Buffer-Größe
  102.                 MOV     AX,A_Buf.offs           ; setze
  103.                 MOV     ES:[DI].fBufPtr.offs,AX ; neuen
  104.                 MOV     AX,A_Buf.segm           ; Zeiger
  105.                 MOV     ES:[DI].fBufPtr.segm,AX ; auf Buffer
  106.                 XOR     AX,AX                   ; lösche
  107.                 MOV     ES:[DI].fBufPos,AX      ; den
  108.                 MOV     ES:[DI].fBufEnd,AX      ; Datei-Buffer
  109.                 RET     
  110. BufferText      ENDP
  111.  
  112.                 ;        
  113.                 ; Procedure Reset(Var f : Text);
  114.                 ;
  115.  
  116.                 PUBLIC  ResetText
  117. ResetText       PROC    PASCAL FAR
  118.                 MOV     DX,fmInput              ; lese Dateimodus für Eingabe
  119.                 mov     cx,OPEN_ACCESS_READONLY ;{CT} allow read only file access
  120.                 JMP     SHORT OpenText
  121. ResetText       ENDP
  122.  
  123.                 ;
  124.                 ; Procedure Rewrite(Var f : Text);
  125.                 ;
  126.  
  127.                 PUBLIC  RewriteText
  128. RewriteText     PROC    PASCAL FAR
  129.                 MOV     DX,fmOutput              ; lese Dateimodus für Ausgabe
  130.                 MOV     CX,OPEN_ACCESS_WRITEONLY ;{CT} Allow readonly File Access
  131.                 JMP     SHORT OpenText
  132. RewriteText     ENDP
  133.  
  134.                 ;
  135.                 ; Procedure Append(Var f : Text);
  136.                 ;
  137.  
  138.                 PUBLIC  AppendText
  139. AppendText      PROC    PASCAL FAR
  140.                 MOV     DX,fmInOut              ; lese Dateimodus für wahlfreien Zugriff
  141.                 MOV     CX,OPEN_ACCESS_READWRITE ;{CT} Allow read only file access
  142. AppendText      ENDP
  143.  
  144.                 ;
  145.                 ; Öffne Datei oder lege Datei neu an.
  146.                 ; In DX wird der Dateimodus übergeben.
  147.                 ;
  148.  
  149.                 PUBLIC  OpenText
  150. OpenText        PROC    PASCAL FAR
  151.                 ARG     A_File : DWORD
  152.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  153.                 MOV     AX,ES:[DI].fMode        ; lese aktuellen Modus der Datei
  154.                 CMP     AX,fmInput              ; ist die Datei zum Lesen geöffnet ?
  155.                 JE      @@CloseFirst            ; ja -> zuerst schließen
  156.                 CMP     AX,fmOutput             ; ist die Datei zum Schreiben geöffnet ?
  157.                 JE      @@CloseFirst            ; ja -> zuerst schließen
  158.                 CMP     AX,fmClosed             ; ist die Datei geschlossen ?
  159.                 JE      @@Open                  ; ja -> ok, öffnen
  160.                 MOV     InOutRes,102            ; sonst Fehler: 'File not assigned'
  161.                 JMP     SHORT @@End             ; -> Ende
  162.  
  163. @@CloseFirst:   PUSH    DX                      ; rette neuen Dateimodus
  164.                 PUSH    ES                   ;{CT} Save es
  165.                 PUSH    DI                   ;{CT} Save DI
  166.                 PUSH    ES                      ; übergebe den Zeiger
  167.                 PUSH    DI                      ; auf TextRec
  168.                 PUSH    CS                      ; schließe die Datei,
  169.                 CALL    NEAR PTR CloseText      ; bevor sie neu geöffnet wird
  170.                 POP     DI                   ;{CT} recover DI
  171.                 POP     ES                   ;{CT} RECOVER ES
  172.                 POP     DX                      ; hole neuen Dateimodus zurück
  173. @@Open:         MOV     ES:[DI].fMode,DX        ; speichere neuen Dateimodus
  174.                 MOV     ES:[Di].Fprivate,CX  ;{CT} Allow REadonly
  175.                 XOR     AX,AX                   ; lösche den
  176.                 MOV     ES:[DI].fBufPos,AX      ; Buffer
  177.                 MOV     ES:[DI].fBufEnd,AX      ; der Textdatei
  178.                 MOV     BX,fOpenProc            ; rufe Funktion
  179.                 CALL    DoFunction              ; zum Öffnen auf
  180.                 JE      @@End                   ; falls kein Fehler -> ok, weiter
  181.                 MOV     ES:[DI].fMode,fmClosed  ; bei Fehler: setze Dateimodus auf geschlossen
  182. @@End:          RET
  183. OpenText        ENDP
  184.  
  185.                 ;
  186.                 ; Procedure Flush(Var f : Text);
  187.                 ;
  188.  
  189.                 PUBLIC  FlushText
  190. FlushText       PROC    PASCAL FAR
  191.                 XOR     AL,AL                   ; lösche Flag für "Schließen"
  192.                 JMP     SHORT FlushClose
  193. FlushText       ENDP
  194.  
  195.                 ;
  196.                 ; Procedure Close(Var f);
  197.                 ;
  198.  
  199.                 PUBLIC  CloseText
  200. CloseText       PROC    PASCAL FAR
  201.                 MOV     AL,1                    ; setze Flag für "Schließen"
  202. CloseText       ENDP
  203.  
  204.                 ;
  205.                 ; Flush/Close.
  206.                 ;
  207.  
  208.                 PUBLIC  FlushClose
  209. FlushClose      PROC    PASCAL FAR
  210.                 ARG     A_File : DWORD
  211.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  212.                 CMP     ES:[DI].fMode,fmInput   ; ist Datei als Eingabe geöffnet ?
  213.                 JE      @@DontFlush             ; ja -> kein Flush nötig
  214.                 CMP     ES:[DI].fMode,fmOutput  ; ist Datei als Ausgabe geöffnet ?
  215.                 JE      @@DoFlush               ; ja -> Flush
  216.                 MOV     InOutRes,103            ; sonst Fehler: 'File not open'
  217.                 JMP     SHORT @@DontClose       ; -> Ende
  218.  
  219. @@DoFlush:      PUSH    AX                      ; rette Flag für "Schließen"
  220.                 MOV     BX,fInOutProc           ; gebe den restlichen
  221.                 CALL    DoFunction              ; Buffer-Inhalt aus
  222.                 POP     AX                      ; hole Flag für "Schließen" zurück
  223. @@DontFlush:    OR      AL,AL                   ; ist Flag für "Schließen" gesetzt ?
  224.                 JE      @@DontClose             ; nein -> weiter, nicht schließen
  225.                 MOV     BX,fCloseProc           ; schließe
  226.                 CALL    DoFunction              ; die Datei
  227.                 MOV     ES:[DI].fMode,fmClosed  ; setze Dateimodus auf 'geschlossen'
  228. @@DontClose:    RET
  229. FlushClose      ENDP
  230.  
  231.                 ;
  232.                 ; Führe eine Funktion eines Textdatei-Gerätetreibers
  233.                 ; aus. Der Offset der Funktion innerhalb des 
  234.                 ; TextRecs wird in BX übergeben.
  235.                 ;
  236.  
  237. DoFunction      PROC    NEAR
  238.                 PUSH    ES                      ; rette Zeiger
  239.                 PUSH    DI                      ; auf TextRec
  240.                 PUSH    ES                      ; übergebe den Zeiger
  241.                 PUSH    DI                      ; auf TextRec als Argument
  242.                 CALL    DWORD PTR ES:[DI+BX]    ; rufe die gewünschte Funktion auf
  243.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  244.                 JE      @@NoErr                 ; nein -> weiter
  245.                 MOV     InOutRes,AX             ; speichere Fehlercode
  246. @@NoErr:        POP     DI                      ; hole Zeiger
  247.                 POP     ES                      ; auf TextRec zurück
  248.                 RET
  249. DoFunction      ENDP
  250.  
  251.                 ;        
  252.                 ; Read-Funktion des Standard-Text-Gerätetreibers.
  253.                 ;
  254.  
  255.                 PUBLIC  FileRead
  256. FileRead        PROC    PASCAL FAR
  257.                 ARG     A_File    : DWORD
  258.                 LOCAL   L_ReadCnt : WORD
  259.                 PUSH    DS                      ; rette Datensegment
  260.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  261.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  262.                 LDS     BX,ES:[DI].fBufPtr      ; übergebe Zeiger
  263.                 PUSH    DS                      ; auf den
  264.                 PUSH    BX                      ; Datei-Buffer
  265.                 PUSH    ES:[DI].fBufSize        ; übergebe Buffer-Größe
  266.                 LEA     BX,L_ReadCnt            ; übergebe Zeiger auf Word,
  267.                 PUSH    SS                      ; in dem die tatsächliche Anzahl
  268.                 PUSH    BX                      ; gelesener Bytes gespeichert wird
  269.                 CALL    DosRead                 ; lese Block aus Datei
  270.                 OR      AX,AX                   ; ist Fehler beim Lesen aufgetreten ?
  271.                 JNZ     @@Error                 ; ja -> Fehler
  272.                 MOV     AX,L_ReadCnt            ; lese Anzahl gelesener Bytes
  273.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  274.                 MOV     ES:[DI].fBufEnd,AX      ; speichere neues Buffer-Ende
  275.                 XOR     AX,AX                   ; lösche Fehlercode
  276. @@End:          MOV     ES:[DI].fBufPos,0       ; setze Position des Zeigers auf Datei-Buffers zurück
  277.                 POP     DS                      ; hole Datensegment zurück
  278.                 RET
  279.  
  280. @@Error:        MOV     ES:[DI].fBufEnd,0       ; lösche den Datei-Buffer
  281.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  282.                 JMP     SHORT @@End             ; -> Ende
  283. FileRead        ENDP
  284.  
  285.                 ;
  286.                 ; Write-Funktion des Standard-Text-Gerätetreibers.
  287.                 ;
  288.  
  289.                 PUBLIC  FileWrite
  290. FileWrite       PROC    PASCAL FAR
  291.                 ARG     A_File     : DWORD
  292.                 LOCAL   L_WriteCnt : WORD
  293.                 PUSH    DS                      ; rette Datensegment
  294.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  295.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  296.                 LDS     BX,ES:[DI].fBufPtr      ; übergebe
  297.                 PUSH    DS                      ; Zeiger auf
  298.                 PUSH    BX                      ; den Datei-Buffer
  299.                 XOR     CX,CX                   ; übergebe aktuelle
  300.                 XCHG    CX,ES:[DI].fBufPos      ; Größe des Datei-Buffers
  301.                 PUSH    CX                      ; und setze sie zurück
  302.                 LEA     BX,L_WriteCnt           ; übergebe Zeiger auf Word,
  303.                 PUSH    SS                      ; in dem die tatsächliche Anzahl
  304.                 PUSH    BX                      ; geschriebener Bytes gespeichert wird
  305.                 CALL    DosWrite                ; schreibe Block in Datei
  306.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  307.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  308.                 JNZ     @@Exit                  ; ja -> Ende
  309.                 MOV     AX,L_WriteCnt           ; lese Anzahl geschriebener Bytes
  310.                 SUB     AX,CX                   ; konnten alle Bytes geschrieben werden ?
  311.                 JE      @@Exit                  ; ja -> ok, weiter
  312.                 MOV     AX,101                  ; sonst Fehler: 'Disk write error'
  313. @@Exit:         POP     DS                      ; hole Datensegment zurück
  314.                 RET
  315. FileWrite       ENDP
  316.  
  317.                 ;
  318.                 ; Write-Funktion des Standard-Text-Gerätetreibers
  319.                 ; für Device-Dateien.
  320.                 ;
  321.  
  322.                 PUBLIC  FileWrDev
  323. FileWrDev       PROC    PASCAL FAR
  324.                 ARG     A_File     : DWORD
  325.                 LOCAL   L_WriteCnt : WORD
  326.                 PUSH    DS                      ; rette Datensegment
  327.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  328.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  329.                 LDS     BX,ES:[DI].fBufPtr      ; übergebe
  330.                 PUSH    DS                      ; Zeiger auf
  331.                 PUSH    BX                      ; den Datei-Buffer
  332.                 XOR     CX,CX                   ; übergebe aktuelle
  333.                 XCHG    CX,ES:[DI].fBufPos      ; Größe des Datei-Buffers
  334.                 PUSH    CX                      ; und setze sie zurück
  335.                 LEA     BX,L_WriteCnt           ; übergebe Zeiger auf Word,
  336.                 PUSH    SS                      ; in dem die tatsächliche Anzahl
  337.                 PUSH    BX                      ; geschriebener Bytes gespeichert wird
  338.                 CALL    DosWrite                ; sende Block an Device
  339.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  340.                 POP     DS                      ; hole Datensegment zurück
  341.                 RET     
  342. FileWrDev       ENDP
  343.  
  344.                 ;
  345.                 ; Close-Funktion des Standard-Text-Gerätetreibers.
  346.                 ;
  347.  
  348.                 PUBLIC  FileClose
  349. FileClose       PROC    PASCAL FAR
  350.                 ARG     A_File : DWORD
  351.                 LES     DI,A_File               ; lese Zeiger auf TextRec
  352.                 MOV     BX,ES:[DI].fHandle      ; lese FileHandle
  353.                 XOR     AX,AX                   ; lösche Fehlercode
  354.                 CMP     BX,2                    ; ist es Handle für Standard-I/O ?
  355.                 JBE     @@Exit                  ; ja -> nicht schließen
  356.                 PUSH    BX                      ; übergebe FileHandle
  357.                 CALL    DosClose                ; schließe Datei
  358.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  359. @@Exit:         RET     
  360. FileClose       ENDP
  361.  
  362.                 ;
  363.                 ; Open-Funktion des Standard-Text-Gerätetreibers.
  364.                 ;
  365.                 ; {CT} 11/11/93
  366.                 ; BUG:  Could not use a TEXTREC Created on heap,
  367.                 ; FIX:  change use of DS to ES.
  368.                 ; DESCRIPTION:
  369.                 ; Procedure origional used DS as segment for access
  370.                 ; to TEXTREC, in doing so, it destroyed the DS segment
  371.                 ; for access to FILEMODE and INOUTRES.
  372.                 ; I change PROC to use ES Segment for access to TEXTREC.
  373.                 ; This fixed the problem.
  374.                 ;
  375.  
  376. FileOpen        PROC    PASCAL FAR
  377.                 ARG     A_File       : DWORD
  378.                 LOCAL   L_Handle     : WORD,  \
  379.                         L_Action     : WORD,  \
  380.                         L_FileSize   : DWORD, \
  381.                         L_FilePtr    : DWORD, \
  382.                         L_Count      : WORD,  \
  383.                         L_HandleType : WORD,  \
  384.                         L_DevAttr    : WORD
  385.                 PUSH    DS                      ; rette Datensegment
  386. ;                LDS     DI,A_File               ; lese Zeiger auf TextRec
  387.                 les     di,a_file              ;{CT} Load ES:DI to point to TextREC
  388. ;                MOV     [DI].fHandle,0          ; Handle für Standardeingabe = 0
  389.                 MOV    es:[DI].fHandle,0       ;{CT} init file handle = 0
  390.                 MOV     AX,FILE_OPEN            ; lese Flags für
  391. ;                MOV     CX,OPEN_ACCESS_READONLY ; Reset()
  392.                 MOV     CX,es:[di].fprivate    ;{CT} Allow readonly access
  393. ;                CMP     [DI].fMode,fmInput      ; wird Datei zum Lesen geöffnet ?
  394.                 CMP     es:[DI].fMode,fmInput   ;{CT}
  395.                 JE      @@ModeOk                ; ja -> ok, weiter
  396. ;                MOV     CX,OPEN_ACCESS_READWRITE; lese Flags für Append()
  397. ;                INC     [DI].fHandle            ; Handle für Standardausgabe = 1
  398.                 INC     ES:[DI].fHandle        ;{CT}
  399. ;                CMP     [DI].fMode,fmInOut      ; wird Datei wahlfrei geöffnet ?
  400.                 CMP     ES:[DI].fMode,fmInOut  ; {CT}
  401.                 JE      @@ModeOk                ; ja -> ok, weiter
  402.                 MOV     AX,FILE_CREATE OR FILE_OPEN; lese Flags für ReWrite()
  403. ;@@ModeOk:       CMP     [DI].fName,0            ; ist Standardein-/ausgabe gemeint ?
  404. @@ModeOk:       CMP     es:[DI].fName,0         ;{CT}
  405.                 JE      @@AlreadyOpen           ; ja -> Datei nicht öffnen
  406.                 LEA     DX,[DI].fName           ; lese Zeiger auf
  407. ;                PUSH    DS                      ; den Dateinamen
  408.                 PUSH    ES                      ; {CT}
  409.                 PUSH    DX                      ; und übergebe ihn als Argument
  410.                 LEA     BX,L_Handle             ; übergebe Zeiger auf
  411.                 PUSH    SS                      ; Speicherbereich, wo
  412.                 PUSH    BX                      ; DateiHandle abgelegt wird
  413.                 LEA     BX,L_Action             ; übergebe Zeiger auf
  414.                 PUSH    SS                      ; Speicherbereich, wo
  415.                 PUSH    BX                      ; ausgeführte Aktion abgelegt wird
  416.                 XOR     BX,BX                   ; übergebe
  417.                 PUSH    BX                      ; Größe
  418.                 PUSH    BX                      ; von 0
  419.                 PUSH    FILE_NORMAL             ; Flag für normale Datei
  420.                 PUSH    AX                      ; übergebe Open Flags
  421.                 mov     ax,filemode          ;{CT} Allow readonly file access
  422.                 and     ax,0FFFCh;           ;{CT} mask off OPEN_ACCESS flags;
  423.                 OR      Cx,Ax                ;{CT} or with shareing ...
  424. ;                OR      CX,FileMode             ; setze Share-Mode
  425.                 PUSH    CX                      ; übergebe Open Mode
  426.                 PUSH    BX                      ; übergebe 0L
  427.                 PUSH    BX                      ; (reserviert)
  428.                 CALL    DosOpen                 ; öffne Datei
  429.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  430.                 OR      AX,AX                   ; Fehler aufgetreten ?
  431.                 JNZ     @@OpenError             ; ja -> Ende
  432.                 MOV     AX,L_Handle             ; lese neues DateiHandle
  433. ;                MOV     [DI].fHandle,AX         ; speichern in TextRec
  434.                 MOV     ES:[DI].fHandle,AX    ;{CT}
  435. @@AlreadyOpen:  MOV     AX,OFFSET FileRead      ; lese Zeiger auf Read-Funktion
  436.                 MOV     DX,CS                   ; in DX:AX
  437.                 XOR     CX,CX                   ; keine Flush-Funktion
  438.                 XOR     BX,BX                   ; für Eingabedatei verfügbar
  439. ;                CMP     [DI].fMode,fmInput      ; ist Dateimodus Eingabe ?
  440.                 CMP     ES:[DI].fMode,fmInput ;{CT}
  441.                 JE      @@SetTextFuncs          ; ja -> weiter
  442. ;                PUSH    [DI].fHandle            ; teste, ob Datei zu einem Device führt
  443.                 PUSH    ES:[DI].fHandle        ;{CT}
  444.                 LEA     BX,L_HandleType         ; übergebe Zeiger auf Word,
  445.                 PUSH    SS                      ; in dem der Handle-Typ
  446.                 PUSH    BX                      ; gespeichert wird
  447.                 LEA     BX,L_DevAttr            ; übergebe Zeiger auf Word,
  448.                 PUSH    SS                      ; in dem die Device-Attribute
  449.                 PUSH    BX                      ; gespeichert werden
  450.                 CALL    DosQHandType            ; erfrage Typ des FileHandles
  451.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  452.                 MOV     DX,0                    ; Datei ist kein Device
  453.                 JNZ     @@NoDevice              ; Fehler -> weiter
  454.                 MOV     AX,L_HandleType         ; lese Typ des FileHandles
  455.                 AND     AX,NOT HANDTYPE_NETWORK ; maskiere Network-Flag aus
  456.                 CMP     AL,HANDTYPE_DEVICE      ; ist es Device ?
  457.                 JNZ     @@NoDevice              ; ja -> weiter
  458.                 INC     DX                      ; setze Flag für "kein Device"
  459. @@NoDevice:
  460.                 OR      DX,DX                   ; ist es Device?
  461.                 MOV     AX,OFFSET FileWrDev     ; lese Zeiger auf Write-Funktion
  462.                 MOV     DX,CS                   ; für Devices in DX:AX
  463.                 MOV     CX,AX                   ; lese Zeiger auf Flush-Funktion
  464.                 MOV     BX,DX                   ; für Devices in BX:CX
  465.                 JNE     @@IsDevice              ; falls Device -> weiter
  466. ;                CMP     [DI].fMode,fmInOut      ; ist es Datei mit wahlfreiem Zugriff ?
  467.                 CMP     ES:[DI].fMode,fmInOut ;{CT}
  468.                 JNE     @@NoAppend              ; nein -> weiter
  469.                 CALL    FileAppend              ; bereite Datei-Anfügung vor
  470. @@NoAppend:     MOV     AX,OFFSET FileWrite     ; lese Zeiger auf Write-Funktion
  471.                 MOV     DX,CS                   ; für Devices in DX:AX
  472.                 XOR     CX,CX                   ; keine Flush-Funktion
  473.                 XOR     BX,BX                   ; verfügbar
  474. ;@@IsDevice:     MOV     [DI].fMode,fmOutput     ; setze Dateimodus für Ausgabe
  475. ;@@SetTextFuncs: MOV     [DI].fInOutProc.offs,AX ; speichere Zeiger auf
  476. ;                MOV     [DI].fInOutProc.segm,DX ; Ein-/Ausgabe-Funktion
  477. ;                MOV     [DI].fFlushProc.offs,CX ; speichere Zeiger auf
  478. ;                MOV     [DI].fFlushProc.segm,BX ; Flush-Funktion
  479. ;                MOV     [DI].fCloseProc.offs,OFFSET FileClose ; speichere Zeiger
  480. ;                MOV     [DI].fCloseProc.segm,CS ; auf Close-Funktion
  481. @@IsDevice:     MOV     ES:[DI].fMode,fmOutput     ;{CT} initialize TEXTREC
  482. @@SetTextFuncs: MOV     ES:[DI].fInOutProc.offs,AX ;{CT} ofs address for inoutproc
  483.                 MOV     ES:[DI].fInOutProc.segm,DX ;{CT} seg address for inoutproc
  484.                 MOV     ES:[DI].fFlushProc.offs,CX ;{CT} ofs address for flushproc
  485.                 MOV     ES:[DI].fFlushProc.segm,BX ;{CT} seg address for flushproc
  486.                 MOV     ES:[DI].fCloseProc.offs,OFFSET FileClose ;{CT}   closeproc
  487.                 MOV     ES:[DI].fCloseProc.segm,CS ;{CT}                 closeproc
  488.                 XOR     AX,AX                   ; lösche Fehlercode
  489. @@OpenError:    POP     DS                      ;{CT} change destinatin of jump to
  490.                                                 ;{CT} restore ds befor return
  491.                 RET                             ;{CT}
  492.  
  493.                 ;
  494.                 ; Bereite Datei-Anfügung vor, indem der Datei-Zeiger an
  495.                 ; das Ende der Datei bewegt wird und der letzte 128-Byte-
  496.                 ; Block der Datei in den Date-Buffer eingelesen wird.
  497.                 ;
  498.  
  499. FileAppend      PROC    NEAR
  500.  
  501.                 ; Bestimme Länge der Datei.
  502.  
  503. ;                PUSH    [DI].fHandle            ; bestimme aktuelle Position
  504.                 PUSH    ES:[DI].fHandle         ;{CT} push correct handle
  505.                 XOR     AX,AX                   ; übergebe 0
  506.                 PUSH    AX                      ; als
  507.                 PUSH    AX                      ; Positionsangabe
  508.                 PUSH    FILE_END                ; vom Dateiende aus
  509.                 LEA     BX,L_FileSize           ; lese Zeiger auf Word, in dem
  510.                 PUSH    SS                      ; die Dateigröße
  511.                 PUSH    BX                      ; gespeichert wird
  512.                 CALL    DosChgFilePtr           ; erfrage Länge der Datei
  513.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  514.                 JNZ     @@GetSizeError          ; ja -> Dateilänge := 0
  515.                 MOV     AX,L_FileSize.offs      ; lese Länge
  516.                 MOV     DX,L_FileSize.segm      ; der Datei
  517.                 SUB     AX,128                  ; berechne Position
  518.                 SBB     DX,0                    ; des letzten 128-Byte-Blocks
  519.                 JNC     @@Seek                  ; falls Datei nicht zu kurz -> weiter
  520. @@GetSizeError: XOR     AX,AX                   ; bei Fehler
  521.                 XOR     DX,DX                   ; -> Datelänge := 0
  522.  
  523.                 ; Bewege Datei-Zeiger auf 128 Bytes vor Dateiende.
  524.  
  525. ;@@Seek:         PUSH    [DI].fHandle            ; übergebe FileHandle
  526. @@Seek:         PUSH    ES:[DI].fHandle         ;{CT} push correct handle
  527.                 PUSH    DX                      ; übergebe neue Position
  528.                 PUSH    AX                      ; des Datei-Zeigers (128 Bytes vor Dateiende)
  529.                 PUSH    FILE_BEGIN              ; vom Dateianfang aus
  530.                 LEA     BX,L_FilePtr            ; lese Zeiger auf Word, in dem
  531.                 PUSH    SS                      ; die neue Position des
  532.                 PUSH    BX                      ; Datei-Zeigers gespeichert wird
  533.                 CALL    DosChgFilePtr           ; setze Datei-Zeiger
  534.  
  535.                 ; Lese die letzten 128 Byte aus der Datei.
  536.  
  537. ;                PUSH    [DI].fHandle            ; übergebe FileHandle
  538.                 PUSH    ES:[DI].fHandle       ;{CT} push correct handle
  539.                 LEA     BX,[DI].fBuffer         ; übergebe Zeiger
  540.                 PUSH    SS                      ; auf den
  541.                 PUSH    BX                      ; Datei-Buffer
  542.                 PUSH    128                     ; Länge := 128 Bytes
  543.                 LEA     BX,L_Count              ; übergebe Zeiger auf Word,
  544.                 PUSH    SS                      ; in dem die Anzahl der gelesenen
  545.                 PUSH    BX                      ; Bytes gespeichert wird
  546.                 CALL    DosRead                 ; lese 128 Bytes aus Datei
  547.                 OR      AX,AX                   ; ist Lesefehler aufgetreten ?
  548.                 MOV     AX,0                    ; für diesen Fall: 0 Bytes gelesen
  549.                 JNZ     @@ReadError             ; Fehler -> weiter
  550.                 MOV     AX,L_Count              ; lese Anzahl tatsächlich gelesener Bytes
  551. @@ReadError:    XOR     BX,BX                   ; init. Index auf Datei-Buffer
  552. @@ChkEofLoop:   CMP     BX,AX                   ; Ende des Buffers erreicht ?
  553.                 JE      @@End                   ; ja -> Ende
  554. ;                CMP     [DI].fBuffer[BX],eof    ; ist EOF-Zeichen im Buffer ?
  555.                 CMP     ES:[DI].fBuffer[BX],eof ;{CT} set correct entry in buffer
  556.                 JE      @@Truncate              ; ja -> schneide Datei ab
  557.                 INC     BX                      ; nächstes Byte im Buffer
  558.                 JMP     @@ChkEofLoop            ; auf EOF testen
  559.  
  560.                 ; Schneide Datei am EOF-Zeichen ab, alle weiteren
  561.                 ; Bytes hinter (logischem) Dateiende werden gelöscht.
  562.  
  563. @@Truncate:     SUB     BX,AX                   ; berechne
  564.                 MOV     AX,L_FileSize.offs      ; Position
  565.                 MOV     DX,L_FileSize.segm      ; zum
  566.                 ADD     AX,BX                   ; Abschneiden
  567.                 ADC     DX,0                    ; der Datei
  568. ;                PUSH    [DI].fHandle            ; übergebe FileHandle
  569.                 PUSH    ES:[DI].fHandle       ;{CT} push correct handle
  570.                 PUSH    DX                      ; übergebe neue Länge
  571.                 PUSH    AX                      ; der Datei
  572.                 CALL    DosNewSize              ; schneide Datei ab
  573.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  574. @@End:          RET
  575. FileAppend      ENDP
  576. FileOpen        ENDP
  577.  
  578. CODE            ENDS
  579.  
  580.                 END
  581.