// Assign standard procedure (typed and untyped files) // procedure Assign(var F; String); // EXPECTS: dl = String/PChar flag // esi = File Name String/PChar // edi = File Variable @ procedure Assign_File; {&USES eax,ecx} {&FRAME-} asm cld xor eax,eax // Initialize file mov [edi].TextRec.Handle,eax // variable mov [edi].TextRec.Mode,fmClosed add edi,TextRec.BufSize mov ecx,(TextRec.Name - TextRec.BufSize)/4 rep stosd mov ecx,TYPE TextRec.Name - 1 test dl,dl // PChar ? jnz @@1 // Yes, @@1 lodsb // No, Get string length movzx ecx,al jecxz @@Done @@1: lodsb test al,al jz @@Done stosb loop @@1 @@Done: mov al,0 // Terminate it with #0 stosb end; procedure _FileAssign(FileVar,S: Pointer); {&USES edx,esi,edi} {&FRAME-} asm mov edi,FileVar mov esi,S mov dl,0 // Flag: 0 = String Call Assign_File end; procedure _FileAssignPCh(FileVar,S: Pointer); {&USES edx,esi,edi} {&FRAME-} asm mov edi,FileVar mov esi,S mov dl,1 // Flag: 1 = PChar Call Assign_File end; // Reset: Reset standard procedure // Rewrite: Rewrite standard procedure // procedure Reset(var F [:File; RecSize:Longint]); // procedure Rewrite(var F [:File; RecSize:Longint]); // where F is file variable other than TEXT. // // Sets InOutRes <> 0 if error occurred procedure OpenFile; {&USES None} {&FRAME-} asm mov esi,eax cmp [edi].TextRec.Mode,fmClosed je @@OK mov eax,RTE_File_Not_Assigned cmp [edi].TextRec.Mode,fmInOut jne @@Error push edi // [1]:Pointer=FileVar Call _FileClose @@OK: lea edx,[edi].TextRec.Name cmp [edx].Byte,0 // Is file name empty ? je @@Done // Yes, StdIn or StdOut push OFFSET FileMode Call _GetTlsVar test cl,cl // Open or Create ? push 0 // Handle mov ecx,esp jnz @@Create // Reset -> Open an existing file mov eax,[eax] // Open mode for Reset push edx // [1]:PChar = FileName push eax // [2]:DWord = Mode push ecx // [3]:DWord = @Handle Call SysFileOpen pop esi // Handle jmp @@2 // Rewrite -> Create a file @@Create: mov eax,[eax+4] // FileModeReadWrite test eax,eax jnz @@1 mov al,42h @@1: push edx // [1]:PChar = FileName push eax // [2]:DWord = Mode push 0 // [3]:DWord = Attr = Normal file push ecx // [4]:DWord = @Handle Call SysFileCreate pop esi // Handle @@2: test eax,eax jz @@Done @@Error: Call SetInOutRes jmp @@RET @@Done: mov [edi].TextRec.Mode,fmInOut mov [edi].TextRec.Handle,esi mov [edi].TextRec.BufSize,ebx // Record Size @@RET: end; procedure _FileReset(FileVar: Pointer; RecSize: Longint); {&USES ALL} {&FRAME-} asm Call SysFileStdIn mov edi,FileVar mov ebx,RecSize mov cl,0 Call OpenFile end; procedure _FileRewrite(FileVar: Pointer; RecSize: Longint); {&USES ALL} {&FRAME-} asm Call SysFileStdOut mov edi,FileVar mov ebx,RecSize mov cl,1 Call OpenFile end; // Truncate standard procedure (typed and untyped files) // procedure Truncate(var F); // Sets InOutRes <> 0 if error occurred procedure _FileTrunc(FileVar: Pointer); {&USES ALL} {&FRAME-} asm mov edi,FileVar Call OpenCheck // Is file Opened ? jne @@RET // No, exit with error push [edi].TextRec.Handle Call TruncateFile test eax,eax jz @@RET Call SetInOutRes @@RET: end; // Seek standard procedure (typed and untyped files) // procedure Seek(var F; N: Longint); // Sets InOutRes <> 0 if error occurred procedure _FileSeek(FileVar: Pointer; FilePos: Longint); {&USES ALL} {&FRAME-} asm mov edi,FileVar Call OpenCheck jne @@RET mov eax,FilePos // FilePtr := FilePos * BufSize mul [edi].TextRec.BufSize push 0 // Actual mov ecx,esp push [edi].TextRec.Handle // [1]:DWord = File Handle push eax // [2]:DWord = Distance push 0 // [3]:DWord = Method(Start file) push ecx // [4]:DWord = @Actual Call SysFileSeek pop ecx test eax,eax jz @@RET Call SetInOutRes @@RET: end; // Close standard procedure (typed and untyped files) // procedure Close(var F); // Sets InOutRes <> 0 if error occurred procedure _FileClose(FileVar: Pointer); {&USES eax,ecx,edx,edi} {&FRAME-} asm mov edi,FileVar Call OpenCheck // Is file Opened ? jne @@RET // No, exit with error push [edi].TextRec.Handle Call SysFileClose test eax,eax jz @@OK Call SetInOutRes @@OK: mov [edi].TextRec.Mode,fmClosed @@RET: end; // _FileRead: Read standard procedure (typed files) // _FileWrite: Write standard procedure (typed files) // Sets InOutRes <> 0 if error occurred // Performs typed file I/O // EXPECTS: eax = Error Code // edx = Buffer @ // edi = File Variable @ procedure InOutFile; {&USES ecx} {&FRAME-} asm Call OpenCheck // Is file Opened ? jne @@RET // No, exit with error push eax // Save Error code push 0 // Bytes Read mov ecx,esp push [edi].TextRec.Handle // [1]:DWord = File Handle push edx // [2]:PChar = Buffer push [edi].TextRec.BufSize // [3]:DWord = Count push ecx // [4]:DWord = @ByteRead cmp eax,RTE_Disk_Write_Error je @@Write Call SysFileRead jmp @@Done @@Write: Call SysFileWrite @@Done: pop ecx // Actual bytes done pop edx // Error code test eax,eax jnz @@ERROR cmp ecx,[edi].TextRec.BufSize // All data processed? je @@RET mov eax,edx // No, set I/O Error @@ERROR: Call SetInOutRes @@RET: end; procedure _FileRead(FileVar,Buffer: Pointer); {&USES eax,edx,edi} {&FRAME-} asm mov eax,RTE_Disk_Read_Error mov edi,FileVar mov edx,Buffer Call InOutFile PopArgs @Params - TYPE FileVar end; procedure _FileWrite(FileVar,Buffer: Pointer); {&USES eax,edx,edi} {&FRAME-} asm mov eax,RTE_Disk_Write_Error mov edi,FileVar mov edx,Buffer Call InOutFile PopArgs @Params - TYPE FileVar end; // BlockRead: BlockRead standard procedure (untyped files) // BlockWrite: BlockWrite standard procedure (untyped files) // procedure BlockRead (var F: file; var Buf; Cnt: Longint; Res:Longint); // procedure BlockWrite(var F: file; var Buf; Cnt: Longint; Res:Longint); // Sets InOutRes <> 0 if error occurred // If result address is <> 0 then number of bytes that have been // actually processed is stored in Result // Performs untyped file I/O } // EXPECTS: esi = Error code // edi = File Variable @ // ecx = Count // edx = Buffer @ // ebx = Result @ procedure InOutBlock; {&USES None} {&FRAME-} asm test ebx,ebx jz @@1 and DWord Ptr [ebx],0 // Result := 0 @@1: Call OpenCheck // Is file Opened ? jne @@RET // No, exit with error(Res=0) mov eax,ecx jecxz @@2 push edx mul [edi].TextRec.BufSize pop edx mov ecx,eax // ecx := Number of bytes push ebx // @Result push ecx // Count push 0 // Bytes Read mov eax,esp push [edi].TextRec.Handle // [1]:DWord = File Handle push edx // [2]:PChar = Buffer push ecx // [3]:DWord = Count push eax // [4]:DWord = @ByteRead cmp esi,RTE_Disk_Write_Error je @@Write Call SysFileRead jmp @@Done @@Write: Call SysFileWrite @@Done: pop ecx // Bytes processed pop edx // Count pop ebx // @Result test eax,eax jnz @@ERROR mov eax,edx @@2: test ebx,ebx // @Result = nil ? jz @@3 mov eax,ecx // Bytes processed xor edx,edx div [edi].TextRec.BufSize mov [ebx],eax // Return result jmp @@RET @@3: cmp ecx,eax // if Actual <> Count then je @@RET // Return error xchg eax,esi @@ERROR: Call SetInOutRes @@RET: end; procedure _BlockRead(FileVar,Buffer: Pointer; Count: Longint; Result: Pointer); {&USES ALL} {&FRAME-} asm mov esi,RTE_Disk_Read_Error mov edi,FileVar mov ecx,Count mov edx,Buffer mov ebx,Result Call InOutBlock end; procedure _BlockWrite(FileVar,Buffer: Pointer; Count: Longint; Result: Pointer); {&USES ALL} {&FRAME-} asm mov esi,RTE_Disk_Write_Error mov edi,FileVar mov ecx,Count mov edx,Buffer mov ebx,Result Call InOutBlock end;