(* Copyright 2016, 2019, 2023 Anton Krotov This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . *) MODULE File; IMPORT sys := SYSTEM, KOSAPI; CONST SEEK_BEG* = 0; SEEK_CUR* = 1; SEEK_END* = 2; TYPE FNAME* = ARRAY 520 OF CHAR; FS* = POINTER TO rFS; rFS* = RECORD subfunc*, pos*, hpos*, bytes*, buffer*: INTEGER; name*: FNAME END; FD* = POINTER TO rFD; rFD* = RECORD attr*: INTEGER; ntyp*: CHAR; reserved: ARRAY 3 OF CHAR; time_create*, date_create*, time_access*, date_access*, time_modif*, date_modif*, size*, hsize*: INTEGER; name*: FNAME END; PROCEDURE [stdcall] f_68_27(file_name: INTEGER; VAR size: INTEGER): INTEGER; BEGIN sys.CODE(053H); (* push ebx *) sys.CODE(06AH, 044H); (* push 68 *) sys.CODE(058H); (* pop eax *) sys.CODE(06AH, 01BH); (* push 27 *) sys.CODE(05BH); (* pop ebx *) sys.CODE(08BH, 04DH, 008H); (* mov ecx, [ebp + 08h] *) sys.CODE(0CDH, 040H); (* int 40h *) sys.CODE(08BH, 04DH, 00CH); (* mov ecx, [ebp + 0Ch] *) sys.CODE(089H, 011H); (* mov [ecx], edx *) sys.CODE(05BH); (* pop ebx *) sys.CODE(0C9H); (* leave *) sys.CODE(0C2H, 008H, 000H); (* ret 08h *) RETURN 0 END f_68_27; PROCEDURE Load*(FName: ARRAY OF CHAR; VAR size: INTEGER): INTEGER; RETURN f_68_27(sys.ADR(FName[0]), size) END Load; PROCEDURE GetFileInfo*(FName: ARRAY OF CHAR; VAR Info: rFD): BOOLEAN; VAR res2: INTEGER; fs: rFS; BEGIN fs.subfunc := 5; fs.pos := 0; fs.hpos := 0; fs.bytes := 0; fs.buffer := sys.ADR(Info); COPY(FName, fs.name) RETURN KOSAPI.sysfunc22(70, sys.ADR(fs), res2) = 0 END GetFileInfo; PROCEDURE Exists*(FName: ARRAY OF CHAR): BOOLEAN; VAR fd: rFD; BEGIN RETURN GetFileInfo(FName, fd) & ~(4 IN BITS(fd.attr)) END Exists; PROCEDURE Close*(VAR F: FS); BEGIN IF F # NIL THEN DISPOSE(F) END END Close; PROCEDURE Open*(FName: ARRAY OF CHAR): FS; VAR F: FS; BEGIN IF Exists(FName) THEN NEW(F); IF F # NIL THEN F.subfunc := 0; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name) END ELSE F := NIL END RETURN F END Open; PROCEDURE Delete*(FName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN IF Exists(FName) THEN NEW(F); IF F # NIL THEN F.subfunc := 8; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END ELSE res := -1 END RETURN res = 0 END Delete; PROCEDURE Seek*(F: FS; Offset, Origin: INTEGER): INTEGER; VAR res: INTEGER; fd: rFD; BEGIN IF (F # NIL) & GetFileInfo(F.name, fd) & (BITS(fd.attr) * {4} = {}) THEN CASE Origin OF |SEEK_BEG: F.pos := Offset |SEEK_CUR: INC(F.pos, Offset) |SEEK_END: F.pos := fd.size + Offset ELSE END; res := F.pos ELSE res := -1 END RETURN res END Seek; PROCEDURE Read*(F: FS; Buffer, Count: INTEGER): INTEGER; VAR res, res2: INTEGER; BEGIN IF F # NIL THEN F.subfunc := 0; F.bytes := Count; F.buffer := Buffer; res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); IF res2 > 0 THEN INC(F.pos, res2) END ELSE res2 := 0 END RETURN res2 END Read; PROCEDURE Write*(F: FS; Buffer, Count: INTEGER): INTEGER; VAR res, res2: INTEGER; BEGIN IF F # NIL THEN F.subfunc := 3; F.bytes := Count; F.buffer := Buffer; res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); IF res2 > 0 THEN INC(F.pos, res2) END ELSE res2 := 0 END RETURN res2 END Write; PROCEDURE Create*(FName: ARRAY OF CHAR): FS; VAR F: FS; res2: INTEGER; BEGIN NEW(F); IF F # NIL THEN F.subfunc := 2; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(FName, F.name); IF KOSAPI.sysfunc22(70, sys.ADR(F^), res2) # 0 THEN DISPOSE(F) END END RETURN F END Create; PROCEDURE DirExists*(FName: ARRAY OF CHAR): BOOLEAN; VAR fd: rFD; BEGIN RETURN GetFileInfo(FName, fd) & (4 IN BITS(fd.attr)) END DirExists; PROCEDURE CreateDir*(DirName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN NEW(F); IF F # NIL THEN F.subfunc := 9; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(DirName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END RETURN res = 0 END CreateDir; PROCEDURE DeleteDir*(DirName: ARRAY OF CHAR): BOOLEAN; VAR F: FS; res, res2: INTEGER; BEGIN IF DirExists(DirName) THEN NEW(F); IF F # NIL THEN F.subfunc := 8; F.pos := 0; F.hpos := 0; F.bytes := 0; F.buffer := 0; COPY(DirName, F.name); res := KOSAPI.sysfunc22(70, sys.ADR(F^), res2); DISPOSE(F) ELSE res := -1 END ELSE res := -1 END RETURN res = 0 END DeleteDir; PROCEDURE ReadChar* (F: FS; VAR x: CHAR): BOOLEAN; RETURN Read(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) END ReadChar; PROCEDURE ReadInt* (F: FS; VAR x: INTEGER): BOOLEAN; RETURN Read(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) END ReadInt; PROCEDURE ReadBool* (F: FS; VAR x: BOOLEAN): BOOLEAN; RETURN Read(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) END ReadBool; PROCEDURE WriteChar*(F: FS; x: CHAR): BOOLEAN; RETURN Write(F, sys.ADR(x), sys.SIZE(CHAR)) = sys.SIZE(CHAR) END WriteChar; PROCEDURE WriteInt*(F: FS; x: INTEGER): BOOLEAN; RETURN Write(F, sys.ADR(x), sys.SIZE(INTEGER)) = sys.SIZE(INTEGER) END WriteInt; PROCEDURE WriteBool*(F: FS; x: BOOLEAN): BOOLEAN; RETURN Write(F, sys.ADR(x), sys.SIZE(BOOLEAN)) = sys.SIZE(BOOLEAN) END WriteBool; END File.