- Add TStorageLifecycleWatch with watch_lifecycle/unwatch_lifecycle API (up to 32 watchers) - Add notify_lifecycle to broadcast mount/unmount/format events to registered callbacks - Replace raw puint32 config in format_volume with typed PFSFormatParams - Add volume_is_busy, volume_is_formatting, volume_set_mounted helpers - Add lifecycleFlags field to TStorage_Volume for tracking busy/formatting state - Expand app.diskutil with improved commands and volume state reporting - Minor improvements to core.util, arch.x86.util, proc.mgr, VFS, and flatfs - Remove obsolete driver.storage.fs.fat32.old.pas
182 lines
4.5 KiB
ObjectPascal
182 lines
4.5 KiB
ObjectPascal
// Copyright 2021 Kieron Morris
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
{
|
|
core.util - Portable data manipulation utilities.
|
|
|
|
Byte/word manipulation, endian swaps, memset/memcpy, BCD conversion,
|
|
hex parsing, and other helpers that have no x86 assembly dependency.
|
|
|
|
@author(Kieron Morris <[email protected]>)
|
|
@author(Aaron Hance <[email protected]>)
|
|
}
|
|
unit core.util;
|
|
|
|
interface
|
|
|
|
function hi(b : uint8) : uint8;
|
|
function lo(b : uint8) : uint8;
|
|
function switchendian(b : uint8) : uint8;
|
|
function switchendian16(b : uint16) : uint16;
|
|
function switchendian32(b : uint32) : uint32;
|
|
function getWord(i : uint32; hi : boolean) : uint16;
|
|
function getByte(i : uint32; index : uint8) : uint8;
|
|
|
|
procedure memset(location : uint32; value : uint8; size : uint32);
|
|
procedure memcpy(source : uint32; dest : uint32; size : uint32);
|
|
|
|
function BCDToUint8(bcd : uint8) : uint8;
|
|
function HexCharToDecimal(hex : char) : uint8;
|
|
|
|
function abs(x : sint32) : uint32;
|
|
|
|
implementation
|
|
{$ifdef CPU386}
|
|
uses
|
|
arch.x86.util;
|
|
|
|
const
|
|
MEMCPY_X86_SMALL_COPY_THRESHOLD = 16;
|
|
{$endif}
|
|
|
|
procedure scalar_memcpy(source : uint32; dest : uint32; size : uint32);
|
|
var
|
|
src, dst : puint8;
|
|
i : uint32;
|
|
begin
|
|
if size = 0 then exit;
|
|
for i := 0 to size - 1 do begin
|
|
src := puint8(source + i);
|
|
dst := puint8(dest + i);
|
|
dst^ := src^;
|
|
end;
|
|
end;
|
|
|
|
function abs(x : sint32) : uint32;
|
|
var
|
|
y : uint32;
|
|
|
|
begin
|
|
y:= x SHR 31;
|
|
abs:= (x XOR y) - y;
|
|
end;
|
|
|
|
function switchendian16(b : uint16) : uint16;
|
|
begin
|
|
switchendian16:= ((b AND $FF00) SHR 8) OR ((b AND $00FF) SHL 8);
|
|
end;
|
|
|
|
function switchendian32(b : uint32) : uint32;
|
|
begin
|
|
switchendian32:= ((b AND $FF000000) SHR 24) OR
|
|
((b AND $00FF0000) SHR 8) OR
|
|
((b AND $0000FF00) SHL 8) OR
|
|
((b AND $000000FF) SHL 24);
|
|
end;
|
|
|
|
function HexCharToDecimal(hex : char) : uint8;
|
|
begin
|
|
case hex of
|
|
'0':HexCharToDecimal:=0;
|
|
'1':HexCharToDecimal:=1;
|
|
'2':HexCharToDecimal:=2;
|
|
'3':HexCharToDecimal:=3;
|
|
'4':HexCharToDecimal:=4;
|
|
'5':HexCharToDecimal:=5;
|
|
'6':HexCharToDecimal:=6;
|
|
'7':HexCharToDecimal:=7;
|
|
'8':HexCharToDecimal:=8;
|
|
'9':HexCharToDecimal:=9;
|
|
'a':HexCharToDecimal:=10;
|
|
'A':HexCharToDecimal:=10;
|
|
'b':HexCharToDecimal:=11;
|
|
'B':HexCharToDecimal:=11;
|
|
'c':HexCharToDecimal:=12;
|
|
'C':HexCharToDecimal:=12;
|
|
'd':HexCharToDecimal:=13;
|
|
'D':HexCharToDecimal:=13;
|
|
'e':HexCharToDecimal:=14;
|
|
'E':HexCharToDecimal:=14;
|
|
'f':HexCharToDecimal:=15;
|
|
'F':HexCharToDecimal:=15;
|
|
else HexCharToDecimal:= 0;
|
|
end;
|
|
end;
|
|
|
|
function hi(b : uint8) : uint8; [public, alias: 'util_hi'];
|
|
begin
|
|
hi:= (b AND $F0) SHR 4;
|
|
end;
|
|
|
|
function lo(b : uint8) : uint8; [public, alias: 'util_lo'];
|
|
begin
|
|
lo:= b AND $0F;
|
|
end;
|
|
|
|
function switchendian(b : uint8) : uint8; [public, alias: 'util_switchendian'];
|
|
begin
|
|
switchendian:= (lo(b) SHL 4) OR hi(b);
|
|
end;
|
|
|
|
procedure memset(location : uint32; value : uint8; size : uint32);
|
|
var
|
|
loc : puint8;
|
|
i : uint32;
|
|
|
|
begin
|
|
if size = 0 then exit;
|
|
for i:=0 to size-1 do begin
|
|
loc:= puint8(location + i);
|
|
loc^:= value;
|
|
end;
|
|
end;
|
|
|
|
procedure memcpy(source : uint32; dest : uint32; size : uint32);
|
|
begin
|
|
if size = 0 then exit;
|
|
{$ifdef CPU386}
|
|
if size < MEMCPY_X86_SMALL_COPY_THRESHOLD then
|
|
scalar_memcpy(source, dest, size)
|
|
else
|
|
arch.x86.util.__REP_MOVSB_memcpy(source, dest, size);
|
|
{$else}
|
|
scalar_memcpy(source, dest, size);
|
|
{$endif}
|
|
end;
|
|
|
|
function getWord(i : uint32; hi : boolean) : uint16;
|
|
begin
|
|
if hi then begin
|
|
getWord:= (i AND $FFFF0000) SHR 16;
|
|
end else begin
|
|
getWord:= (i AND $0000FFFF);
|
|
end;
|
|
end;
|
|
|
|
function getByte(i : uint32; index : uint8) : uint8;
|
|
var
|
|
mask : uint32;
|
|
|
|
begin
|
|
mask:= ($FF SHL (8*index));
|
|
getByte:= (i AND mask) SHR (8*index);
|
|
end;
|
|
|
|
function BCDToUint8(bcd : uint8) : uint8;
|
|
begin
|
|
BCDToUint8:= ((bcd SHR 4) * 10) + (bcd AND $0F);
|
|
end;
|
|
|
|
end.
|