home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wunderki.zip / FCTL.ASM < prev    next >
Assembly Source File  |  1993-08-16  |  22KB  |  432 lines

  1. ;//////////////////////////////////////////////////////
  2. ;/                                                    /
  3. ;/ Run-time Library für Borland Pascal 7.0 unter OS/2 /
  4. ;/ Datei-Routinen.                                    /
  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.                 ;
  25.                 ; Konvertiere OS/2-Fehlercode in AX in DOS-Fehlercode.
  26.                 ; Falls kein korrespondierender Fehlercode existiert,
  27.                 ; wird der OS/2-Code mit gesetztem Bit 15 zurückgegeben.
  28.                 ;
  29.  
  30.                 PUBLIC  ConvErrCode
  31. ConvErrCode     PROC    NEAR
  32.                 CMP     AX,110
  33.                 JNZ     @@1
  34.                 MOV     AX,2
  35. @@1:            CMP     AX,88                   ; muß Code konvertiert werden ?
  36.                                                 ; Fehlercodes 1-87 sind gleich für MS-DOS und OS/2!
  37.                 JAE     @@Convert               ; ja -> setze Bit 15
  38.                 RET
  39.  
  40. @@Convert:      OR      AH,80H                  ; setze Bit 15 für OS/2-Fehlercode
  41.                 RET
  42. ConvErrCode     ENDP
  43.  
  44.                 ;
  45.                 ; Procedure Assign(Var f;Name : PChar);
  46.                 ;
  47.  
  48.                 PUBLIC  AssignFileC
  49. AssignFileC     PROC    PASCAL FAR
  50.                 MOV     DL,1                    ; setze Flag für PChar-Argument
  51.                 JMP     SHORT Assign
  52. AssignFileC     ENDP
  53.  
  54.                 ;
  55.                 ; Procedure Assign(Var f;Name : String);
  56.                 ;
  57.  
  58.                 PUBLIC  AssignFile
  59. AssignFile      PROC    PASCAL FAR
  60.                 XOR     DX,DX                   ;lösche Flag für PChar-Argument
  61. AssignFile      ENDP
  62.  
  63.                 ; 
  64.                 ; Gemeinsame Routine für Assign.
  65.                 ;
  66.  
  67. Assign          PROC    PASCAL FAR
  68.                 ARG     A_File : DWORD,  \
  69.                         A_Name : DWORD
  70.                 PUSH    DS                      ; rette Datensegment
  71.                 LES     DI,A_File               ; lese Zeiger auf FileRec
  72.                 LDS     SI,A_Name               ; lese Zeiger auf Namen
  73.                 MOV     ES:[DI].fHandle,0       ; markiere Handle als ungültig
  74.                 MOV     ES:[DI].fMode,fmClosed  ; Datei ist geschlossen
  75.                 XOR     AX,AX                   ; lösche die 
  76.                 MOV     CX,(fName-fBufSize)/2   ; restlichen 
  77.                 ADD     DI,fBufSize             ; Komponenten
  78.                 CLD                             ; des
  79.                 REP     STOSW                   ; FileRecs
  80.                 MOV     CX,79                   ; lese max. Länge des Dateinamens
  81.                 OR      DX,DX                   ; ist es PChar-Routine ?
  82.                 JNE     @@CopyNameLoop          ; ja -> weiter
  83.                 LODSB                           ; lese Längenbyte des Namens
  84.                 CMP     CL,AL                   ; ist max. Länge überschritten ?
  85.                 JBE     @@CopyNameLoop          ; nein -> ok, weiter
  86.                 MOV     CL,AL                   ; schneide Namen ab
  87.                 JCXZ    @@CopyNameEnd           ; falls Namen Leerstring -> weiter
  88. @@CopyNameLoop: LODSB                           ; lese Zeichen aus angegebenem Dateinamen
  89.                 OR      AL,AL                   ; Ende erreicht (bei PChar-Routine) ?
  90.                 JE      @@CopyNameEnd           ; ja -> Kopieren des Namens beenden
  91.                 STOSB                           ; speichere Zeichen in TextRec
  92.                 LOOP    @@CopyNameLoop          ; gesamten Namen kopieren
  93. @@CopyNameEnd:  XOR     AL,AL                   ; schließe Namen in TextRec
  94.                 STOSB                           ; mit Nullbyte ab
  95.                 POP     DS                      ; stelle Datensegment wieder her
  96.                 RET     
  97. Assign          ENDP
  98.  
  99.                 ;
  100.                 ; Procedure Close(Var f);
  101.                 ;
  102.  
  103.                 PUBLIC  CloseFile
  104. CloseFile       PROC    PASCAL FAR
  105.                 ARG     A_File : DWORD
  106.                 LES     DI,A_File               ; lese Zeiger auf FileRec
  107.                 CALL    OpenCheck               ; ist Datei geöffnet ?
  108.                 JNE     @@Exit                  ; falls nein -> Ende
  109.                 MOV     BX,ES:[DI].fHandle      ; lese Handle der Datei
  110.                 CMP     BX,2                    ; ist es Handle für Standard-I/O ?
  111.                 JBE     @@Closed                ; ja -> nicht schließen
  112.                 PUSH    BX                      ; übergebe FileHandle
  113.                 CALL    DosClose                ; schließe Datei
  114.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  115.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  116.                 JZ      @@Closed                ; nein -> Ende
  117.                 MOV     InOutRes,AX             ; speichere Fehlercode
  118. @@Closed:       MOV     ES:[DI].fMode,fmClosed  ; markiere Datei als geschlossen
  119. @@Exit:         RET
  120. CloseFile       ENDP
  121.  
  122.                 ;
  123.                 ; Procedure Reset(Var f;RecSize : Word); 
  124.                 ;
  125.  
  126.                 PUBLIC  ResetFile
  127. ResetFile       PROC    PASCAL FAR
  128.                 MOV     AX,FILE_OPEN            ; lese Flags für Öffnen
  129.                 XOR     DX,DX                   ; Handle der Standard-Eingabe := 0
  130.                 JMP     SHORT OpenFile          ; -> öffne Datei
  131. ResetFile       ENDP
  132.  
  133.                 ;
  134.                 ; Procedure Rewrite(Var f;RecSize : Word); 
  135.                 ;
  136.  
  137.                 PUBLIC  RewriteFile
  138. RewriteFile     PROC    PASCAL FAR
  139.                 MOV     AX,FILE_CREATE OR FILE_OPEN; lese Flags für neue Datei
  140.                 MOV     DX,1                    ; Handle der Standard-Ausgabe := 1
  141. RewriteFile     ENDP
  142.  
  143.                 ;
  144.                 ; Open file
  145.                 ;
  146.  
  147. OpenFile        PROC    PASCAL FAR
  148.                 ARG     A_FileP   : DWORD, \
  149.                         A_RecSize : WORD
  150.                 LOCAL   L_Handle  : WORD,  \
  151.                         L_Action  : WORD
  152.                 LES     DI,A_FileP              ; lese Zeiger auf FileRec
  153.                 CMP     ES:[DI].fMode,fmClosed  ; ist die Datei geschlossen ?
  154.                 JE      @@FileClosed            ; ja -> weiter
  155.                 CMP     ES:[DI].fMode,fmInOut   ; ist die Datei geöffnet ?
  156.                 JE      @@CloseFile             ; ja -> Datei zuerst schließen
  157.                 MOV     InOutRes,102            ; sonst Fehler: 'File not assigned'
  158.                 JMP     SHORT @@Exit            ; -> Ende
  159.  
  160. @@CloseFile:    PUSH    AX                      ; rette
  161.                 PUSH    DX                      ; Register
  162.                 PUSH    ES                      ; übergebe Zeiger
  163.                 PUSH    DI                      ; auf FileRec
  164.                 PUSH    CS                      ; schließe Datei, bevor
  165.                 CALL    CloseFile               ; sie wieder geöffnet wird
  166.                 POP     DX                      ; hole Register
  167.                 POP     AX                      ; zurück
  168. @@FileClosed:   CMP     ES:[DI].fName,0         ; soll Standard-Ein-/Ausgabe geöffnet werden ?
  169.                 JE      @@OpenOk                ; ja -> weiter, bereits offen
  170.                 LEA     DX,[DI].fName           ; übergebe
  171.                 PUSH    ES                      ; Zeiger auf
  172.                 PUSH    DX                      ; Dateinamen
  173.                 LEA     DX,L_Handle             ; übergebe Zeiger auf 
  174.                 PUSH    SS                      ; Speicherbereich, wo
  175.                 PUSH    DX                      ; DateiHandle abgelegt wird
  176.                 LEA     DX,L_Action             ; übergebe Zeiger auf 
  177.                 PUSH    SS                      ; Speicherbereich, wo
  178.                 PUSH    DX                      ; ausgeführte Aktion abgelegt wird
  179.                 XOR     DX,DX                   ; übergebe 
  180.                 PUSH    DX                      ; Größe
  181.                 PUSH    DX                      ; von 0
  182.                 PUSH    FILE_NORMAL             ; Flag für normale Datei
  183.                 PUSH    AX                      ; übergebe Open Flags
  184.                 MOV     AX,OPEN_ACCESS_READWRITE; öffne für Ein-/Ausgabe
  185.                 OR      AX,FileMode             ; übergebe 
  186.                 PUSH    AX                      ; Open Mode
  187.                 PUSH    DX                      ; übergebe 0L
  188.                 PUSH    DX                      ; (reserviert)
  189.                 CALL    DosOpen                 ; öffne Datei
  190.                 MOV     DX,L_Handle             ; lese Handle der neuen Datei
  191.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  192.                 OR      AX,AX                   ; Fehler aufgetreten ?
  193.                 JZ      @@OpenOk                ; nein -> ok, weiter
  194.                 MOV     InOutRes,AX             ; speichere Fehlercode
  195.                 JMP     SHORT @@Exit            ; -> Ende
  196.  
  197. @@OpenOk:       XCHG    AX,DX                   ; lese Handle in AX
  198.                 MOV     ES:[DI].fMode,fmInOut   ; setze Dateimodus
  199.                 MOV     ES:[DI].fHandle,AX      ; speichere Handle
  200.                 MOV     AX,A_RecSize            ; speichere angegebene
  201.                 MOV     ES:[DI].fBufSize,AX     ; Record-Größe im FileRec
  202. @@Exit:         RET
  203. OpenFile        ENDP
  204.  
  205.                 ;
  206.                 ; Procedure Truncate(Var f);
  207.                 ;
  208.  
  209.                 PUBLIC  TruncFile
  210. TruncFile       PROC    PASCAL FAR
  211.                 ARG     A_FileP   : DWORD
  212.                 LOCAL   L_FilePos : DWORD
  213.                 LES     DI,A_FileP              ; lese Zeiger auf FileRec
  214.                 CALL    OpenCheck               ; ist Datei geöffnet ?
  215.                 JNE     @@Exit                  ; nein -> weiter
  216.                 PUSH    ES:[DI].fHandle         ; bestimme aktuelle Position
  217.                 XOR     AX,AX                   ; übergebe 0
  218.                 PUSH    AX                      ; als
  219.                 PUSH    AX                      ; Positionsangabe
  220.                 PUSH    FILE_CURRENT            ; von aktueller Position aus
  221.                 LEA     BX,L_FilePos            ; lese Zeiger auf Word, in dem 
  222.                 PUSH    SS                      ; die aktuelle Position des
  223.                 PUSH    BX                      ; Datei-Zeigers gespeichert wird
  224.                 CALL    DosChgFilePtr           ; erfrage aktuelle Position der Datei
  225.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  226.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  227.                 JNZ     @@Error                 ; ja -> Ende
  228.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  229.                 PUSH    L_FilePos.segm          ; übergebe neue
  230.                 PUSH    L_FilePos.offs          ; Dateigröße
  231.                 CALL    DosNewSize              ; schneide Datei ab
  232.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  233.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  234.                 JZ      @@Exit                  ; nein -> weiter
  235. @@Error:        MOV     InOutRes,AX             ; speichere Fehlercode
  236. @@Exit:         RET
  237. TruncFile       ENDP
  238.                 
  239.                 ;
  240.                 ; Teste, ob Datei geöffnet ist.
  241.                 ;
  242.  
  243. OpenCheck       PROC    NEAR
  244.                 CMP     ES:[DI].fMode,fmInOut   ; ist Datei offen ?
  245.                 JE      @@Exit                  ; ja -> Ende
  246.                 MOV     InOutRes,103            ; sonst Fehler: 'File not open'
  247. @@Exit:         RET
  248. OpenCheck       ENDP
  249.  
  250.                 ;
  251.                 ; Procedure Read(Var f;Var V);
  252.                 ;
  253.  
  254.                 PUBLIC  ReadFile
  255. ReadFile        PROC    PASCAL FAR
  256.                 XOR     AH,AH                   ; setze Flag für Lesen
  257.                 MOV     DX,100                  ; Fehlernummer für 'Disk read error'
  258.                 JMP     SHORT InOutFile         ; -> lese Datei
  259. ReadFile        ENDP
  260.  
  261.                 ;
  262.                 ; Procedure Write(Var f;Var V);
  263.                 ;
  264.  
  265.                 PUBLIC  WriteFile
  266. WriteFile       PROC    PASCAL FAR
  267.                 MOV     AH,1                    ; setze Flag für Schreiben
  268.                 MOV     DX,101                  ; Fehlernummer für 'Disk write error'
  269. WriteFile       ENDP
  270.  
  271.                 ;
  272.                 ; Typed file I/O
  273.                 ;
  274.  
  275. InOutFile       PROC    PASCAL FAR
  276.                 ARG     A_FileP    : DWORD, \
  277.                         A_BufferP  : DWORD
  278.                 LOCAL   L_Count    : WORD
  279.                 LES     DI,A_FileP              ; lese Zeiger auf FileRec
  280.                 CALL    OpenCheck               ; ist Datei geöffnet ?
  281.                 JNE     @@Exit                  ; nein -> Fehler, Ende
  282.                 PUSH    DS                      ; rette Datensegment
  283.                 PUSH    DX                      ; rette Fehlernummer
  284.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  285.                 LDS     DX,A_BufferP            ; übergebe 
  286.                 PUSH    DS                      ; Zeiger auf
  287.                 PUSH    DX                      ; Buffer
  288.                 PUSH    ES:[DI].fBufSize        ; übergebe Anzahl Bytes zum Lesen/Schreiben
  289.                 LEA     BX,L_Count              ; übergebe Zeiger auf Word,
  290.                 PUSH    SS                      ; in dem die tatsächliche Anzahl
  291.                 PUSH    BX                      ; gelesener/geschriebener Bytes gespeichert wird
  292.                 OR      AH,AH                   ; Schreiben ?
  293.                 JZ      @@Read                  ; nein -> Lesen
  294.                 CALL    DosWrite                ; schreibe Block in Datei
  295.                 JMP     SHORT @@Ok              ; -> weiter
  296.  
  297. @@Read:         CALL    DosRead                 ; lese Block aus Datei
  298. @@Ok:           CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  299.                 POP     DX                      ; hole Fehlernummer zurück
  300.                 POP     DS                      ; hole Datensegment zurück
  301.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  302.                 JNZ     @@Error                 ; ja -> speichere Fehlernummer
  303.                 MOV     AX,L_Count              ; lese Anzahl gelesener/geschriebener Bytes
  304.                 CMP     AX,ES:[DI].fBufSize     ; konnte alles verarbeitet werden ?
  305.                 JE      @@Exit                  ; ja -> Ende
  306.                 MOV     AX,DX                   ; lese Fehlernummer in AX
  307. @@Error:        MOV     InOutRes,AX             ; speichere Fehlernummer
  308. @@Exit:         LEAVE                           ; nur A_BufferP vom Stack nehmen,
  309.                 RET     4                       ; A_FileP dort lassen !
  310. InOutFile       ENDP
  311.  
  312.                 ;
  313.                 ; Procedure BlockRead(Var f : File;Var Buf;Count : Word;Var Result : Word);
  314.                 ;
  315.  
  316.                 PUBLIC  ReadBlock
  317. ReadBlock       PROC    PASCAL FAR
  318.                 XOR     BL,BL                   ; setze Flag für Lesen
  319.                 MOV     CX,100                  ; Fehlernummer für 'Disk read error'
  320.                 JMP     SHORT InOutBlock
  321. ReadBlock       ENDP
  322.  
  323.                 ;
  324.                 ; Procedure BlockWrite(Var f : File;Var Buf;Count : Word;Var Result : Word);
  325.                 ;
  326.  
  327.                 PUBLIC  WriteBlock
  328. WriteBlock      PROC    PASCAL FAR
  329.                 MOV     BL,1                    ; setze Flag für Schreiben
  330.                 MOV     CX,101                  ; Fehlernummer für 'Disk write error'
  331. WriteBlock      ENDP
  332.  
  333.                 ;
  334.                 ; Ein-/Ausgabe von untypisierten Dateien.
  335.                 ;
  336.  
  337. InOutBlock      PROC    PASCAL FAR
  338.                 ARG     A_FileP   : DWORD, \
  339.                         A_BufferP : DWORD, \
  340.                         A_Count   : WORD,  \
  341.                         A_ResultP : DWORD
  342.                 LOCAL   L_Count   : WORD
  343.                 LES     DI,A_FileP              ; lese Zeiger auf FileRec
  344.                 CALL    OpenCheck               ; ist Datei geöffnet ?
  345.                 JNE     @@NotOpen               ; nein -> Fehler, Ende
  346.                 MOV     AX,A_Count              ; lese Anzahl zu lesender/schreibender Bytes
  347.                 OR      AX,AX                   ; 0 Bytes lesen/schreiben ?
  348.                 JE      @@ZeroBuf               ; ja -> weiter
  349.                 PUSH    DS                      ; rette Datensegment
  350.                 PUSH    CX                      ; rette Fehlernummer
  351.                 PUSH    ES:[DI].fHandle         ; übergebe FileHandle
  352.                 LDS     DX,A_BufferP            ; übergebe 
  353.                 PUSH    DS                      ; Zeiger auf
  354.                 PUSH    DX                      ; Buffer
  355.                 MUL     ES:[DI].fBufSize        ; Anzahl Bytes := RecCount * RecSize
  356.                 PUSH    AX                      ; übergebe Anzahl Bytes zum Lesen/Schreiben
  357.                 LEA     DX,L_Count              ; übergebe Zeiger auf Word,
  358.                 PUSH    SS                      ; in dem die tatsächliche Anzahl
  359.                 PUSH    DX                      ; gelesener/geschriebener Bytes gespeichert wird
  360.                 OR      BL,BL                   ; Schreiben ?
  361.                 JZ      @@Read                  ; nein -> Lesen
  362.                 CALL    DosWrite                ; schreibe Block in Datei
  363.                 JMP     SHORT @@Ok              ; -> weiter
  364.  
  365. @@Read:         CALL    DosRead                 ; lese Block aus Datei
  366. @@Ok:           POP     CX                      ; hole Fehlernummer zurück
  367.                 POP     DS                      ; hole Datensegment zurück
  368.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  369.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  370.                 JNZ     @@Error                 ; ja -> speichere Fehlernummer
  371.                 MOV     AX,L_Count              ; berechne Anzahl 
  372.                 XOR     DX,DX                   ; der gelesenen/geschriebenen
  373.                 DIV     ES:[DI].fBufSize        ; Records
  374. @@ZeroBuf:      LES     DI,A_ResultP            ; lese Zeiger auf Ergebnis-Word
  375.                 MOV     DX,ES                   ; ist Ergebnis-Word
  376.                 OR      DX,DI                   ; überhaupt angegeben ?
  377.                 JE      @@NoResult              ; nein -> weiter
  378.                 MOV     ES:[DI],AX              ; speichere Anzahl Records im Ergebnis-Word
  379.                 JMP     SHORT @@Exit            ; -> Ende
  380.  
  381. @@NoResult:     CMP     AX,A_Count              ; wurde alles verarbeitet ?
  382.                 JE      @@Exit                  ; ja -> Ende
  383.                 MOV     InOutRes,CX             ; sonst setze Fehlercode
  384.                 JMP     SHORT @@Exit            ; -> Ende
  385.  
  386. @@Error:        MOV     InOutRes,AX             ; speichere Fehlercode
  387. @@NotOpen:      LES     DI,A_ResultP            ; lese Zeiger auf Ergebnis-Word
  388.                 MOV     DX,ES                   ; ist Ergebnis-Word
  389.                 OR      DX,DI                   ; überhaupt angegeben ?
  390.                 JE      @@Exit                  ; nein -> Ende
  391.                 XOR     AX,AX                   ; speichere 0 als 
  392.                 MOV     ES:[DI],AX              ; Ergebnis im Fehlerfall
  393. @@Exit:         RET
  394. InOutBlock      ENDP
  395.  
  396.                 ;
  397.                 ; Procedure Seek(Var f;Pos : LongInt);
  398.                 ;
  399.  
  400.                 PUBLIC  SeekFile
  401. SeekFile        PROC    PASCAL FAR
  402.                 ARG     A_FileP   : DWORD, \
  403.                         A_FilePos : DWORD
  404.                 LOCAL   L_FilePtr : DWORD
  405.                 LES     DI,A_FileP              ; lese Zeiger auf FileRec
  406.                 CALL    OpenCheck               ; ist Datei geöffnet ?
  407.                 JNE     @@Exit                  ; nein -> Fehler, Ende
  408.                 MOV     AX,A_FilePos.w2         ; berechne 
  409.                 MUL     ES:[DI].fBufSize        ; die
  410.                 MOV     CX,AX                   ; neue
  411.                 MOV     AX,A_FilePos.w0         ; Position
  412.                 MUL     ES:[DI].fBufSize        ; des 
  413.                 ADD     CX,DX                   ; Datei-Zeigers
  414.                 PUSH    [DI].fHandle            ; übergebe FileHandle
  415.                 PUSH    CX                      ; übergebe neue Position
  416.                 PUSH    AX                      ; des Datei-Zeigers
  417.                 PUSH    FILE_BEGIN              ; vom Dateianfang aus
  418.                 LEA     BX,L_FilePtr            ; lese Zeiger auf Word, in dem 
  419.                 PUSH    SS                      ; die neue Position des
  420.                 PUSH    BX                      ; Datei-Zeigers gespeichert wird
  421.                 CALL    DosChgFilePtr           ; setze Datei-Zeiger
  422.                 OR      AX,AX                   ; ist Fehler aufgetreten ?
  423.                 JZ      @@Exit                  ; nein -> Ende
  424.                 CALL    ConvErrCode             ; konvertiere Fehlercode nach OS/2-Code
  425.                 MOV     InOutRes,AX             ; speichere Fehlercode
  426. @@Exit:         RET
  427. SeekFile        ENDP
  428.  
  429. CODE            ENDS
  430.  
  431.                 END
  432.