diff --git a/config/RSPE01_01/splits.txt b/config/RSPE01_01/splits.txt index 5ce4bdd9..bb5e7f1d 100644 --- a/config/RSPE01_01/splits.txt +++ b/config/RSPE01_01/splits.txt @@ -2563,14 +2563,173 @@ revolution/NWC24/NWC24System.c: .sdata start:0x804BDAF0 end:0x804BDAF8 .sbss start:0x804BF468 end:0x804BF478 -revolution/VF/vf_unsplit.o: - .text start:0x8014AE44 end:0x80167B2C - .rodata start:0x8037CB58 end:0x80380E90 - .data start:0x803B7F48 end:0x803B8008 - .bss start:0x8047A920 end:0x804A3B78 - .sdata start:0x804BDAF8 end:0x804BDB58 - .sbss start:0x804BF478 end:0x804BF4A8 - .sdata2 start:0x804C13E8 end:0x804C1400 +revolution/VF/pf_clib.c: + .text start:0x8014AE44 end:0x8014B144 + +revolution/VF/pf_code.c: + .text start:0x8014B144 end:0x8014B160 + +revolution/VF/pf_service.c: + .text start:0x8014B160 end:0x8014B288 + +revolution/VF/pf_str.c: + .text start:0x8014B288 end:0x8014B810 + +revolution/VF/pf_w_clib.c: + .text start:0x8014B810 end:0x8014B8A4 + +revolution/VF/pf_driver.c: + .text start:0x8014B8A4 end:0x8014C2A0 + +revolution/VF/pdm_bpb.c: + .text start:0x8014C2A0 end:0x8014CBC0 + +revolution/VF/pdm_disk.c: + .text start:0x8014CBC0 end:0x8014E110 + +revolution/VF/pdm_partition.c: + .text start:0x8014E110 end:0x8014F548 + +revolution/VF/pdm_mbr.c: + .text start:0x8014F548 end:0x8014FB08 + +revolution/VF/pdm_dskmng.c: + .text start:0x8014FB08 end:0x8014FD2C + .bss start:0x8047A920 end:0x8047B488 + +revolution/VF/pf_cache.c: + .text start:0x8014FD2C end:0x80151C60 + +revolution/VF/pf_cluster.c: + .text start:0x80151C60 end:0x80152118 + +revolution/VF/pf_dir.c: + .text start:0x80152118 end:0x801521A8 + +revolution/VF/pf_entry.c: + .text start:0x801521A8 end:0x80153C40 + .data start:0x803B7F48 end:0x803B7F58 + .sdata2 start:0x804C13E8 end:0x804C13F0 + +revolution/VF/pf_entry_iterator.c: + .text start:0x80153C40 end:0x8015557C + .sdata start:0x804BDAF8 end:0x804BDB20 + +revolution/VF/pf_fat.c: + .text start:0x8015557C end:0x801583F4 + .rodata start:0x8037CB58 end:0x8037CBF8 + +revolution/VF/pf_fat12.c: + .text start:0x801583F4 end:0x80158EDC + +revolution/VF/pf_fat16.c: + .text start:0x80158EDC end:0x80159454 + +revolution/VF/pf_fat32.c: + .text start:0x80159454 end:0x80159A94 + +revolution/VF/pf_fatfs.c: + .text start:0x80159A94 end:0x80159A98 + +revolution/VF/pf_file.c: + .text start:0x80159A98 end:0x8015D03C + +revolution/VF/pf_path.c: + .text start:0x8015D03C end:0x8015FD7C + .sdata start:0x804BDB20 end:0x804BDB58 + .sdata2 start:0x804C13F0 end:0x804C1400 + +revolution/VF/pf_sector.c: + .text start:0x8015FD7C end:0x8016046C + +revolution/VF/pf_volume.c: + .text start:0x8016046C end:0x80161B74 + .bss start:0x8047B488 end:0x804A3440 + +revolution/VF/pf_cp932.c: + .text start:0x80161B74 end:0x80162084 + .rodata start:0x8037CBF8 end:0x80380E70 + +revolution/VF/pf_api_util.c: + .text start:0x80162084 end:0x801621F0 + .data start:0x803B7F58 end:0x803B7FF8 + +revolution/VF/pf_attach.c: + .text start:0x801621F0 end:0x80162274 + +revolution/VF/pf_detach.c: + .text start:0x80162274 end:0x8016229C + +revolution/VF/pf_errnum.c: + .text start:0x8016229C end:0x801622C0 + +revolution/VF/pf_fclose.c: + .text start:0x801622C0 end:0x801622E4 + +revolution/VF/pf_finfo.c: + .text start:0x801622E4 end:0x80162308 + +revolution/VF/pf_fopen.c: + .text start:0x80162308 end:0x801623A4 + +revolution/VF/pf_fread.c: + .text start:0x801623A4 end:0x801623CC + +revolution/VF/pf_fseek.c: + .text start:0x801623CC end:0x801623F0 + +revolution/VF/pf_fwrite.c: + .text start:0x801623F0 end:0x80162418 + +revolution/VF/pf_getdev.c: + .text start:0x80162418 end:0x80162440 + +revolution/VF/pf_init_prfile2.c: + .text start:0x80162440 end:0x80162480 + +revolution/VF/pf_remove.c: + .text start:0x80162480 end:0x801624D0 + +revolution/VF/pf_unmount.c: + .text start:0x801624D0 end:0x801624F8 + +revolution/VF/pf_filelock.c: + .text start:0x801624F8 end:0x8016250C + .sbss start:0x804BF478 end:0x804BF480 + +revolution/VF/pf_system.c: + .text start:0x8016250C end:0x80162584 + +revolution/VF/d_vf.c: + .text start:0x80162584 end:0x80163040 + .bss start:0x804A3440 end:0x804A3458 + .sbss start:0x804BF480 end:0x804BF488 + +revolution/VF/d_vf_sys.c: + .text start:0x80163040 end:0x80164B1C + .data start:0x803B7FF8 end:0x803B8008 + .bss start:0x804A3458 end:0x804A3590 + .sbss start:0x804BF488 end:0x804BF4A0 + +revolution/VF/d_hash.c: + .text start:0x80164B1C end:0x8016519C + .bss start:0x804A3590 end:0x804A37D0 + +revolution/VF/d_time.c: + .text start:0x8016519C end:0x8016522C + +revolution/VF/d_common.c: + .text start:0x8016522C end:0x80165D74 + .bss start:0x804A37D0 end:0x804A39D8 + +revolution/VF/nand_drv.c: + .text start:0x80165D74 end:0x80167B28 + .rodata start:0x80380E70 end:0x80380E90 + .bss start:0x804A39D8 end:0x804A3B78 + .sbss start:0x804BF4A0 end:0x804BF4A8 + +revolution/VF/sd_drv.c: + .text start:0x80167B28 end:0x80167B2C RVLFaceLib/RFL_System.c: extab start:0x80006738 end:0x80006768 diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 3d222f0a..028fd51f 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -6140,7 +6140,7 @@ VFipdm_bpb_check_fsinfo_sector = .text:0x8014CB14; // type:function size:0xAC sc VFipdm_disk_convert_sector_into_block = .text:0x8014CBC0; // type:function size:0xB0 scope:global VFipdm_disk_convert_block_into_sector = .text:0x8014CC70; // type:function size:0xB0 scope:global VFipdm_disk_get_handle = .text:0x8014CD20; // type:function size:0x1E4 scope:global -fn_8014CF04 = .text:0x8014CF04; // type:function size:0x11C +VFipdm_disk_do_get_permission = .text:0x8014CF04; // type:function size:0x11C VFipdm_disk_check_disk_handle = .text:0x8014D020; // type:function size:0xBC scope:global VFipdm_disk_open_disk = .text:0x8014D0DC; // type:function size:0x15C scope:global VFipdm_disk_close_disk = .text:0x8014D238; // type:function size:0x258 scope:global @@ -6168,7 +6168,7 @@ VFipdm_part_get_media_information = .text:0x8014F004; // type:function size:0x12 VFipdm_part_check_media_write_protect = .text:0x8014F124; // type:function size:0x110 scope:global VFipdm_part_check_media_insert = .text:0x8014F234; // type:function size:0x110 scope:global VFipdm_part_check_media_detect = .text:0x8014F344; // type:function size:0x110 scope:global -fn_8014F454 = .text:0x8014F454; // type:function size:0xBC +VFipdm_part_set_change_media_state = .text:0x8014F454; // type:function size:0xBC VFipdm_part_set_driver_error_code = .text:0x8014F510; // type:function size:0x1C scope:global VFipdm_part_get_driver_error_code = .text:0x8014F52C; // type:function size:0x1C scope:global VFipdm_mbr_get_table = .text:0x8014F548; // type:function size:0x114 scope:global @@ -6273,8 +6273,8 @@ VFiPFFAT_GetBeforeChain = .text:0x80157A2C; // type:function size:0x198 scope:gl VFiPFFAT_InitFATRegion = .text:0x80157BC4; // type:function size:0x284 scope:global VFiPFFAT_MakeRootDir = .text:0x80157E48; // type:function size:0x1D4 scope:global VFiPFFAT_InitHint = .text:0x8015801C; // type:function size:0x14 scope:global -VFiPFFAT_TraceClustersChain = .text:0x80158030; // type:function size:0x240 scope:local -VFiPFFAT_TraceClustersChain = .text:0x80158270; // type:function size:0x7C scope:local +VFiPFFAT_TraceClustersChain = .text:0x80158030; // type:function size:0x240 scope:global +VFiPFFAT_ReadValueToSpecifiedCluster = .text:0x80158270; // type:function size:0x7C scope:global VFiPFFAT_ResetFFD = .text:0x801582EC; // type:function size:0x60 scope:global VFiPFFAT_InitFFD = .text:0x8015834C; // type:function size:0x6C scope:global VFiPFFAT_FinalizeFFD = .text:0x801583B8; // type:function size:0x20 scope:global @@ -6419,9 +6419,9 @@ VFSysInit = .text:0x801633A4; // type:function size:0x184 scope:global VFSysSetDeviceNANDFlash = .text:0x80163528; // type:function size:0x1EC scope:global VFSysUnsetDevice = .text:0x80163714; // type:function size:0x158 scope:global VFSysCheckExistPrfFile_nandflash_sub = .text:0x8016386C; // type:function size:0x160 scope:global -fn_801639CC = .text:0x801639CC; // type:function size:0xC -fn_801639D8 = .text:0x801639D8; // type:function size:0x3C -fn_80163A14 = .text:0x80163A14; // type:function size:0x134 +VFSysCheckExistPrfFile_nandflash = .text:0x801639CC; // type:function size:0xC +VFSysCheckExistPrfFile_ram = .text:0x801639D8; // type:function size:0x3C +VFSysCheckExistPrfFile_dvd = .text:0x80163A14; // type:function size:0x134 VFSysCheckExistPrfFile = .text:0x80163B48; // type:function size:0x88 scope:global VFSysMountDrv = .text:0x80163BD0; // type:function size:0x2C0 scope:global VFSysUnmountDrv = .text:0x80163E90; // type:function size:0x150 scope:global @@ -18286,7 +18286,7 @@ XYPAL = .data:0x803B7230; // type:object size:0x30 scope:local align:8 @1049 = .data:0x803B7298; // type:object size:0x2B scope:local align:4 data:string lbl_803B72C8 = .data:0x803B72C8; // type:object size:0x31 data:string lbl_803B7300 = .data:0x803B7300; // type:object size:0x278 data:4byte -@1 = .data:0x803B7578; // type:object size:0x39 scope:local data:string +lbl_803B7578 = .data:0x803B7578; // type:object size:0x39 data:string jumptable_803B75B8 = .data:0x803B75B8; // type:object size:0x84 scope:local gap_08_803B763C_data = .data:0x803B763C; // type:object size:0x4 scope:global @1838 = .data:0x803B7640; // type:object size:0x2C scope:local align:4 @@ -19848,14 +19848,13 @@ nwc24TimeCommonResult = .bss:0x8047A8A0; // type:object size:0x20 scope:local ShutdownFuncInfo = .bss:0x8047A8C0; // type:object size:0x10 scope:local data:4byte shtBuffer$1986 = .bss:0x8047A8E0; // type:object size:0x20 scope:local data:4byte shtResult$1987 = .bss:0x8047A900; // type:object size:0x20 scope:local -lbl_8047A920 = .bss:0x8047A920; // type:object size:0xB68 data:2byte -lbl_8047B488 = .bss:0x8047B488; // type:object size:0x4B77 -lbl_8047FFFF = .bss:0x8047FFFF; // type:object size:0x23441 +VFipdm_disk_set = .bss:0x8047A920; // type:object size:0xB68 data:2byte +VFipf_vol_set = .bss:0x8047B488; // type:object size:0x27FB8 data:4byte l_Mutex = .bss:0x804A3440; // type:object size:0x18 scope:global lbl_804A3458 = .bss:0x804A3458; // type:object size:0x68 data:4byte lbl_804A34C0 = .bss:0x804A34C0; // type:object size:0xD0 -lbl_804A3590 = .bss:0x804A3590; // type:object size:0x10 data:2byte -lbl_804A35A0 = .bss:0x804A35A0; // type:object size:0x230 data:byte +l_tmpWName = .bss:0x804A3590; // type:object size:0x10 data:2byte +hashTable = .bss:0x804A35A0; // type:object size:0x230 data:byte l_driveInfo = .bss:0x804A37D0; // type:object size:0x208 scope:global data:4byte lbl_804A39D8 = .bss:0x804A39D8; // type:object size:0x1A0 sAllocator = .bss:0x804A3B78; // type:object size:0x10 scope:local @@ -20365,7 +20364,7 @@ __SIVersion = .sdata:0x804BD9A0; // type:object size:0x4 scope:global data:4byte gap_10_804BD9A4_sdata = .sdata:0x804BD9A4; // type:object size:0x4 scope:global @1048 = .sdata:0x804BD9A8; // type:object size:0x6 scope:local align:4 data:string __esFd = .sdata:0x804BD9B0; // type:object size:0x4 scope:local data:4byte -NETRexPPCVersionPrintableString = .sdata:0x804BD9B8; // type:object size:0x4 scope:global data:4byte +NETRexPPCVersionPrintableString = .sdata:0x804BD9B8; // type:object size:0x8 scope:global data:4byte @1856 = .sdata:0x804BD9C0; // type:object size:0x2 scope:local align:4 data:byte @1857 = .sdata:0x804BD9C4; // type:object size:0x2 scope:local align:4 data:string @1858 = .sdata:0x804BD9C8; // type:object size:0x4 scope:local align:4 data:string @@ -21828,7 +21827,8 @@ Initialized$694 = .sbss:0x804BF3DC; // type:object size:0x4 scope:local data:4by cmdTypeAndStatus$877 = .sbss:0x804BF3E0; // type:object size:0x4 scope:local __PADFixBits = .sbss:0x804BF3E4; // type:object size:0x4 scope:global data:4byte SamplingRate = .sbss:0x804BF3E8; // type:object size:0x4 scope:local data:4byte -whenCached$690 = .sbss:0x804BF3F0; // type:object size:0x8 scope:global data:4byte +whenCached$690 = .sbss:0x804BF3F0; // type:object size:0x4 scope:global data:4byte +lbl_804BF3F4 = .sbss:0x804BF3F4; // type:object size:0x4 data:4byte RdBufferMutex = .sbss:0x804BF3F8; // type:object size:0x4 scope:local data:4byte WrBufferMutex = .sbss:0x804BF3FC; // type:object size:0x4 scope:local data:4byte InstanceIdGen = .sbss:0x804BF400; // type:object size:0x4 scope:local data:4byte @@ -23406,7 +23406,7 @@ gap_12_804C13CE_sdata2 = .sdata2:0x804C13CE; // type:object size:0x2 scope:globa lbl_804C13D0 = .sdata2:0x804C13D0; // type:object size:0x8 @1547 = .sdata2:0x804C13D8; // type:object size:0x4 scope:local data:byte @109 = .sdata2:0x804C13E0; // type:object size:0x8 scope:local align:8 data:double -lbl_804C13E8 = .sdata2:0x804C13E8; // type:object size:0x8 data:byte +FAT_DELETED = .sdata2:0x804C13E8; // type:object size:0x1 data:byte lbl_804C13F0 = .sdata2:0x804C13F0; // type:object size:0x1 data:byte lbl_804C13F1 = .sdata2:0x804C13F1; // type:object size:0x1 data:byte gap_12_804C13F2_sdata2 = .sdata2:0x804C13F2; // type:object size:0x2 scope:global diff --git a/configure.py b/configure.py index 4a088e03..83c4aeb6 100755 --- a/configure.py +++ b/configure.py @@ -1040,13 +1040,62 @@ def MatchingFor(*versions): Object(Matching, "revolution/NWC24/NWC24Parser.c"), Object(NonMatching, "revolution/NWC24/NWC24MsgCommit.c"), Object(Matching, "revolution/NWC24/NWC24Schedule.c"), - Object(Matching, "revolution/NWC24/NWC24DateParser.c"), + Object(NonMatching, "revolution/NWC24/NWC24DateParser.c"), Object(Matching, "revolution/NWC24/NWC24FriendList.c"), Object(Matching, "revolution/NWC24/NWC24SecretFList.c"), Object(Matching, "revolution/NWC24/NWC24Time.c"), Object(Matching, "revolution/NWC24/NWC24Ipc.c"), Object(Matching, "revolution/NWC24/NWC24Download.c"), Object(Matching, "revolution/NWC24/NWC24System.c"), + Object(Matching, "revolution/VF/pf_clib.c"), + Object(Matching, "revolution/VF/pf_code.c"), + Object(Matching, "revolution/VF/pf_service.c"), + Object(Matching, "revolution/VF/pf_str.c"), + Object(Matching, "revolution/VF/pf_w_clib.c"), + Object(Matching, "revolution/VF/pf_driver.c"), + Object(Matching, "revolution/VF/pdm_bpb.c"), + Object(NonMatching, "revolution/VF/pdm_disk.c"), + Object(NonMatching, "revolution/VF/pdm_partition.c"), + Object(Matching, "revolution/VF/pdm_mbr.c"), + Object(Matching, "revolution/VF/pdm_dskmng.c"), + Object(NonMatching, "revolution/VF/pf_cache.c"), + Object(Matching, "revolution/VF/pf_cluster.c"), + Object(Matching, "revolution/VF/pf_dir.c"), + Object(NonMatching, "revolution/VF/pf_entry.c"), + Object(NonMatching, "revolution/VF/pf_entry_iterator.c"), + Object(NonMatching, "revolution/VF/pf_fat.c"), + Object(Matching, "revolution/VF/pf_fat12.c"), + Object(Matching, "revolution/VF/pf_fat16.c"), + Object(Matching, "revolution/VF/pf_fat32.c"), + Object(Matching, "revolution/VF/pf_fatfs.c"), + Object(NonMatching, "revolution/VF/pf_file.c"), + Object(NonMatching, "revolution/VF/pf_path.c"), + Object(Matching, "revolution/VF/pf_sector.c"), + Object(NonMatching, "revolution/VF/pf_volume.c"), + Object(NonMatching, "revolution/VF/pf_cp932.c"), + Object(Matching, "revolution/VF/pf_api_util.c"), + Object(Matching, "revolution/VF/pf_attach.c"), + Object(Matching, "revolution/VF/pf_detach.c"), + Object(Matching, "revolution/VF/pf_errnum.c"), + Object(Matching, "revolution/VF/pf_fclose.c"), + Object(Matching, "revolution/VF/pf_finfo.c"), + Object(Matching, "revolution/VF/pf_fopen.c"), + Object(Matching, "revolution/VF/pf_fread.c"), + Object(Matching, "revolution/VF/pf_fseek.c"), + Object(Matching, "revolution/VF/pf_fwrite.c"), + Object(Matching, "revolution/VF/pf_getdev.c"), + Object(Matching, "revolution/VF/pf_init_prfile2.c"), + Object(Matching, "revolution/VF/pf_remove.c"), + Object(Matching, "revolution/VF/pf_unmount.c"), + Object(Matching, "revolution/VF/pf_filelock.c"), + Object(Matching, "revolution/VF/pf_system.c"), + Object(NonMatching, "revolution/VF/d_vf.c"), + Object(NonMatching, "revolution/VF/d_vf_sys.c"), + Object(NonMatching, "revolution/VF/d_hash.c"), + Object(Matching, "revolution/VF/d_time.c"), + Object(NonMatching, "revolution/VF/d_common.c"), + Object(NonMatching, "revolution/VF/nand_drv.c"), + Object(Matching, "revolution/VF/sd_drv.c"), ], }, { diff --git a/include/revolution/VF.h b/include/revolution/VF.h index c76c3e63..ccfc2727 100644 --- a/include/revolution/VF.h +++ b/include/revolution/VF.h @@ -4,7 +4,60 @@ extern "C" { #endif +#define SWAP16(x) (((x) >> 8) & 0xFF) | (((x) << 8) & 0xFF00) +#define SWAP32(x) ((x) >> 24) | (((x) >> 8) & 0xFF00) | (((x) << 8) & 0xFF0000) | ((x) << 24) + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include #ifdef __cplusplus } diff --git a/include/revolution/VF/d_common.h b/include/revolution/VF/d_common.h new file mode 100644 index 00000000..54c4e359 --- /dev/null +++ b/include/revolution/VF/d_common.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_D_COMMON_H +#define RVL_SDK_VF_D_COMMON_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/d_hash.h b/include/revolution/VF/d_hash.h new file mode 100644 index 00000000..c87df4c4 --- /dev/null +++ b/include/revolution/VF/d_hash.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_D_HASH_H +#define RVL_SDK_VF_D_HASH_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/d_time.h b/include/revolution/VF/d_time.h new file mode 100644 index 00000000..6604c64d --- /dev/null +++ b/include/revolution/VF/d_time.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_D_TIME_H +#define RVL_SDK_VF_D_TIME_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/d_vf_sys.h b/include/revolution/VF/d_vf_sys.h new file mode 100644 index 00000000..c619b7bf --- /dev/null +++ b/include/revolution/VF/d_vf_sys.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_D_VF_SYS_H +#define RVL_SDK_VF_D_VF_SYS_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/nand_drv.h b/include/revolution/VF/nand_drv.h new file mode 100644 index 00000000..6663d974 --- /dev/null +++ b/include/revolution/VF/nand_drv.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_NAND_DRV_H +#define RVL_SDK_VF_NAND_DRV_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pdm_bpb.h b/include/revolution/VF/pdm_bpb.h new file mode 100644 index 00000000..30ca8690 --- /dev/null +++ b/include/revolution/VF/pdm_bpb.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PDM_BPB_H +#define RVL_SDK_VF_PDM_BPB_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pdm_disk.h b/include/revolution/VF/pdm_disk.h new file mode 100644 index 00000000..09982b12 --- /dev/null +++ b/include/revolution/VF/pdm_disk.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PDM_DISK_H +#define RVL_SDK_VF_PDM_DISK_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pdm_dskmng.h b/include/revolution/VF/pdm_dskmng.h new file mode 100644 index 00000000..06df4b94 --- /dev/null +++ b/include/revolution/VF/pdm_dskmng.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PDM_DSKMNG_H +#define RVL_SDK_VF_PDM_DSKMNG_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pdm_mbr.h b/include/revolution/VF/pdm_mbr.h new file mode 100644 index 00000000..57fc22bd --- /dev/null +++ b/include/revolution/VF/pdm_mbr.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PDM_MBR_H +#define RVL_SDK_VF_PDM_MBR_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pdm_partition.h b/include/revolution/VF/pdm_partition.h new file mode 100644 index 00000000..6f45ca4a --- /dev/null +++ b/include/revolution/VF/pdm_partition.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PDM_PARTITION_H +#define RVL_SDK_VF_PDM_PARTITION_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_api_util.h b/include/revolution/VF/pf_api_util.h new file mode 100644 index 00000000..c65c695f --- /dev/null +++ b/include/revolution/VF/pf_api_util.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_API_UTIL_H +#define RVL_SDK_VF_PF_API_UTIL_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_attach.h b/include/revolution/VF/pf_attach.h new file mode 100644 index 00000000..f02a29c6 --- /dev/null +++ b/include/revolution/VF/pf_attach.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_ATTACH_H +#define RVL_SDK_VF_PF_ATTACH_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_cache.h b/include/revolution/VF/pf_cache.h new file mode 100644 index 00000000..edf2e506 --- /dev/null +++ b/include/revolution/VF/pf_cache.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_CACHE_H +#define RVL_SDK_VF_PF_CACHE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_clib.h b/include/revolution/VF/pf_clib.h new file mode 100644 index 00000000..0dabe6c1 --- /dev/null +++ b/include/revolution/VF/pf_clib.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_CLIB_H +#define RVL_SDK_VF_PF_CLIB_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_cluster.h b/include/revolution/VF/pf_cluster.h new file mode 100644 index 00000000..7ab7cf8e --- /dev/null +++ b/include/revolution/VF/pf_cluster.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_CLUSTER_H +#define RVL_SDK_VF_PF_CLUSTER_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_code.h b/include/revolution/VF/pf_code.h new file mode 100644 index 00000000..f9e85f30 --- /dev/null +++ b/include/revolution/VF/pf_code.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_CODE_H +#define RVL_SDK_VF_PF_CODE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_cp932.h b/include/revolution/VF/pf_cp932.h new file mode 100644 index 00000000..8dcb31b5 --- /dev/null +++ b/include/revolution/VF/pf_cp932.h @@ -0,0 +1,74 @@ +#ifndef RVL_SDK_VF_PF_CP932_H +#define RVL_SDK_VF_PF_CP932_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PFSTR_CODEMODE_NONE, + PFSTR_CODEMODE_OEM, + PFSTR_CODEMODE_UNICODE, + PFSTR_CODEMODE_LOCAL +} PFSTR_CodeMode; + +typedef struct PFSTR { + const void* begin; + const void* end; + const void* local; + PFSTR_CodeMode mode; +} PFSTR; + +static const u16 cp932_to_unicode[45][189] = +{ + {0x3000, 0x3001, 0x3002, 0xFF0C, 0xFF0E, 0x30FB, 0xFF1A, 0xFF1B, 0xFF1F, 0xFF01, 0x309B, 0x309C, 0x00B4, 0xFF40, 0x00A8, 0xFF3E, 0xFFE3, 0xFF3F, 0x30FD, 0x30FE, 0x309D, 0x309E, 0x3003, 0x4EDD, 0x3005, 0x3006, 0x3007, 0x30FC, 0x2015, 0x2010, 0xFF0F, 0xFF3C, 0xFF5E, 0x2225, 0xFF5C, 0x2026, 0x2025, 0x2018, 0x2019, 0x201C, 0x201D, 0xFF08, 0xFF09, 0x3014, 0x3015, 0xFF3B, 0xFF3D, 0xFF5B, 0xFF5D, 0x3008, 0x3009, 0x300A, 0x300B, 0x300C, 0x300D, 0x300E, 0x300F, 0x3010, 0x3011, 0xFF0B, 0xFF0D, 0x00B1, 0x00D7, 0x0000, 0x00F7, 0xFF1D, 0x2260, 0xFF1C, 0xFF1E, 0x2266, 0x2267, 0x221E, 0x2234, 0x2642, 0x2640, 0x00B0, 0x2032, 0x2033, 0x2103, 0xFFE5, 0xFF04, 0xFFE0, 0xFFE1, 0xFF05, 0xFF03, 0xFF06, 0xFF0A, 0xFF20, 0x00A7, 0x2606, 0x2605, 0x25CB, 0x25CF, 0x25CE, 0x25C7, 0x25C6, 0x25A1, 0x25A0, 0x25B3, 0x25B2, 0x25BD, 0x25BC, 0x203B, 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2208, 0x220B, 0x2286, 0x2287, 0x2282, 0x2283, 0x222A, 0x2229, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2227, 0x2228, 0xFFE2, 0x21D2, 0x21D4, 0x2200, 0x2203, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2220, 0x22A5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, 0x226A, 0x226B, 0x221A, 0x223D, 0x221D, 0x2235, 0x222B, 0x222C, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x212B, 0x2030, 0x266F, 0x266D, 0x266A, 0x2020, 0x2021, 0x00B6, 0x0000, 0x0000, 0x0000, 0x0000, 0x25EF}, + {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF10, 0xFF11, 0xFF12, 0xFF13, 0xFF14, 0xFF15, 0xFF16, 0xFF17, 0xFF18, 0xFF19, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF21, 0xFF22, 0xFF23, 0xFF24, 0xFF25, 0xFF26, 0xFF27, 0xFF28, 0xFF29, 0xFF2A, 0xFF2B, 0xFF2C, 0xFF2D, 0xFF2E, 0xFF2F, 0xFF30, 0xFF31, 0xFF32, 0xFF33, 0xFF34, 0xFF35, 0xFF36, 0xFF37, 0xFF38, 0xFF39, 0xFF3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xFF41, 0xFF42, 0xFF43, 0xFF44, 0xFF45, 0xFF46, 0xFF47, 0xFF48, 0xFF49, 0xFF4A, 0xFF4B, 0xFF4C, 0xFF4D, 0xFF4E, 0xFF4F, 0xFF50, 0xFF51, 0xFF52, 0xFF53, 0xFF54, 0xFF55, 0xFF56, 0xFF57, 0xFF58, 0xFF59, 0xFF5A, 0x0000, 0x0000, 0x0000, 0x0000, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304A, 0x304B, 0x304C, 0x304D, 0x304E, 0x304F, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305A, 0x305B, 0x305C, 0x305D, 0x305E, 0x305F, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306A, 0x306B, 0x306C, 0x306D, 0x306E, 0x306F, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307A, 0x307B, 0x307C, 0x307D, 0x307E, 0x307F, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, 0x3089, 0x308A, 0x308B, 0x308C, 0x308D, 0x308E, 0x308F, 0x3090, 0x3091, 0x3092, 0x3093, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x30A1, 0x30A2, 0x30A3, 0x30A4, 0x30A5, 0x30A6, 0x30A7, 0x30A8, 0x30A9, 0x30AA, 0x30AB, 0x30AC, 0x30AD, 0x30AE, 0x30AF, 0x30B0, 0x30B1, 0x30B2, 0x30B3, 0x30B4, 0x30B5, 0x30B6, 0x30B7, 0x30B8, 0x30B9, 0x30BA, 0x30BB, 0x30BC, 0x30BD, 0x30BE, 0x30BF, 0x30C0, 0x30C1, 0x30C2, 0x30C3, 0x30C4, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9, 0x30CA, 0x30CB, 0x30CC, 0x30CD, 0x30CE, 0x30CF, 0x30D0, 0x30D1, 0x30D2, 0x30D3, 0x30D4, 0x30D5, 0x30D6, 0x30D7, 0x30D8, 0x30D9, 0x30DA, 0x30DB, 0x30DC, 0x30DD, 0x30DE, 0x30DF, 0x0000, 0x30E0, 0x30E1, 0x30E2, 0x30E3, 0x30E4, 0x30E5, 0x30E6, 0x30E7, 0x30E8, 0x30E9, 0x30EA, 0x30EB, 0x30EC, 0x30ED, 0x30EE, 0x30EF, 0x30F0, 0x30F1, 0x30F2, 0x30F3, 0x30F4, 0x30F5, 0x30F6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, 0x03A0, 0x03A1, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, 0x03A8, 0x03A9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, 0x03C0, 0x03C1, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, 0x03C8, 0x03C9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x0000, 0x043E, 0x043F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2500, 0x2502, 0x250C, 0x2510, 0x2518, 0x2514, 0x251C, 0x252C, 0x2524, 0x2534, 0x253C, 0x2501, 0x2503, 0x250F, 0x2513, 0x251B, 0x2517, 0x2523, 0x2533, 0x252B, 0x253B, 0x254B, 0x2520, 0x252F, 0x2528, 0x2537, 0x253F, 0x251D, 0x2530, 0x2525, 0x2538, 0x2542, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246A, 0x246B, 0x246C, 0x246D, 0x246E, 0x246F, 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0x0000, 0x3349, 0x3314, 0x3322, 0x334D, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351, 0x3357, 0x330D, 0x3326, 0x3323, 0x332B, 0x334A, 0x333B, 0x339C, 0x339D, 0x339E, 0x338E, 0x338F, 0x33C4, 0x33A1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x337B, 0x0000, 0x301D, 0x301F, 0x2116, 0x33CD, 0x2121, 0x32A4, 0x32A5, 0x32A6, 0x32A7, 0x32A8, 0x3231, 0x3232, 0x3239, 0x337E, 0x337D, 0x337C, 0x2252, 0x2261, 0x222B, 0x222E, 0x2211, 0x221A, 0x22A5, 0x2220, 0x221F, 0x22BF, 0x2235, 0x2229, 0x222A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x4E9C, 0x5516, 0x5A03, 0x963F, 0x54C0, 0x611B, 0x6328, 0x59F6, 0x9022, 0x8475, 0x831C, 0x7A50, 0x60AA, 0x63E1, 0x6E25, 0x65ED, 0x8466, 0x82A6, 0x9BF5, 0x6893, 0x5727, 0x65A1, 0x6271, 0x5B9B, 0x59D0, 0x867B, 0x98F4, 0x7D62, 0x7DBE, 0x9B8E, 0x6216, 0x7C9F, 0x88B7, 0x5B89, 0x5EB5, 0x6309, 0x6697, 0x6848, 0x95C7, 0x978D, 0x674F, 0x4EE5, 0x4F0A, 0x4F4D, 0x4F9D, 0x5049, 0x56F2, 0x5937, 0x59D4, 0x5A01, 0x5C09, 0x60DF, 0x610F, 0x6170, 0x6613, 0x6905, 0x70BA, 0x754F, 0x7570, 0x79FB, 0x7DAD, 0x7DEF, 0x80C3, 0x840E, 0x8863, 0x8B02, 0x9055, 0x907A, 0x533B, 0x4E95, 0x4EA5, 0x57DF, 0x80B2, 0x90C1, 0x78EF, 0x4E00, 0x58F1, 0x6EA2, 0x9038, 0x7A32, 0x8328, 0x828B, 0x9C2F, 0x5141, 0x5370, 0x54BD, 0x54E1, 0x56E0, 0x59FB, 0x5F15, 0x98F2, 0x6DEB, 0x80E4, 0x852D}, + {0x9662, 0x9670, 0x96A0, 0x97FB, 0x540B, 0x53F3, 0x5B87, 0x70CF, 0x7FBD, 0x8FC2, 0x96E8, 0x536F, 0x9D5C, 0x7ABA, 0x4E11, 0x7893, 0x81FC, 0x6E26, 0x5618, 0x5504, 0x6B1D, 0x851A, 0x9C3B, 0x59E5, 0x53A9, 0x6D66, 0x74DC, 0x958F, 0x5642, 0x4E91, 0x904B, 0x96F2, 0x834F, 0x990C, 0x53E1, 0x55B6, 0x5B30, 0x5F71, 0x6620, 0x66F3, 0x6804, 0x6C38, 0x6CF3, 0x6D29, 0x745B, 0x76C8, 0x7A4E, 0x9834, 0x82F1, 0x885B, 0x8A60, 0x92ED, 0x6DB2, 0x75AB, 0x76CA, 0x99C5, 0x60A6, 0x8B01, 0x8D8A, 0x95B2, 0x698E, 0x53AD, 0x5186, 0x0000, 0x5712, 0x5830, 0x5944, 0x5BB4, 0x5EF6, 0x6028, 0x63A9, 0x63F4, 0x6CBF, 0x6F14, 0x708E, 0x7114, 0x7159, 0x71D5, 0x733F, 0x7E01, 0x8276, 0x82D1, 0x8597, 0x9060, 0x925B, 0x9D1B, 0x5869, 0x65BC, 0x6C5A, 0x7525, 0x51F9, 0x592E, 0x5965, 0x5F80, 0x5FDC, 0x62BC, 0x65FA, 0x6A2A, 0x6B27, 0x6BB4, 0x738B, 0x7FC1, 0x8956, 0x9D2C, 0x9D0E, 0x9EC4, 0x5CA1, 0x6C96, 0x837B, 0x5104, 0x5C4B, 0x61B6, 0x81C6, 0x6876, 0x7261, 0x4E59, 0x4FFA, 0x5378, 0x6069, 0x6E29, 0x7A4F, 0x97F3, 0x4E0B, 0x5316, 0x4EEE, 0x4F55, 0x4F3D, 0x4FA1, 0x4F73, 0x52A0, 0x53EF, 0x5609, 0x590F, 0x5AC1, 0x5BB6, 0x5BE1, 0x79D1, 0x6687, 0x679C, 0x67B6, 0x6B4C, 0x6CB3, 0x706B, 0x73C2, 0x798D, 0x79BE, 0x7A3C, 0x7B87, 0x82B1, 0x82DB, 0x8304, 0x8377, 0x83EF, 0x83D3, 0x8766, 0x8AB2, 0x5629, 0x8CA8, 0x8FE6, 0x904E, 0x971E, 0x868A, 0x4FC4, 0x5CE8, 0x6211, 0x7259, 0x753B, 0x81E5, 0x82BD, 0x86FE, 0x8CC0, 0x96C5, 0x9913, 0x99D5, 0x4ECB, 0x4F1A, 0x89E3, 0x56DE, 0x584A, 0x58CA, 0x5EFB, 0x5FEB, 0x602A, 0x6094, 0x6062, 0x61D0, 0x6212, 0x62D0, 0x6539}, + {0x9B41, 0x6666, 0x68B0, 0x6D77, 0x7070, 0x754C, 0x7686, 0x7D75, 0x82A5, 0x87F9, 0x958B, 0x968E, 0x8C9D, 0x51F1, 0x52BE, 0x5916, 0x54B3, 0x5BB3, 0x5D16, 0x6168, 0x6982, 0x6DAF, 0x788D, 0x84CB, 0x8857, 0x8A72, 0x93A7, 0x9AB8, 0x6D6C, 0x99A8, 0x86D9, 0x57A3, 0x67FF, 0x86CE, 0x920E, 0x5283, 0x5687, 0x5404, 0x5ED3, 0x62E1, 0x64B9, 0x683C, 0x6838, 0x6BBB, 0x7372, 0x78BA, 0x7A6B, 0x899A, 0x89D2, 0x8D6B, 0x8F03, 0x90ED, 0x95A3, 0x9694, 0x9769, 0x5B66, 0x5CB3, 0x697D, 0x984D, 0x984E, 0x639B, 0x7B20, 0x6A2B, 0x0000, 0x6A7F, 0x68B6, 0x9C0D, 0x6F5F, 0x5272, 0x559D, 0x6070, 0x62EC, 0x6D3B, 0x6E07, 0x6ED1, 0x845B, 0x8910, 0x8F44, 0x4E14, 0x9C39, 0x53F6, 0x691B, 0x6A3A, 0x9784, 0x682A, 0x515C, 0x7AC3, 0x84B2, 0x91DC, 0x938C, 0x565B, 0x9D28, 0x6822, 0x8305, 0x8431, 0x7CA5, 0x5208, 0x82C5, 0x74E6, 0x4E7E, 0x4F83, 0x51A0, 0x5BD2, 0x520A, 0x52D8, 0x52E7, 0x5DFB, 0x559A, 0x582A, 0x59E6, 0x5B8C, 0x5B98, 0x5BDB, 0x5E72, 0x5E79, 0x60A3, 0x611F, 0x6163, 0x61BE, 0x63DB, 0x6562, 0x67D1, 0x6853, 0x68FA, 0x6B3E, 0x6B53, 0x6C57, 0x6F22, 0x6F97, 0x6F45, 0x74B0, 0x7518, 0x76E3, 0x770B, 0x7AFF, 0x7BA1, 0x7C21, 0x7DE9, 0x7F36, 0x7FF0, 0x809D, 0x8266, 0x839E, 0x89B3, 0x8ACC, 0x8CAB, 0x9084, 0x9451, 0x9593, 0x9591, 0x95A2, 0x9665, 0x97D3, 0x9928, 0x8218, 0x4E38, 0x542B, 0x5CB8, 0x5DCC, 0x73A9, 0x764C, 0x773C, 0x5CA9, 0x7FEB, 0x8D0B, 0x96C1, 0x9811, 0x9854, 0x9858, 0x4F01, 0x4F0E, 0x5371, 0x559C, 0x5668, 0x57FA, 0x5947, 0x5B09, 0x5BC4, 0x5C90, 0x5E0C, 0x5E7E, 0x5FCC, 0x63EE, 0x673A, 0x65D7, 0x65E2, 0x671F, 0x68CB, 0x68C4}, + {0x6A5F, 0x5E30, 0x6BC5, 0x6C17, 0x6C7D, 0x757F, 0x7948, 0x5B63, 0x7A00, 0x7D00, 0x5FBD, 0x898F, 0x8A18, 0x8CB4, 0x8D77, 0x8ECC, 0x8F1D, 0x98E2, 0x9A0E, 0x9B3C, 0x4E80, 0x507D, 0x5100, 0x5993, 0x5B9C, 0x622F, 0x6280, 0x64EC, 0x6B3A, 0x72A0, 0x7591, 0x7947, 0x7FA9, 0x87FB, 0x8ABC, 0x8B70, 0x63AC, 0x83CA, 0x97A0, 0x5409, 0x5403, 0x55AB, 0x6854, 0x6A58, 0x8A70, 0x7827, 0x6775, 0x9ECD, 0x5374, 0x5BA2, 0x811A, 0x8650, 0x9006, 0x4E18, 0x4E45, 0x4EC7, 0x4F11, 0x53CA, 0x5438, 0x5BAE, 0x5F13, 0x6025, 0x6551, 0x0000, 0x673D, 0x6C42, 0x6C72, 0x6CE3, 0x7078, 0x7403, 0x7A76, 0x7AAE, 0x7B08, 0x7D1A, 0x7CFE, 0x7D66, 0x65E7, 0x725B, 0x53BB, 0x5C45, 0x5DE8, 0x62D2, 0x62E0, 0x6319, 0x6E20, 0x865A, 0x8A31, 0x8DDD, 0x92F8, 0x6F01, 0x79A6, 0x9B5A, 0x4EA8, 0x4EAB, 0x4EAC, 0x4F9B, 0x4FA0, 0x50D1, 0x5147, 0x7AF6, 0x5171, 0x51F6, 0x5354, 0x5321, 0x537F, 0x53EB, 0x55AC, 0x5883, 0x5CE1, 0x5F37, 0x5F4A, 0x602F, 0x6050, 0x606D, 0x631F, 0x6559, 0x6A4B, 0x6CC1, 0x72C2, 0x72ED, 0x77EF, 0x80F8, 0x8105, 0x8208, 0x854E, 0x90F7, 0x93E1, 0x97FF, 0x9957, 0x9A5A, 0x4EF0, 0x51DD, 0x5C2D, 0x6681, 0x696D, 0x5C40, 0x66F2, 0x6975, 0x7389, 0x6850, 0x7C81, 0x50C5, 0x52E4, 0x5747, 0x5DFE, 0x9326, 0x65A4, 0x6B23, 0x6B3D, 0x7434, 0x7981, 0x79BD, 0x7B4B, 0x7DCA, 0x82B9, 0x83CC, 0x887F, 0x895F, 0x8B39, 0x8FD1, 0x91D1, 0x541F, 0x9280, 0x4E5D, 0x5036, 0x53E5, 0x533A, 0x72D7, 0x7396, 0x77E9, 0x82E6, 0x8EAF, 0x99C6, 0x99C8, 0x99D2, 0x5177, 0x611A, 0x865E, 0x55B0, 0x7A7A, 0x5076, 0x5BD3, 0x9047, 0x9685, 0x4E32, 0x6ADB, 0x91E7, 0x5C51, 0x5C48}, + {0x6398, 0x7A9F, 0x6C93, 0x9774, 0x8F61, 0x7AAA, 0x718A, 0x9688, 0x7C82, 0x6817, 0x7E70, 0x6851, 0x936C, 0x52F2, 0x541B, 0x85AB, 0x8A13, 0x7FA4, 0x8ECD, 0x90E1, 0x5366, 0x8888, 0x7941, 0x4FC2, 0x50BE, 0x5211, 0x5144, 0x5553, 0x572D, 0x73EA, 0x578B, 0x5951, 0x5F62, 0x5F84, 0x6075, 0x6176, 0x6167, 0x61A9, 0x63B2, 0x643A, 0x656C, 0x666F, 0x6842, 0x6E13, 0x7566, 0x7A3D, 0x7CFB, 0x7D4C, 0x7D99, 0x7E4B, 0x7F6B, 0x830E, 0x834A, 0x86CD, 0x8A08, 0x8A63, 0x8B66, 0x8EFD, 0x981A, 0x9D8F, 0x82B8, 0x8FCE, 0x9BE8, 0x0000, 0x5287, 0x621F, 0x6483, 0x6FC0, 0x9699, 0x6841, 0x5091, 0x6B20, 0x6C7A, 0x6F54, 0x7A74, 0x7D50, 0x8840, 0x8A23, 0x6708, 0x4EF6, 0x5039, 0x5026, 0x5065, 0x517C, 0x5238, 0x5263, 0x55A7, 0x570F, 0x5805, 0x5ACC, 0x5EFA, 0x61B2, 0x61F8, 0x62F3, 0x6372, 0x691C, 0x6A29, 0x727D, 0x72AC, 0x732E, 0x7814, 0x786F, 0x7D79, 0x770C, 0x80A9, 0x898B, 0x8B19, 0x8CE2, 0x8ED2, 0x9063, 0x9375, 0x967A, 0x9855, 0x9A13, 0x9E78, 0x5143, 0x539F, 0x53B3, 0x5E7B, 0x5F26, 0x6E1B, 0x6E90, 0x7384, 0x73FE, 0x7D43, 0x8237, 0x8A00, 0x8AFA, 0x9650, 0x4E4E, 0x500B, 0x53E4, 0x547C, 0x56FA, 0x59D1, 0x5B64, 0x5DF1, 0x5EAB, 0x5F27, 0x6238, 0x6545, 0x67AF, 0x6E56, 0x72D0, 0x7CCA, 0x88B4, 0x80A1, 0x80E1, 0x83F0, 0x864E, 0x8A87, 0x8DE8, 0x9237, 0x96C7, 0x9867, 0x9F13, 0x4E94, 0x4E92, 0x4F0D, 0x5348, 0x5449, 0x543E, 0x5A2F, 0x5F8C, 0x5FA1, 0x609F, 0x68A7, 0x6A8E, 0x745A, 0x7881, 0x8A9E, 0x8AA4, 0x8B77, 0x9190, 0x4E5E, 0x9BC9, 0x4EA4, 0x4F7C, 0x4FAF, 0x5019, 0x5016, 0x5149, 0x516C, 0x529F, 0x52B9, 0x52FE, 0x539A, 0x53E3, 0x5411}, + {0x540E, 0x5589, 0x5751, 0x57A2, 0x597D, 0x5B54, 0x5B5D, 0x5B8F, 0x5DE5, 0x5DE7, 0x5DF7, 0x5E78, 0x5E83, 0x5E9A, 0x5EB7, 0x5F18, 0x6052, 0x614C, 0x6297, 0x62D8, 0x63A7, 0x653B, 0x6602, 0x6643, 0x66F4, 0x676D, 0x6821, 0x6897, 0x69CB, 0x6C5F, 0x6D2A, 0x6D69, 0x6E2F, 0x6E9D, 0x7532, 0x7687, 0x786C, 0x7A3F, 0x7CE0, 0x7D05, 0x7D18, 0x7D5E, 0x7DB1, 0x8015, 0x8003, 0x80AF, 0x80B1, 0x8154, 0x818F, 0x822A, 0x8352, 0x884C, 0x8861, 0x8B1B, 0x8CA2, 0x8CFC, 0x90CA, 0x9175, 0x9271, 0x783F, 0x92FC, 0x95A4, 0x964D, 0x0000, 0x9805, 0x9999, 0x9AD8, 0x9D3B, 0x525B, 0x52AB, 0x53F7, 0x5408, 0x58D5, 0x62F7, 0x6FE0, 0x8C6A, 0x8F5F, 0x9EB9, 0x514B, 0x523B, 0x544A, 0x56FD, 0x7A40, 0x9177, 0x9D60, 0x9ED2, 0x7344, 0x6F09, 0x8170, 0x7511, 0x5FFD, 0x60DA, 0x9AA8, 0x72DB, 0x8FBC, 0x6B64, 0x9803, 0x4ECA, 0x56F0, 0x5764, 0x58BE, 0x5A5A, 0x6068, 0x61C7, 0x660F, 0x6606, 0x6839, 0x68B1, 0x6DF7, 0x75D5, 0x7D3A, 0x826E, 0x9B42, 0x4E9B, 0x4F50, 0x53C9, 0x5506, 0x5D6F, 0x5DE6, 0x5DEE, 0x67FB, 0x6C99, 0x7473, 0x7802, 0x8A50, 0x9396, 0x88DF, 0x5750, 0x5EA7, 0x632B, 0x50B5, 0x50AC, 0x518D, 0x6700, 0x54C9, 0x585E, 0x59BB, 0x5BB0, 0x5F69, 0x624D, 0x63A1, 0x683D, 0x6B73, 0x6E08, 0x707D, 0x91C7, 0x7280, 0x7815, 0x7826, 0x796D, 0x658E, 0x7D30, 0x83DC, 0x88C1, 0x8F09, 0x969B, 0x5264, 0x5728, 0x6750, 0x7F6A, 0x8CA1, 0x51B4, 0x5742, 0x962A, 0x583A, 0x698A, 0x80B4, 0x54B2, 0x5D0E, 0x57FC, 0x7895, 0x9DFA, 0x4F5C, 0x524A, 0x548B, 0x643E, 0x6628, 0x6714, 0x67F5, 0x7A84, 0x7B56, 0x7D22, 0x932F, 0x685C, 0x9BAD, 0x7B39, 0x5319, 0x518A, 0x5237}, + {0x5BDF, 0x62F6, 0x64AE, 0x64E6, 0x672D, 0x6BBA, 0x85A9, 0x96D1, 0x7690, 0x9BD6, 0x634C, 0x9306, 0x9BAB, 0x76BF, 0x6652, 0x4E09, 0x5098, 0x53C2, 0x5C71, 0x60E8, 0x6492, 0x6563, 0x685F, 0x71E6, 0x73CA, 0x7523, 0x7B97, 0x7E82, 0x8695, 0x8B83, 0x8CDB, 0x9178, 0x9910, 0x65AC, 0x66AB, 0x6B8B, 0x4ED5, 0x4ED4, 0x4F3A, 0x4F7F, 0x523A, 0x53F8, 0x53F2, 0x55E3, 0x56DB, 0x58EB, 0x59CB, 0x59C9, 0x59FF, 0x5B50, 0x5C4D, 0x5E02, 0x5E2B, 0x5FD7, 0x601D, 0x6307, 0x652F, 0x5B5C, 0x65AF, 0x65BD, 0x65E8, 0x679D, 0x6B62, 0x0000, 0x6B7B, 0x6C0F, 0x7345, 0x7949, 0x79C1, 0x7CF8, 0x7D19, 0x7D2B, 0x80A2, 0x8102, 0x81F3, 0x8996, 0x8A5E, 0x8A69, 0x8A66, 0x8A8C, 0x8AEE, 0x8CC7, 0x8CDC, 0x96CC, 0x98FC, 0x6B6F, 0x4E8B, 0x4F3C, 0x4F8D, 0x5150, 0x5B57, 0x5BFA, 0x6148, 0x6301, 0x6642, 0x6B21, 0x6ECB, 0x6CBB, 0x723E, 0x74BD, 0x75D4, 0x78C1, 0x793A, 0x800C, 0x8033, 0x81EA, 0x8494, 0x8F9E, 0x6C50, 0x9E7F, 0x5F0F, 0x8B58, 0x9D2B, 0x7AFA, 0x8EF8, 0x5B8D, 0x96EB, 0x4E03, 0x53F1, 0x57F7, 0x5931, 0x5AC9, 0x5BA4, 0x6089, 0x6E7F, 0x6F06, 0x75BE, 0x8CEA, 0x5B9F, 0x8500, 0x7BE0, 0x5072, 0x67F4, 0x829D, 0x5C61, 0x854A, 0x7E1E, 0x820E, 0x5199, 0x5C04, 0x6368, 0x8D66, 0x659C, 0x716E, 0x793E, 0x7D17, 0x8005, 0x8B1D, 0x8ECA, 0x906E, 0x86C7, 0x90AA, 0x501F, 0x52FA, 0x5C3A, 0x6753, 0x707C, 0x7235, 0x914C, 0x91C8, 0x932B, 0x82E5, 0x5BC2, 0x5F31, 0x60F9, 0x4E3B, 0x53D6, 0x5B88, 0x624B, 0x6731, 0x6B8A, 0x72E9, 0x73E0, 0x7A2E, 0x816B, 0x8DA3, 0x9152, 0x9996, 0x5112, 0x53D7, 0x546A, 0x5BFF, 0x6388, 0x6A39, 0x7DAC, 0x9700, 0x56DA, 0x53CE, 0x5468}, + {0x5B97, 0x5C31, 0x5DDE, 0x4FEE, 0x6101, 0x62FE, 0x6D32, 0x79C0, 0x79CB, 0x7D42, 0x7E4D, 0x7FD2, 0x81ED, 0x821F, 0x8490, 0x8846, 0x8972, 0x8B90, 0x8E74, 0x8F2F, 0x9031, 0x914B, 0x916C, 0x96C6, 0x919C, 0x4EC0, 0x4F4F, 0x5145, 0x5341, 0x5F93, 0x620E, 0x67D4, 0x6C41, 0x6E0B, 0x7363, 0x7E26, 0x91CD, 0x9283, 0x53D4, 0x5919, 0x5BBF, 0x6DD1, 0x795D, 0x7E2E, 0x7C9B, 0x587E, 0x719F, 0x51FA, 0x8853, 0x8FF0, 0x4FCA, 0x5CFB, 0x6625, 0x77AC, 0x7AE3, 0x821C, 0x99FF, 0x51C6, 0x5FAA, 0x65EC, 0x696F, 0x6B89, 0x6DF3, 0x0000, 0x6E96, 0x6F64, 0x76FE, 0x7D14, 0x5DE1, 0x9075, 0x9187, 0x9806, 0x51E6, 0x521D, 0x6240, 0x6691, 0x66D9, 0x6E1A, 0x5EB6, 0x7DD2, 0x7F72, 0x66F8, 0x85AF, 0x85F7, 0x8AF8, 0x52A9, 0x53D9, 0x5973, 0x5E8F, 0x5F90, 0x6055, 0x92E4, 0x9664, 0x50B7, 0x511F, 0x52DD, 0x5320, 0x5347, 0x53EC, 0x54E8, 0x5546, 0x5531, 0x5617, 0x5968, 0x59BE, 0x5A3C, 0x5BB5, 0x5C06, 0x5C0F, 0x5C11, 0x5C1A, 0x5E84, 0x5E8A, 0x5EE0, 0x5F70, 0x627F, 0x6284, 0x62DB, 0x638C, 0x6377, 0x6607, 0x660C, 0x662D, 0x6676, 0x677E, 0x68A2, 0x6A1F, 0x6A35, 0x6CBC, 0x6D88, 0x6E09, 0x6E58, 0x713C, 0x7126, 0x7167, 0x75C7, 0x7701, 0x785D, 0x7901, 0x7965, 0x79F0, 0x7AE0, 0x7B11, 0x7CA7, 0x7D39, 0x8096, 0x83D6, 0x848B, 0x8549, 0x885D, 0x88F3, 0x8A1F, 0x8A3C, 0x8A54, 0x8A73, 0x8C61, 0x8CDE, 0x91A4, 0x9266, 0x937E, 0x9418, 0x969C, 0x9798, 0x4E0A, 0x4E08, 0x4E1E, 0x4E57, 0x5197, 0x5270, 0x57CE, 0x5834, 0x58CC, 0x5B22, 0x5E38, 0x60C5, 0x64FE, 0x6761, 0x6756, 0x6D44, 0x72B6, 0x7573, 0x7A63, 0x84B8, 0x8B72, 0x91B8, 0x9320, 0x5631, 0x57F4, 0x98FE}, + {0x62ED, 0x690D, 0x6B96, 0x71ED, 0x7E54, 0x8077, 0x8272, 0x89E6, 0x98DF, 0x8755, 0x8FB1, 0x5C3B, 0x4F38, 0x4FE1, 0x4FB5, 0x5507, 0x5A20, 0x5BDD, 0x5BE9, 0x5FC3, 0x614E, 0x632F, 0x65B0, 0x664B, 0x68EE, 0x699B, 0x6D78, 0x6DF1, 0x7533, 0x75B9, 0x771F, 0x795E, 0x79E6, 0x7D33, 0x81E3, 0x82AF, 0x85AA, 0x89AA, 0x8A3A, 0x8EAB, 0x8F9B, 0x9032, 0x91DD, 0x9707, 0x4EBA, 0x4EC1, 0x5203, 0x5875, 0x58EC, 0x5C0B, 0x751A, 0x5C3D, 0x814E, 0x8A0A, 0x8FC5, 0x9663, 0x976D, 0x7B25, 0x8ACF, 0x9808, 0x9162, 0x56F3, 0x53A8, 0x0000, 0x9017, 0x5439, 0x5782, 0x5E25, 0x63A8, 0x6C34, 0x708A, 0x7761, 0x7C8B, 0x7FE0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968F, 0x745E, 0x9AC4, 0x5D07, 0x5D69, 0x6570, 0x67A2, 0x8DA8, 0x96DB, 0x636E, 0x6749, 0x6919, 0x83C5, 0x9817, 0x96C0, 0x88FE, 0x6F84, 0x647A, 0x5BF8, 0x4E16, 0x702C, 0x755D, 0x662F, 0x51C4, 0x5236, 0x52E2, 0x59D3, 0x5F81, 0x6027, 0x6210, 0x653F, 0x6574, 0x661F, 0x6674, 0x68F2, 0x6816, 0x6B63, 0x6E05, 0x7272, 0x751F, 0x76DB, 0x7CBE, 0x8056, 0x58F0, 0x88FD, 0x897F, 0x8AA0, 0x8A93, 0x8ACB, 0x901D, 0x9192, 0x9752, 0x9759, 0x6589, 0x7A0E, 0x8106, 0x96BB, 0x5E2D, 0x60DC, 0x621A, 0x65A5, 0x6614, 0x6790, 0x77F3, 0x7A4D, 0x7C4D, 0x7E3E, 0x810A, 0x8CAC, 0x8D64, 0x8DE1, 0x8E5F, 0x78A9, 0x5207, 0x62D9, 0x63A5, 0x6442, 0x6298, 0x8A2D, 0x7A83, 0x7BC0, 0x8AAC, 0x96EA, 0x7D76, 0x820C, 0x8749, 0x4ED9, 0x5148, 0x5343, 0x5360, 0x5BA3, 0x5C02, 0x5C16, 0x5DDD, 0x6226, 0x6247, 0x64B0, 0x6813, 0x6834, 0x6CC9, 0x6D45, 0x6D17, 0x67D3, 0x6F5C, 0x714E, 0x717D, 0x65CB, 0x7A7F, 0x7BAD, 0x7DDA}, + {0x7E4A, 0x7FA8, 0x817A, 0x821B, 0x8239, 0x85A6, 0x8A6E, 0x8CCE, 0x8DF5, 0x9078, 0x9077, 0x92AD, 0x9291, 0x9583, 0x9BAE, 0x524D, 0x5584, 0x6F38, 0x7136, 0x5168, 0x7985, 0x7E55, 0x81B3, 0x7CCE, 0x564C, 0x5851, 0x5CA8, 0x63AA, 0x66FE, 0x66FD, 0x695A, 0x72D9, 0x758F, 0x758E, 0x790E, 0x7956, 0x79DF, 0x7C97, 0x7D20, 0x7D44, 0x8607, 0x8A34, 0x963B, 0x9061, 0x9F20, 0x50E7, 0x5275, 0x53CC, 0x53E2, 0x5009, 0x55AA, 0x58EE, 0x594F, 0x723D, 0x5B8B, 0x5C64, 0x531D, 0x60E3, 0x60F3, 0x635C, 0x6383, 0x633F, 0x63BB, 0x0000, 0x64CD, 0x65E9, 0x66F9, 0x5DE3, 0x69CD, 0x69FD, 0x6F15, 0x71E5, 0x4E89, 0x75E9, 0x76F8, 0x7A93, 0x7CDF, 0x7DCF, 0x7D9C, 0x8061, 0x8349, 0x8358, 0x846C, 0x84BC, 0x85FB, 0x88C5, 0x8D70, 0x9001, 0x906D, 0x9397, 0x971C, 0x9A12, 0x50CF, 0x5897, 0x618E, 0x81D3, 0x8535, 0x8D08, 0x9020, 0x4FC3, 0x5074, 0x5247, 0x5373, 0x606F, 0x6349, 0x675F, 0x6E2C, 0x8DB3, 0x901F, 0x4FD7, 0x5C5E, 0x8CCA, 0x65CF, 0x7D9A, 0x5352, 0x8896, 0x5176, 0x63C3, 0x5B58, 0x5B6B, 0x5C0A, 0x640D, 0x6751, 0x905C, 0x4ED6, 0x591A, 0x592A, 0x6C70, 0x8A51, 0x553E, 0x5815, 0x59A5, 0x60F0, 0x6253, 0x67C1, 0x8235, 0x6955, 0x9640, 0x99C4, 0x9A28, 0x4F53, 0x5806, 0x5BFE, 0x8010, 0x5CB1, 0x5E2F, 0x5F85, 0x6020, 0x614B, 0x6234, 0x66FF, 0x6CF0, 0x6EDE, 0x80CE, 0x817F, 0x82D4, 0x888B, 0x8CB8, 0x9000, 0x902E, 0x968A, 0x9EDB, 0x9BDB, 0x4EE3, 0x53F0, 0x5927, 0x7B2C, 0x918D, 0x984C, 0x9DF9, 0x6EDD, 0x7027, 0x5353, 0x5544, 0x5B85, 0x6258, 0x629E, 0x62D3, 0x6CA2, 0x6FEF, 0x7422, 0x8A17, 0x9438, 0x6FC1, 0x8AFE, 0x8338, 0x51E7, 0x86F8, 0x53EA}, + {0x53E9, 0x4F46, 0x9054, 0x8FB0, 0x596A, 0x8131, 0x5DFD, 0x7AEA, 0x8FBF, 0x68DA, 0x8C37, 0x72F8, 0x9C48, 0x6A3D, 0x8AB0, 0x4E39, 0x5358, 0x5606, 0x5766, 0x62C5, 0x63A2, 0x65E6, 0x6B4E, 0x6DE1, 0x6E5B, 0x70AD, 0x77ED, 0x7AEF, 0x7BAA, 0x7DBB, 0x803D, 0x80C6, 0x86CB, 0x8A95, 0x935B, 0x56E3, 0x58C7, 0x5F3E, 0x65AD, 0x6696, 0x6A80, 0x6BB5, 0x7537, 0x8AC7, 0x5024, 0x77E5, 0x5730, 0x5F1B, 0x6065, 0x667A, 0x6C60, 0x75F4, 0x7A1A, 0x7F6E, 0x81F4, 0x8718, 0x9045, 0x99B3, 0x7BC9, 0x755C, 0x7AF9, 0x7B51, 0x84C4, 0x0000, 0x9010, 0x79E9, 0x7A92, 0x8336, 0x5AE1, 0x7740, 0x4E2D, 0x4EF2, 0x5B99, 0x5FE0, 0x62BD, 0x663C, 0x67F1, 0x6CE8, 0x866B, 0x8877, 0x8A3B, 0x914E, 0x92F3, 0x99D0, 0x6A17, 0x7026, 0x732A, 0x82E7, 0x8457, 0x8CAF, 0x4E01, 0x5146, 0x51CB, 0x558B, 0x5BF5, 0x5E16, 0x5E33, 0x5E81, 0x5F14, 0x5F35, 0x5F6B, 0x5FB4, 0x61F2, 0x6311, 0x66A2, 0x671D, 0x6F6E, 0x7252, 0x753A, 0x773A, 0x8074, 0x8139, 0x8178, 0x8776, 0x8ABF, 0x8ADC, 0x8D85, 0x8DF3, 0x929A, 0x9577, 0x9802, 0x9CE5, 0x52C5, 0x6357, 0x76F4, 0x6715, 0x6C88, 0x73CD, 0x8CC3, 0x93AE, 0x9673, 0x6D25, 0x589C, 0x690E, 0x69CC, 0x8FFD, 0x939A, 0x75DB, 0x901A, 0x585A, 0x6802, 0x63B4, 0x69FB, 0x4F43, 0x6F2C, 0x67D8, 0x8FBB, 0x8526, 0x7DB4, 0x9354, 0x693F, 0x6F70, 0x576A, 0x58F7, 0x5B2C, 0x7D2C, 0x722A, 0x540A, 0x91E3, 0x9DB4, 0x4EAD, 0x4F4E, 0x505C, 0x5075, 0x5243, 0x8C9E, 0x5448, 0x5824, 0x5B9A, 0x5E1D, 0x5E95, 0x5EAD, 0x5EF7, 0x5F1F, 0x608C, 0x62B5, 0x633A, 0x63D0, 0x68AF, 0x6C40, 0x7887, 0x798E, 0x7A0B, 0x7DE0, 0x8247, 0x8A02, 0x8AE6, 0x8E44, 0x9013}, + {0x90B8, 0x912D, 0x91D8, 0x9F0E, 0x6CE5, 0x6458, 0x64E2, 0x6575, 0x6EF4, 0x7684, 0x7B1B, 0x9069, 0x93D1, 0x6EBA, 0x54F2, 0x5FB9, 0x64A4, 0x8F4D, 0x8FED, 0x9244, 0x5178, 0x586B, 0x5929, 0x5C55, 0x5E97, 0x6DFB, 0x7E8F, 0x751C, 0x8CBC, 0x8EE2, 0x985B, 0x70B9, 0x4F1D, 0x6BBF, 0x6FB1, 0x7530, 0x96FB, 0x514E, 0x5410, 0x5835, 0x5857, 0x59AC, 0x5C60, 0x5F92, 0x6597, 0x675C, 0x6E21, 0x767B, 0x83DF, 0x8CED, 0x9014, 0x90FD, 0x934D, 0x7825, 0x783A, 0x52AA, 0x5EA6, 0x571F, 0x5974, 0x6012, 0x5012, 0x515A, 0x51AC, 0x0000, 0x51CD, 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5B95, 0x5CF6, 0x5D8B, 0x60BC, 0x6295, 0x642D, 0x6771, 0x6843, 0x68BC, 0x68DF, 0x76D7, 0x6DD8, 0x6E6F, 0x6D9B, 0x706F, 0x71C8, 0x5F53, 0x75D8, 0x7977, 0x7B49, 0x7B54, 0x7B52, 0x7CD6, 0x7D71, 0x5230, 0x8463, 0x8569, 0x85E4, 0x8A0E, 0x8B04, 0x8C46, 0x8E0F, 0x9003, 0x900F, 0x9419, 0x9676, 0x982D, 0x9A30, 0x95D8, 0x50CD, 0x52D5, 0x540C, 0x5802, 0x5C0E, 0x61A7, 0x649E, 0x6D1E, 0x77B3, 0x7AE5, 0x80F4, 0x8404, 0x9053, 0x9285, 0x5CE0, 0x9D07, 0x533F, 0x5F97, 0x5FB3, 0x6D9C, 0x7279, 0x7763, 0x79BF, 0x7BE4, 0x6BD2, 0x72EC, 0x8AAD, 0x6803, 0x6A61, 0x51F8, 0x7A81, 0x6934, 0x5C4A, 0x9CF6, 0x82EB, 0x5BC5, 0x9149, 0x701E, 0x5678, 0x5C6F, 0x60C7, 0x6566, 0x6C8C, 0x8C5A, 0x9041, 0x9813, 0x5451, 0x66C7, 0x920D, 0x5948, 0x90A3, 0x5185, 0x4E4D, 0x51EA, 0x8599, 0x8B0E, 0x7058, 0x637A, 0x934B, 0x6962, 0x99B4, 0x7E04, 0x7577, 0x5357, 0x6960, 0x8EDF, 0x96E3, 0x6C5D, 0x4E8C, 0x5C3C, 0x5F10, 0x8FE9, 0x5302, 0x8CD1, 0x8089, 0x8679, 0x5EFF, 0x65E5, 0x4E73, 0x5165}, + {0x5982, 0x5C3F, 0x97EE, 0x4EFB, 0x598A, 0x5FCD, 0x8A8D, 0x6FE1, 0x79B0, 0x7962, 0x5BE7, 0x8471, 0x732B, 0x71B1, 0x5E74, 0x5FF5, 0x637B, 0x649A, 0x71C3, 0x7C98, 0x4E43, 0x5EFC, 0x4E4B, 0x57DC, 0x56A2, 0x60A9, 0x6FC3, 0x7D0D, 0x80FD, 0x8133, 0x81BF, 0x8FB2, 0x8997, 0x86A4, 0x5DF4, 0x628A, 0x64AD, 0x8987, 0x6777, 0x6CE2, 0x6D3E, 0x7436, 0x7834, 0x5A46, 0x7F75, 0x82AD, 0x99AC, 0x4FF3, 0x5EC3, 0x62DD, 0x6392, 0x6557, 0x676F, 0x76C3, 0x724C, 0x80CC, 0x80BA, 0x8F29, 0x914D, 0x500D, 0x57F9, 0x5A92, 0x6885, 0x0000, 0x6973, 0x7164, 0x72FD, 0x8CB7, 0x58F2, 0x8CE0, 0x966A, 0x9019, 0x877F, 0x79E4, 0x77E7, 0x8429, 0x4F2F, 0x5265, 0x535A, 0x62CD, 0x67CF, 0x6CCA, 0x767D, 0x7B94, 0x7C95, 0x8236, 0x8584, 0x8FEB, 0x66DD, 0x6F20, 0x7206, 0x7E1B, 0x83AB, 0x99C1, 0x9EA6, 0x51FD, 0x7BB1, 0x7872, 0x7BB8, 0x8087, 0x7B48, 0x6AE8, 0x5E61, 0x808C, 0x7551, 0x7560, 0x516B, 0x9262, 0x6E8C, 0x767A, 0x9197, 0x9AEA, 0x4F10, 0x7F70, 0x629C, 0x7B4F, 0x95A5, 0x9CE9, 0x567A, 0x5859, 0x86E4, 0x96BC, 0x4F34, 0x5224, 0x534A, 0x53CD, 0x53DB, 0x5E06, 0x642C, 0x6591, 0x677F, 0x6C3E, 0x6C4E, 0x7248, 0x72AF, 0x73ED, 0x7554, 0x7E41, 0x822C, 0x85E9, 0x8CA9, 0x7BC4, 0x91C6, 0x7169, 0x9812, 0x98EF, 0x633D, 0x6669, 0x756A, 0x76E4, 0x78D0, 0x8543, 0x86EE, 0x532A, 0x5351, 0x5426, 0x5983, 0x5E87, 0x5F7C, 0x60B2, 0x6249, 0x6279, 0x62AB, 0x6590, 0x6BD4, 0x6CCC, 0x75B2, 0x76AE, 0x7891, 0x79D8, 0x7DCB, 0x7F77, 0x80A5, 0x88AB, 0x8AB9, 0x8CBB, 0x907F, 0x975E, 0x98DB, 0x6A0B, 0x7C38, 0x5099, 0x5C3E, 0x5FAE, 0x6787, 0x6BD8, 0x7435, 0x7709, 0x7F8E}, + {0x9F3B, 0x67CA, 0x7A17, 0x5339, 0x758B, 0x9AED, 0x5F66, 0x819D, 0x83F1, 0x8098, 0x5F3C, 0x5FC5, 0x7562, 0x7B46, 0x903C, 0x6867, 0x59EB, 0x5A9B, 0x7D10, 0x767E, 0x8B2C, 0x4FF5, 0x5F6A, 0x6A19, 0x6C37, 0x6F02, 0x74E2, 0x7968, 0x8868, 0x8A55, 0x8C79, 0x5EDF, 0x63CF, 0x75C5, 0x79D2, 0x82D7, 0x9328, 0x92F2, 0x849C, 0x86ED, 0x9C2D, 0x54C1, 0x5F6C, 0x658C, 0x6D5C, 0x7015, 0x8CA7, 0x8CD3, 0x983B, 0x654F, 0x74F6, 0x4E0D, 0x4ED8, 0x57E0, 0x592B, 0x5A66, 0x5BCC, 0x51A8, 0x5E03, 0x5E9C, 0x6016, 0x6276, 0x6577, 0x0000, 0x65A7, 0x666E, 0x6D6E, 0x7236, 0x7B26, 0x8150, 0x819A, 0x8299, 0x8B5C, 0x8CA0, 0x8CE6, 0x8D74, 0x961C, 0x9644, 0x4FAE, 0x64AB, 0x6B66, 0x821E, 0x8461, 0x856A, 0x90E8, 0x5C01, 0x6953, 0x98A8, 0x847A, 0x8557, 0x4F0F, 0x526F, 0x5FA9, 0x5E45, 0x670D, 0x798F, 0x8179, 0x8907, 0x8986, 0x6DF5, 0x5F17, 0x6255, 0x6CB8, 0x4ECF, 0x7269, 0x9B92, 0x5206, 0x543B, 0x5674, 0x58B3, 0x61A4, 0x626E, 0x711A, 0x596E, 0x7C89, 0x7CDE, 0x7D1B, 0x96F0, 0x6587, 0x805E, 0x4E19, 0x4F75, 0x5175, 0x5840, 0x5E63, 0x5E73, 0x5F0A, 0x67C4, 0x4E26, 0x853D, 0x9589, 0x965B, 0x7C73, 0x9801, 0x50FB, 0x58C1, 0x7656, 0x78A7, 0x5225, 0x77A5, 0x8511, 0x7B86, 0x504F, 0x5909, 0x7247, 0x7BC7, 0x7DE8, 0x8FBA, 0x8FD4, 0x904D, 0x4FBF, 0x52C9, 0x5A29, 0x5F01, 0x97AD, 0x4FDD, 0x8217, 0x92EA, 0x5703, 0x6355, 0x6B69, 0x752B, 0x88DC, 0x8F14, 0x7A42, 0x52DF, 0x5893, 0x6155, 0x620A, 0x66AE, 0x6BCD, 0x7C3F, 0x83E9, 0x5023, 0x4FF8, 0x5305, 0x5446, 0x5831, 0x5949, 0x5B9D, 0x5CF0, 0x5CEF, 0x5D29, 0x5E96, 0x62B1, 0x6367, 0x653E, 0x65B9, 0x670B}, + {0x6CD5, 0x6CE1, 0x70F9, 0x7832, 0x7E2B, 0x80DE, 0x82B3, 0x840C, 0x84EC, 0x8702, 0x8912, 0x8A2A, 0x8C4A, 0x90A6, 0x92D2, 0x98FD, 0x9CF3, 0x9D6C, 0x4E4F, 0x4EA1, 0x508D, 0x5256, 0x574A, 0x59A8, 0x5E3D, 0x5FD8, 0x5FD9, 0x623F, 0x66B4, 0x671B, 0x67D0, 0x68D2, 0x5192, 0x7D21, 0x80AA, 0x81A8, 0x8B00, 0x8C8C, 0x8CBF, 0x927E, 0x9632, 0x5420, 0x982C, 0x5317, 0x50D5, 0x535C, 0x58A8, 0x64B2, 0x6734, 0x7267, 0x7766, 0x7A46, 0x91E6, 0x52C3, 0x6CA1, 0x6B86, 0x5800, 0x5E4C, 0x5954, 0x672C, 0x7FFB, 0x51E1, 0x76C6, 0x0000, 0x6469, 0x78E8, 0x9B54, 0x9EBB, 0x57CB, 0x59B9, 0x6627, 0x679A, 0x6BCE, 0x54E9, 0x69D9, 0x5E55, 0x819C, 0x6795, 0x9BAA, 0x67FE, 0x9C52, 0x685D, 0x4EA6, 0x4FE3, 0x53C8, 0x62B9, 0x672B, 0x6CAB, 0x8FC4, 0x4FAD, 0x7E6D, 0x9EBF, 0x4E07, 0x6162, 0x6E80, 0x6F2B, 0x8513, 0x5473, 0x672A, 0x9B45, 0x5DF3, 0x7B95, 0x5CAC, 0x5BC6, 0x871C, 0x6E4A, 0x84D1, 0x7A14, 0x8108, 0x5999, 0x7C8D, 0x6C11, 0x7720, 0x52D9, 0x5922, 0x7121, 0x725F, 0x77DB, 0x9727, 0x9D61, 0x690B, 0x5A7F, 0x5A18, 0x51A5, 0x540D, 0x547D, 0x660E, 0x76DF, 0x8FF7, 0x9298, 0x9CF4, 0x59EA, 0x725D, 0x6EC5, 0x514D, 0x68C9, 0x7DBF, 0x7DEC, 0x9762, 0x9EBA, 0x6478, 0x6A21, 0x8302, 0x5984, 0x5B5F, 0x6BDB, 0x731B, 0x76F2, 0x7DB2, 0x8017, 0x8499, 0x5132, 0x6728, 0x9ED9, 0x76EE, 0x6762, 0x52FF, 0x9905, 0x5C24, 0x623B, 0x7C7E, 0x8CB0, 0x554F, 0x60B6, 0x7D0B, 0x9580, 0x5301, 0x4E5F, 0x51B6, 0x591C, 0x723A, 0x8036, 0x91CE, 0x5F25, 0x77E2, 0x5384, 0x5F79, 0x7D04, 0x85AC, 0x8A33, 0x8E8D, 0x9756, 0x67F3, 0x85AE, 0x9453, 0x6109, 0x6108, 0x6CB9, 0x7652}, + {0x8AED, 0x8F38, 0x552F, 0x4F51, 0x512A, 0x52C7, 0x53CB, 0x5BA5, 0x5E7D, 0x60A0, 0x6182, 0x63D6, 0x6709, 0x67DA, 0x6E67, 0x6D8C, 0x7336, 0x7337, 0x7531, 0x7950, 0x88D5, 0x8A98, 0x904A, 0x9091, 0x90F5, 0x96C4, 0x878D, 0x5915, 0x4E88, 0x4F59, 0x4E0E, 0x8A89, 0x8F3F, 0x9810, 0x50AD, 0x5E7C, 0x5996, 0x5BB9, 0x5EB8, 0x63DA, 0x63FA, 0x64C1, 0x66DC, 0x694A, 0x69D8, 0x6D0B, 0x6EB6, 0x7194, 0x7528, 0x7AAF, 0x7F8A, 0x8000, 0x8449, 0x84C9, 0x8981, 0x8B21, 0x8E0A, 0x9065, 0x967D, 0x990A, 0x617E, 0x6291, 0x6B32, 0x0000, 0x6C83, 0x6D74, 0x7FCC, 0x7FFC, 0x6DC0, 0x7F85, 0x87BA, 0x88F8, 0x6765, 0x83B1, 0x983C, 0x96F7, 0x6D1B, 0x7D61, 0x843D, 0x916A, 0x4E71, 0x5375, 0x5D50, 0x6B04, 0x6FEB, 0x85CD, 0x862D, 0x89A7, 0x5229, 0x540F, 0x5C65, 0x674E, 0x68A8, 0x7406, 0x7483, 0x75E2, 0x88CF, 0x88E1, 0x91CC, 0x96E2, 0x9678, 0x5F8B, 0x7387, 0x7ACB, 0x844E, 0x63A0, 0x7565, 0x5289, 0x6D41, 0x6E9C, 0x7409, 0x7559, 0x786B, 0x7C92, 0x9686, 0x7ADC, 0x9F8D, 0x4FB6, 0x616E, 0x65C5, 0x865C, 0x4E86, 0x4EAE, 0x50DA, 0x4E21, 0x51CC, 0x5BEE, 0x6599, 0x6881, 0x6DBC, 0x731F, 0x7642, 0x77AD, 0x7A1C, 0x7CE7, 0x826F, 0x8AD2, 0x907C, 0x91CF, 0x9675, 0x9818, 0x529B, 0x7DD1, 0x502B, 0x5398, 0x6797, 0x6DCB, 0x71D0, 0x7433, 0x81E8, 0x8F2A, 0x96A3, 0x9C57, 0x9E9F, 0x7460, 0x5841, 0x6D99, 0x7D2F, 0x985E, 0x4EE4, 0x4F36, 0x4F8B, 0x51B7, 0x52B1, 0x5DBA, 0x601C, 0x73B2, 0x793C, 0x82D3, 0x9234, 0x96B7, 0x96F6, 0x970A, 0x9E97, 0x9F62, 0x66A6, 0x6B74, 0x5217, 0x52A3, 0x70C8, 0x88C2, 0x5EC9, 0x604B, 0x6190, 0x6F23, 0x7149, 0x7C3E, 0x7DF4, 0x806F}, + {0x84EE, 0x9023, 0x932C, 0x5442, 0x9B6F, 0x6AD3, 0x7089, 0x8CC2, 0x8DEF, 0x9732, 0x52B4, 0x5A41, 0x5ECA, 0x5F04, 0x6717, 0x697C, 0x6994, 0x6D6A, 0x6F0F, 0x7262, 0x72FC, 0x7BED, 0x8001, 0x807E, 0x874B, 0x90CE, 0x516D, 0x9E93, 0x7984, 0x808B, 0x9332, 0x8AD6, 0x502D, 0x548C, 0x8A71, 0x6B6A, 0x8CC4, 0x8107, 0x60D1, 0x67A0, 0x9DF2, 0x4E99, 0x4E98, 0x9C10, 0x8A6B, 0x85C1, 0x8568, 0x6900, 0x6E7E, 0x7897, 0x8155, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x5F0C, 0x4E10, 0x4E15, 0x4E2A, 0x4E31, 0x4E36, 0x4E3C, 0x4E3F, 0x4E42, 0x4E56, 0x4E58, 0x4E82, 0x4E85, 0x8C6B, 0x4E8A, 0x8212, 0x5F0D, 0x4E8E, 0x4E9E, 0x4E9F, 0x4EA0, 0x4EA2, 0x4EB0, 0x4EB3, 0x4EB6, 0x4ECE, 0x4ECD, 0x4EC4, 0x4EC6, 0x4EC2, 0x4ED7, 0x4EDE, 0x4EED, 0x4EDF, 0x4EF7, 0x4F09, 0x4F5A, 0x4F30, 0x4F5B, 0x4F5D, 0x4F57, 0x4F47, 0x4F76, 0x4F88, 0x4F8F, 0x4F98, 0x4F7B, 0x4F69, 0x4F70, 0x4F91, 0x4F6F, 0x4F86, 0x4F96, 0x5118, 0x4FD4, 0x4FDF, 0x4FCE, 0x4FD8, 0x4FDB, 0x4FD1, 0x4FDA, 0x4FD0, 0x4FE4, 0x4FE5, 0x501A, 0x5028, 0x5014, 0x502A, 0x5025, 0x5005, 0x4F1C, 0x4FF6, 0x5021, 0x5029, 0x502C, 0x4FFE, 0x4FEF, 0x5011, 0x5006, 0x5043, 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505A, 0x5056, 0x506C, 0x5078, 0x5080, 0x509A, 0x5085, 0x50B4, 0x50B2}, + {0x50C9, 0x50CA, 0x50B3, 0x50C2, 0x50D6, 0x50DE, 0x50E5, 0x50ED, 0x50E3, 0x50EE, 0x50F9, 0x50F5, 0x5109, 0x5101, 0x5102, 0x5116, 0x5115, 0x5114, 0x511A, 0x5121, 0x513A, 0x5137, 0x513C, 0x513B, 0x513F, 0x5140, 0x5152, 0x514C, 0x5154, 0x5162, 0x7AF8, 0x5169, 0x516A, 0x516E, 0x5180, 0x5182, 0x56D8, 0x518C, 0x5189, 0x518F, 0x5191, 0x5193, 0x5195, 0x5196, 0x51A4, 0x51A6, 0x51A2, 0x51A9, 0x51AA, 0x51AB, 0x51B3, 0x51B1, 0x51B2, 0x51B0, 0x51B5, 0x51BD, 0x51C5, 0x51C9, 0x51DB, 0x51E0, 0x8655, 0x51E9, 0x51ED, 0x0000, 0x51F0, 0x51F5, 0x51FE, 0x5204, 0x520B, 0x5214, 0x520E, 0x5227, 0x522A, 0x522E, 0x5233, 0x5239, 0x524F, 0x5244, 0x524B, 0x524C, 0x525E, 0x5254, 0x526A, 0x5274, 0x5269, 0x5273, 0x527F, 0x527D, 0x528D, 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8FA8, 0x8FA7, 0x52AC, 0x52AD, 0x52BC, 0x52B5, 0x52C1, 0x52CD, 0x52D7, 0x52DE, 0x52E3, 0x52E6, 0x98ED, 0x52E0, 0x52F3, 0x52F5, 0x52F8, 0x52F9, 0x5306, 0x5308, 0x7538, 0x530D, 0x5310, 0x530F, 0x5315, 0x531A, 0x5323, 0x532F, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, 0x5345, 0x4E17, 0x5349, 0x534D, 0x51D6, 0x535E, 0x5369, 0x536E, 0x5918, 0x537B, 0x5377, 0x5382, 0x5396, 0x53A0, 0x53A6, 0x53A5, 0x53AE, 0x53B0, 0x53B6, 0x53C3, 0x7C12, 0x96D9, 0x53DF, 0x66FC, 0x71EE, 0x53EE, 0x53E8, 0x53ED, 0x53FA, 0x5401, 0x543D, 0x5440, 0x542C, 0x542D, 0x543C, 0x542E, 0x5436, 0x5429, 0x541D, 0x544E, 0x548F, 0x5475, 0x548E, 0x545F, 0x5471, 0x5477, 0x5470, 0x5492, 0x547B, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54C7, 0x54A2, 0x54B8, 0x54A5, 0x54AC, 0x54C4, 0x54C8, 0x54A8}, + {0x54AB, 0x54C2, 0x54A4, 0x54BE, 0x54BC, 0x54D8, 0x54E5, 0x54E6, 0x550F, 0x5514, 0x54FD, 0x54EE, 0x54ED, 0x54FA, 0x54E2, 0x5539, 0x5540, 0x5563, 0x554C, 0x552E, 0x555C, 0x5545, 0x5556, 0x5557, 0x5538, 0x5533, 0x555D, 0x5599, 0x5580, 0x54AF, 0x558A, 0x559F, 0x557B, 0x557E, 0x5598, 0x559E, 0x55AE, 0x557C, 0x5583, 0x55A9, 0x5587, 0x55A8, 0x55DA, 0x55C5, 0x55DF, 0x55C4, 0x55DC, 0x55E4, 0x55D4, 0x5614, 0x55F7, 0x5616, 0x55FE, 0x55FD, 0x561B, 0x55F9, 0x564E, 0x5650, 0x71DF, 0x5634, 0x5636, 0x5632, 0x5638, 0x0000, 0x566B, 0x5664, 0x562F, 0x566C, 0x566A, 0x5686, 0x5680, 0x568A, 0x56A0, 0x5694, 0x568F, 0x56A5, 0x56AE, 0x56B6, 0x56B4, 0x56C2, 0x56BC, 0x56C1, 0x56C3, 0x56C0, 0x56C8, 0x56CE, 0x56D1, 0x56D3, 0x56D7, 0x56EE, 0x56F9, 0x5700, 0x56FF, 0x5704, 0x5709, 0x5708, 0x570B, 0x570D, 0x5713, 0x5718, 0x5716, 0x55C7, 0x571C, 0x5726, 0x5737, 0x5738, 0x574E, 0x573B, 0x5740, 0x574F, 0x5769, 0x57C0, 0x5788, 0x5761, 0x577F, 0x5789, 0x5793, 0x57A0, 0x57B3, 0x57A4, 0x57AA, 0x57B0, 0x57C3, 0x57C6, 0x57D4, 0x57D2, 0x57D3, 0x580A, 0x57D6, 0x57E3, 0x580B, 0x5819, 0x581D, 0x5872, 0x5821, 0x5862, 0x584B, 0x5870, 0x6BC0, 0x5852, 0x583D, 0x5879, 0x5885, 0x58B9, 0x589F, 0x58AB, 0x58BA, 0x58DE, 0x58BB, 0x58B8, 0x58AE, 0x58C5, 0x58D3, 0x58D1, 0x58D7, 0x58D9, 0x58D8, 0x58E5, 0x58DC, 0x58E4, 0x58DF, 0x58EF, 0x58FA, 0x58F9, 0x58FB, 0x58FC, 0x58FD, 0x5902, 0x590A, 0x5910, 0x591B, 0x68A6, 0x5925, 0x592C, 0x592D, 0x5932, 0x5938, 0x593E, 0x7AD2, 0x5955, 0x5950, 0x594E, 0x595A, 0x5958, 0x5962, 0x5960, 0x5967, 0x596C, 0x5969}, + {0x5978, 0x5981, 0x599D, 0x4F5E, 0x4FAB, 0x59A3, 0x59B2, 0x59C6, 0x59E8, 0x59DC, 0x598D, 0x59D9, 0x59DA, 0x5A25, 0x5A1F, 0x5A11, 0x5A1C, 0x5A09, 0x5A1A, 0x5A40, 0x5A6C, 0x5A49, 0x5A35, 0x5A36, 0x5A62, 0x5A6A, 0x5A9A, 0x5ABC, 0x5ABE, 0x5ACB, 0x5AC2, 0x5ABD, 0x5AE3, 0x5AD7, 0x5AE6, 0x5AE9, 0x5AD6, 0x5AFA, 0x5AFB, 0x5B0C, 0x5B0B, 0x5B16, 0x5B32, 0x5AD0, 0x5B2A, 0x5B36, 0x5B3E, 0x5B43, 0x5B45, 0x5B40, 0x5B51, 0x5B55, 0x5B5A, 0x5B5B, 0x5B65, 0x5B69, 0x5B70, 0x5B73, 0x5B75, 0x5B78, 0x6588, 0x5B7A, 0x5B80, 0x0000, 0x5B83, 0x5BA6, 0x5BB8, 0x5BC3, 0x5BC7, 0x5BC9, 0x5BD4, 0x5BD0, 0x5BE4, 0x5BE6, 0x5BE2, 0x5BDE, 0x5BE5, 0x5BEB, 0x5BF0, 0x5BF6, 0x5BF3, 0x5C05, 0x5C07, 0x5C08, 0x5C0D, 0x5C13, 0x5C20, 0x5C22, 0x5C28, 0x5C38, 0x5C39, 0x5C41, 0x5C46, 0x5C4E, 0x5C53, 0x5C50, 0x5C4F, 0x5B71, 0x5C6C, 0x5C6E, 0x4E62, 0x5C76, 0x5C79, 0x5C8C, 0x5C91, 0x5C94, 0x599B, 0x5CAB, 0x5CBB, 0x5CB6, 0x5CBC, 0x5CB7, 0x5CC5, 0x5CBE, 0x5CC7, 0x5CD9, 0x5CE9, 0x5CFD, 0x5CFA, 0x5CED, 0x5D8C, 0x5CEA, 0x5D0B, 0x5D15, 0x5D17, 0x5D5C, 0x5D1F, 0x5D1B, 0x5D11, 0x5D14, 0x5D22, 0x5D1A, 0x5D19, 0x5D18, 0x5D4C, 0x5D52, 0x5D4E, 0x5D4B, 0x5D6C, 0x5D73, 0x5D76, 0x5D87, 0x5D84, 0x5D82, 0x5DA2, 0x5D9D, 0x5DAC, 0x5DAE, 0x5DBD, 0x5D90, 0x5DB7, 0x5DBC, 0x5DC9, 0x5DCD, 0x5DD3, 0x5DD2, 0x5DD6, 0x5DDB, 0x5DEB, 0x5DF2, 0x5DF5, 0x5E0B, 0x5E1A, 0x5E19, 0x5E11, 0x5E1B, 0x5E36, 0x5E37, 0x5E44, 0x5E43, 0x5E40, 0x5E4E, 0x5E57, 0x5E54, 0x5E5F, 0x5E62, 0x5E64, 0x5E47, 0x5E75, 0x5E76, 0x5E7A, 0x9EBC, 0x5E7F, 0x5EA0, 0x5EC1, 0x5EC2, 0x5EC8, 0x5ED0, 0x5ECF}, + {0x5ED6, 0x5EE3, 0x5EDD, 0x5EDA, 0x5EDB, 0x5EE2, 0x5EE1, 0x5EE8, 0x5EE9, 0x5EEC, 0x5EF1, 0x5EF3, 0x5EF0, 0x5EF4, 0x5EF8, 0x5EFE, 0x5F03, 0x5F09, 0x5F5D, 0x5F5C, 0x5F0B, 0x5F11, 0x5F16, 0x5F29, 0x5F2D, 0x5F38, 0x5F41, 0x5F48, 0x5F4C, 0x5F4E, 0x5F2F, 0x5F51, 0x5F56, 0x5F57, 0x5F59, 0x5F61, 0x5F6D, 0x5F73, 0x5F77, 0x5F83, 0x5F82, 0x5F7F, 0x5F8A, 0x5F88, 0x5F91, 0x5F87, 0x5F9E, 0x5F99, 0x5F98, 0x5FA0, 0x5FA8, 0x5FAD, 0x5FBC, 0x5FD6, 0x5FFB, 0x5FE4, 0x5FF8, 0x5FF1, 0x5FDD, 0x60B3, 0x5FFF, 0x6021, 0x6060, 0x0000, 0x6019, 0x6010, 0x6029, 0x600E, 0x6031, 0x601B, 0x6015, 0x602B, 0x6026, 0x600F, 0x603A, 0x605A, 0x6041, 0x606A, 0x6077, 0x605F, 0x604A, 0x6046, 0x604D, 0x6063, 0x6043, 0x6064, 0x6042, 0x606C, 0x606B, 0x6059, 0x6081, 0x608D, 0x60E7, 0x6083, 0x609A, 0x6084, 0x609B, 0x6096, 0x6097, 0x6092, 0x60A7, 0x608B, 0x60E1, 0x60B8, 0x60E0, 0x60D3, 0x60B4, 0x5FF0, 0x60BD, 0x60C6, 0x60B5, 0x60D8, 0x614D, 0x6115, 0x6106, 0x60F6, 0x60F7, 0x6100, 0x60F4, 0x60FA, 0x6103, 0x6121, 0x60FB, 0x60F1, 0x610D, 0x610E, 0x6147, 0x613E, 0x6128, 0x6127, 0x614A, 0x613F, 0x613C, 0x612C, 0x6134, 0x613D, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615A, 0x616B, 0x6174, 0x616F, 0x6165, 0x6171, 0x615F, 0x615D, 0x6153, 0x6175, 0x6199, 0x6196, 0x6187, 0x61AC, 0x6194, 0x619A, 0x618A, 0x6191, 0x61AB, 0x61AE, 0x61CC, 0x61CA, 0x61C9, 0x61F7, 0x61C8, 0x61C3, 0x61C6, 0x61BA, 0x61CB, 0x7F79, 0x61CD, 0x61E6, 0x61E3, 0x61F6, 0x61FA, 0x61F4, 0x61FF, 0x61FD, 0x61FC, 0x61FE, 0x6200, 0x6208, 0x6209, 0x620D, 0x620C, 0x6214, 0x621B}, + {0x621E, 0x6221, 0x622A, 0x622E, 0x6230, 0x6232, 0x6233, 0x6241, 0x624E, 0x625E, 0x6263, 0x625B, 0x6260, 0x6268, 0x627C, 0x6282, 0x6289, 0x627E, 0x6292, 0x6293, 0x6296, 0x62D4, 0x6283, 0x6294, 0x62D7, 0x62D1, 0x62BB, 0x62CF, 0x62FF, 0x62C6, 0x64D4, 0x62C8, 0x62DC, 0x62CC, 0x62CA, 0x62C2, 0x62C7, 0x629B, 0x62C9, 0x630C, 0x62EE, 0x62F1, 0x6327, 0x6302, 0x6308, 0x62EF, 0x62F5, 0x6350, 0x633E, 0x634D, 0x641C, 0x634F, 0x6396, 0x638E, 0x6380, 0x63AB, 0x6376, 0x63A3, 0x638F, 0x6389, 0x639F, 0x63B5, 0x636B, 0x0000, 0x6369, 0x63BE, 0x63E9, 0x63C0, 0x63C6, 0x63E3, 0x63C9, 0x63D2, 0x63F6, 0x63C4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651D, 0x6417, 0x6428, 0x640F, 0x6467, 0x646F, 0x6476, 0x644E, 0x652A, 0x6495, 0x6493, 0x64A5, 0x64A9, 0x6488, 0x64BC, 0x64DA, 0x64D2, 0x64C5, 0x64C7, 0x64BB, 0x64D8, 0x64C2, 0x64F1, 0x64E7, 0x8209, 0x64E0, 0x64E1, 0x62AC, 0x64E3, 0x64EF, 0x652C, 0x64F6, 0x64F4, 0x64F2, 0x64FA, 0x6500, 0x64FD, 0x6518, 0x651C, 0x6505, 0x6524, 0x6523, 0x652B, 0x6534, 0x6535, 0x6537, 0x6536, 0x6538, 0x754B, 0x6548, 0x6556, 0x6555, 0x654D, 0x6558, 0x655E, 0x655D, 0x6572, 0x6578, 0x6582, 0x6583, 0x8B8A, 0x659B, 0x659F, 0x65AB, 0x65B7, 0x65C3, 0x65C6, 0x65C1, 0x65C4, 0x65CC, 0x65D2, 0x65DB, 0x65D9, 0x65E0, 0x65E1, 0x65F1, 0x6772, 0x660A, 0x6603, 0x65FB, 0x6773, 0x6635, 0x6636, 0x6634, 0x661C, 0x664F, 0x6644, 0x6649, 0x6641, 0x665E, 0x665D, 0x6664, 0x6667, 0x6668, 0x665F, 0x6662, 0x6670, 0x6683, 0x6688, 0x668E, 0x6689, 0x6684, 0x6698, 0x669D, 0x66C1, 0x66B9, 0x66C9, 0x66BE, 0x66BC}, + {0x66C4, 0x66B8, 0x66D6, 0x66DA, 0x66E0, 0x663F, 0x66E6, 0x66E9, 0x66F0, 0x66F5, 0x66F7, 0x670F, 0x6716, 0x671E, 0x6726, 0x6727, 0x9738, 0x672E, 0x673F, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746, 0x675E, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67A9, 0x677C, 0x676A, 0x678C, 0x678B, 0x67A6, 0x67A1, 0x6785, 0x67B7, 0x67EF, 0x67B4, 0x67EC, 0x67B3, 0x67E9, 0x67B8, 0x67E4, 0x67DE, 0x67DD, 0x67E2, 0x67EE, 0x67B9, 0x67CE, 0x67C6, 0x67E7, 0x6A9C, 0x681E, 0x6846, 0x6829, 0x6840, 0x684D, 0x6832, 0x684E, 0x0000, 0x68B3, 0x682B, 0x6859, 0x6863, 0x6877, 0x687F, 0x689F, 0x688F, 0x68AD, 0x6894, 0x689D, 0x689B, 0x6883, 0x6AAE, 0x68B9, 0x6874, 0x68B5, 0x68A0, 0x68BA, 0x690F, 0x688D, 0x687E, 0x6901, 0x68CA, 0x6908, 0x68D8, 0x6922, 0x6926, 0x68E1, 0x690C, 0x68CD, 0x68D4, 0x68E7, 0x68D5, 0x6936, 0x6912, 0x6904, 0x68D7, 0x68E3, 0x6925, 0x68F9, 0x68E0, 0x68EF, 0x6928, 0x692A, 0x691A, 0x6923, 0x6921, 0x68C6, 0x6979, 0x6977, 0x695C, 0x6978, 0x696B, 0x6954, 0x697E, 0x696E, 0x6939, 0x6974, 0x693D, 0x6959, 0x6930, 0x6961, 0x695E, 0x695D, 0x6981, 0x696A, 0x69B2, 0x69AE, 0x69D0, 0x69BF, 0x69C1, 0x69D3, 0x69BE, 0x69CE, 0x5BE8, 0x69CA, 0x69DD, 0x69BB, 0x69C3, 0x69A7, 0x6A2E, 0x6991, 0x69A0, 0x699C, 0x6995, 0x69B4, 0x69DE, 0x69E8, 0x6A02, 0x6A1B, 0x69FF, 0x6B0A, 0x69F9, 0x69F2, 0x69E7, 0x6A05, 0x69B1, 0x6A1E, 0x69ED, 0x6A14, 0x69EB, 0x6A0A, 0x6A12, 0x6AC1, 0x6A23, 0x6A13, 0x6A44, 0x6A0C, 0x6A72, 0x6A36, 0x6A78, 0x6A47, 0x6A62, 0x6A59, 0x6A66, 0x6A48, 0x6A38, 0x6A22, 0x6A90, 0x6A8D, 0x6AA0, 0x6A84, 0x6AA2, 0x6AA3}, + {0x6A97, 0x8617, 0x6ABB, 0x6AC3, 0x6AC2, 0x6AB8, 0x6AB3, 0x6AAC, 0x6ADE, 0x6AD1, 0x6ADF, 0x6AAA, 0x6ADA, 0x6AEA, 0x6AFB, 0x6B05, 0x8616, 0x6AFA, 0x6B12, 0x6B16, 0x9B31, 0x6B1F, 0x6B38, 0x6B37, 0x76DC, 0x6B39, 0x98EE, 0x6B47, 0x6B43, 0x6B49, 0x6B50, 0x6B59, 0x6B54, 0x6B5B, 0x6B5F, 0x6B61, 0x6B78, 0x6B79, 0x6B7F, 0x6B80, 0x6B84, 0x6B83, 0x6B8D, 0x6B98, 0x6B95, 0x6B9E, 0x6BA4, 0x6BAA, 0x6BAB, 0x6BAF, 0x6BB2, 0x6BB1, 0x6BB3, 0x6BB7, 0x6BBC, 0x6BC6, 0x6BCB, 0x6BD3, 0x6BDF, 0x6BEC, 0x6BEB, 0x6BF3, 0x6BEF, 0x0000, 0x9EBE, 0x6C08, 0x6C13, 0x6C14, 0x6C1B, 0x6C24, 0x6C23, 0x6C5E, 0x6C55, 0x6C62, 0x6C6A, 0x6C82, 0x6C8D, 0x6C9A, 0x6C81, 0x6C9B, 0x6C7E, 0x6C68, 0x6C73, 0x6C92, 0x6C90, 0x6CC4, 0x6CF1, 0x6CD3, 0x6CBD, 0x6CD7, 0x6CC5, 0x6CDD, 0x6CAE, 0x6CB1, 0x6CBE, 0x6CBA, 0x6CDB, 0x6CEF, 0x6CD9, 0x6CEA, 0x6D1F, 0x884D, 0x6D36, 0x6D2B, 0x6D3D, 0x6D38, 0x6D19, 0x6D35, 0x6D33, 0x6D12, 0x6D0C, 0x6D63, 0x6D93, 0x6D64, 0x6D5A, 0x6D79, 0x6D59, 0x6D8E, 0x6D95, 0x6FE4, 0x6D85, 0x6DF9, 0x6E15, 0x6E0A, 0x6DB5, 0x6DC7, 0x6DE6, 0x6DB8, 0x6DC6, 0x6DEC, 0x6DDE, 0x6DCC, 0x6DE8, 0x6DD2, 0x6DC5, 0x6DFA, 0x6DD9, 0x6DE4, 0x6DD5, 0x6DEA, 0x6DEE, 0x6E2D, 0x6E6E, 0x6E2E, 0x6E19, 0x6E72, 0x6E5F, 0x6E3E, 0x6E23, 0x6E6B, 0x6E2B, 0x6E76, 0x6E4D, 0x6E1F, 0x6E43, 0x6E3A, 0x6E4E, 0x6E24, 0x6EFF, 0x6E1D, 0x6E38, 0x6E82, 0x6EAA, 0x6E98, 0x6EC9, 0x6EB7, 0x6ED3, 0x6EBD, 0x6EAF, 0x6EC4, 0x6EB2, 0x6ED4, 0x6ED5, 0x6E8F, 0x6EA5, 0x6EC2, 0x6E9F, 0x6F41, 0x6F11, 0x704C, 0x6EEC, 0x6EF8, 0x6EFE, 0x6F3F, 0x6EF2, 0x6F31, 0x6EEF, 0x6F32, 0x6ECC}, + {0x6F3E, 0x6F13, 0x6EF7, 0x6F86, 0x6F7A, 0x6F78, 0x6F81, 0x6F80, 0x6F6F, 0x6F5B, 0x6FF3, 0x6F6D, 0x6F82, 0x6F7C, 0x6F58, 0x6F8E, 0x6F91, 0x6FC2, 0x6F66, 0x6FB3, 0x6FA3, 0x6FA1, 0x6FA4, 0x6FB9, 0x6FC6, 0x6FAA, 0x6FDF, 0x6FD5, 0x6FEC, 0x6FD4, 0x6FD8, 0x6FF1, 0x6FEE, 0x6FDB, 0x7009, 0x700B, 0x6FFA, 0x7011, 0x7001, 0x700F, 0x6FFE, 0x701B, 0x701A, 0x6F74, 0x701D, 0x7018, 0x701F, 0x7030, 0x703E, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70AF, 0x70F1, 0x70AC, 0x70B8, 0x70B3, 0x70AE, 0x70DF, 0x70CB, 0x70DD, 0x0000, 0x70D9, 0x7109, 0x70FD, 0x711C, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, 0x7162, 0x714C, 0x7156, 0x716C, 0x718F, 0x71FB, 0x7184, 0x7195, 0x71A8, 0x71AC, 0x71D7, 0x71B9, 0x71BE, 0x71D2, 0x71C9, 0x71D4, 0x71CE, 0x71E0, 0x71EC, 0x71E7, 0x71F5, 0x71FC, 0x71F9, 0x71FF, 0x720D, 0x7210, 0x721B, 0x7228, 0x722D, 0x722C, 0x7230, 0x7232, 0x723B, 0x723C, 0x723F, 0x7240, 0x7246, 0x724B, 0x7258, 0x7274, 0x727E, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, 0x72A2, 0x72A7, 0x72B9, 0x72B2, 0x72C3, 0x72C6, 0x72C4, 0x72CE, 0x72D2, 0x72E2, 0x72E0, 0x72E1, 0x72F9, 0x72F7, 0x500F, 0x7317, 0x730A, 0x731C, 0x7316, 0x731D, 0x7334, 0x732F, 0x7329, 0x7325, 0x733E, 0x734E, 0x734F, 0x9ED8, 0x7357, 0x736A, 0x7368, 0x7370, 0x7378, 0x7375, 0x737B, 0x737A, 0x73C8, 0x73B3, 0x73CE, 0x73BB, 0x73C0, 0x73E5, 0x73EE, 0x73DE, 0x74A2, 0x7405, 0x746F, 0x7425, 0x73F8, 0x7432, 0x743A, 0x7455, 0x743F, 0x745F, 0x7459, 0x7441, 0x745C, 0x7469, 0x7470, 0x7463, 0x746A, 0x7476, 0x747E, 0x748B, 0x749E, 0x74A7, 0x74CA, 0x74CF, 0x74D4, 0x73F1}, + {0x74E0, 0x74E3, 0x74E7, 0x74E9, 0x74EE, 0x74F2, 0x74F0, 0x74F1, 0x74F8, 0x74F7, 0x7504, 0x7503, 0x7505, 0x750C, 0x750E, 0x750D, 0x7515, 0x7513, 0x751E, 0x7526, 0x752C, 0x753C, 0x7544, 0x754D, 0x754A, 0x7549, 0x755B, 0x7546, 0x755A, 0x7569, 0x7564, 0x7567, 0x756B, 0x756D, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758A, 0x7589, 0x7582, 0x7594, 0x759A, 0x759D, 0x75A5, 0x75A3, 0x75C2, 0x75B3, 0x75C3, 0x75B5, 0x75BD, 0x75B8, 0x75BC, 0x75B1, 0x75CD, 0x75CA, 0x75D2, 0x75D9, 0x75E3, 0x75DE, 0x75FE, 0x75FF, 0x0000, 0x75FC, 0x7601, 0x75F0, 0x75FA, 0x75F2, 0x75F3, 0x760B, 0x760D, 0x7609, 0x761F, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630, 0x763B, 0x7647, 0x7648, 0x7646, 0x765C, 0x7658, 0x7661, 0x7662, 0x7668, 0x7669, 0x766A, 0x7667, 0x766C, 0x7670, 0x7672, 0x7676, 0x7678, 0x767C, 0x7680, 0x7683, 0x7688, 0x768B, 0x768E, 0x7696, 0x7693, 0x7699, 0x769A, 0x76B0, 0x76B4, 0x76B8, 0x76B9, 0x76BA, 0x76C2, 0x76CD, 0x76D6, 0x76D2, 0x76DE, 0x76E1, 0x76E5, 0x76E7, 0x76EA, 0x862F, 0x76FB, 0x7708, 0x7707, 0x7704, 0x7729, 0x7724, 0x771E, 0x7725, 0x7726, 0x771B, 0x7737, 0x7738, 0x7747, 0x775A, 0x7768, 0x776B, 0x775B, 0x7765, 0x777F, 0x777E, 0x7779, 0x778E, 0x778B, 0x7791, 0x77A0, 0x779E, 0x77B0, 0x77B6, 0x77B9, 0x77BF, 0x77BC, 0x77BD, 0x77BB, 0x77C7, 0x77CD, 0x77D7, 0x77DA, 0x77DC, 0x77E3, 0x77EE, 0x77FC, 0x780C, 0x7812, 0x7926, 0x7820, 0x792A, 0x7845, 0x788E, 0x7874, 0x7886, 0x787C, 0x789A, 0x788C, 0x78A3, 0x78B5, 0x78AA, 0x78AF, 0x78D1, 0x78C6, 0x78CB, 0x78D4, 0x78BE, 0x78BC, 0x78C5, 0x78CA, 0x78EC}, + {0x78E7, 0x78DA, 0x78FD, 0x78F4, 0x7907, 0x7912, 0x7911, 0x7919, 0x792C, 0x792B, 0x7940, 0x7960, 0x7957, 0x795F, 0x795A, 0x7955, 0x7953, 0x797A, 0x797F, 0x798A, 0x799D, 0x79A7, 0x9F4B, 0x79AA, 0x79AE, 0x79B3, 0x79B9, 0x79BA, 0x79C9, 0x79D5, 0x79E7, 0x79EC, 0x79E1, 0x79E3, 0x7A08, 0x7A0D, 0x7A18, 0x7A19, 0x7A20, 0x7A1F, 0x7980, 0x7A31, 0x7A3B, 0x7A3E, 0x7A37, 0x7A43, 0x7A57, 0x7A49, 0x7A61, 0x7A62, 0x7A69, 0x9F9D, 0x7A70, 0x7A79, 0x7A7D, 0x7A88, 0x7A97, 0x7A95, 0x7A98, 0x7A96, 0x7AA9, 0x7AC8, 0x7AB0, 0x0000, 0x7AB6, 0x7AC5, 0x7AC4, 0x7ABF, 0x9083, 0x7AC7, 0x7ACA, 0x7ACD, 0x7ACF, 0x7AD5, 0x7AD3, 0x7AD9, 0x7ADA, 0x7ADD, 0x7AE1, 0x7AE2, 0x7AE6, 0x7AED, 0x7AF0, 0x7B02, 0x7B0F, 0x7B0A, 0x7B06, 0x7B33, 0x7B18, 0x7B19, 0x7B1E, 0x7B35, 0x7B28, 0x7B36, 0x7B50, 0x7B7A, 0x7B04, 0x7B4D, 0x7B0B, 0x7B4C, 0x7B45, 0x7B75, 0x7B65, 0x7B74, 0x7B67, 0x7B70, 0x7B71, 0x7B6C, 0x7B6E, 0x7B9D, 0x7B98, 0x7B9F, 0x7B8D, 0x7B9C, 0x7B9A, 0x7B8B, 0x7B92, 0x7B8F, 0x7B5D, 0x7B99, 0x7BCB, 0x7BC1, 0x7BCC, 0x7BCF, 0x7BB4, 0x7BC6, 0x7BDD, 0x7BE9, 0x7C11, 0x7C14, 0x7BE6, 0x7BE5, 0x7C60, 0x7C00, 0x7C07, 0x7C13, 0x7BF3, 0x7BF7, 0x7C17, 0x7C0D, 0x7BF6, 0x7C23, 0x7C27, 0x7C2A, 0x7C1F, 0x7C37, 0x7C2B, 0x7C3D, 0x7C4C, 0x7C43, 0x7C54, 0x7C4F, 0x7C40, 0x7C50, 0x7C58, 0x7C5F, 0x7C64, 0x7C56, 0x7C65, 0x7C6C, 0x7C75, 0x7C83, 0x7C90, 0x7CA4, 0x7CAD, 0x7CA2, 0x7CAB, 0x7CA1, 0x7CA8, 0x7CB3, 0x7CB2, 0x7CB1, 0x7CAE, 0x7CB9, 0x7CBD, 0x7CC0, 0x7CC5, 0x7CC2, 0x7CD8, 0x7CD2, 0x7CDC, 0x7CE2, 0x9B3B, 0x7CEF, 0x7CF2, 0x7CF4, 0x7CF6, 0x7CFA, 0x7D06}, + {0x7D02, 0x7D1C, 0x7D15, 0x7D0A, 0x7D45, 0x7D4B, 0x7D2E, 0x7D32, 0x7D3F, 0x7D35, 0x7D46, 0x7D73, 0x7D56, 0x7D4E, 0x7D72, 0x7D68, 0x7D6E, 0x7D4F, 0x7D63, 0x7D93, 0x7D89, 0x7D5B, 0x7D8F, 0x7D7D, 0x7D9B, 0x7DBA, 0x7DAE, 0x7DA3, 0x7DB5, 0x7DC7, 0x7DBD, 0x7DAB, 0x7E3D, 0x7DA2, 0x7DAF, 0x7DDC, 0x7DB8, 0x7D9F, 0x7DB0, 0x7DD8, 0x7DDD, 0x7DE4, 0x7DDE, 0x7DFB, 0x7DF2, 0x7DE1, 0x7E05, 0x7E0A, 0x7E23, 0x7E21, 0x7E12, 0x7E31, 0x7E1F, 0x7E09, 0x7E0B, 0x7E22, 0x7E46, 0x7E66, 0x7E3B, 0x7E35, 0x7E39, 0x7E43, 0x7E37, 0x0000, 0x7E32, 0x7E3A, 0x7E67, 0x7E5D, 0x7E56, 0x7E5E, 0x7E59, 0x7E5A, 0x7E79, 0x7E6A, 0x7E69, 0x7E7C, 0x7E7B, 0x7E83, 0x7DD5, 0x7E7D, 0x8FAE, 0x7E7F, 0x7E88, 0x7E89, 0x7E8C, 0x7E92, 0x7E90, 0x7E93, 0x7E94, 0x7E96, 0x7E8E, 0x7E9B, 0x7E9C, 0x7F38, 0x7F3A, 0x7F45, 0x7F4C, 0x7F4D, 0x7F4E, 0x7F50, 0x7F51, 0x7F55, 0x7F54, 0x7F58, 0x7F5F, 0x7F60, 0x7F68, 0x7F69, 0x7F67, 0x7F78, 0x7F82, 0x7F86, 0x7F83, 0x7F88, 0x7F87, 0x7F8C, 0x7F94, 0x7F9E, 0x7F9D, 0x7F9A, 0x7FA3, 0x7FAF, 0x7FB2, 0x7FB9, 0x7FAE, 0x7FB6, 0x7FB8, 0x8B71, 0x7FC5, 0x7FC6, 0x7FCA, 0x7FD5, 0x7FD4, 0x7FE1, 0x7FE6, 0x7FE9, 0x7FF3, 0x7FF9, 0x98DC, 0x8006, 0x8004, 0x800B, 0x8012, 0x8018, 0x8019, 0x801C, 0x8021, 0x8028, 0x803F, 0x803B, 0x804A, 0x8046, 0x8052, 0x8058, 0x805A, 0x805F, 0x8062, 0x8068, 0x8073, 0x8072, 0x8070, 0x8076, 0x8079, 0x807D, 0x807F, 0x8084, 0x8086, 0x8085, 0x809B, 0x8093, 0x809A, 0x80AD, 0x5190, 0x80AC, 0x80DB, 0x80E5, 0x80D9, 0x80DD, 0x80C4, 0x80DA, 0x80D6, 0x8109, 0x80EF, 0x80F1, 0x811B, 0x8129, 0x8123, 0x812F, 0x814B}, + {0x968B, 0x8146, 0x813E, 0x8153, 0x8151, 0x80FC, 0x8171, 0x816E, 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818A, 0x8180, 0x8182, 0x81A0, 0x8195, 0x81A4, 0x81A3, 0x815F, 0x8193, 0x81A9, 0x81B0, 0x81B5, 0x81BE, 0x81B8, 0x81BD, 0x81C0, 0x81C2, 0x81BA, 0x81C9, 0x81CD, 0x81D1, 0x81D9, 0x81D8, 0x81C8, 0x81DA, 0x81DF, 0x81E0, 0x81E7, 0x81FA, 0x81FB, 0x81FE, 0x8201, 0x8202, 0x8205, 0x8207, 0x820A, 0x820D, 0x8210, 0x8216, 0x8229, 0x822B, 0x8238, 0x8233, 0x8240, 0x8259, 0x8258, 0x825D, 0x825A, 0x825F, 0x8264, 0x0000, 0x8262, 0x8268, 0x826A, 0x826B, 0x822E, 0x8271, 0x8277, 0x8278, 0x827E, 0x828D, 0x8292, 0x82AB, 0x829F, 0x82BB, 0x82AC, 0x82E1, 0x82E3, 0x82DF, 0x82D2, 0x82F4, 0x82F3, 0x82FA, 0x8393, 0x8303, 0x82FB, 0x82F9, 0x82DE, 0x8306, 0x82DC, 0x8309, 0x82D9, 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, 0x8345, 0x832F, 0x832B, 0x8317, 0x8318, 0x8385, 0x839A, 0x83AA, 0x839F, 0x83A2, 0x8396, 0x8323, 0x838E, 0x8387, 0x838A, 0x837C, 0x83B5, 0x8373, 0x8375, 0x83A0, 0x8389, 0x83A8, 0x83F4, 0x8413, 0x83EB, 0x83CE, 0x83FD, 0x8403, 0x83D8, 0x840B, 0x83C1, 0x83F7, 0x8407, 0x83E0, 0x83F2, 0x840D, 0x8422, 0x8420, 0x83BD, 0x8438, 0x8506, 0x83FB, 0x846D, 0x842A, 0x843C, 0x855A, 0x8484, 0x8477, 0x846B, 0x84AD, 0x846E, 0x8482, 0x8469, 0x8446, 0x842C, 0x846F, 0x8479, 0x8435, 0x84CA, 0x8462, 0x84B9, 0x84BF, 0x849F, 0x84D9, 0x84CD, 0x84BB, 0x84DA, 0x84D0, 0x84C1, 0x84C6, 0x84D6, 0x84A1, 0x8521, 0x84FF, 0x84F4, 0x8517, 0x8518, 0x852C, 0x851F, 0x8515, 0x8514, 0x84FC, 0x8540, 0x8563, 0x8558, 0x8548}, + {0x8541, 0x8602, 0x854B, 0x8555, 0x8580, 0x85A4, 0x8588, 0x8591, 0x858A, 0x85A8, 0x856D, 0x8594, 0x859B, 0x85EA, 0x8587, 0x859C, 0x8577, 0x857E, 0x8590, 0x85C9, 0x85BA, 0x85CF, 0x85B9, 0x85D0, 0x85D5, 0x85DD, 0x85E5, 0x85DC, 0x85F9, 0x860A, 0x8613, 0x860B, 0x85FE, 0x85FA, 0x8606, 0x8622, 0x861A, 0x8630, 0x863F, 0x864D, 0x4E55, 0x8654, 0x865F, 0x8667, 0x8671, 0x8693, 0x86A3, 0x86A9, 0x86AA, 0x868B, 0x868C, 0x86B6, 0x86AF, 0x86C4, 0x86C6, 0x86B0, 0x86C9, 0x8823, 0x86AB, 0x86D4, 0x86DE, 0x86E9, 0x86EC, 0x0000, 0x86DF, 0x86DB, 0x86EF, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86FB, 0x8711, 0x8709, 0x870D, 0x86F9, 0x870A, 0x8734, 0x873F, 0x8737, 0x873B, 0x8725, 0x8729, 0x871A, 0x8760, 0x875F, 0x8778, 0x874C, 0x874E, 0x8774, 0x8757, 0x8768, 0x876E, 0x8759, 0x8753, 0x8763, 0x876A, 0x8805, 0x87A2, 0x879F, 0x8782, 0x87AF, 0x87CB, 0x87BD, 0x87C0, 0x87D0, 0x96D6, 0x87AB, 0x87C4, 0x87B3, 0x87C7, 0x87C6, 0x87BB, 0x87EF, 0x87F2, 0x87E0, 0x880F, 0x880D, 0x87FE, 0x87F6, 0x87F7, 0x880E, 0x87D2, 0x8811, 0x8816, 0x8815, 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883B, 0x8844, 0x8842, 0x8852, 0x8859, 0x885E, 0x8862, 0x886B, 0x8881, 0x887E, 0x889E, 0x8875, 0x887D, 0x88B5, 0x8872, 0x8882, 0x8897, 0x8892, 0x88AE, 0x8899, 0x88A2, 0x888D, 0x88A4, 0x88B0, 0x88BF, 0x88B1, 0x88C3, 0x88C4, 0x88D4, 0x88D8, 0x88D9, 0x88DD, 0x88F9, 0x8902, 0x88FC, 0x88F4, 0x88E8, 0x88F2, 0x8904, 0x890C, 0x890A, 0x8913, 0x8943, 0x891E, 0x8925, 0x892A, 0x892B, 0x8941, 0x8944, 0x893B, 0x8936, 0x8938, 0x894C, 0x891D, 0x8960, 0x895E}, + {0x8966, 0x8964, 0x896D, 0x896A, 0x896F, 0x8974, 0x8977, 0x897E, 0x8983, 0x8988, 0x898A, 0x8993, 0x8998, 0x89A1, 0x89A9, 0x89A6, 0x89AC, 0x89AF, 0x89B2, 0x89BA, 0x89BD, 0x89BF, 0x89C0, 0x89DA, 0x89DC, 0x89DD, 0x89E7, 0x89F4, 0x89F8, 0x8A03, 0x8A16, 0x8A10, 0x8A0C, 0x8A1B, 0x8A1D, 0x8A25, 0x8A36, 0x8A41, 0x8A5B, 0x8A52, 0x8A46, 0x8A48, 0x8A7C, 0x8A6D, 0x8A6C, 0x8A62, 0x8A85, 0x8A82, 0x8A84, 0x8AA8, 0x8AA1, 0x8A91, 0x8AA5, 0x8AA6, 0x8A9A, 0x8AA3, 0x8AC4, 0x8ACD, 0x8AC2, 0x8ADA, 0x8AEB, 0x8AF3, 0x8AE7, 0x0000, 0x8AE4, 0x8AF1, 0x8B14, 0x8AE0, 0x8AE2, 0x8AF7, 0x8ADE, 0x8ADB, 0x8B0C, 0x8B07, 0x8B1A, 0x8AE1, 0x8B16, 0x8B10, 0x8B17, 0x8B20, 0x8B33, 0x97AB, 0x8B26, 0x8B2B, 0x8B3E, 0x8B28, 0x8B41, 0x8B4C, 0x8B4F, 0x8B4E, 0x8B49, 0x8B56, 0x8B5B, 0x8B5A, 0x8B6B, 0x8B5F, 0x8B6C, 0x8B6F, 0x8B74, 0x8B7D, 0x8B80, 0x8B8C, 0x8B8E, 0x8B92, 0x8B93, 0x8B96, 0x8B99, 0x8B9A, 0x8C3A, 0x8C41, 0x8C3F, 0x8C48, 0x8C4C, 0x8C4E, 0x8C50, 0x8C55, 0x8C62, 0x8C6C, 0x8C78, 0x8C7A, 0x8C82, 0x8C89, 0x8C85, 0x8C8A, 0x8C8D, 0x8C8E, 0x8C94, 0x8C7C, 0x8C98, 0x621D, 0x8CAD, 0x8CAA, 0x8CBD, 0x8CB2, 0x8CB3, 0x8CAE, 0x8CB6, 0x8CC8, 0x8CC1, 0x8CE4, 0x8CE3, 0x8CDA, 0x8CFD, 0x8CFA, 0x8CFB, 0x8D04, 0x8D05, 0x8D0A, 0x8D07, 0x8D0F, 0x8D0D, 0x8D10, 0x9F4E, 0x8D13, 0x8CCD, 0x8D14, 0x8D16, 0x8D67, 0x8D6D, 0x8D71, 0x8D73, 0x8D81, 0x8D99, 0x8DC2, 0x8DBE, 0x8DBA, 0x8DCF, 0x8DDA, 0x8DD6, 0x8DCC, 0x8DDB, 0x8DCB, 0x8DEA, 0x8DEB, 0x8DDF, 0x8DE3, 0x8DFC, 0x8E08, 0x8E09, 0x8DFF, 0x8E1D, 0x8E1E, 0x8E10, 0x8E1F, 0x8E42, 0x8E35, 0x8E30, 0x8E34, 0x8E4A}, + {0x8E47, 0x8E49, 0x8E4C, 0x8E50, 0x8E48, 0x8E59, 0x8E64, 0x8E60, 0x8E2A, 0x8E63, 0x8E55, 0x8E76, 0x8E72, 0x8E7C, 0x8E81, 0x8E87, 0x8E85, 0x8E84, 0x8E8B, 0x8E8A, 0x8E93, 0x8E91, 0x8E94, 0x8E99, 0x8EAA, 0x8EA1, 0x8EAC, 0x8EB0, 0x8EC6, 0x8EB1, 0x8EBE, 0x8EC5, 0x8EC8, 0x8ECB, 0x8EDB, 0x8EE3, 0x8EFC, 0x8EFB, 0x8EEB, 0x8EFE, 0x8F0A, 0x8F05, 0x8F15, 0x8F12, 0x8F19, 0x8F13, 0x8F1C, 0x8F1F, 0x8F1B, 0x8F0C, 0x8F26, 0x8F33, 0x8F3B, 0x8F39, 0x8F45, 0x8F42, 0x8F3E, 0x8F4C, 0x8F49, 0x8F46, 0x8F4E, 0x8F57, 0x8F5C, 0x0000, 0x8F62, 0x8F63, 0x8F64, 0x8F9C, 0x8F9F, 0x8FA3, 0x8FAD, 0x8FAF, 0x8FB7, 0x8FDA, 0x8FE5, 0x8FE2, 0x8FEA, 0x8FEF, 0x9087, 0x8FF4, 0x9005, 0x8FF9, 0x8FFA, 0x9011, 0x9015, 0x9021, 0x900D, 0x901E, 0x9016, 0x900B, 0x9027, 0x9036, 0x9035, 0x9039, 0x8FF8, 0x904F, 0x9050, 0x9051, 0x9052, 0x900E, 0x9049, 0x903E, 0x9056, 0x9058, 0x905E, 0x9068, 0x906F, 0x9076, 0x96A8, 0x9072, 0x9082, 0x907D, 0x9081, 0x9080, 0x908A, 0x9089, 0x908F, 0x90A8, 0x90AF, 0x90B1, 0x90B5, 0x90E2, 0x90E4, 0x6248, 0x90DB, 0x9102, 0x9112, 0x9119, 0x9132, 0x9130, 0x914A, 0x9156, 0x9158, 0x9163, 0x9165, 0x9169, 0x9173, 0x9172, 0x918B, 0x9189, 0x9182, 0x91A2, 0x91AB, 0x91AF, 0x91AA, 0x91B5, 0x91B4, 0x91BA, 0x91C0, 0x91C1, 0x91C9, 0x91CB, 0x91D0, 0x91D6, 0x91DF, 0x91E1, 0x91DB, 0x91FC, 0x91F5, 0x91F6, 0x921E, 0x91FF, 0x9214, 0x922C, 0x9215, 0x9211, 0x925E, 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923F, 0x924B, 0x9250, 0x929C, 0x9296, 0x9293, 0x929B, 0x925A, 0x92CF, 0x92B9, 0x92B7, 0x92E9, 0x930F, 0x92FA, 0x9344, 0x932E}, + {0x9319, 0x9322, 0x931A, 0x9323, 0x933A, 0x9335, 0x933B, 0x935C, 0x9360, 0x937C, 0x936E, 0x9356, 0x93B0, 0x93AC, 0x93AD, 0x9394, 0x93B9, 0x93D6, 0x93D7, 0x93E8, 0x93E5, 0x93D8, 0x93C3, 0x93DD, 0x93D0, 0x93C8, 0x93E4, 0x941A, 0x9414, 0x9413, 0x9403, 0x9407, 0x9410, 0x9436, 0x942B, 0x9435, 0x9421, 0x943A, 0x9441, 0x9452, 0x9444, 0x945B, 0x9460, 0x9462, 0x945E, 0x946A, 0x9229, 0x9470, 0x9475, 0x9477, 0x947D, 0x945A, 0x947C, 0x947E, 0x9481, 0x947F, 0x9582, 0x9587, 0x958A, 0x9594, 0x9596, 0x9598, 0x9599, 0x0000, 0x95A0, 0x95A8, 0x95A7, 0x95AD, 0x95BC, 0x95BB, 0x95B9, 0x95BE, 0x95CA, 0x6FF6, 0x95C3, 0x95CD, 0x95CC, 0x95D5, 0x95D4, 0x95D6, 0x95DC, 0x95E1, 0x95E5, 0x95E2, 0x9621, 0x9628, 0x962E, 0x962F, 0x9642, 0x964C, 0x964F, 0x964B, 0x9677, 0x965C, 0x965E, 0x965D, 0x965F, 0x9666, 0x9672, 0x966C, 0x968D, 0x9698, 0x9695, 0x9697, 0x96AA, 0x96A7, 0x96B1, 0x96B2, 0x96B0, 0x96B4, 0x96B6, 0x96B8, 0x96B9, 0x96CE, 0x96CB, 0x96C9, 0x96CD, 0x894D, 0x96DC, 0x970D, 0x96D5, 0x96F9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970E, 0x9711, 0x970F, 0x9716, 0x9719, 0x9724, 0x972A, 0x9730, 0x9739, 0x973D, 0x973E, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975C, 0x9760, 0x9764, 0x9766, 0x9768, 0x52D2, 0x976B, 0x9771, 0x9779, 0x9785, 0x977C, 0x9781, 0x977A, 0x9786, 0x978B, 0x978F, 0x9790, 0x979C, 0x97A8, 0x97A6, 0x97A3, 0x97B3, 0x97B4, 0x97C3, 0x97C6, 0x97C8, 0x97CB, 0x97DC, 0x97ED, 0x9F4F, 0x97F2, 0x7ADF, 0x97F6, 0x97F5, 0x980F, 0x980C, 0x9838, 0x9824, 0x9821, 0x9837, 0x983D, 0x9846, 0x984F, 0x984B, 0x986B, 0x986F, 0x9870}, + {0x9871, 0x9874, 0x9873, 0x98AA, 0x98AF, 0x98B1, 0x98B6, 0x98C4, 0x98C3, 0x98C6, 0x98E9, 0x98EB, 0x9903, 0x9909, 0x9912, 0x9914, 0x9918, 0x9921, 0x991D, 0x991E, 0x9924, 0x9920, 0x992C, 0x992E, 0x993D, 0x993E, 0x9942, 0x9949, 0x9945, 0x9950, 0x994B, 0x9951, 0x9952, 0x994C, 0x9955, 0x9997, 0x9998, 0x99A5, 0x99AD, 0x99AE, 0x99BC, 0x99DF, 0x99DB, 0x99DD, 0x99D8, 0x99D1, 0x99ED, 0x99EE, 0x99F1, 0x99F2, 0x99FB, 0x99F8, 0x9A01, 0x9A0F, 0x9A05, 0x99E2, 0x9A19, 0x9A2B, 0x9A37, 0x9A45, 0x9A42, 0x9A40, 0x9A43, 0x0000, 0x9A3E, 0x9A55, 0x9A4D, 0x9A5B, 0x9A57, 0x9A5F, 0x9A62, 0x9A65, 0x9A64, 0x9A69, 0x9A6B, 0x9A6A, 0x9AAD, 0x9AB0, 0x9ABC, 0x9AC0, 0x9ACF, 0x9AD1, 0x9AD3, 0x9AD4, 0x9ADE, 0x9ADF, 0x9AE2, 0x9AE3, 0x9AE6, 0x9AEF, 0x9AEB, 0x9AEE, 0x9AF4, 0x9AF1, 0x9AF7, 0x9AFB, 0x9B06, 0x9B18, 0x9B1A, 0x9B1F, 0x9B22, 0x9B23, 0x9B25, 0x9B27, 0x9B28, 0x9B29, 0x9B2A, 0x9B2E, 0x9B2F, 0x9B32, 0x9B44, 0x9B43, 0x9B4F, 0x9B4D, 0x9B4E, 0x9B51, 0x9B58, 0x9B74, 0x9B93, 0x9B83, 0x9B91, 0x9B96, 0x9B97, 0x9B9F, 0x9BA0, 0x9BA8, 0x9BB4, 0x9BC0, 0x9BCA, 0x9BB9, 0x9BC6, 0x9BCF, 0x9BD1, 0x9BD2, 0x9BE3, 0x9BE2, 0x9BE4, 0x9BD4, 0x9BE1, 0x9C3A, 0x9BF2, 0x9BF1, 0x9BF0, 0x9C15, 0x9C14, 0x9C09, 0x9C13, 0x9C0C, 0x9C06, 0x9C08, 0x9C12, 0x9C0A, 0x9C04, 0x9C2E, 0x9C1B, 0x9C25, 0x9C24, 0x9C21, 0x9C30, 0x9C47, 0x9C32, 0x9C46, 0x9C3E, 0x9C5A, 0x9C60, 0x9C67, 0x9C76, 0x9C78, 0x9CE7, 0x9CEC, 0x9CF0, 0x9D09, 0x9D08, 0x9CEB, 0x9D03, 0x9D06, 0x9D2A, 0x9D26, 0x9DAF, 0x9D23, 0x9D1F, 0x9D44, 0x9D15, 0x9D12, 0x9D41, 0x9D3F, 0x9D3E, 0x9D46, 0x9D48}, + {0x9D5D, 0x9D5E, 0x9D64, 0x9D51, 0x9D50, 0x9D59, 0x9D72, 0x9D89, 0x9D87, 0x9DAB, 0x9D6F, 0x9D7A, 0x9D9A, 0x9DA4, 0x9DA9, 0x9DB2, 0x9DC4, 0x9DC1, 0x9DBB, 0x9DB8, 0x9DBA, 0x9DC6, 0x9DCF, 0x9DC2, 0x9DD9, 0x9DD3, 0x9DF8, 0x9DE6, 0x9DED, 0x9DEF, 0x9DFD, 0x9E1A, 0x9E1B, 0x9E1E, 0x9E75, 0x9E79, 0x9E7D, 0x9E81, 0x9E88, 0x9E8B, 0x9E8C, 0x9E92, 0x9E95, 0x9E91, 0x9E9D, 0x9EA5, 0x9EA9, 0x9EB8, 0x9EAA, 0x9EAD, 0x9761, 0x9ECC, 0x9ECE, 0x9ECF, 0x9ED0, 0x9ED4, 0x9EDC, 0x9EDE, 0x9EDD, 0x9EE0, 0x9EE5, 0x9EE8, 0x9EEF, 0x0000, 0x9EF4, 0x9EF6, 0x9EF7, 0x9EF9, 0x9EFB, 0x9EFC, 0x9EFD, 0x9F07, 0x9F08, 0x76B7, 0x9F15, 0x9F21, 0x9F2C, 0x9F3E, 0x9F4A, 0x9F52, 0x9F54, 0x9F63, 0x9F5F, 0x9F60, 0x9F61, 0x9F66, 0x9F67, 0x9F6C, 0x9F6A, 0x9F77, 0x9F72, 0x9F76, 0x9F95, 0x9F9C, 0x9FA0, 0x582F, 0x69C7, 0x9059, 0x7464, 0x51DC, 0x7199, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, + {0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631, 0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC, 0x4F00, 0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD, 0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, 0x5094, 0x50F4, 0x50D8, 0x514A, 0x5164, 0x519D, 0x51BE, 0x51EC, 0x5215, 0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF, 0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F, 0x0000, 0xFA10, 0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4, 0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6, 0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, 0x5DB8, 0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7, 0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5, 0x6460, 0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, 0x662E, 0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, 0x6699, 0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766, 0x67BB, 0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14, 0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, 0x6D04, 0x6D87, 0x6D6F, 0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, 0x6DFC, 0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, 0x6FF5, 0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104, 0x715C, 0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1}, + {0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, 0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E, 0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, 0x769B, 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, 0x787A, 0x7930, 0xFA18, 0xFA19, 0xFA1A, 0x7994, 0xFA1B, 0x799B, 0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, 0x7DB7, 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, 0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559, 0x0000, 0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, 0x8A37, 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, 0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24, 0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA, 0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, 0x999E, 0x9A4E, 0x9AD9, 0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0x0000, 0x0000, 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02}, + {0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0xFFE2, 0xFFE4, 0xFF07, 0xFF02, 0x3231, 0x2116, 0x2121, 0x2235, 0x7E8A, 0x891C, 0x9348, 0x9288, 0x84DC, 0x4FC9, 0x70BB, 0x6631, 0x68C8, 0x92F9, 0x66FB, 0x5F45, 0x4E28, 0x4EE1, 0x4EFC, 0x4F00, 0x4F03, 0x4F39, 0x4F56, 0x4F92, 0x4F8A, 0x4F9A, 0x4F94, 0x4FCD, 0x5040, 0x5022, 0x4FFF, 0x501E, 0x5046, 0x5070, 0x5042, 0x5094, 0x50F4, 0x50D8, 0x514A, 0x0000, 0x5164, 0x519D, 0x51BE, 0x51EC, 0x5215, 0x529C, 0x52A6, 0x52C0, 0x52DB, 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53B2, 0x53DD, 0xFA0E, 0x549C, 0x548A, 0x54A9, 0x54FF, 0x5586, 0x5759, 0x5765, 0x57AC, 0x57C8, 0x57C7, 0xFA0F, 0xFA10, 0x589E, 0x58B2, 0x590B, 0x5953, 0x595B, 0x595D, 0x5963, 0x59A4, 0x59BA, 0x5B56, 0x5BC0, 0x752F, 0x5BD8, 0x5BEC, 0x5C1E, 0x5CA6, 0x5CBA, 0x5CF5, 0x5D27, 0x5D53, 0xFA11, 0x5D42, 0x5D6D, 0x5DB8, 0x5DB9, 0x5DD0, 0x5F21, 0x5F34, 0x5F67, 0x5FB7, 0x5FDE, 0x605D, 0x6085, 0x608A, 0x60DE, 0x60D5, 0x6120, 0x60F2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62A6, 0x63F5, 0x6460, 0x649D, 0x64CE, 0x654E, 0x6600, 0x6615, 0x663B, 0x6609, 0x662E, 0x661E, 0x6624, 0x6665, 0x6657, 0x6659, 0xFA12, 0x6673, 0x6699, 0x66A0, 0x66B2, 0x66BF, 0x66FA, 0x670E, 0xF929, 0x6766, 0x67BB, 0x6852, 0x67C0, 0x6801, 0x6844, 0x68CF, 0xFA13, 0x6968, 0xFA14, 0x6998, 0x69E2, 0x6A30, 0x6A6B, 0x6A46, 0x6A73, 0x6A7E, 0x6AE2, 0x6AE4, 0x6BD6, 0x6C3F, 0x6C5C, 0x6C86, 0x6C6F, 0x6CDA, 0x6D04, 0x6D87, 0x6D6F}, + {0x6D96, 0x6DAC, 0x6DCF, 0x6DF8, 0x6DF2, 0x6DFC, 0x6E39, 0x6E5C, 0x6E27, 0x6E3C, 0x6EBF, 0x6F88, 0x6FB5, 0x6FF5, 0x7005, 0x7007, 0x7028, 0x7085, 0x70AB, 0x710F, 0x7104, 0x715C, 0x7146, 0x7147, 0xFA15, 0x71C1, 0x71FE, 0x72B1, 0x72BE, 0x7324, 0xFA16, 0x7377, 0x73BD, 0x73C9, 0x73D6, 0x73E3, 0x73D2, 0x7407, 0x73F5, 0x7426, 0x742A, 0x7429, 0x742E, 0x7462, 0x7489, 0x749F, 0x7501, 0x756F, 0x7682, 0x769C, 0x769E, 0x769B, 0x76A6, 0xFA17, 0x7746, 0x52AF, 0x7821, 0x784E, 0x7864, 0x787A, 0x7930, 0xFA18, 0xFA19, 0x0000, 0xFA1A, 0x7994, 0xFA1B, 0x799B, 0x7AD1, 0x7AE7, 0xFA1C, 0x7AEB, 0x7B9E, 0xFA1D, 0x7D48, 0x7D5C, 0x7DB7, 0x7DA0, 0x7DD6, 0x7E52, 0x7F47, 0x7FA1, 0xFA1E, 0x8301, 0x8362, 0x837F, 0x83C7, 0x83F6, 0x8448, 0x84B4, 0x8553, 0x8559, 0x856B, 0xFA1F, 0x85B0, 0xFA20, 0xFA21, 0x8807, 0x88F5, 0x8A12, 0x8A37, 0x8A79, 0x8AA7, 0x8ABE, 0x8ADF, 0xFA22, 0x8AF6, 0x8B53, 0x8B7F, 0x8CF0, 0x8CF4, 0x8D12, 0x8D76, 0xFA23, 0x8ECF, 0xFA24, 0xFA25, 0x9067, 0x90DE, 0xFA26, 0x9115, 0x9127, 0x91DA, 0x91D7, 0x91DE, 0x91ED, 0x91EE, 0x91E4, 0x91E5, 0x9206, 0x9210, 0x920A, 0x923A, 0x9240, 0x923C, 0x924E, 0x9259, 0x9251, 0x9239, 0x9267, 0x92A7, 0x9277, 0x9278, 0x92E7, 0x92D7, 0x92D9, 0x92D0, 0xFA27, 0x92D5, 0x92E0, 0x92D3, 0x9325, 0x9321, 0x92FB, 0xFA28, 0x931E, 0x92FF, 0x931D, 0x9302, 0x9370, 0x9357, 0x93A4, 0x93C6, 0x93DE, 0x93F8, 0x9431, 0x9445, 0x9448, 0x9592, 0xF9DC, 0xFA29, 0x969D, 0x96AF, 0x9733, 0x973B, 0x9743, 0x974D, 0x974F, 0x9751, 0x9755, 0x9857, 0x9865, 0xFA2A, 0xFA2B, 0x9927, 0xFA2C, 0x999E, 0x9A4E, 0x9AD9}, + {0x9ADC, 0x9B75, 0x9B72, 0x9B8F, 0x9BB1, 0x9BBB, 0x9C00, 0x9D70, 0x9D6B, 0xFA2D, 0x9E19, 0x9ED1, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000} +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_detach.h b/include/revolution/VF/pf_detach.h new file mode 100644 index 00000000..7dc91551 --- /dev/null +++ b/include/revolution/VF/pf_detach.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_DETACH_H +#define RVL_SDK_VF_PF_DETACH_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_dir.h b/include/revolution/VF/pf_dir.h new file mode 100644 index 00000000..6d3f02b7 --- /dev/null +++ b/include/revolution/VF/pf_dir.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_DIR_H +#define RVL_SDK_VF_PF_DIR_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_driver.h b/include/revolution/VF/pf_driver.h new file mode 100644 index 00000000..332167f5 --- /dev/null +++ b/include/revolution/VF/pf_driver.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_DRIVER_H +#define RVL_SDK_VF_PF_DRIVER_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_entry.h b/include/revolution/VF/pf_entry.h new file mode 100644 index 00000000..eeb95af6 --- /dev/null +++ b/include/revolution/VF/pf_entry.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_ENTRY_H +#define RVL_SDK_VF_PF_ENTRY_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_entry_iterator.h b/include/revolution/VF/pf_entry_iterator.h new file mode 100644 index 00000000..de4c1e16 --- /dev/null +++ b/include/revolution/VF/pf_entry_iterator.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_ENTRY_ITERATOR_H +#define RVL_SDK_VF_PF_ENTRY_ITERATOR_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_errnum.h b/include/revolution/VF/pf_errnum.h new file mode 100644 index 00000000..21630a6e --- /dev/null +++ b/include/revolution/VF/pf_errnum.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_ERRNUM_H +#define RVL_SDK_VF_PF_ERRNUM_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fat.h b/include/revolution/VF/pf_fat.h new file mode 100644 index 00000000..f6c8c813 --- /dev/null +++ b/include/revolution/VF/pf_fat.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FAT_H +#define RVL_SDK_VF_PF_FAT_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fat12.h b/include/revolution/VF/pf_fat12.h new file mode 100644 index 00000000..25875106 --- /dev/null +++ b/include/revolution/VF/pf_fat12.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FAT12_H +#define RVL_SDK_VF_PF_FAT12_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fat16.h b/include/revolution/VF/pf_fat16.h new file mode 100644 index 00000000..176734e7 --- /dev/null +++ b/include/revolution/VF/pf_fat16.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FAT16_H +#define RVL_SDK_VF_PF_FAT16_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fat32.h b/include/revolution/VF/pf_fat32.h new file mode 100644 index 00000000..550a8157 --- /dev/null +++ b/include/revolution/VF/pf_fat32.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FAT32_H +#define RVL_SDK_VF_PF_FAT32_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fatfs.h b/include/revolution/VF/pf_fatfs.h new file mode 100644 index 00000000..463b3fd9 --- /dev/null +++ b/include/revolution/VF/pf_fatfs.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FATFS_H +#define RVL_SDK_VF_PF_FATFS_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fclose.h b/include/revolution/VF/pf_fclose.h new file mode 100644 index 00000000..653df159 --- /dev/null +++ b/include/revolution/VF/pf_fclose.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FCLOSE_H +#define RVL_SDK_VF_PF_FCLOSE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_file.h b/include/revolution/VF/pf_file.h new file mode 100644 index 00000000..70b13c4c --- /dev/null +++ b/include/revolution/VF/pf_file.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FILE_H +#define RVL_SDK_VF_PF_FILE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_filelock.h b/include/revolution/VF/pf_filelock.h new file mode 100644 index 00000000..3284f16f --- /dev/null +++ b/include/revolution/VF/pf_filelock.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FILELOCK_H +#define RVL_SDK_VF_PF_FILELOCK_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_finfo.h b/include/revolution/VF/pf_finfo.h new file mode 100644 index 00000000..437fd1d8 --- /dev/null +++ b/include/revolution/VF/pf_finfo.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FINFO_H +#define RVL_SDK_VF_PF_FINFO_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fopen.h b/include/revolution/VF/pf_fopen.h new file mode 100644 index 00000000..bc1f10da --- /dev/null +++ b/include/revolution/VF/pf_fopen.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FOPEN_H +#define RVL_SDK_VF_PF_FOPEN_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fread.h b/include/revolution/VF/pf_fread.h new file mode 100644 index 00000000..787f1d06 --- /dev/null +++ b/include/revolution/VF/pf_fread.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FREAD_H +#define RVL_SDK_VF_PF_FREAD_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fseek.h b/include/revolution/VF/pf_fseek.h new file mode 100644 index 00000000..dfda5060 --- /dev/null +++ b/include/revolution/VF/pf_fseek.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FSEEK_H +#define RVL_SDK_VF_PF_FSEEK_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_fwrite.h b/include/revolution/VF/pf_fwrite.h new file mode 100644 index 00000000..5713ce4b --- /dev/null +++ b/include/revolution/VF/pf_fwrite.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_FWRITE_H +#define RVL_SDK_VF_PF_FWRITE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_getdev.h b/include/revolution/VF/pf_getdev.h new file mode 100644 index 00000000..768d9f53 --- /dev/null +++ b/include/revolution/VF/pf_getdev.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_GETDEV_H +#define RVL_SDK_VF_PF_GETDEV_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_init_prfile2.h b/include/revolution/VF/pf_init_prfile2.h new file mode 100644 index 00000000..9fa97298 --- /dev/null +++ b/include/revolution/VF/pf_init_prfile2.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_INIT_PRFILE2_H +#define RVL_SDK_VF_PF_INIT_PRFILE2_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_path.h b/include/revolution/VF/pf_path.h new file mode 100644 index 00000000..3402fc30 --- /dev/null +++ b/include/revolution/VF/pf_path.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_PATH_H +#define RVL_SDK_VF_PF_PATH_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_remove.h b/include/revolution/VF/pf_remove.h new file mode 100644 index 00000000..cb7f041c --- /dev/null +++ b/include/revolution/VF/pf_remove.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_REMOVE_H +#define RVL_SDK_VF_PF_REMOVE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_sector.h b/include/revolution/VF/pf_sector.h new file mode 100644 index 00000000..eab3ad0a --- /dev/null +++ b/include/revolution/VF/pf_sector.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_SECTOR_H +#define RVL_SDK_VF_PF_SECTOR_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_service.h b/include/revolution/VF/pf_service.h new file mode 100644 index 00000000..dd8c5c84 --- /dev/null +++ b/include/revolution/VF/pf_service.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_SERVICE_H +#define RVL_SDK_VF_PF_SERVICE_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_str.h b/include/revolution/VF/pf_str.h new file mode 100644 index 00000000..8342e203 --- /dev/null +++ b/include/revolution/VF/pf_str.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_STR_H +#define RVL_SDK_VF_PF_STR_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_system.h b/include/revolution/VF/pf_system.h new file mode 100644 index 00000000..9359aab6 --- /dev/null +++ b/include/revolution/VF/pf_system.h @@ -0,0 +1,24 @@ +#ifndef RVL_SDK_VF_PF_SYSTEM_H +#define RVL_SDK_VF_PF_SYSTEM_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PFDATE { + /* 0x00 */ u16 year; + /* 0x02 */ u16 month; + /* 0x04 */ u16 day; +} PFDATE; + +typedef struct PFTIME { + /* 0x00 */ u16 hour; + /* 0x02 */ u16 minute; + /* 0x04 */ u16 second; + /* 0x06 */ u16 millisecond; +} PFTIME; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_unmount.h b/include/revolution/VF/pf_unmount.h new file mode 100644 index 00000000..fc4fe7d0 --- /dev/null +++ b/include/revolution/VF/pf_unmount.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_UNMOUNT_H +#define RVL_SDK_VF_PF_UNMOUNT_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_volume.h b/include/revolution/VF/pf_volume.h new file mode 100644 index 00000000..49a6e815 --- /dev/null +++ b/include/revolution/VF/pf_volume.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_VOLUME_H +#define RVL_SDK_VF_PF_VOLUME_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/pf_w_clib.h b/include/revolution/VF/pf_w_clib.h new file mode 100644 index 00000000..4dc85aa2 --- /dev/null +++ b/include/revolution/VF/pf_w_clib.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_PF_W_CLIB_H +#define RVL_SDK_VF_PF_W_CLIB_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/sd_drv.h b/include/revolution/VF/sd_drv.h new file mode 100644 index 00000000..9c78c13a --- /dev/null +++ b/include/revolution/VF/sd_drv.h @@ -0,0 +1,13 @@ +#ifndef RVL_SDK_VF_SD_DRV_H +#define RVL_SDK_VF_SD_DRV_H +#include +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/include/revolution/VF/vf_struct.h b/include/revolution/VF/vf_struct.h new file mode 100644 index 00000000..2ab7c379 --- /dev/null +++ b/include/revolution/VF/vf_struct.h @@ -0,0 +1,546 @@ +#ifndef RVL_SDK_VF_VF_STRUCT_H +#define RVL_SDK_VF_VF_STRUCT_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PF_CURSOR { + // total size: 0x10 + unsigned long position; // offset 0x0, size 0x4 + unsigned long sector; // offset 0x4, size 0x4 + unsigned long file_sector_index; // offset 0x8, size 0x4 + unsigned short offset_in_sector; // offset 0xC, size 0x2 +} PF_CURSOR; + +typedef struct PF_BPB { + // total size: 0x38 + unsigned short bytes_per_sector; // offset 0x0, size 0x2 + unsigned short num_reserved_sectors; // offset 0x2, size 0x2 + unsigned short num_root_dir_entries; // offset 0x4, size 0x2 + unsigned char sectors_per_cluster; // offset 0x6, size 0x1 + unsigned char num_FATs; // offset 0x7, size 0x1 + unsigned long total_sectors; // offset 0x8, size 0x4 + unsigned long sectors_per_FAT; // offset 0xC, size 0x4 + unsigned long root_dir_cluster; // offset 0x10, size 0x4 + unsigned short fs_info_sector; // offset 0x14, size 0x2 + unsigned short backup_boot_sector; // offset 0x16, size 0x2 + unsigned short ext_flags; // offset 0x18, size 0x2 + unsigned char media; // offset 0x1A, size 0x1 + enum /* @enum$142pf_volume_c */ { + FAT_12 = 0, + FAT_16 = 1, + FAT_32 = 2, + FAT_ERR = -1, + } fat_type; // offset 0x1C, size 0x4 + unsigned char log2_bytes_per_sector; // offset 0x20, size 0x1 + unsigned char log2_sectors_per_cluster; // offset 0x21, size 0x1 + unsigned char num_active_FATs; // offset 0x22, size 0x1 + unsigned short num_root_dir_sectors; // offset 0x24, size 0x2 + unsigned long active_FAT_sector; // offset 0x28, size 0x4 + unsigned long first_root_dir_sector; // offset 0x2C, size 0x4 + unsigned long first_data_sector; // offset 0x30, size 0x4 + unsigned long num_clusters; // offset 0x34, size 0x4 +} PF_BPB; + +typedef struct PDM_BPB { + // total size: 0x70 + unsigned char oem_name[8]; // offset 0x0, size 0x8 + unsigned short bytes_per_sector; // offset 0x8, size 0x2 + unsigned char sectors_per_cluster; // offset 0xA, size 0x1 + unsigned char num_FATs; // offset 0xB, size 0x1 + unsigned short num_reserved_sectors; // offset 0xC, size 0x2 + unsigned short num_root_dir_entries; // offset 0xE, size 0x2 + unsigned short total_sectors16; // offset 0x10, size 0x2 + unsigned short sectors_per_FAT16; // offset 0x12, size 0x2 + unsigned short sector_per_track; // offset 0x14, size 0x2 + unsigned long num_hidden_sectors; // offset 0x18, size 0x4 + unsigned long total_sectors32; // offset 0x1C, size 0x4 + unsigned short num_heads; // offset 0x20, size 0x2 + unsigned char media; // offset 0x22, size 0x1 + unsigned char drive; // offset 0x23, size 0x1 + unsigned long vol_id; // offset 0x24, size 0x4 + unsigned char boot_sig; // offset 0x28, size 0x1 + unsigned char vol_label[11]; // offset 0x29, size 0xB + unsigned char fs_type[8]; // offset 0x34, size 0x8 + unsigned long sectors_per_FAT32; // offset 0x3C, size 0x4 + unsigned short ext_flags; // offset 0x40, size 0x2 + unsigned short fs_version; // offset 0x42, size 0x2 + unsigned long root_dir_cluster; // offset 0x44, size 0x4 + unsigned short fs_info_sector; // offset 0x48, size 0x2 + unsigned short backup_boot_sector; // offset 0x4A, size 0x2 + unsigned char jump_boot[3]; // offset 0x4C, size 0x3 + unsigned char num_active_FATs; // offset 0x4F, size 0x1 + enum /* @enum$52pdm_bpb_c */ { + PDM_FAT_12 = 0, + PDM_FAT_16 = 1, + PDM_FAT_32 = 2, + PDM_FAT_ERR = -1, + } fat_type; // offset 0x50, size 0x4 + unsigned char log2_bytes_per_sector; // offset 0x54, size 0x1 + unsigned char log2_sectors_per_cluster; // offset 0x55, size 0x1 + unsigned short num_root_dir_sectors; // offset 0x56, size 0x2 + unsigned long active_FAT_sector; // offset 0x58, size 0x4 + unsigned long first_root_dir_sector; // offset 0x5C, size 0x4 + unsigned long first_data_sector; // offset 0x60, size 0x4 + unsigned long num_clusters; // offset 0x64, size 0x4 + unsigned long total_sectors; // offset 0x68, size 0x4 + unsigned long sectors_per_FAT; // offset 0x6C, size 0x4 +} PDM_BPB; + +typedef struct PDM_PARTITION { + // total size: 0x2C + unsigned long status; // offset 0x0, size 0x4 + struct PDM_DISK* p_disk; // offset 0x4, size 0x4 + unsigned long signature; // offset 0x8, size 0x4 + unsigned short part_id; // offset 0xC, size 0x2 + unsigned short open_part_cnt; // offset 0xE, size 0x2 + struct PDM_PARTITION* part_lock_handle; // offset 0x10, size 0x4 + unsigned long start_sector; // offset 0x14, size 0x4 + unsigned long total_sector; // offset 0x18, size 0x4 + unsigned long mbr_sector; // offset 0x1C, size 0x4 + unsigned char partition_type; // offset 0x20, size 0x1 + long driver_last_error; // offset 0x24, size 0x4 + void* p_vol; // offset 0x28, size 0x4 +} PDM_PARTITION; + +typedef struct PDM_FSINFO { + // total size: 0x8 + unsigned long free_count; // offset 0x0, size 0x4 + unsigned long next_free; // offset 0x4, size 0x4 +} PDM_FSINFO; + +typedef struct PDM_DISK_INFO { + // total size: 0x14 + unsigned long total_sectors; // offset 0x0, size 0x4 + unsigned short cylinders; // offset 0x4, size 0x2 + unsigned char heads; // offset 0x6, size 0x1 + unsigned char sectors_per_track; // offset 0x7, size 0x1 + unsigned short bytes_per_sector; // offset 0x8, size 0x2 + unsigned long media_attr; // offset 0xC, size 0x4 + void* format_param; // offset 0x10, size 0x4 +} PDM_DISK_INFO; + +struct PF_LAST_CLUSTER { + // total size: 0x8 + unsigned long num_last_cluster; // offset 0x0, size 0x4 + unsigned long max_chain_index; // offset 0x4, size 0x4 +}; + +struct PF_FAT_LAST_ACCESS { + // total size: 0x8 + unsigned long chain_index; // offset 0x0, size 0x4 + unsigned long cluster; // offset 0x4, size 0x4 +}; + +typedef struct PF_DIR_ENT { + // total size: 0x240 + unsigned short long_name[261]; // offset 0x0, size 0x20A + unsigned char num_entry_LFNs; // offset 0x20A, size 0x1 + unsigned char ordinal; // offset 0x20B, size 0x1 + unsigned char check_sum; // offset 0x20C, size 0x1 + unsigned char align_pad[1]; // offset 0x20D, size 0x1 + signed char short_name[13]; // offset 0x20E, size 0xD + unsigned char small_letter_flag; // offset 0x21B, size 0x1 + unsigned char attr; // offset 0x21C, size 0x1 + unsigned char create_time_ms; // offset 0x21D, size 0x1 + unsigned short create_time; // offset 0x21E, size 0x2 + unsigned short create_date; // offset 0x220, size 0x2 + unsigned short access_date; // offset 0x222, size 0x2 + unsigned short modify_time; // offset 0x224, size 0x2 + unsigned short modify_date; // offset 0x226, size 0x2 + unsigned long file_size; // offset 0x228, size 0x4 + struct PF_VOLUME* p_vol; // offset 0x22C, size 0x4 + unsigned long path_len; // offset 0x230, size 0x4 + unsigned long start_cluster; // offset 0x234, size 0x4 + unsigned long entry_sector; // offset 0x238, size 0x4 + unsigned short entry_offset; // offset 0x23C, size 0x2 +} PF_DIR_ENT; + +typedef struct PF_FAT_HINT { + // total size: 0xC + unsigned long chain_index; // offset 0x0, size 0x4 + unsigned long cluster; // offset 0x4, size 0x4 + unsigned long file_version; // offset 0x8, size 0x4 +} PF_FAT_HINT; + +struct PF_CLUSTER_LINK { + // total size: 0x14 + unsigned long* buffer; // offset 0x0, size 0x4 + unsigned short interval; // offset 0x4, size 0x2 + unsigned short interval_offset; // offset 0x6, size 0x2 + unsigned long position; // offset 0x8, size 0x4 + unsigned long max_count; // offset 0xC, size 0x4 + unsigned long save_index; // offset 0x10, size 0x4 +}; + +typedef struct PF_FFD { + // total size: 0x38 + unsigned long file_version; // offset 0x0, size 0x4 + unsigned long start_cluster; // offset 0x4, size 0x4 + unsigned long* p_start_cluster; // offset 0x8, size 0x4 + struct PF_LAST_CLUSTER last_cluster; // offset 0xC, size 0x8 + struct PF_FAT_LAST_ACCESS last_access_cluster; // offset 0x14, size 0x8 + struct PF_CLUSTER_LINK cluster_link; // offset 0x1C, size 0x14 + struct PF_FAT_HINT* p_hint; // offset 0x30, size 0x4 + struct PF_VOLUME* p_vol; // offset 0x34, size 0x4 +} PF_FFD; + +typedef struct PF_SDD { + // total size: 0x280 + unsigned long stat; // offset 0x0, size 0x4 + unsigned short num_handlers; // offset 0x4, size 0x2 + struct PF_FFD ffd; // offset 0x8, size 0x38 + struct PF_DIR_ENT dir_entry; // offset 0x40, size 0x240 +} PF_SDD; + +struct PF_DIR_CURSOR { + // total size: 0xC + unsigned long physical_entry_index; // offset 0x0, size 0x4 + unsigned long logical_entry_index; // offset 0x4, size 0x4 + unsigned long logical_seek_index; // offset 0x8, size 0x4 +}; + +typedef struct PF_DIR { + // total size: 0x20 + unsigned long stat; // offset 0x0, size 0x4 + struct PF_SDD* p_sdd; // offset 0x4, size 0x4 + struct PF_FAT_HINT hint; // offset 0x8, size 0xC + struct PF_DIR_CURSOR cursor; // offset 0x14, size 0xC +} PF_DIR; + +typedef struct PF_CACHE_PAGE { + // total size: 0x28 + unsigned short stat; // offset 0x0, size 0x2 + unsigned short option; // offset 0x2, size 0x2 + unsigned char* buffer; // offset 0x4, size 0x4 + unsigned char* p_buf; // offset 0x8, size 0x4 + unsigned char* p_mod_sbuf; // offset 0xC, size 0x4 + unsigned char* p_mod_ebuf; // offset 0x10, size 0x4 + unsigned long size; // offset 0x14, size 0x4 + unsigned long sector; // offset 0x18, size 0x4 + void* signature; // offset 0x1C, size 0x4 + struct PF_CACHE_PAGE* p_next; // offset 0x20, size 0x4 + struct PF_CACHE_PAGE* p_prev; // offset 0x24, size 0x4 +} PF_CACHE_PAGE; + +struct PF_SECTOR_CACHE { + // total size: 0x24 + unsigned long mode; // offset 0x0, size 0x4 + unsigned short num_fat_pages; // offset 0x4, size 0x2 + unsigned short num_data_pages; // offset 0x6, size 0x2 + struct PF_CACHE_PAGE* pages; // offset 0x8, size 0x4 + struct PF_CACHE_PAGE* p_current_fat; // offset 0xC, size 0x4 + struct PF_CACHE_PAGE* p_current_data; // offset 0x10, size 0x4 + unsigned char (*buffers)[512]; // offset 0x14, size 0x4 + unsigned long fat_buff_size; // offset 0x18, size 0x4 + unsigned long data_buff_size; // offset 0x1C, size 0x4 + void* signature; // offset 0x20, size 0x4 +}; + +typedef struct PF_CUR_DIR { + // total size: 0x248 + unsigned long stat; // offset 0x0, size 0x4 + long context_id; // offset 0x4, size 0x4 + struct PF_DIR_ENT directory; // offset 0x8, size 0x240 +} PF_CUR_DIR; + +struct PF_DIR_TAIL { + // total size: 0xC + unsigned long tracker_size; // offset 0x0, size 0x4 + unsigned long tracker_buff[1]; // offset 0x4, size 0x4 + unsigned long* tracker_bits; // offset 0x8, size 0x4 +}; + +typedef struct PF_CLUSTER_LINK_VOL { + // total size: 0xC + unsigned short flag; // offset 0x0, size 0x2 + unsigned short interval; // offset 0x2, size 0x2 + unsigned long* buffer; // offset 0x4, size 0x4 + unsigned long link_max; // offset 0x8, size 0x4 +} PF_CLUSTER_LINK_VOL; + +typedef struct PF_FILE { + // total size: 0x30 + unsigned long stat; // offset 0x0, size 0x4 + long open_mode; // offset 0x4, size 0x4 + struct PF_SFD* p_sfd; // offset 0x8, size 0x4 + struct PF_FAT_HINT hint; // offset 0xC, size 0xC + long last_error; // offset 0x18, size 0x4 + struct PF_CURSOR cursor; // offset 0x1C, size 0x10 + unsigned short lock_count; // offset 0x2C, size 0x2 +} PF_FILE; + +typedef struct PF_INFO { + // total size: 0x20 + unsigned long file_size; // offset 0x0, size 0x4 + unsigned long io_pointer; // offset 0x4, size 0x4 + unsigned long empty_size; // offset 0x8, size 0x4 + unsigned long allocated_size; // offset 0xC, size 0x4 + unsigned long lock_mode; // offset 0x10, size 0x4 + struct PF_FILE* lock_owner; // offset 0x14, size 0x4 + unsigned long lock_count; // offset 0x18, size 0x4 + unsigned long lock_tcount; // offset 0x1C, size 0x4 +} PF_INFO; + +typedef struct PF_LOCK { + // total size: 0x10 + unsigned short mode; // offset 0x0, size 0x2 + unsigned short count; // offset 0x2, size 0x2 + unsigned long wcount; // offset 0x4, size 0x4 + struct PF_FILE* owner; // offset 0x8, size 0x4 + long resource; // offset 0xC, size 0x4 +} PF_LOCK; + +typedef struct PF_SFD { + // total size: 0x290 + unsigned long stat; // offset 0x0, size 0x4 + struct PF_FFD ffd; // offset 0x4, size 0x38 + struct PF_DIR_ENT dir_entry; // offset 0x3C, size 0x240 + struct PF_LOCK lock; // offset 0x27C, size 0x10 + unsigned short num_handlers; // offset 0x28C, size 0x2 +} PF_SFD; + +typedef struct PF_VOLUME { + // total size: 0x1898 + struct PF_BPB bpb; // offset 0x0, size 0x38 + unsigned long num_free_clusters; // offset 0x38, size 0x4 + unsigned long last_free_cluster; // offset 0x3C, size 0x4 + struct PF_SFD sfds[5]; // offset 0x40, size 0xCD0 + struct PF_FILE ufds[5]; // offset 0xD10, size 0xF0 + struct PF_SDD sdds[3]; // offset 0xE00, size 0x780 + struct PF_DIR udds[3]; // offset 0x1580, size 0x60 + long num_opened_files; // offset 0x15E0, size 0x4 + long num_opened_directories; // offset 0x15E4, size 0x4 + struct PF_SECTOR_CACHE cache; // offset 0x15E8, size 0x24 + signed char label[12]; // offset 0x160C, size 0xC + struct PF_CUR_DIR current_dir[1]; // offset 0x1618, size 0x248 + struct PF_DIR_TAIL tail_entry; // offset 0x1860, size 0xC + long last_error; // offset 0x186C, size 0x4 + long last_driver_error; // offset 0x1870, size 0x4 + unsigned long file_config; // offset 0x1874, size 0x4 + unsigned short flags; // offset 0x1878, size 0x2 + signed char drv_char; // offset 0x187A, size 0x1 + unsigned short fsi_flag; // offset 0x187C, size 0x2 + struct PF_CLUSTER_LINK_VOL cluster_link; // offset 0x1880, size 0xC + void* p_part; // offset 0x188C, size 0x4 + void (* p_callback)(); // offset 0x1890, size 0x4 + const unsigned char* format_param; // offset 0x1894, size 0x4 +} PF_VOLUME; + +struct PF_CUR_VOLUME { + // total size: 0xC + unsigned long stat; // offset 0x0, size 0x4 + long context_id; // offset 0x4, size 0x4 + struct PF_VOLUME* p_vol; // offset 0x8, size 0x4 +}; + +struct PF_CONTEXT { + // total size: 0x8 + unsigned long stat; // offset 0x0, size 0x4 + long context_id; // offset 0x4, size 0x4 +}; + +typedef struct PF_CHARCODE { + // total size: 0x18 + s32 (*oem2unicode)(const s8*, u16*); // offset 0x0, size 0x4 + s32 (*unicode2oem)(const u16*, s8*); // offset 0x4, size 0x4 + s32 (*oem_char_width)(const s8*); // offset 0x8, size 0x4 + u32 (*is_oem_mb_char)(const s8, u32); // offset 0xC, size 0x4 + s32 (*unicode_char_width)(const u16*); // offset 0x10, size 0x4 + u32 (*is_unicode_mb_char)(u16, u32); // offset 0x14, size 0x4 +} PF_CHARCODE; + +typedef struct PF_VOLUME_SET { + // total size: 0x27FB8 + struct PF_CUR_VOLUME current_vol[1]; // offset 0x0, size 0xC + long num_attached_drives; // offset 0xC, size 0x4 + long num_mounted_volumes; // offset 0x10, size 0x4 + unsigned long config; // offset 0x14, size 0x4 + void* param; // offset 0x18, size 0x4 + long last_error; // offset 0x1C, size 0x4 + long last_driver_error; // offset 0x20, size 0x4 + struct PF_CHARCODE codeset; // offset 0x24, size 0x18 + unsigned long setting; // offset 0x3C, size 0x4 + struct PF_CONTEXT context[1]; // offset 0x40, size 0x8 + struct PF_VOLUME volumes[26]; // offset 0x48, size 0x27F70 +} PF_VOLUME_SET; + +typedef struct PF_CACHE_SETTING { + // total size: 0x14 + struct PF_CACHE_PAGE* pages; // offset 0x0, size 0x4 + unsigned char (*buffers)[512]; // offset 0x4, size 0x4 + unsigned short num_fat_pages; // offset 0x8, size 0x2 + unsigned short num_data_pages; // offset 0xA, size 0x2 + unsigned long num_fat_buf_size; // offset 0xC, size 0x4 + unsigned long num_data_buf_size; // offset 0x10, size 0x4 +} PF_CACHE_SETTING; + +typedef struct PF_DRV_TBL { + // total size: 0xC + void* p_part; // offset 0x0, size 0x4 + struct PF_CACHE_SETTING* cache; // offset 0x4, size 0x4 + signed char drive; // offset 0x8, size 0x1 + unsigned char stat; // offset 0x9, size 0x1 +} PF_DRV_TBL; + +typedef struct PF_DEV_INF { + // total size: 0x10 + unsigned long cls; // offset 0x0, size 0x4 + unsigned long ecl; // offset 0x4, size 0x4 + unsigned long bps; // offset 0x8, size 0x4 + unsigned long spc; // offset 0xC, size 0x4 +} PF_DEV_INF; + +typedef struct PF_STR { + // total size: 0x10 + const signed char* p_head; // offset 0x0, size 0x4 + const signed char* p_tail; // offset 0x4, size 0x4 + const signed char* p_local; // offset 0x8, size 0x4 + unsigned long code_mode; // offset 0xC, size 0x4 +} PF_STR; + +typedef struct PF_SYS_DATE { + // total size: 0x6 + unsigned short sys_year; // offset 0x0, size 0x2 + unsigned short sys_month; // offset 0x2, size 0x2 + unsigned short sys_day; // offset 0x4, size 0x2 +} PF_SYS_DATE; + +typedef struct PF_SYS_TIME { + // total size: 0x8 + unsigned short sys_hour; // offset 0x0, size 0x2 + unsigned short sys_min; // offset 0x2, size 0x2 + unsigned short sys_sec; // offset 0x4, size 0x2 + unsigned short sys_ms; // offset 0x6, size 0x2 +} PF_SYS_TIME; + +typedef struct PF_ENT_ITER { + // total size: 0x70 + unsigned long index; // offset 0x0, size 0x4 + struct PF_VOLUME* p_vol; // offset 0x4, size 0x4 + struct PF_FFD ffd; // offset 0x8, size 0x38 + unsigned long file_sector_index; // offset 0x40, size 0x4 + unsigned long sector; // offset 0x44, size 0x4 + unsigned short offset; // offset 0x48, size 0x2 + unsigned short offset_mask; // offset 0x4A, size 0x2 + unsigned char buf[32]; // offset 0x4C, size 0x20 + unsigned char log2_entries_per_sector; // offset 0x6C, size 0x1 +} PF_ENT_ITER; + +typedef struct PF_FILE_NAME_ITER { + // total size: 0x10 + const signed char* buf; // offset 0x0, size 0x4 + unsigned long dot_inserted; // offset 0x4, size 0x4 + unsigned long is_long_name; // offset 0x8, size 0x4 + unsigned short index; // offset 0xC, size 0x2 +} PF_FILE_NAME_ITER; + +typedef struct PF_SYSTEM_SET { + // total size: 0x4 + unsigned long flock_count; // offset 0x0, size 0x4 +} PF_SYSTEM_SET; + +typedef struct VFSysTime { + // total size: 0x18 + long sec; // offset 0x0, size 0x4 + long min; // offset 0x4, size 0x4 + long hour; // offset 0x8, size 0x4 + long day; // offset 0xC, size 0x4 + long month; // offset 0x10, size 0x4 + long year; // offset 0x14, size 0x4 +} VFSysTime; + +struct PDM_FUNCTBL { + // total size: 0x20 + long (*init)(struct PDM_DISK*); // offset 0x0, size 0x4 + long (*finalize)(struct PDM_DISK*); // offset 0x4, size 0x4 + long (*mount)(struct PDM_DISK*); // offset 0x8, size 0x4 + long (*unmount)(struct PDM_DISK*); // offset 0xC, size 0x4 + long (*format)(struct PDM_DISK*, unsigned char*); // offset 0x10, size 0x4 + long (*physical_read)(struct PDM_DISK*, unsigned char*, unsigned long, unsigned long, unsigned long*); // offset 0x14, size 0x4 + long (*physical_write)(struct PDM_DISK*, unsigned char*, unsigned long, unsigned long, unsigned long*); // offset 0x18, size 0x4 + long (*get_disk_info)(struct PDM_DISK*, struct PDM_DISK_INFO*); // offset 0x1C, size 0x4 +}; + +typedef struct PDM_DISK_TBL { + // total size: 0x8 + struct PDM_FUNCTBL* p_func; // offset 0x0, size 0x4 + unsigned long ui_ext; // offset 0x4, size 0x4 +} PDM_DISK_TBL; + +typedef struct PDM_INIT_DISK { + // total size: 0x8 + long (*p_func)(struct PDM_DISK_TBL*, unsigned long); // offset 0x0, size 0x4 + unsigned long ui_ext; // offset 0x4, size 0x4 +} PDM_INIT_DISK; + +typedef struct PDM_DISK { + // total size: 0x34 + unsigned long status; // offset 0x0, size 0x4 + struct PDM_DISK_TBL disk_tbl; // offset 0x4, size 0x8 + unsigned long signature; // offset 0xC, size 0x4 + unsigned short open_disk_cnt; // offset 0x10, size 0x2 + unsigned short disk_lock_cnt; // offset 0x12, size 0x2 + struct PDM_DISK* disk_lock_handle; // offset 0x14, size 0x4 + struct PDM_DISK_INFO disk_info; // offset 0x18, size 0x14 + struct PDM_INIT_DISK* p_init_disk_tbl; // offset 0x2C, size 0x4 + struct PDM_PARTITION* p_cur_part; // offset 0x30, size 0x4 +} PDM_DISK; + +struct PDM_DISK_HANDLE { + // total size: 0x8 + unsigned long signature; // offset 0x0, size 0x4 + struct PDM_DISK* handle; // offset 0x4, size 0x4 +}; + +struct PDM_PARTITION_HANDLE { + // total size: 0x8 + unsigned long signature; // offset 0x0, size 0x4 + struct PDM_PARTITION* handle; // offset 0x4, size 0x4 +}; + +typedef struct PDM_DISK_SET { + // total size: 0xB64 + unsigned short num_partition; // offset 0x0, size 0x2 + unsigned short num_allocated_disk; // offset 0x2, size 0x2 + struct PDM_DISK_HANDLE disk_handle[26]; // offset 0x4, size 0xD0 + struct PDM_PARTITION_HANDLE partition_handle[26]; // offset 0xD4, size 0xD0 + struct PDM_DISK disk[26]; // offset 0x1A4, size 0x548 + struct PDM_PARTITION partition[26]; // offset 0x6EC, size 0x478 +} PDM_DISK_SET; + +typedef struct PDM_PART_TBL { + // total size: 0x14 + unsigned char boot_flag; // offset 0x0, size 0x1 + unsigned char partition_type; // offset 0x1, size 0x1 + unsigned short s_cylinder; // offset 0x2, size 0x2 + unsigned char s_head; // offset 0x4, size 0x1 + unsigned char s_sector; // offset 0x5, size 0x1 + unsigned short e_cylinder; // offset 0x6, size 0x2 + unsigned char e_head; // offset 0x8, size 0x1 + unsigned char e_sector; // offset 0x9, size 0x1 + unsigned char pad[2]; // offset 0xA, size 0x2 + unsigned long lba_start_sector; // offset 0xC, size 0x4 + unsigned long lba_num_sectors; // offset 0x10, size 0x4 +} PDM_PART_TBL; + +typedef struct PDM_MBR { + // total size: 0x58 + unsigned long current_sector; // offset 0x0, size 0x4 + unsigned long epbr_base_sector; // offset 0x4, size 0x4 + struct PDM_PART_TBL partition_table[4]; // offset 0x8, size 0x50 +} PDM_MBR; + +struct PDM_MBR_SEC { + // total size: 0x200 + unsigned char bootprg[446]; // offset 0x0, size 0x1BE + unsigned char partition_tbl[64]; // offset 0x1BE, size 0x40 + unsigned char signature1; // offset 0x1FE, size 0x1 + unsigned char signature2; // offset 0x1FF, size 0x1 +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/revolution/VF/d_hash.c b/src/revolution/VF/d_hash.c new file mode 100644 index 00000000..3c215490 --- /dev/null +++ b/src/revolution/VF/d_hash.c @@ -0,0 +1,205 @@ +#include + +static int _MakeWStr(const s8* i_Name); +void dHash_InitHashTable(); +static s32 dHash_SearchHashW(const u16* i_Name); +int dHash_GetArg(const s8* i_Name); +int dHash_SetArgW(const u16* i_Name, u8 i_Arg); +int dHash_SetArg(const s8* i_Name, u8 i_Arg); + +typedef struct { + u16 Name[8]; + u8 arg; +} pHashCell; + +extern PF_VOLUME_SET VFipf_vol_set; + +static u16 l_tmpWName[8]; +static pHashCell hashTable[31]; + +int _MakeWStr(const s8* i_Name) { + u32 len; + const s8* Id = i_Name; + int next2nd; + int skip = 0; + u32 i; + + for (len = 0; Id[len] != '\0'; ++len) {} + if (len >= 8) { + return 0; + } + + for (next2nd = 0; Id[next2nd] != '\0'; ++next2nd) {} + + for (i = 0; i < next2nd; ++i) { + if (skip) { + skip = 0; + continue; + } + if (VFipf_vol_set.codeset.is_oem_mb_char(Id[i], 1)) { + skip = 1; + l_tmpWName[i] = ((s8)Id[i] << 8) | (u16)(s8)Id[i + 1]; + } else { + l_tmpWName[i] = (s8)Id[i]; + } + } + + l_tmpWName[7] = 0; + l_tmpWName[i] = 0; + + return 1; +} + +void dHash_InitHashTable() { + int i; + + for (i = 0; i < 30; i++) { + hashTable[i].Name[0] = 0; + hashTable[i].arg = 0; + } + + hashTable[30].Name[0] = 0; + hashTable[30].arg = 0; +} + +s32 dHash_SearchHashW(const u16* i_Name) { + s32 firstHash; + int len; + int i; + int hashval; + int k; + const u16* str0_p; + const u16* str1_p; + int len2; + int success; + + for (len = 0; i_Name[len] != 0; ++len) {} + + if (len >= 8) { + firstHash = -1; + } else { + hashval = 0; + k = 0; + for (i = 0; i < len; ++i) { + if (k > 7) { + k = 0; + } + hashval += i_Name[i] << (k * 4); + k++; + } + firstHash = (u32)hashval % 31; + } + + if (firstHash == -1) { + return -1; + } + + for (len2 = 0; i_Name[len2] != 0; ++len2) {} + + for (k = 0; k < 15; ++k) { + int hash = (firstHash + k * k) % 31; + + for (len = 0; hashTable[hash].Name[len] != 0; ++len) {} + + if (len2 == len) { + str0_p = i_Name; + str1_p = hashTable[hash].Name; + success = 1; + + for (i = 0; i < len2; ++i) { + if (*str0_p != *str1_p) { + success = 0; + break; + } + str0_p++; + str1_p++; + } + + if (success) { + return hash; + } + } + } + + return -1; +} + +int dHash_GetArg(const s8* i_Name) { + int searchHash; + + if (_MakeWStr(i_Name)) { + searchHash = dHash_SearchHashW(l_tmpWName); + if (searchHash == -1) { + return -1; + } else { + return hashTable[searchHash].arg; + } + } + + return -1; +} + +int dHash_SetArgW(const u16* i_Name, u8 i_Arg) { + s32 newHash; + + if (_MakeWStr((const s8*)i_Name)) { + u32 len; + for (len = 0; l_tmpWName[len] != 0; ++len) {} + + if (len >= 8) { + newHash = -1; + } else { + u32 hashval = 0; + u32 shift = 0; + u32 i; + + for (i = 0; i < len; ++i) { + if (shift > 7) { + shift = 0; + } + hashval += l_tmpWName[i] << (shift * 4); + shift++; + } + newHash = (u32)hashval % 31; + } + + if (newHash != -1) { + if (hashTable[newHash].Name[0] != 0) { + int k; + for (k = 1; k < 15; ++k) { + int hash = (newHash + k * k) % 31; + if (hashTable[hash].Name[0] == 0) { + newHash = hash; + break; + } + } + if (k == 15) { + newHash = -1; + } + } + } + + if (newHash != -1) { + VFipf_memcpy(&hashTable[newHash], l_tmpWName, 16); + hashTable[newHash].arg = i_Arg; + return 1; + } + } + + return 0; +} + +int dHash_SetArg(const s8* i_Name, u8 i_Arg) { + if (_MakeWStr(i_Name)) { + long hash = dHash_SearchHashW(l_tmpWName); + if (hash != -1) { + if (hash >= 0 && hash < 31) { + hashTable[hash].Name[0] = 0; + hashTable[hash].arg = 0; + } + return 1; + } + return 0; + } + return 0; +} diff --git a/src/revolution/VF/d_time.c b/src/revolution/VF/d_time.c new file mode 100644 index 00000000..7ff1ec21 --- /dev/null +++ b/src/revolution/VF/d_time.c @@ -0,0 +1,23 @@ +#include +#include + +void dTM_GetNowTime(PF_SYS_DATE* sdate, PF_SYS_TIME* stime) { + VFSysTime time; + OSCalendarTime CalenderTime; + + sdate->sys_year = 0; + sdate->sys_month = 0; + sdate->sys_day = 0; + stime->sys_hour = 0; + stime->sys_min = 0; + stime->sys_sec = 0; + + OSTicksToCalendarTime(OSGetTime(), &CalenderTime); + sdate->sys_year = CalenderTime.year; + sdate->sys_month = CalenderTime.month + 1; + sdate->sys_day = CalenderTime.mday; + stime->sys_hour = CalenderTime.hour; + stime->sys_min = CalenderTime.min; + stime->sys_sec = CalenderTime.sec; + +} diff --git a/src/revolution/VF/d_vf.c b/src/revolution/VF/d_vf.c new file mode 100644 index 00000000..4240327b --- /dev/null +++ b/src/revolution/VF/d_vf.c @@ -0,0 +1,442 @@ +#include +#include + +static OSMutex l_Mutex; +static s32 l_vf_init; +static s32 l_InitedMutex; + +#define VF_ERROR_B001 0xB001 +#define VF_ERR_GENERIC 0xB002 +#define VF_ERR_DRIVE_NOT_FOUND 0xB003 +#define VF_ERR_0xB004 0xB004 +#define VF_ERR_0xB005 0xB005 + +struct DriveP { + void* file_p; + struct PDM_DISK* pf_disk_p; + struct PF_DRV_TBL pf_drv; + struct PDM_PARTITION* pf_part_p; + struct { + struct MEMiHeapHead* heap_handle; + unsigned long cache_pages; + struct PF_CACHE_PAGE* pf_cache_page_p; + unsigned char (*pf_cache_buf_p)[512]; + } cache; + struct PF_CACHE_SETTING pf_cache_set; + unsigned char pf_filename[255]; +} DriveP; + +s32 VFIsAvailable(void) { + return l_vf_init != 0; +} + +void VFInitEx(void* i_heap_start_address_p, u32 i_size) { + if (l_InitedMutex == 0) { + OSInitMutex(&l_Mutex); + l_InitedMutex = 1; + } + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + if (l_vf_init == 0) { + l_vf_init = 1; + VFSysInit(i_heap_start_address_p, i_size); + VFipdm_init_diskmanager(0, 0); + VFipf2_init_prfile2(0, 0); + dHash_InitHashTable(); + } + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } +} + +long VF_activate_drive_common(long i_handle_idx, const char * i_sys_file_name_p, void * i_memory_p) { + long err; + struct DriveP* drive_p; + struct PF_DRV_TBL * drv_tbl[2]; + + err = VFSysCheckExistPrfFile((char *)i_handle_idx); + if (err != 0) { + VFSysSetLastError(err); + return err; + } + + err = VFSysMountDrv(i_handle_idx, i_sys_file_name_p, i_memory_p); + if (err != 0) { + VFSysSetLastError(err); + return err; + } + + drive_p = (void *)VFSysGetDriveP(i_handle_idx); + + if (drive_p == 0) { + VFSysSetLastError(0xb002); + return 0xb002; + } + + drv_tbl[0] = &drive_p->pf_drv; + drv_tbl[1] = 0; + + err = VFipf2_attach(drv_tbl); + + if (err != 0) { + err = VFipf2_errnum(); + VFSysSetLastError(err); + VFipdm_close_partition(drive_p->pf_part_p); + return err; + } + + return 0; +} + +s32 VFMountDriveNANDFlashEx(const char* i_drive, const char* i_sys_file_name_p) { + s32 result = VF_ERR_0xB004; + int arg; + int buf = -1; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + arg = dHash_GetArg(i_drive); + if (arg == -1) { + result = VFSysSetDeviceNANDFlash((char*)&buf, 0, 0); + if (result == 0) { + dHash_SetArgW((int)i_drive, (*(int*)&buf) & 0xFF); + } + } + + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + if (result == 0 || result == VF_ERR_0xB004) { + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + arg = dHash_GetArg(i_drive); + VFSysSetNandFuncNormal(arg); + result = VF_activate_drive_common(arg, (char*)i_sys_file_name_p, 0); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + if (result != VF_OK && result != VF_ERR_0xB005) { + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + arg = dHash_GetArg(i_drive); + if (VFSysUnsetDevice(arg) == 0) { + dHash_SetArg((int)i_drive); + } + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + } + } + + return result; +} + +s32 VFUnmountDrive(const char* i_drive) { + s32 result; + s32 arg; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + arg = dHash_GetArg(i_drive); + result = VFSysUnmountDrv(arg, 0); + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + if (result == VF_OK) { + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + dHash_GetArg(i_drive); + result = VFSysUnsetDevice(); + if (result == VF_OK) { + dHash_SetArg(i_drive); + } + + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + } + + return result; +} + +char *VF_path2handleidx(s32* o_handle_idx_p, const char* i_path_p) { + char drive[8]; + const char* str_p; + s32 idx; + const char* ret_p; + + *o_handle_idx_p = -1; + str_p = i_path_p; + idx = 0; + ret_p = i_path_p; + + VFipf_memset(drive, 0, 8); + + while (*str_p != '\0') { + if (*str_p == '\\' || *str_p == '/') { + break; + } + + if (*str_p == ':') { + *o_handle_idx_p = dHash_GetArg(drive); + if (*o_handle_idx_p == -1 || idx > 7) { + ret_p = 0; + } else { + ret_p = str_p + 1; + } + break; + } + + if (idx < 7) { + drive[idx] = *str_p; + } + + str_p++; + idx++; + } + + return (char*)ret_p; +} + +VFFile VFOpenFile(const char* i_path_p, const char* i_mode, u32 i_attr) { + s32 handleIdx = -1; + VFFile result; + char *relativePath; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + relativePath = VF_path2handleidx(&handleIdx, (char*)i_path_p); + + if (relativePath == 0) { + VFSysSetLastError(VF_ERR_DRIVE_NOT_FOUND); + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + return 0; + } + + if (handleIdx != -1) { + result = (VFFile)VFSysOpenFile(handleIdx, (int)relativePath, (int)i_mode); + } else { + result = (VFFile)VFSysOpenFile_current((int)relativePath, (int)i_mode); + } + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFCloseFile(VFFile i_file_p) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + result = VFSysCloseFile((int)i_file_p); + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFSeekFile(VFFile i_file_p, s32 i_offset, s32 i_origin) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + result = VFSysSeekFile((int)i_file_p, i_offset, i_origin); + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFReadFile(VFFile i_file_p, void* o_buf_p, u32 i_size, u32* o_read_size_p) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + result = VFSysReadFile((int)o_read_size_p, (int)o_buf_p, i_size, (int)i_file_p); + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFWriteFile(VFFile i_file_p, const void* i_buf_p, u32 i_size) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + result = VFSysWriteFile((int)i_buf_p, (int)i_size, (int)i_file_p); + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFDeleteFile(const char* i_path_p) { + s32 handleIdx = -1; + s32 result; + char *relativePath; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + relativePath = VF_path2handleidx(&handleIdx, (char*)i_path_p); + + if (relativePath == 0) { + result = VF_ERR_DRIVE_NOT_FOUND; + VFSysSetLastError(result); + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + return VF_ERR_DRIVE_NOT_FOUND; + } + + if (handleIdx != -1) { + result = VFSysDeleteFile(handleIdx, (int)relativePath); + } else { + result = VFSysDeleteFile_current((int)relativePath); + } + + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFGetFileSizeByFd(VFFile i_file_p) { + int size = -1; + int result = VFSysGetFileSizeByFd(&size, (int)i_file_p); + + if (result != 0) { + VFSysSetLastError(result); + } + + return size; +} + +s32 VFGetLastError(void) { + return VFSysGetLastError(); +} + +s32 VFGetLastDeviceError(const char* i_drive) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + if (i_drive != 0) { + int arg = dHash_GetArg(i_drive); + result = VFSysGetLastDeviceError(arg); + } else { + result = VFSysGetLastDeviceError_current(); + } + + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} + +s32 VFGetDriveFreeSize(const char* i_drive) { + s32 size; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + if (i_drive != 0) { + int arg = dHash_GetArg(i_drive); + size = VFSysGetDriveFreeSize(arg); + } else { + VFSysSetLastError(-1); + size = -1; + } + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return size; +} + +s32 VFSetSyncMode(const char* i_drive, u32 i_mode) { + s32 result; + + if (l_InitedMutex != 0) { + OSLockMutex(&l_Mutex); + } + + if (i_drive != 0) { + int arg = dHash_GetArg(i_drive); + result = VFSysSetSyncMode(arg, i_mode); + } else { + result = -1; + } + + VFSysSetLastError(result); + + if (l_InitedMutex != 0) { + OSUnlockMutex(&l_Mutex); + } + + return result; +} diff --git a/src/revolution/VF/pdm_bpb.c b/src/revolution/VF/pdm_bpb.c new file mode 100644 index 00000000..73e43014 --- /dev/null +++ b/src/revolution/VF/pdm_bpb.c @@ -0,0 +1,261 @@ +#include + +void VFipdm_bpb_calculate_common_bpb_fields(PDM_BPB *bpb) { + u32 temp; + u32 root_secs; + u32 data_secs; + + bpb->log2_bytes_per_sector = 0; + temp = bpb->bytes_per_sector; + while ((temp = (temp >> 1) & 0x7FFF) != 0) { + bpb->log2_bytes_per_sector++; + } + + bpb->log2_sectors_per_cluster = 0; + temp = bpb->sectors_per_cluster; + while ((temp = (temp >> 1) & 0x7FFF) != 0) { + bpb->log2_sectors_per_cluster++; + } + + root_secs = ((bpb->bytes_per_sector + (bpb->num_root_dir_entries * 32)) - 1) >> bpb->log2_bytes_per_sector; + bpb->num_root_dir_sectors = root_secs; + + root_secs = ((u16)root_secs + bpb->num_reserved_sectors) + (bpb->num_FATs * bpb->sectors_per_FAT); + bpb->first_data_sector = root_secs; + + data_secs = bpb->total_sectors - root_secs; + bpb->num_clusters = data_secs >> bpb->log2_sectors_per_cluster; + + if ((data_secs >> bpb->log2_sectors_per_cluster) < 0xFF5) { + bpb->fat_type = PDM_FAT_12; + } else if ((data_secs >> bpb->log2_sectors_per_cluster) < 0xFFF5) { + bpb->fat_type = PDM_FAT_16; + } else { + bpb->fat_type = PDM_FAT_32; + } +} + +static void VFipdm_bpb_calculate_specific_bpb_fields(PDM_BPB *dst) { + switch ((s32)dst->fat_type) { + case PDM_FAT_12: + case PDM_FAT_16: { + dst->active_FAT_sector = dst->num_reserved_sectors; + dst->num_active_FATs = dst->num_FATs; + dst->first_root_dir_sector = dst->num_reserved_sectors + (dst->num_FATs * dst->sectors_per_FAT); + } break; + case PDM_FAT_32: { + dst->first_root_dir_sector = dst->first_data_sector + ((dst->root_dir_cluster - 2) << dst->log2_sectors_per_cluster); + if (dst->ext_flags & 0x80) { + dst->num_active_FATs = 1; + dst->active_FAT_sector = dst->num_reserved_sectors + ((dst->ext_flags & 0x7) * dst->sectors_per_FAT); + } else { + dst->num_active_FATs = dst->num_FATs; + dst->active_FAT_sector = dst->num_reserved_sectors; + } + } + } +} + +static s32 VFipdm_bpb_load_string(const u8 *src, u32 length, u8 *dst) { + u32 i; + if (src == NULL || dst == NULL || length == 0) { + return 1; + } + for (i = 0; i < length; ++i) { + dst[i] = src[i]; + } + return 0; +} + +s32 VFipdm_bpb_get_bpb_information(const u8 *src, PDM_BPB *dst) { + s32 result; + int i; + + if (src == 0 || dst == 0) { + return 1; + } + + result = 0; + + VFipdm_bpb_load_string(src, 3, dst->jump_boot); + VFipdm_bpb_load_string(src + 3, 8, dst->oem_name); + + dst->bytes_per_sector = src[0xB] | (src[0xC] << 8); + dst->sectors_per_cluster = src[0xD]; + dst->num_reserved_sectors = src[0xE] | (src[0xF] << 8); + dst->num_FATs = src[0x10]; + dst->num_root_dir_entries = src[0x11] | (src[0x12] << 8); + + dst->total_sectors16 = src[0x13] | (src[0x14] << 8); + dst->media = src[0x15]; + dst->sectors_per_FAT16 = src[0x16] | (src[0x17] << 8); + dst->sector_per_track = src[0x18] | (src[0x19] << 8); + dst->num_heads = src[0x1A] | (src[0x1B] << 8); + dst->num_hidden_sectors = src[0x1C] | (src[0x1D] << 8) | (src[0x1E] << 16) | (src[0x1F] << 24); + dst->total_sectors32 = src[0x20] | (src[0x21] << 8) | (src[0x22] << 16) | (src[0x23] << 24); + + dst->total_sectors = (dst->total_sectors16 == 0) ? dst->total_sectors32 : (u32)dst->total_sectors16; + + if (dst->sectors_per_FAT16 == 0) { + dst->sectors_per_FAT = (dst->sectors_per_FAT32 = src[0x24] | (src[0x25] << 8) | (src[0x26] << 16) | (src[0x27] << 24)); + } else { + dst->sectors_per_FAT = dst->sectors_per_FAT16; + dst->sectors_per_FAT32 = 0; + } + + VFipdm_bpb_calculate_common_bpb_fields(dst); + + switch ((s32)dst->fat_type) { + case PDM_FAT_12: + case PDM_FAT_16: { + if (dst->sectors_per_FAT16 == 0) { + result = 4; + } + + dst->ext_flags = 0; + dst->fs_version = 0; + dst->root_dir_cluster = 0; + dst->fs_info_sector = 0; + dst->backup_boot_sector = 0; + + dst->drive = src[0x24]; + dst->boot_sig = src[0x26]; + dst->vol_id = src[0x27] | (src[0x28] << 8) | (src[0x29] << 16) | (src[0x2A] << 24); + + VFipdm_bpb_load_string(src + 0x2b, 11, dst->vol_label); + VFipdm_bpb_load_string(src + 0x36, 8, dst->fs_type); + } break; + case PDM_FAT_32: { + if (dst->total_sectors16 != 0 || dst->sectors_per_FAT16 != 0) { + result = 4; + } + + dst->ext_flags = src[0x28] | (src[0x29] << 8); + dst->fs_version = src[0x2A] | (src[0x2B] << 8); + dst->root_dir_cluster = src[0x2C] | (src[0x2D] << 8) | (src[0x2E] << 16) | (src[0x2F] << 24); + dst->fs_info_sector = (src[0x31] << 8) | src[0x30]; + dst->backup_boot_sector = (src[0x33] << 8) | src[0x32]; + + dst->drive = src[0x40]; + dst->boot_sig = src[0x42]; + dst->vol_id = src[0x43] | (src[0x44] << 8) | (src[0x45] << 16) | (src[0x46] << 24); + + VFipdm_bpb_load_string(src + 0x47, 11, dst->vol_label); + VFipdm_bpb_load_string(src + 0x52, 8, dst->fs_type); + + if (dst->fs_version != 0) { + result = 4; + } + } break; + default: + result = 4; + } + + VFipdm_bpb_calculate_specific_bpb_fields(dst); + + return result; +} + +s32 VFipdm_bpb_get_fsinfo_information(const u8 *src, u32 *dst) { + if ((src == NULL) || (dst == NULL)) { + return 1; + } + + dst[0] = src[0x1E8] | (src[0x1E9] << 8) | (src[0x1EA] << 16) | (src[0x1EB] << 24); + dst[1] = src[0x1EC] | (src[0x1ED] << 8) | (src[0x1EE] << 16) | (src[0x1EF] << 24); + + return 0; +} + +s32 VFipdm_bpb_set_fsinfo_information(const u32 *src, u8 *dst) { + if (dst == NULL || src == NULL) { + return 1; + } + + dst[0] = 0x52; + dst[1] = 0x52; + dst[2] = 0x61; + dst[3] = 0x41; + dst[0x1E4] = 0x72; + dst[0x1E5] = 0x72; + dst[0x1E6] = 0x41; + dst[0x1E7] = 0x61; + + dst[0x1E8] = src[0]; + dst[0x1E9] = src[0] >> 8; + dst[0x1EA] = src[0] >> 16; + dst[0x1EB] = src[0] >> 24; + + dst[0x1EC] = src[1]; + dst[0x1ED] = src[1] >> 8; + dst[0x1EE] = src[1] >> 16; + dst[0x1EF] = src[1] >> 24; + + dst[0x1FC] = 0x00; + dst[0x1FD] = 0x00; + dst[0x1FE] = 0x55; + dst[0x1FF] = 0xAA; + + return 0; +} + +s32 VFipdm_bpb_check_boot_sector(const u8 *buf, u32 *is_boot) { + u16 bps; + u8 spc; + u8 media; + + if (buf == NULL || is_boot == NULL) { + return 1; + } + + *is_boot = 1; + + if (buf[0] != 0xEB || buf[2] != 0x90) { + if (buf[0] != 0xE9) { + *is_boot = 0; + } + } + + if (buf[0x1FE] != 0x55 || buf[0x1FF] != 0xAA) { + *is_boot = 0; + } + + bps = (buf[0xC] << 8) | buf[0xB]; + if (bps != 512 && bps != 1024 && bps != 2048 && bps != 4096) { + *is_boot = 0; + } + + spc = buf[0xD]; + if (spc != 1 && spc != 2 && spc != 4 && spc != 8 && spc != 16 && spc != 32 && spc != 64 && spc != 128) { + *is_boot = 0; + } + + media = buf[0x15]; + if (media != 0xF0 && media != 0xF8 && media != 0xF9 && media != 0xFA && media != 0xFB && media != 0xFC && media != 0xFD && media != 0xFE && media != 0xFF) { + *is_boot = 0; + } + + return 0; +} + +s32 VFipdm_bpb_check_fsinfo_sector(const u8 *buf, u32 *is_fsinfo) { + u32 lead_sig; + u32 struct_sig; + u32 trail_sig; + + if (buf == NULL || is_fsinfo == NULL) { + return 1; + } + + lead_sig = buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); + struct_sig = buf[0x1E4] | (buf[0x1E5] << 8) | (buf[0x1E6] << 16) | (buf[0x1E7] << 24); + trail_sig = buf[0x1FC] | (buf[0x1FD] << 8) | (buf[0x1FE] << 16) | (buf[0x1FF] << 24); + + if (lead_sig == 0x41615252 && struct_sig == 0x61417272 && trail_sig == 0xAA550000) { + *is_fsinfo = 1; + } else { + *is_fsinfo = 0; + } + + return 0; +} diff --git a/src/revolution/VF/pdm_dskmng.c b/src/revolution/VF/pdm_dskmng.c new file mode 100644 index 00000000..f02255e1 --- /dev/null +++ b/src/revolution/VF/pdm_dskmng.c @@ -0,0 +1,82 @@ +#include + +PDM_DISK_SET VFipdm_disk_set; + +s32 VFipdm_init_diskmanager(u32 config, void* param) { + u32 i; + + VFipf_memset(&VFipdm_disk_set, 0, 2916); + for (i = 0; i < 0x1A; i++) { + VFipdm_disk_set.disk[i].disk_lock_handle = 0; + } + + for (i = 0; i < 0x1A; i++) { + VFipdm_disk_set.partition[i].part_lock_handle = 0; + } + + return 0; +} + +s32 VFipdm_open_disk(PDM_INIT_DISK* p_init_disk_tbl, PDM_DISK** pp_disk) { + s32 err; + + if (!pp_disk) { + return 1; + } + + *pp_disk = 0; + err = VFipdm_disk_open_disk(p_init_disk_tbl, pp_disk); + + if (!err) { + return 0; + } + + return err; +} + +s32 VFipdm_close_disk(PDM_DISK* p_disk) { + s32 result; + + if (!p_disk) { + return 1; + } + + result = VFipdm_disk_close_disk(p_disk); + return result; +} + +s32 VFipdm_open_partition(PDM_DISK* p_disk, s32 part_id, PDM_PARTITION** pp_part) { + int result; + + if (!p_disk) { + return 1; + } + + if (!pp_part) { + return 1; + } + + *pp_part = 0; + part_id &= 0xFFFF; + result = VFipdm_part_open_partition(p_disk, part_id, pp_part); + if (!result) { + return 0; + } + + return result; +} + +s32 VFipdm_close_partition(struct PDM_PARTITION* p_part) { + int result; + + if (!p_part) { + return 1; + } + + result = VFipdm_part_close_partition(p_part); + if (!result) { + return 0; + } + + return result; +} diff --git a/src/revolution/VF/pdm_mbr.c b/src/revolution/VF/pdm_mbr.c new file mode 100644 index 00000000..b6cd267f --- /dev/null +++ b/src/revolution/VF/pdm_mbr.c @@ -0,0 +1,169 @@ +#include + +s32 VFipdm_mbr_get_table(u8* buf, u32 sector, PDM_MBR* p_mbr_tbl); +s32 VFipdm_mbr_get_mbr_part_table(PDM_DISK* p_disk, PDM_MBR* p_mbr_tbl); +s32 VFipdm_mbr_get_epbr_part_table(PDM_DISK* p_disk, PDM_MBR* p_mbr_tbl); +s32 VFipdm_mbr_check_master_boot_record(PDM_DISK* p_disk, u8* buf, u32* is_master_boot); + +extern PDM_DISK_SET VFipdm_disk_set; + +s32 VFipdm_mbr_get_table(u8* buf, u32 sector, PDM_MBR* p_mbr_tbl) { + u8* p_buf; + u16 cs_val; + u32 i; + + if (!buf || !p_mbr_tbl) { + return 1; + } + if (!sector) { + p_mbr_tbl->epbr_base_sector = 0; + p_mbr_tbl->current_sector = 0; + } else { + if (!p_mbr_tbl->epbr_base_sector) { + p_mbr_tbl->epbr_base_sector = sector; + } + p_mbr_tbl->current_sector = sector; + } + + p_buf = buf + 446; + for (i = 0; i < 4; ++i) { + p_mbr_tbl->partition_table[i].boot_flag = p_buf[0]; + p_mbr_tbl->partition_table[i].partition_type = p_buf[4]; + p_mbr_tbl->partition_table[i].s_head = p_buf[1]; + + cs_val = p_buf[2] | (p_buf[3] << 8); + p_mbr_tbl->partition_table[i].s_cylinder = ((cs_val << 2) & 0x300) + (cs_val >> 8); + p_mbr_tbl->partition_table[i].s_sector = cs_val & 0x3F; + + p_mbr_tbl->partition_table[i].e_head = ((p_buf[6] << 8) & 0xFF00) | (p_buf[5] & 0xFFFF00FF); + + cs_val = p_buf[6] | (p_buf[7] << 8); + p_mbr_tbl->partition_table[i].e_cylinder = ((cs_val << 2) & 0x300) + (cs_val >> 8); + p_mbr_tbl->partition_table[i].e_sector = cs_val & 0x3F; + + p_mbr_tbl->partition_table[i].lba_start_sector = p_buf[8] | (p_buf[9] << 8) | (p_buf[10] << 16) | (p_buf[11] << 24); + p_mbr_tbl->partition_table[i].lba_num_sectors = p_buf[12] | (p_buf[13] << 8) | (p_buf[14] << 16) | (p_buf[15] << 24); + + p_buf += 16; + } + + return 0; +} + +s32 VFipdm_mbr_get_mbr_part_table(PDM_DISK* p_disk, PDM_MBR* p_mbr_tbl) { + s32 err; + u8 buf[512]; + u32 num_success; + u32 is_master_boot; + + if (!p_disk || !p_mbr_tbl) { + return 1; + } + err = VFipdm_disk_check_disk_handle(p_disk); + if (err) { + return err; + } + + err = VFipdm_disk_physical_read(p_disk, buf, 0, 1, 512, &num_success); + if (err) { + return err; + } + + VFipdm_mbr_check_master_boot_record(p_disk, buf, &is_master_boot); + if (is_master_boot) { + VFipdm_mbr_get_table(buf, 0, p_mbr_tbl); + } else { + return 5; + } + + return 0; +} + +s32 VFipdm_mbr_get_epbr_part_table(PDM_DISK* p_disk, PDM_MBR* p_mbr_tbl) { + s32 err; + u8 buf[512]; + u32 extend_start_sector; + u16 tbl_index; + u32 num_success; + u32 is_master_boot; + struct PDM_DISK_INFO disk_info; + u32 extend_start_block; + + if (!p_disk || !p_mbr_tbl) { + return 1; + } + err = VFipdm_disk_check_disk_handle(p_disk); + if (err) { + return err; + } + extend_start_sector = 0; + for (tbl_index = 0; tbl_index < 4u; ++tbl_index) { + if (p_mbr_tbl->partition_table[tbl_index].partition_type == 5 || p_mbr_tbl->partition_table[tbl_index].partition_type == 15) { + extend_start_sector = p_mbr_tbl->epbr_base_sector + p_mbr_tbl->partition_table[tbl_index].lba_start_sector; + break; + } + } + if (tbl_index == 4) { + return 7; + } else { + err = VFipdm_disk_get_media_information(p_disk, &disk_info); + if (err) { + return err; + } + extend_start_block = extend_start_sector * (disk_info.bytes_per_sector >> 9); + err = VFipdm_disk_physical_read(p_disk, buf, extend_start_block, 1, 512, &num_success); + if (err) { + return err; + } + VFipdm_mbr_check_master_boot_record(p_disk, buf, &is_master_boot); + if (is_master_boot) { + VFipdm_mbr_get_table(buf, extend_start_sector, p_mbr_tbl); + } else { + return 6; + } + return 0; + } +} + +extern s32 VFipdm_bpb_check_boot_sector(u8* buf, u32* is_boot); + +s32 VFipdm_mbr_check_master_boot_record(PDM_DISK *p_disk, u8 *buf, u32 *is_master_boot) { + s16 part_cnt; + struct PDM_MBR_SEC *p_mbr_sec; + struct PDM_MBR mbr_tbl; + struct PDM_DISK *lp_disk; + u32 is_boot; + s32 err; + + if (!p_disk || !buf || !is_master_boot) { + return 1; + } + err = VFipdm_disk_check_disk_handle(p_disk); + if (err) { + return err; + } + *is_master_boot = 0; + p_mbr_sec = (struct PDM_MBR_SEC *)buf; + if (p_mbr_sec->signature1 != 0x55 || p_mbr_sec->signature2 != 0xaa) { + return 0; + } + lp_disk = VFipdm_disk_set.disk; + VFipdm_mbr_get_table(buf, 0, &mbr_tbl); + for (part_cnt = 0; part_cnt < 4; ++part_cnt) { + if (mbr_tbl.partition_table[part_cnt].lba_num_sectors > (u32)(-1) - mbr_tbl.partition_table[part_cnt].lba_start_sector || mbr_tbl.partition_table[part_cnt].lba_start_sector + mbr_tbl.partition_table[part_cnt].lba_num_sectors > lp_disk[(u8)(u32)p_disk].disk_info.total_sectors) { + *is_master_boot = 0; + break; + } + if (mbr_tbl.partition_table[part_cnt].lba_start_sector) { + *is_master_boot = 1; + } + } + if (!*is_master_boot && !mbr_tbl.partition_table[0].lba_start_sector && !mbr_tbl.partition_table[1].lba_start_sector && !mbr_tbl.partition_table[2].lba_start_sector && !mbr_tbl.partition_table[3].lba_start_sector) { + VFipdm_bpb_check_boot_sector(buf, &is_boot); + if (!is_boot) + *is_master_boot = 1; + else + *is_master_boot = 0; + } + return 0; +} diff --git a/src/revolution/VF/pf_api_util.c b/src/revolution/VF/pf_api_util.c new file mode 100644 index 00000000..25a1d149 --- /dev/null +++ b/src/revolution/VF/pf_api_util.c @@ -0,0 +1,105 @@ +#include + +int VFipf_error_to_api_error[40] = { + 0x00000000, 0x00000016, 0x00000016, 0x00000002, + 0x00000010, 0x0000005A, 0x0000001C, 0x00000008, + 0x00000011, 0x00000008, 0x00000016, 0x0000000D, + 0x00000058, 0x00000008, 0x00000008, 0x00000008, + 0x0000000D, 0x00000005, 0x00000008, 0x0000000D, + 0x00000002, 0x00000017, 0x00000018, 0x00000015, + 0x0000000D, 0x00000001, 0x00000008, 0x00000008, + 0x00000008, 0x00000008, 0x0000000C, 0x00000016, + 0x00000016, 0x00000008, 0x00000002, 0x00000008, + 0x00000008, 0x0000001B, 0x00000009, 0x0000002E +}; + +u32 VFiPFAPI_ParseOpenModeString(const char *mode_str) { + u32 open_mode; + u32 i; + + if (mode_str == 0) { + return 10; + } + + i = 1; + + switch (mode_str[0]) { + case 'r': + open_mode = 2; + break; + case 'w': + open_mode = 1; + break; + case 'a': + open_mode = 4; + break; + default: + return 0; + } + + if (mode_str[1] == 'b') { + i = 2; + } + + switch (mode_str[i++]) { + case 0: + return open_mode; + + case '+': { + open_mode |= 8; + break; + } + + case 't': + default: + return 0; + } + + switch (mode_str[i++]) { + case 0: { + return open_mode; + } + } + + return 0; +} + +int VFiPFAPI_convertError(int err) { + if (err == 0) { + return 0; + } + if (err == -1) { + return -1; + } + if (err > 0 && err < 160) { + return VFipf_error_to_api_error[err]; + } + if (err == 4096) { + return 5; + } + return err; +} + +int VFiPFAPI_convertReturnValue(int err) { + return (-err | err) >> 31; +} + +void* VFiPFAPI_convertReturnValue2NULL(int err, void* p_stream) { + if (err) { + return NULL; + } else { + return p_stream; + } +} + +int VFiPFAPI_convertReturnValue4unmount(int err) { + if (err == 0) { + return 0; + } + + if (err == 1) { + return 1; + } + + return -1; +} diff --git a/src/revolution/VF/pf_attach.c b/src/revolution/VF/pf_attach.c new file mode 100644 index 00000000..267b6564 --- /dev/null +++ b/src/revolution/VF/pf_attach.c @@ -0,0 +1,20 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +int VFipf2_attach(PF_DRV_TBL** drv_tbl) { + s32 err; + if (drv_tbl == 0 || !*drv_tbl) { + err = 10; + VFipf_vol_set.last_error = err; + } else { + while (*drv_tbl) { + err = VFiPFVOL_attach(*drv_tbl); + if (err != 0) { + return VFiPFAPI_convertReturnValue(err); + } + drv_tbl++; + } + } + return VFiPFAPI_convertReturnValue(err); +} diff --git a/src/revolution/VF/pf_clib.c b/src/revolution/VF/pf_clib.c new file mode 100644 index 00000000..e55827cf --- /dev/null +++ b/src/revolution/VF/pf_clib.c @@ -0,0 +1,107 @@ +#include + +s32 VFipf_toupper(s32 c); +void *VFipf_memcpy(void *dst, const void *src, u32 length); +void *VFipf_memset(void *dst, s32 c, u32 length); +u32 VFipf_strlen(const s8 *s); +VFipf_strcpy(char *dest, const char *src); +s32 VFipf_strcmp(const s8 *s1, const s8 *s2); +s32 VFipf_strncmp(const s8 *s1, const s8 *s2, u32 length); + +s32 VFipf_toupper(s32 c) { + if (c >= 'a' && c <= 'z') { + return c - ('a' - 'A'); + } + + return c; +} + +void *VFipf_memcpy(void *dst, const void *src, u32 length) { + u32 *ld; + const u32 *ls; + s8 *d; + const s8 *s; + + ld = dst; + ls = src; + if (((u32)ld & 3) == 0 && ((u32)ls & 3) == 0) { + while (length > 3) { + *ld++ = *ls++; + length -= 4; + } + } + + d = (s8 *)ld; + s = (const s8 *)ls; + while (length != 0) { + *d++ = *s++; + length--; + } + + return dst; +} + +void *VFipf_memset(void *dst, s32 c, u32 length) { + s8 *d; + u32 *ld; + s8 *v1; + for (d = dst; ((((u32)d) & 3) != 0) && length; ++d) { + --length; + *d = c; + } + + ld = (u32 *)d; + while (length > 3) { + *(ld++) = (c | (c << 8)) | ((c << 24) | (c << 16)); + length -= 4; + } + + for (v1 = (s8 *)ld; (length--) != 0; ++v1) { + *v1 = c; + } + + return dst; +} + +u32 VFipf_strlen(const s8 *s) { + const s8 *t = s; + while (*t) { + t++; + } + return t - s; +} + +VFipf_strcpy(char *dest, const char *src) { + goto idk; + while ((*src) != '\0') { + src++; + dest++; + idk: + *dest = *src; + } +} + +s32 VFipf_strcmp(const s8 *s1, const s8 *s2) { + const u8 *p1 = (const u8 *)s1; + const u8 *p2 = (const u8 *)s2; + + while (*p1 && *p2 && *p1 == *p2) { + ++p1; + ++p2; + } + return *p1 - *p2; +} + +s32 VFipf_strncmp(const s8 *s1, const s8 *s2, u32 length) { + const u8 *p1 = (const u8 *)s1; + const u8 *p2 = (const u8 *)s2; + + while (length-- != 0) { + if (!*p1 || !*p2 || *p1 != *p2) { + return *p1 - *p2; + } + ++p1; + ++p2; + } + return 0; +} diff --git a/src/revolution/VF/pf_cluster.c b/src/revolution/VF/pf_cluster.c new file mode 100644 index 00000000..bb7f244b --- /dev/null +++ b/src/revolution/VF/pf_cluster.c @@ -0,0 +1,174 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +void VFiPFCLUSTER_UpdateLastAccessCluster(PF_FILE* p_file, u32 sector) { + struct PF_VOLUME* p_vol; + if (!p_file->cursor.position) { + p_file->p_sfd->ffd.last_access_cluster.cluster = 0; + p_file->p_sfd->ffd.last_access_cluster.chain_index = 0; + } else { + if (p_file == 0) { + p_vol = 0; + } else { + p_vol = p_file->p_sfd->dir_entry.p_vol; + } + if ((p_file->cursor.position & (p_vol->bpb.bytes_per_sector - 1)) == 0 && ((p_file->cursor.file_sector_index & (p_vol->bpb.sectors_per_cluster - 1))) == 0) { + if (p_file->cursor.file_sector_index != 0) { + p_file->p_sfd->ffd.last_access_cluster.chain_index = (p_file->cursor.file_sector_index - 1) >> p_vol->bpb.log2_sectors_per_cluster; + p_file->p_sfd->ffd.last_access_cluster.cluster = ((sector - 1 - p_vol->bpb.first_data_sector) >> p_vol->bpb.log2_sectors_per_cluster) + 2; + } + + } else { + p_file->p_sfd->ffd.last_access_cluster.chain_index = p_file->cursor.file_sector_index >> p_vol->bpb.log2_sectors_per_cluster; + p_file->p_sfd->ffd.last_access_cluster.cluster = ((sector - p_vol->bpb.first_data_sector) >> p_vol->bpb.log2_sectors_per_cluster) + 2; + } + } +} + +s32 VFiPFCLUSTER_AppendCluster(PF_FILE* p_file, u32 byte, u32* p_success, u32* sector) { + s32 err; + PF_VOLUME* p_vol; + u32 num_sector; + u32 max_appendable_size; + PF_CURSOR save_cursor; + PF_FAT_HINT save_hint; + + *p_success = 0; + + if ((u32)&VFipf_vol_set > (u32)p_file || (u32)&VFipf_vol_set + 0x27FB8 < (u32)p_file) { + return 10; + } + if (!p_file || !p_file->p_sfd || (p_file->stat & 1) == 0 || (p_file->p_sfd->stat & 1) == 0 || (p_file->p_sfd->stat & 2) == 0) { + return 38; + } + if ((p_file->p_sfd->stat & 1) == 0 || (p_file->p_sfd->stat & 2) == 0) { + return 38; + } + if (p_file == 0) { + p_vol = 0; + } else { + p_vol = p_file->p_sfd->dir_entry.p_vol; + } + + if (!p_vol) { + return 38; + } + + save_cursor = p_file->cursor; + save_hint = p_file->hint; + p_file->p_sfd->ffd.p_hint = &p_file->hint; + + *sector = (u32)-1; + if ((p_vol->fsi_flag & 4) != 0 && (p_vol->num_free_clusters != (u32)-1) && (p_vol->num_free_clusters == 0)) { + return 6; + } + + VFiPFFILE_Cursor_MoveToClusterEnd(p_file, p_file->p_sfd->dir_entry.file_size + byte); + if (p_file->cursor.position == (u32)-1) { + *p_success = 0; + return 37; + } + + err = VFiPFFAT_GetSectorAllocated(&p_file->p_sfd->ffd, p_file->cursor.file_sector_index, byte, sector, &num_sector); + if (err) { + p_file->cursor = save_cursor; + p_file->hint = save_hint; + return err; + } else { + p_file->cursor = save_cursor; + p_file->hint = save_hint; + + max_appendable_size = num_sector << p_vol->bpb.log2_bytes_per_sector; + if (byte < max_appendable_size) { + max_appendable_size = byte; + } + + *p_success = max_appendable_size; + return 0; + } +} + +s32 VFiPFCLUSTER_GetAppendSize(PF_FILE* p_file, u32* p_size) { + PF_VOLUME* p_vol; + u32 cluster_size; + u32 file_cluster_size; + u32 total_allocated_size; + u32 file_end_cluster; + u32 unused_cluster; + u32 next_cluster; + u32 num_append_cluster; + u32 sig_eoc; + u32 file_size; + u32 start_cluster; + u32 v6; + s32 err; + + *p_size = 0; + + if ((u32)&VFipf_vol_set > (u32)p_file || (u32)&VFipf_vol_set + 0x27FB8 < (u32)p_file) { + return 10; + } + + if (!p_file || !p_file->p_sfd || (p_file->stat & 1) == 0 || (p_file->p_sfd->stat & 1) == 0 || (p_file->p_sfd->stat & 2) == 0) { + return 38; + } + + if ((p_file->p_sfd->stat & 1) == 0 || (p_file->p_sfd->stat & 2) == 0) { + return 38; + } + + if (p_file == 0) { + p_vol = 0; + } else { + p_vol = p_file->p_sfd->dir_entry.p_vol; + } + + if (!p_vol) { + return 38; + } + + cluster_size = p_vol->bpb.bytes_per_sector << p_vol->bpb.log2_sectors_per_cluster; + + start_cluster = p_file->p_sfd->dir_entry.start_cluster; + if (start_cluster != 0) { + file_size = p_file->p_sfd->dir_entry.file_size; + if (file_size % cluster_size) { + v6 = cluster_size - file_size % cluster_size; + } else { + v6 = 0; + } + + file_cluster_size = file_size + v6; + file_size = p_file->p_sfd->dir_entry.file_size; + + if (p_file->p_sfd->ffd.last_cluster.max_chain_index) { + total_allocated_size = ((p_file->p_sfd->ffd.last_cluster.max_chain_index + 1) * cluster_size); + } else { + if (file_size != 0) { + err = VFiPFFAT_TraceClustersChain(&p_file->p_sfd->ffd, start_cluster, file_size, &file_end_cluster, &unused_cluster); + if (err) { + return err; + } + } else { + unused_cluster = start_cluster; + } + + sig_eoc = VFiPFFAT_GetValueOfEOC2(p_vol); + num_append_cluster = 0; + + while (unused_cluster != sig_eoc) { + num_append_cluster++; + err = VFiPFFAT_ReadValueToSpecifiedCluster(p_vol, unused_cluster, &next_cluster); + if (err != 0) { + return err; + } + unused_cluster = next_cluster; + } + + total_allocated_size = (file_cluster_size + num_append_cluster * cluster_size); + } + *p_size = total_allocated_size - file_cluster_size; + } + return 0; +} diff --git a/src/revolution/VF/pf_code.c b/src/revolution/VF/pf_code.c new file mode 100644 index 00000000..0ecfb5e5 --- /dev/null +++ b/src/revolution/VF/pf_code.c @@ -0,0 +1,10 @@ +#include + +int VFiPFCODE_Combine_Width(s16 oem_width, s16 uni_width) { + return (oem_width << 16) + uni_width; +} + +void VFiPFCODE_Divide_Width(u32 width, s16* oem_width, s16* uni_width) { + *oem_width = width >> 16; + *uni_width = width; +} diff --git a/src/revolution/VF/pf_cp932.c b/src/revolution/VF/pf_cp932.c new file mode 100644 index 00000000..01eec538 --- /dev/null +++ b/src/revolution/VF/pf_cp932.c @@ -0,0 +1,188 @@ +#include + +int VFiPFCODE_CP932_OEM2Unicode(const char *src, wchar_t *dst) { + u8 hi; + u8 lo; + int row; + int col; + + lo = (u8)src[0]; + hi = (u8)src[1]; + + if (lo < 0x80) { + *dst = lo; + return VFiPFCODE_Combine_Width(1, 2); + } + + if (lo >= 0xA1 && lo <= 0xDF) { + *dst = lo + 0xFEC0; + return VFiPFCODE_Combine_Width(1, 2); + } + + if (lo == 0x80 || lo == 0x85 || lo == 0x86 || lo == 0xA0 || lo == 0xEB || lo == 0xEC || (lo >= 0xEF && lo <= 0xF9) || (lo >= 0xFD && lo == 0xFF)) { + *dst = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + if (hi >= 0xFD) { + *dst = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + if ((lo >= 0x81) && (lo <= 0x84)) { + row = lo - 0x81; + } else if ((lo >= 0x87) && (lo <= 0x9F)) { + row = lo - 0x83; + } else if ((lo >= 0xE0) && (lo <= 0xEA)) { + row = lo - 0xC3; + } else if ((lo >= 0xED) && (lo <= 0xEE)) { + row = lo - 0xC5; + } else if ((lo >= 0xFA) && (lo <= 0xFC)) { + row = lo - 0xD0; + } else { + *dst = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + col = hi - 0x40; + if (col < 0 || col >= 189) { + *dst = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + *dst = cp932_to_unicode[row][col]; + if (*dst == 0) { + *dst = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + return VFiPFCODE_Combine_Width(2, 2); +} + +int VFiPFCODE_CP932_Unicode2OEM(const wchar_t *src, u8 *dst) { + u8 lo; + u8 hi; + int row; + int col; + u16 oem; + const u16 *row_ptr; + u16 uni; + u16 temp; + + lo = *src & 0xFF; + hi = *src >> 8; + + if ((lo < 0x80) && (hi == 0)) { + dst[0] = (u8)lo; + dst[1] = 0; + return VFiPFCODE_Combine_Width(1, 2); + } + + uni = (u16)((hi << 8) + lo); + if ((0xFF61 <= uni) && (uni <= 0xFF9F)) { + temp = (u16)(uni - 0xFEC0); + dst[0] = (u8)(temp); + dst[1] = 0; + return VFiPFCODE_Combine_Width(1, 2); + } + + if (uni == 0x5F) { + dst[0] = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + row = 0; + while (row < 45) { + row_ptr = cp932_to_unicode[row]; + col = 0; + while (col < 189) { + if (*row_ptr == uni) { + break; + } + col++; + row_ptr++; + } + if (col < 189) { + break; + } + row++; + } + + if (col == 189) { + dst[0] = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + if ((row >= 0) && (row <= 3)) { + oem = ((row + 0x81) << 8) | (col + 0x40); + } else if ((row >= 4) && (row <= 0x1C)) { + oem = ((row + 0x83) << 8) | (col + 0x40); + } else if ((row >= 0x1D) && (row <= 0x27)) { + oem = ((row + 0xC3) << 8) | (col + 0x40); + } else if ((row >= 0x28) && (row <= 0x29)) { + oem = ((row + 0xC5) << 8) | (col + 0x40); + } else if ((row >= 0x2A) && (row <= 0x2C)) { + oem = ((row + 0xD0) << 8) | (col + 0x40); + } else { + dst[0] = 0x5F; + return VFiPFCODE_Combine_Width(1, 2); + } + + dst[1] = (u8)(oem & 0xFF); + dst[0] = (oem >> 8) & 0xFF; + return VFiPFCODE_Combine_Width(2, 2); +} + +int VFiPFCODE_CP932_OEMCharWidth(const char* buf) { + wchar_t temp_uni; + int packed_width; + s16 oem_width; + s16 uni_width; + + packed_width = VFiPFCODE_CP932_OEM2Unicode(buf, &temp_uni); + VFiPFCODE_Divide_Width(packed_width, &oem_width, &uni_width); + return oem_width; +} + +BOOL VFiPFCODE_CP932_isOEMMBchar(char code, u32 type) { + u8 c = (u8)code; + BOOL is_mb = FALSE; + + switch (type) { + case 1: + is_mb = FALSE; + if ((c >= 0x81 && c <= 0x9F) || (c >= 0xE0 && c <= 0xFC)) { + is_mb = TRUE; + } + return is_mb; + + case 2: + is_mb = FALSE; + if ((c >= 0x40 && c <= 0x7E) || (c >= 0x80 && c <= 0xFC)) { + is_mb = TRUE; + } + return is_mb; + } + return is_mb; +} + +s32 VFiPFCODE_CP932_UnicodeCharWidth(const wchar_t* src) { + // Structure preserves stack layout used in the original assembly + struct { + s16 uni_width; // Offset 0 + s16 oem_width; // Offset 2 + u8 temp_buf[2]; // Offset 4 (Buffer for Unicode2OEM output) + } vars; + + VFiPFCODE_Divide_Width( + VFiPFCODE_CP932_Unicode2OEM(src, vars.temp_buf), + &vars.oem_width, + &vars.uni_width + ); + + return vars.uni_width; +} + +u32 VFiPFCODE_CP932_isUnicodeMBchar(void) { + return 0; +} diff --git a/src/revolution/VF/pf_detach.c b/src/revolution/VF/pf_detach.c new file mode 100644 index 00000000..9b80e1e9 --- /dev/null +++ b/src/revolution/VF/pf_detach.c @@ -0,0 +1,5 @@ +#include + +int VFipf2_detach(s8 drive) { + return VFiPFAPI_convertReturnValue(VFiPFVOL_detach(drive)); +} diff --git a/src/revolution/VF/pf_dir.c b/src/revolution/VF/pf_dir.c new file mode 100644 index 00000000..75042d1d --- /dev/null +++ b/src/revolution/VF/pf_dir.c @@ -0,0 +1,21 @@ +#include + +static void VFiPFDIR_FinalizeUDD(PF_DIR* p_dir) { + p_dir->stat &= ~1u; +} + +static void VFiPFDIR_FinalizeSDD(PF_SDD* p_sdd) { + p_sdd->stat = 0; + VFiPFFAT_FinalizeFFD(&p_sdd->ffd); +} + +void VFiPFDIR_FinalizeAllDirs(PF_VOLUME *p_vol) { + u16 i; + for (i = 0; i < 3u; ++i) { + VFiPFDIR_FinalizeSDD(&p_vol->sdds[i]); + } + for (i = 0; i < 3u; ++i) { + VFiPFDIR_FinalizeUDD(&p_vol->udds[i]); + } + p_vol->num_opened_directories = 0; +} diff --git a/src/revolution/VF/pf_driver.c b/src/revolution/VF/pf_driver.c new file mode 100644 index 00000000..31450cb8 --- /dev/null +++ b/src/revolution/VF/pf_driver.c @@ -0,0 +1,370 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +int VFiPFDRV_GetBPBInformation(unsigned char* p_buf, PF_BPB* p_bpb); +s32 VFiPFDRV_GetFSINFOInformation(PF_VOLUME* p_vol); +s32 VFiPFDRV_StoreFreeCountToFSINFO(PF_VOLUME* p_vol); +u32 VFiPFDRV_IsInserted(PF_VOLUME* p_vol); +u32 VFiPFDRV_IsDetected(PF_VOLUME* p_vol); +u32 VFiPFDRV_IsWProtected(PF_VOLUME* p_vol); +int VFiPFDRV_init(int r3); +s32 VFiPFDRV_finalize(PF_VOLUME* p_vol); +s32 VFiPFDRV_mount(PF_VOLUME* p_vol); +s32 VFiPFDRV_unmount(PF_VOLUME* p_vol, u32 mode); +s32 VFiPFDRV_format(PF_VOLUME* p_vol, const u8* param); +s32 VFiPFDRV_lread(PF_VOLUME* p_vol, u8* buf, u32 sector, u32 num_sectors, u32* p_num_success); +s32 VFiPFDRV_lwrite(PF_VOLUME* p_vol, const u8* buf, u32 sector, u32 num_sectors, u32* p_num_success); + +int VFiPFDRV_GetBPBInformation(unsigned char* p_buf, PF_BPB* p_bpb) { + struct PDM_BPB bpb; + + if (VFipdm_bpb_get_bpb_information(p_buf, &bpb)) { + return 7; + } + + p_bpb->bytes_per_sector = bpb.bytes_per_sector; + p_bpb->num_reserved_sectors = bpb.num_reserved_sectors; + p_bpb->num_root_dir_entries = bpb.num_root_dir_entries; + p_bpb->sectors_per_cluster = bpb.sectors_per_cluster; + p_bpb->num_FATs = bpb.num_FATs; + p_bpb->total_sectors = bpb.total_sectors; + p_bpb->sectors_per_FAT = bpb.sectors_per_FAT; + p_bpb->root_dir_cluster = bpb.root_dir_cluster; + p_bpb->fs_info_sector = bpb.fs_info_sector; + p_bpb->backup_boot_sector = bpb.backup_boot_sector; + p_bpb->ext_flags = bpb.ext_flags; + p_bpb->media = bpb.media; + p_bpb->fat_type = bpb.fat_type; + p_bpb->log2_bytes_per_sector = bpb.log2_bytes_per_sector; + p_bpb->log2_sectors_per_cluster = bpb.log2_sectors_per_cluster; + p_bpb->num_active_FATs = bpb.num_active_FATs; + p_bpb->num_root_dir_sectors = bpb.num_root_dir_sectors; + p_bpb->active_FAT_sector = bpb.active_FAT_sector; + p_bpb->first_root_dir_sector = bpb.first_root_dir_sector; + p_bpb->first_data_sector = bpb.first_data_sector; + p_bpb->num_clusters = bpb.num_clusters; + return 0; +} + +static void VFiPFDRV_notifyExecuteFormatAfterMount(PF_VOLUME* p_vol, const u8* format_param) { + p_vol->flags |= 0x10u; + p_vol->format_param = format_param; +} + +static void VFiPFDRV_notifyNoExecuteLogicalFormat(PF_VOLUME* p_vol) { + p_vol->flags |= 0x20u; +} + +static s32 VFiPFDRV_LoadFSINFOInformation(unsigned char* p_buf, PF_VOLUME* p_vol) { + PDM_FSINFO v4; + + if (VFipdm_bpb_get_fsinfo_information(p_buf, &v4)) + return 7; + if (v4.free_count >= 2 && v4.free_count < p_vol->bpb.num_clusters + 2) + p_vol->num_free_clusters = v4.free_count; + if (v4.next_free >= 2 && v4.next_free < p_vol->bpb.num_clusters + 2) + p_vol->last_free_cluster = v4.next_free; + return 0; +} + +s32 VFiPFDRV_GetFSINFOInformation(PF_VOLUME* p_vol) { + int result; + int v3; + int driver_error_code; + int v5; + PF_CACHE_PAGE* p_page; + u32 nSector; + u32 is_valid; + + result = VFiPFCACHE_AllocateDataPage(p_vol, 0xFFFFFFFF, &p_page); + if (result) { + return result; + } + + v3 = VFipdm_part_logical_read(p_vol->p_part, p_page->buffer, p_vol->bpb.fs_info_sector, 1, p_vol->bpb.bytes_per_sector, &nSector); + if (v3) { + if (v3 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + v5 = 4096; + } else { + v5 = -1; + } + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return v5; + } else { + if (VFipdm_bpb_check_fsinfo_sector(p_page->buffer, &is_valid)) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return -1; + } + + if (!is_valid) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return 7; + } + if (VFiPFDRV_LoadFSINFOInformation(p_page->buffer, p_vol)) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return -1; + } + VFiPFCACHE_FreeDataPage(p_vol, p_page); + return 0; + } +} + +s32 VFiPFDRV_StoreFreeCountToFSINFO(PF_VOLUME* p_vol) { + int result; + int v3; + struct PF_CACHE_PAGE* p_page; + u32 num_success; + + result = VFiPFCACHE_AllocateDataPage(p_vol, 0xFFFFFFFF, &p_page); + if (result) { + return result; + } + + v3 = VFiPFDRV_lread(p_vol, p_page->p_buf, p_vol->bpb.fs_info_sector, 1, &num_success); + if (v3 || num_success != 1) + v3 = 17; + if (!v3) { + p_page->p_buf[488] = (u8)(p_vol->num_free_clusters & 0xFF); + p_page->p_buf[489] = (u8)((p_vol->num_free_clusters >> 8) & 0xFF); + p_page->p_buf[490] = (u8)((p_vol->num_free_clusters >> 16) & 0xFF); + p_page->p_buf[491] = (u8)((p_vol->num_free_clusters >> 24) & 0xFF); + v3 = VFiPFDRV_lwrite(p_vol, p_page->p_buf, p_vol->bpb.fs_info_sector, 1u, &num_success); + if (v3 || num_success != 1) + v3 = 17; + } + VFiPFCACHE_FreeDataPage(p_vol, p_page); + return v3; +} + +u32 VFiPFDRV_IsInserted(PF_VOLUME* p_vol) { + u32 is_insert; + VFipdm_part_check_media_insert(p_vol->p_part, &is_insert); + return is_insert; +} + +u32 VFiPFDRV_IsDetected(PF_VOLUME* p_vol) { + u32 is_detect; + VFipdm_part_check_media_detect(p_vol->p_part, &is_detect); + return is_detect; +} + +u32 VFiPFDRV_IsWProtected(PF_VOLUME* p_vol) { + u32 is_wprotect; + VFipdm_part_check_media_write_protect(p_vol->p_part, &is_wprotect); + return is_wprotect; +} + +int VFiPFDRV_init(int r3) { + unsigned int r0 = __cntlzw(r3); + r0 = (r0 << 26) >> 31; + return -r0 & 0xa; +} + + +s32 VFiPFDRV_finalize(PF_VOLUME* p_vol) { + if (p_vol) { + return 0; + } else { + return 10; + } +} + +s32 VFiPFDRV_mount(PF_VOLUME* p_vol) { + int permission; + int driver_error_code; + int v5; + int v6; + int v7; + + PF_CACHE_PAGE* p_page; + u32 nSector; + int BPBInformation; + u32 is_valid; + + PDM_DISK_INFO disk_inf; + + if (!p_vol) + return 10; + permission = VFipdm_part_get_permission(p_vol->p_part); + if (permission) { + if (permission == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } else { + return -1; + } + } else if (VFipdm_part_get_media_information(p_vol->p_part, &disk_inf)) { + VFipdm_part_release_permission(p_vol->p_part, 1); + return -1; + } else { + if ((disk_inf.media_attr & 2) != 0) + VFiPFDRV_notifyExecuteFormatAfterMount(p_vol, disk_inf.format_param); + if ((disk_inf.media_attr & 8) != 0) + VFiPFDRV_notifyNoExecuteLogicalFormat(p_vol); + VFiPFCACHE_AllocateDataPage(p_vol, 0xFFFFFFFF, &p_page); + v5 = VFipdm_part_logical_read(p_vol->p_part, p_page->buffer, 0, 1, 512, &nSector); + if (v5) { + if (v5 == 21) { + v6 = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = v6; + p_vol->last_driver_error = v6; + v7 = 4096; + } else { + v7 = -1; + } + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return v7; + } else if (VFipdm_bpb_check_boot_sector(p_page->buffer, &is_valid)) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return -1; + } else if (!is_valid) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return 7; + } else { + BPBInformation = VFiPFDRV_GetBPBInformation(p_page->buffer, &p_vol->bpb); + if (BPBInformation) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + VFipdm_part_release_permission(p_vol->p_part, 1); + return BPBInformation; + } else { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + p_vol->num_free_clusters = -1; + p_vol->last_free_cluster = -1; + if (p_vol->bpb.fat_type == FAT_32) { + BPBInformation = VFiPFDRV_GetFSINFOInformation(p_vol); + } + } + } + + return BPBInformation; + } +} + +s32 VFiPFDRV_unmount(PF_VOLUME* p_vol, u32 mode) { + int v4; + int driver_error_code; + + if (!p_vol) + return 10; + v4 = VFipdm_part_release_permission(p_vol->p_part, mode == 1); + + if (v4) { + if (v4 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + + return -1; + } + + return 0; +} + +s32 VFiPFDRV_format(PF_VOLUME* p_vol, const u8* param) { + int permission; + int v5; + int v6; + int driver_error_code; + + if (!p_vol) + return 10; + + if ((p_vol->flags & 2) == 0) { + permission = VFipdm_part_get_permission(p_vol->p_part); + if (permission) { + if (permission == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + return -1; + } + } + + v5 = VFipdm_part_format(p_vol->p_part, param); + if (v5) { + if (v5 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + return -1; + } + + if ((p_vol->flags & 2) == 0) { + v6 = VFipdm_part_release_permission(p_vol->p_part, 1); + if (v6) { + if (v6 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + + return -1; + } + } + + return 0; +} + +s32 VFiPFDRV_lread(PF_VOLUME* p_vol, u8* buf, u32 sector, u32 num_sectors, u32* p_num_success) { + int v7; + int driver_error_code; + + if (!p_vol) + return 10; + v7 = VFipdm_part_logical_read(p_vol->p_part, buf, sector, num_sectors, p_vol->bpb.bytes_per_sector, p_num_success); + + if (v7) { + if (v7 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + + return -1; + } + + return 0; +} + +s32 VFiPFDRV_lwrite(PF_VOLUME* p_vol, const u8* buf, u32 sector, u32 num_sectors, u32* p_num_success) { + int v7; + int driver_error_code; + + if (!p_vol) + return 10; + v7 = VFipdm_part_logical_write(p_vol->p_part, buf, sector, num_sectors, p_vol->bpb.bytes_per_sector, p_num_success); + + if (v7) { + if (v7 == 21) { + driver_error_code = VFipdm_part_get_driver_error_code(p_vol->p_part); + VFipf_vol_set.last_driver_error = driver_error_code; + p_vol->last_driver_error = driver_error_code; + return 4096; + } + + return -1; + } + + return 0; +} diff --git a/src/revolution/VF/pf_entry.c b/src/revolution/VF/pf_entry.c new file mode 100644 index 00000000..5a831046 --- /dev/null +++ b/src/revolution/VF/pf_entry.c @@ -0,0 +1,907 @@ +#include + +u32 VFiPFENT_compareAttr(u8 attr, u8 attr_required, u8 attr_unwanted); +s32 VFiPFENT_compareEntryName(struct PF_DIR_ENT* p_ent, struct PF_STR* p_pattern, u8 attr); +s32 VFiPFENT_getEntry(struct PF_DIR_ENT* p_ent, struct PF_ENT_ITER* p_iter, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted, u32* logical_index); +s32 VFiPFENT_searchEmptyTailSFN(struct PF_FFD* p_ffd, u32 tail_index, const s8* pattern, u32* p_tail_bit); +s32 VFiPFENT_findEmptyTailSFN(struct PF_DIR_ENT* p_ent_containig_dir, const s8* name, u32* p_tails); +u8 VFiPFENT_CalcCheckSum(struct PF_DIR_ENT* p_ent); +void VFiPFENT_LoadShortNameFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf); +void VFiPFENT_loadEntryNumericFieldsFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf); +s32 VFiPFENT_LoadLFNEntryFieldsFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf); +void VFiPFENT_storeLFNEntryFieldsToBuf(u8* buf, struct PF_DIR_ENT* p_ent, u8 ord, u8 sum, u32 is_last); +s32 VFiPFENT_findEntryPos(struct PF_FFD* p_ffd, struct PF_DIR_ENT* p_ent, u32 index_search_from, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted, u32* p_lpos, u32* p_ppos); +s32 VFiPFENT_findEntry(struct PF_FFD* p_ffd, struct PF_DIR_ENT* p_ent, u32 index_search_from, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted); +s32 VFiPFENT_allocateEntryPos(struct PF_DIR_ENT* p_ent, u8 num_entries, struct PF_FFD* p_ffd, u32* p_next_chain, struct PF_STR* p_filename, u32* p_pos); +s32 VFiPFENT_allocateEntry(struct PF_DIR_ENT* p_ent, u8 num_entries, struct PF_FFD* p_ffd, u32* p_next_chain, struct PF_STR* p_filename); +s32 VFiPFENT_GetRootDir(struct PF_VOLUME* p_vol, struct PF_DIR_ENT* p_ent); +s32 VFiPFENT_MakeRootDir(struct PF_VOLUME* p_vol); +s32 VFiPFENT_updateEntry(struct PF_DIR_ENT* p_ent, u32 flag); +s32 VFiPFENT_AdjustSFN(struct PF_DIR_ENT* p_ent, s8* p_s16_name); +s32 VFiPFENT_RemoveEntry(struct PF_DIR_ENT* p_ent, struct PF_ENT_ITER* p_iter); +u8 VFiPFENT_getcurrentDateTimeForEnt(u16* p_date, u16* p_time); + +extern PF_VOLUME_SET VFipf_vol_set; +static u8 FAT_DELETED = 0xE5; + +u32 VFiPFENT_compareAttr(u8 attr, u8 attr_required, u8 attr_unwanted) { + u32 is_valid = 1; + if (attr == 0) { + attr = 0x40; + } + if (attr_required & 0x80) { + s32 req = attr_required & 0x7F; + s32 unw = attr_unwanted & 0x7F; + if (req != 0 && req != (req & attr) || ((attr_unwanted & 0x7F) != 0) && (unw == ((attr_unwanted & 0x7F) & attr))) { + is_valid = 0; + } + } else { + if ((attr_required != 0x7F && attr != attr_required) && (!(attr & attr_required) || (attr & attr_unwanted))) { + is_valid = 0; + } + } + return is_valid; +} + +s32 VFiPFENT_compareEntryName(struct PF_DIR_ENT* p_ent, struct PF_STR* p_pattern, u8 attr) { + s32 is_match = 1; + u8 buf[11]; + u8 sum; + u16 i; + + if (p_ent->num_entry_LFNs != 0 && p_ent->ordinal == 1) { + VFiPFPATH_putShortName(buf, (s8*)p_ent->short_name, 0); + sum = 0; + for (i = 0; i < 0xB; i++) { + sum = (sum >> 1) + (((sum & 1) != 0) ? 0x80 : 0) + buf[i]; + } + if (p_ent->check_sum == sum) { + if (VFiPFPATH_cmpNameUni((u16*)p_ent, p_pattern) == 0) { + is_match = 0; + } else { + is_match = 1; + } + } + } + + if (is_match == 1) { + if ((VFipf_vol_set.setting & 2) == 2 && (attr & 8) == 0) { + if (VFiPFPATH_cmpName((s8*)p_ent->short_name, p_pattern, 0) == 0) { + is_match = 0; + } + } else { + if (VFiPFPATH_cmpName((s8*)p_ent->short_name, p_pattern, 1) == 0) { + is_match = 0; + } + } + } + + return is_match; +} + +s32 VFiPFENT_getEntry(struct PF_DIR_ENT* p_ent, struct PF_ENT_ITER* p_iter, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted, u32* logical_index) { + s32 err; + s32 is_match; + u32 is_valid; + u8 attr; + s32 lengthName; + s8 filename[13]; + + attr = p_iter->buf[11]; + is_valid = attr & 0xF; + + if ((s32)is_valid == 0xF) { + is_match = 1; + } else { + if (VFiPFENT_compareAttr(attr, attr_required, attr_unwanted) == 0) { + is_match = 1; + } else { + if ((attr & 8) != 0) { + p_ent->num_entry_LFNs = 0; + p_ent->long_name[0] = 0; + } + + VFiPFPATH_getShortName((s8*)p_ent->short_name, p_iter->buf, p_iter->buf[11]); + if (p_ent->short_name[0] == 5) { + p_ent->short_name[0] = 0xE5; + } + + is_match = VFiPFENT_compareEntryName(p_ent, p_pattern, attr); + + if (is_match == 1) { + (*logical_index)++; + } + } + } + + if (is_match == 1) { + if ((s32)is_valid == 0xF) { + if (VFiPFENT_LoadLFNEntryFieldsFromBuf(p_ent, p_iter->buf) != 0) { + p_ent->num_entry_LFNs = 0; + p_ent->long_name[0] = 0; + } + } else { + p_ent->num_entry_LFNs = 0; + p_ent->long_name[0] = 0; + } + return -1; + } + + if (p_ent->num_entry_LFNs == 0 && (p_iter->buf[12] & 0x18) != 0) { + u16 i; + u8 sum; + u8 sum_buf[16]; + + VFiPFPATH_getLongNameformShortName((s8*)p_ent->short_name, filename, p_iter->buf[12]); + lengthName = VFiPFPATH_transformInUnicode((u16*)p_ent->long_name, filename); + + p_ent->num_entry_LFNs = (lengthName / 13) + (lengthName % 13 != 0); + + VFiPFPATH_putShortName(sum_buf, (s8*)p_ent->short_name, 0); + sum = 0; + for (i = 0; i < 11; i++) { + sum = (sum >> 1) + ((sum & 1) ? 0x80 : 0) + sum_buf[i]; + } + p_ent->check_sum = sum; + p_ent->ordinal = 1; + } + + p_ent->attr = p_iter->buf[11]; + p_ent->small_letter_flag = p_iter->buf[12]; + p_ent->create_time_ms = p_iter->buf[13]; + p_ent->create_time = SWAP16(*(u16*)&p_iter->buf[14]); + p_ent->create_date = SWAP16(*(u16*)&p_iter->buf[16]); + p_ent->access_date = SWAP16(*(u16*)&p_iter->buf[18]); + p_ent->modify_time = SWAP16(*(u16*)&p_iter->buf[22]); + p_ent->modify_date = SWAP16(*(u16*)&p_iter->buf[24]); + p_ent->file_size = SWAP32(*(u32*)&p_iter->buf[28]); + + p_ent->start_cluster = ((SWAP16(*(u16*)&p_iter->buf[20])) << 16) | ((u16)(SWAP16(*(u16*)&p_iter->buf[26]))); + + p_ent->entry_sector = p_iter->sector; + p_ent->entry_offset = p_iter->offset; + + if ((p_ent->attr & 0x10) != 0 && p_ent->start_cluster == 0) { + p_ent->start_cluster = 1; + } + return 0; +} + +s32 VFiPFENT_searchEmptyTailSFN(struct PF_FFD* p_ffd, u32 tail_index, const s8* pattern, u32* p_tail_bit) { + struct PF_ENT_ITER iter; + u8 attr; + s32 err; + u32 bit_pos; + u32 sfn_taillen; + u32 sfn_baselen; + u32 i; + s8 sfnbuf[13]; + s8 patbuf[13]; + struct PF_VOLUME* p_vol; + + p_vol = p_ffd->p_vol; + VFipf_memset(p_tail_bit, 0, 4 * p_vol->tail_entry.tracker_size); + iter.ffd = *p_ffd; + for (err = VFiPFENT_ITER_IteratorInitialize(&iter, 0); !VFiPFENT_ITER_IsAtLogicalEnd(&iter); err = VFiPFENT_ITER_Advance(&iter, 0)) { + if (err) { + return err; + } + if (!iter.buf[0]) { + break; + } + if (iter.buf[0] != 229 && (iter.buf[11] & 0xF) != 0xF && (iter.buf[11] & 8) == 0) { + VFiPFPATH_getShortName(sfnbuf, iter.buf, 0); + for (sfn_taillen = 1; sfnbuf[sfn_taillen] != 126 && sfnbuf[sfn_taillen] && sfn_taillen < 7; ++sfn_taillen); + if (sfn_taillen < 7 && sfnbuf[sfn_taillen] == 126) { + for (sfn_baselen = sfn_taillen + 1; sfnbuf[sfn_baselen] >= 48 && sfnbuf[sfn_baselen] <= 57; ++sfn_baselen); + if (sfnbuf[sfn_baselen] == 46 || !sfnbuf[sfn_baselen]) { + i = sfn_baselen - sfn_taillen - 1; + bit_pos = 0; + while (i) { + bit_pos = bit_pos * 10; + bit_pos += sfnbuf[sfn_baselen - i] - 48; + i--; + } + VFipf_strcpy(patbuf, pattern); + VFiPFPATH_parseShortNameNumeric(patbuf, bit_pos); + if (!VFiPFPATH_cmpTailSFN(sfnbuf, patbuf) && bit_pos >= tail_index && + bit_pos < 32 * p_vol->tail_entry.tracker_size + tail_index) { + bit_pos -= tail_index; + p_tail_bit[bit_pos >> 5] |= 1u << bit_pos; + } + } + } + } + } + return 0; +} + +s32 VFiPFENT_findEmptyTailSFN(struct PF_DIR_ENT* p_ent_containig_dir, const s8* name, u32* p_tails) { + struct PF_FFD ffd; + struct PF_FAT_HINT hint; + s32 err; + u32 num; + struct PF_VOLUME* p_vol; + u32 track_num; + + p_vol = p_ent_containig_dir->p_vol; + *p_tails = 1; + VFiPFFAT_InitFFD(&ffd, &hint, p_ent_containig_dir->p_vol, &p_ent_containig_dir->start_cluster); + for (num = 1; num <= 0xF423F; num += 32 * p_vol->tail_entry.tracker_size) { + err = VFiPFENT_searchEmptyTailSFN(&ffd, num, name, p_vol->tail_entry.tracker_bits); + if (err) + return err; + for (track_num = 0; track_num < p_vol->tail_entry.tracker_size; ++track_num) { + if (p_vol->tail_entry.tracker_bits[track_num] != -1) { + while ((p_vol->tail_entry.tracker_bits[track_num] & 1) != 0) { + p_vol->tail_entry.tracker_bits[track_num] >>= 1; + ++*p_tails; + } + num = 1000000; + break; + } + *p_tails += 32; + } + } + return 0; +} + +u8 VFiPFENT_CalcCheckSum(struct PF_DIR_ENT* p_ent) { + u16 i; + u8 sum; + u8 buf[13]; + + VFiPFPATH_putShortName(buf, p_ent->short_name, 0); + sum = 0; + for (i = 0; i < 0xB; i++) { + sum = (sum >> 1) + (((sum & 0x1) != 0) ? 0x80 : 0) + buf[i]; + } + return sum; +} + +void VFiPFENT_LoadShortNameFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf) { + VFiPFPATH_getShortName(p_ent->short_name, buf, buf[11]); + if (p_ent->short_name[0] == 5) { + p_ent->short_name[0] = -27; + } +} + +void VFiPFENT_loadEntryNumericFieldsFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf) { + p_ent->attr = buf[11]; + p_ent->small_letter_flag = buf[12]; + p_ent->create_time_ms = buf[13]; + + p_ent->create_time = SWAP16(*(u16*)&buf[14]); + p_ent->create_date = SWAP16(*(u16*)&buf[16]); + p_ent->access_date = SWAP16(*(u16*)&buf[18]); + p_ent->modify_time = SWAP16(*(u16*)&buf[22]); + p_ent->modify_date = SWAP16(*(u16*)&buf[24]); + p_ent->file_size = SWAP32(*(u32*)&buf[28]); + + p_ent->start_cluster = ((SWAP16(*(u16*)&buf[20])) << 16) | ((u16)(SWAP16(*(u16*)&buf[26]))); +} + +s32 VFiPFENT_LoadLFNEntryFieldsFromBuf(struct PF_DIR_ENT* p_ent, const u8* buf) { + u8 ordinal; + u8 check_sum; + u32 is_last; + u8* p; + u16* q; + u16* q_after; + + ordinal = buf[0]; + check_sum = buf[13]; + + if ((ordinal & ~0x40) > 20) { + p_ent->ordinal = 0; + p_ent->check_sum = 0; + p_ent->num_entry_LFNs = 0; + return 33; + } + + if (ordinal & 0x40) { + ordinal &= ~0x40; + p_ent->num_entry_LFNs = 0; + is_last = 1; + } else { + is_last = 0; + if (p_ent->num_entry_LFNs == 0) { + return 33; + } + + if (ordinal != p_ent->ordinal - 1 || check_sum != p_ent->check_sum) { + p_ent->ordinal = 0; + p_ent->check_sum = 0; + p_ent->num_entry_LFNs = 0; + return 33; + } + } + + p_ent->ordinal = ordinal; + p_ent->check_sum = check_sum; + + p = (u8*)p_ent->long_name + (ordinal - 1) * 26; + + VFipf_memcpy(p, (void*)(buf + 1), 10); + VFipf_memcpy(p + 10, (void*)(buf + 14), 12); + VFipf_memcpy(p + 22, (void*)(buf + 28), 4); + + VFiPF_LE16_TO_U16_STR(p, 10); + VFiPF_LE16_TO_U16_STR(p + 10, 12); + VFiPF_LE16_TO_U16_STR(p + 22, 4); + + if (is_last) { + *((u16*)(p + 26)) = 0; + q = (u16*)p; + q_after = (u16*)(p + 26); + + while (q < q_after) { + if (*q == 0x0000) { + q++; + break; + } + q++; + } + + while (q < q_after) { + if (*q != 0xFFFF) { + p_ent->num_entry_LFNs = 0; + return 33; + } + q++; + } + } + + p_ent->num_entry_LFNs++; + return 0; +} + +void VFiPFENT_storeLFNEntryFieldsToBuf(u8* buf, struct PF_DIR_ENT* p_ent, u8 ord, u8 sum, u32 is_last) { + u8* p_seg; + u16* p; + u16* p_after; + + if (is_last) { + buf[0] = ord | 0x40; + } else { + buf[0] = ord; + } + + buf[11] = 0x0F; + buf[13] = sum; + buf[12] = 0; + *(u16*)&buf[26] = 0; + + p_seg = (u8*)p_ent->long_name + (u32)(ord - 1) * 26; + + if (is_last) { + p = (u16*)p_seg; + p_after = (u16*)(p_seg + 26); + + while (p < p_after) { + if (*p == 0) { + p++; + break; + } + p++; + } + + while (p < p_after) { + *p++ = 0xFFFF; + } + } + + VFipf_memcpy(buf + 1, p_seg, 10); + VFipf_memcpy(buf + 14, p_seg + 10, 12); + VFipf_memcpy(buf + 28, p_seg + 22, 4); + + VFiPF_LE16_TO_U16_STR(buf + 1, 10); + VFiPF_LE16_TO_U16_STR(buf + 14, 12); + VFiPF_LE16_TO_U16_STR(buf + 28, 4); +} + +s32 VFiPFENT_findEntryPos(struct PF_FFD* p_ffd, struct PF_DIR_ENT* p_ent, u32 index_search_from, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted, u32* p_lpos, u32* p_ppos) { + s32 err; + struct PF_ENT_ITER iter; + u32 logical_index; + u32 is_extsfn; + u32 start_idx; + + start_idx = index_search_from; + is_extsfn = 0; + + if (!p_ffd) { + *p_lpos = 999999; + *p_ppos = 999999; + return 10; + } + + if (!p_ent) { + *p_lpos = 999999; + *p_ppos = 999999; + return 10; + } + + if (index_search_from >= 999999) { + *p_lpos = 999999; + *p_ppos = 999999; + return 10; + } + + if (!p_pattern) { + *p_lpos = 999999; + *p_ppos = 999999; + return 10; + } + + if ((attr_required & attr_unwanted) != 0) { + *p_lpos = 999999; + *p_ppos = 999999; + return 10; + } + + *p_lpos = 0; + *p_ppos = 0; + + p_ent->num_entry_LFNs = 0; + p_ent->ordinal = 0; + p_ent->check_sum = 0; + p_ent->long_name[0] = 0; + + logical_index = 0; + + if ((VFipf_vol_set.setting & 2) == 2) { + is_extsfn = VFiPFPATH_GetExtShortNameIndex(p_pattern, &start_idx); + } + + iter.ffd = *p_ffd; + + if (is_extsfn == 1) { + err = VFiPFENT_ITER_IteratorInitialize(&iter, start_idx - 1); + if (err != 0) { + *p_lpos = 999999; + *p_ppos = 999999; + return err; + } + + err = VFiPFENT_getEntry(p_ent, &iter, p_pattern, attr_required, attr_unwanted, &logical_index); + + if (err == 0) { + *p_lpos = 999999; + *p_ppos = 999999; + return 3; + } + + if ((iter.buf[0] & 0x40) != 0) { + err = VFiPFENT_ITER_IteratorInitialize(&iter, start_idx); + if (err != 0) { + *p_lpos = 999999; + *p_ppos = 999999; + return err; + } + + err = VFiPFENT_getEntry(p_ent, &iter, p_pattern, attr_required, attr_unwanted, &logical_index); + + if (err == 0) { + p_ent->p_vol = p_ffd->p_vol; + *p_lpos = logical_index; + *p_ppos = iter.index; + return 0; + } + } + + } else { + err = VFiPFENT_ITER_IteratorInitialize(&iter, start_idx); + while (VFiPFENT_ITER_IsAtLogicalEnd(&iter) == 0) { + if (err != 0) { + *p_lpos = 999999; + *p_ppos = 999999; + return err; + } + if (iter.buf[0] == 0) { + break; + } + if (iter.buf[0] == 0xE5) { + p_ent->num_entry_LFNs = 0; + p_ent->long_name[0] = 0; + + } else { + err = VFiPFENT_getEntry(p_ent, &iter, p_pattern, attr_required, attr_unwanted, &logical_index); + + if (err == 0) { + p_ent->p_vol = p_ffd->p_vol; + *p_lpos = logical_index; + *p_ppos = iter.index; + return 0; + } + } + + err = VFiPFENT_ITER_Advance(&iter, 0); + } + } + + *p_lpos = 999999; + *p_ppos = 999999; + return 3; +} + +s32 VFiPFENT_findEntry(struct PF_FFD* p_ffd, struct PF_DIR_ENT* p_ent, u32 index_search_from, struct PF_STR* p_pattern, u8 attr_required, u8 attr_unwanted) { + u32 logical_pos; + u32 physical_pos; + + return VFiPFENT_findEntryPos(p_ffd, p_ent, index_search_from, p_pattern, attr_required, attr_unwanted, &logical_pos, &physical_pos); +} + +s32 VFiPFENT_allocateEntryPos(struct PF_DIR_ENT* p_ent, u8 num_entries, struct PF_FFD* p_ffd, u32* p_next_chain, struct PF_STR* p_filename, u32* p_pos) { + s32 err; + struct PF_VOLUME* p_vol; + struct PF_ENT_ITER iter; + struct PF_DIR_ENT wk_ent; + u32 wk_sector; + u16 wk_offset; + u32 prev_sector; + u32 next_sector1; + u32 next_sector2; + u32 is_found; + u32 sector; + u32 count_unused_entries; + u32 physical_index; + u32 dummy_index; + + if (!p_ffd) { + return 10; + } + if (!p_ffd->p_vol) { + return 10; + } + if (!num_entries) { + return 10; + } + if (num_entries > 21) { + return 10; + } + + if ((VFipf_vol_set.setting & 2) == 2) { + if ((u32)VFiPFPATH_CheckExtShortNameSignature(p_filename) == 1) { + return 1; + } + } + + p_vol = p_ffd->p_vol; + count_unused_entries = 0; + physical_index = 0; + + wk_sector = -1; + wk_offset = 0; + p_next_chain[1] = -1; + p_next_chain[0] = -1; + prev_sector = -1; + next_sector2 = -1; + next_sector1 = -1; + is_found = 0; + + iter.sector = 0; + iter.index = 0; + iter.ffd = *p_ffd; + err = VFiPFENT_ITER_IteratorInitialize(&iter, 0); + + while (1) { + if (err != 0) { + if (err == 16) { + break; + } + return err; + } + + if (iter.sector == -1) { + break; + } + if (is_found == 0 && count_unused_entries == 0) { + wk_offset = iter.offset; + wk_sector = iter.sector; + prev_sector = iter.sector; + } + if (is_found == 0) { + if (iter.buf[0] == 0 || iter.buf[0] == 0xE5) { + if (prev_sector != iter.sector) { + if (next_sector1 == -1) { + next_sector1 = iter.sector; + } else { + next_sector2 = iter.sector; + } + prev_sector = iter.sector; + } + count_unused_entries++; + } else { + count_unused_entries = 0; + next_sector1 = -1; + next_sector2 = -1; + } + } + if (count_unused_entries >= num_entries) { + if (is_found == 0) { + physical_index = iter.index; + is_found = 1; + } + if (iter.buf[0] == 0) { + break; + } + } + if (iter.buf[0] != 0 && iter.buf[0] != 0xE5) { + err = VFiPFENT_getEntry(&wk_ent, &iter, p_filename, 0x7F, 0, &dummy_index); + if (err == 0) { + *p_ent = wk_ent; + p_ent->p_vol = p_ffd->p_vol; + return 8; + } + } + if (iter.offset + 32 == p_vol->bpb.bytes_per_sector) { + err = VFiPFFAT_GetSectorSpecified(p_ffd, iter.file_sector_index + 1, 0, §or); + if (err != 0) { + return err; + } + if (sector == -1 && is_found == 1) { + break; + } + } + err = VFiPFENT_ITER_Advance(&iter, 1); + } + + if (is_found == 0) { + return 5; + } + + p_next_chain[0] = next_sector1; + p_next_chain[1] = next_sector2; + p_ent->entry_sector = wk_sector; + p_ent->entry_offset = wk_offset; + *p_pos = physical_index; + return 0; +} + +s32 VFiPFENT_allocateEntry(struct PF_DIR_ENT* p_ent, u8 num_entries, struct PF_FFD* p_ffd, u32* p_next_chain, struct PF_STR* p_filename) { + u32 position; + + return VFiPFENT_allocateEntryPos(p_ent, num_entries, p_ffd, p_next_chain, p_filename, &position); +} + +s32 VFiPFENT_GetRootDir(struct PF_VOLUME* p_vol, struct PF_DIR_ENT* p_ent) { + if (!p_vol) { + return 10; + } + if (!p_ent) { + return 10; + } + if ((p_vol->flags & 2) == 0) { + return 9; + } + + p_ent->long_name[0] = 92; + p_ent->long_name[1] = 0; + + p_ent->num_entry_LFNs = 0; + p_ent->ordinal = 0; + p_ent->check_sum = 0; + + p_ent->short_name[0] = 92; + p_ent->short_name[1] = 0; + p_ent->small_letter_flag = 0; + + p_ent->attr = 0x10; + + p_ent->create_time_ms = 0; + p_ent->create_time = 0; + p_ent->create_date = 0; + p_ent->access_date = 0; + p_ent->modify_time = 0; + p_ent->modify_date = 0; + p_ent->file_size = 0; + + p_ent->p_vol = p_vol; + p_ent->path_len = 3; + p_ent->start_cluster = 1; + p_ent->entry_sector = -1; + p_ent->entry_offset = 0; + + return 0; +} + +s32 VFiPFENT_MakeRootDir(struct PF_VOLUME* p_vol) { + struct PF_CACHE_PAGE* p_page; + u32 sector; + u32 success_size; + s32 err; + + if (!p_vol) { + return 10; + } + + switch (p_vol->bpb.fat_type) { + case FAT_32: + VFiPFFAT_MakeRootDir(p_vol); + break; + case FAT_12: + case FAT_16: + err = VFiPFCACHE_AllocateDataPage(p_vol, 0xFFFFFFFF, &p_page); + if (err != 0) { + return err; + } + + VFipf_memset(p_page->p_buf, 0, p_vol->bpb.bytes_per_sector); + + for (sector = p_vol->bpb.first_root_dir_sector; sector < p_vol->bpb.first_data_sector; sector++) { + err = VFiPFSEC_WriteData(p_vol, p_page->p_buf, sector, 0, p_vol->bpb.bytes_per_sector, &success_size, 0); + if (err != 0) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + return err; + } + + if (success_size != p_vol->bpb.bytes_per_sector) { + VFiPFCACHE_FreeDataPage(p_vol, p_page); + return 17; + } + } + + VFiPFCACHE_FreeDataPage(p_vol, p_page); + break; + default: + return 7; + } + + // VFiPFVOL_LoadVolumeLabelFromBuf((const u8*)"NO NAME ", p_vol); + VFiPFVOL_LoadVolumeLabelFromBuf((const u8*)"NO NAME \0\0\0\0", p_vol); + return 0; +} + +s32 VFiPFENT_updateEntry(struct PF_DIR_ENT* p_ent, u32 flag) { + struct PF_VOLUME* p_vol; + u32 success_size; + u8 buf[32]; + s32 err; + + if (!p_ent) { + return 10; + } + + p_vol = p_ent->p_vol; + if (!p_vol) { + return 10; + } + + if (p_ent->entry_sector < p_vol->bpb.first_data_sector - p_vol->bpb.num_root_dir_sectors) { + return 28; + } + + if (p_ent->entry_sector >= p_vol->bpb.total_sectors) { + return 16; + } + + if (p_ent->start_cluster == 1) { + return 14; + } + + if (flag == 1) { + p_ent->attr |= 0x20; + } + + VFiPFPATH_putShortName(buf, p_ent->short_name, p_ent->attr); + + if (buf[0] == 0xE5) { + buf[0] = 5; + } + + buf[11] = p_ent->attr; + buf[12] = p_ent->small_letter_flag; + buf[13] = p_ent->create_time_ms; + + *(u16*)&buf[14] = SWAP16(p_ent->create_time); + *(u16*)&buf[16] = SWAP16(p_ent->create_date); + *(u16*)&buf[18] = SWAP16(p_ent->access_date); + *(u16*)&buf[22] = SWAP16(p_ent->modify_time); + *(u16*)&buf[24] = SWAP16(p_ent->modify_date); + *(u16*)&buf[20] = SWAP16((u16)(p_ent->start_cluster >> 16)); + *(u16*)&buf[26] = SWAP16(p_ent->start_cluster); + *(u32*)&buf[28] = SWAP32(p_ent->file_size); + + err = VFiPFSEC_WriteData(p_vol, buf, p_ent->entry_sector, p_ent->entry_offset, 32, &success_size, 0); + + if (err != 0) { + return err; + } + + return (success_size != 32) ? 17 : 0; +} + +s32 VFiPFENT_AdjustSFN(struct PF_DIR_ENT* p_ent, s8* p_s16_name) { + u32 i; + u32 tail_num; + s32 err; + + for (i = 1; p_s16_name[i] != 126 && p_s16_name[i] != 0 && i < 7; ++i) { + } + + if (i < 7 && p_s16_name[i] == 126) { + for (i = i + 1; p_s16_name[i] >= 48 && p_s16_name[i] <= 57; ++i) { + } + + if (p_s16_name[i] == 46 || p_s16_name[i] == 0) { + err = VFiPFENT_findEmptyTailSFN(p_ent, p_s16_name, &tail_num); + if (err != 0) { + return err; + } + + if (tail_num != 1) { + VFiPFPATH_parseShortNameNumeric(p_s16_name, tail_num); + } + } + } + return 0; +} + +s32 VFiPFENT_RemoveEntry(struct PF_DIR_ENT* p_ent, struct PF_ENT_ITER* p_iter) { + u32 success_size; + s32 err; + u32 entry_sector; + u16 entry_offset; + u32 i; + struct PF_VOLUME* p_vol; + u8 dir_fb_free[1]; + + dir_fb_free[0] = FAT_DELETED; + p_vol = p_ent->p_vol; + + if (!p_vol) { + return 10; + } + if (!p_ent) { + return 10; + } + if (!p_iter) { + return 10; + } + + if (p_ent->num_entry_LFNs != 0 && (p_ent->small_letter_flag & 0x18) == 0) { + for (i = 1; i <= p_ent->num_entry_LFNs; ++i) { + err = VFiPFENT_ITER_Retreat(p_iter, 0); + if (err != 0) { + return err; + } + + err = VFiPFSEC_WriteData(p_vol, dir_fb_free, p_iter->sector, p_iter->offset, 1, &success_size, 0); + if (err != 0) { + return err; + } + + if (success_size != 1) { + return 17; + } + } + } + + err = VFiPFSEC_WriteData(p_vol, dir_fb_free, p_ent->entry_sector, p_ent->entry_offset, 1, &success_size, 0); + if (err != 0) { + return err; + } + + if (success_size != 1) { + return 17; + } else { + err = VFiPFCACHE_FlushDataCacheSpecific(p_vol, 0); + if (err != 0) { + return err; + } + return 0; + } +} + +u8 VFiPFENT_getcurrentDateTimeForEnt(u16* p_date, u16* p_time) { + struct PF_SYS_DATE sys_date; + struct PF_SYS_TIME sys_time; + + VFiPFSYS_TimeStamp(&sys_date, &sys_time); + + *p_date = (((sys_date.sys_year - 1980) & 0x7F) << 9) | ((sys_date.sys_month & 0x0F) << 5) | ((sys_date.sys_day & 0x1F) << 0); + *p_time = ((sys_time.sys_hour & 0x1F) << 11) | ((sys_time.sys_min & 0x3F) << 5) | ((sys_time.sys_sec >> 1) & 0x1F); + + return sys_time.sys_ms; +} diff --git a/src/revolution/VF/pf_errnum.c b/src/revolution/VF/pf_errnum.c new file mode 100644 index 00000000..f7d613d2 --- /dev/null +++ b/src/revolution/VF/pf_errnum.c @@ -0,0 +1,5 @@ +#include + +int VFipf2_errnum(void) { + return VFiPFAPI_convertError(VFiPFVOL_errnum()); +} diff --git a/src/revolution/VF/pf_fat12.c b/src/revolution/VF/pf_fat12.c new file mode 100644 index 00000000..b23bb5f1 --- /dev/null +++ b/src/revolution/VF/pf_fat12.c @@ -0,0 +1,389 @@ +#include + +s32 VFiPFFAT12_ReadFATEntry(PF_VOLUME* p_vol, u16 cluster, u32* p_value) { + long err; + unsigned short fat_offset; + unsigned short fat_sector; + unsigned short offset_in_sector; + unsigned short word; + unsigned char buf[2]; + unsigned long current_fat; + long result; + + if (!p_vol) { + *p_value = -1; + return 10; + } + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + *p_value = -1; + return 14; + } + + fat_offset = (u16)(cluster + (cluster >> 1)); + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = (u16)(fat_offset & (p_vol->bpb.bytes_per_sector - 1)); + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (u32)(p_vol->bpb.ext_flags & 7); + } + + do { + if (offset_in_sector < p_vol->bpb.bytes_per_sector - 1) { + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 2); + } else { + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 1); + if (err == 0) { + err = VFiPFSEC_ReadFAT(p_vol, &buf[1], fat_sector + 1, 0, 1); + } + } + + if (err == 0x1000 && p_vol->p_callback != 0) { + result = ((s32(*)(s32))p_vol->p_callback)(p_vol->last_driver_error); + + if (result == 0) { + goto loop_check; + } + + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < (u32)p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += (u16)p_vol->bpb.sectors_per_FAT; + goto loop_check; + } + } + + if (err != 0) { + *p_value = -1; + return err; + } + + loop_check:; + } while (err != 0); + + word = *(u16*)buf; + word = SWAP16(word); + if ((cluster & 1) != 0) { + *p_value = word >> 4; + } else { + *p_value = word & 0xFFF; + } + + return 0; +} + +s32 VFiPFFAT12_ReadFATEntryPage(PF_VOLUME* p_vol, u16 cluster, u32* p_value, PF_CACHE_PAGE** pp_page) { + long err; + unsigned long offset; + unsigned long sector; + unsigned long current_fat; + long result; + + if (!p_vol) { + return 10; + } + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + offset = (u16)(cluster + (cluster >> 1)); + sector = p_vol->bpb.active_FAT_sector + (offset >> p_vol->bpb.log2_bytes_per_sector) & 0xFFFF; + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (u32)(p_vol->bpb.ext_flags & 7); + } + + err = 0; + do { + if (err == 0x1000 && p_vol->p_callback != 0) { + result = ((s32(*)(s32))p_vol->p_callback)(p_vol->last_driver_error); + if (result == 0) { + err = 0; + continue; + } + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < (u32)p_vol->bpb.num_active_FATs) { + current_fat++; + sector += p_vol->bpb.sectors_per_FAT; + err = 0; + continue; + } + + } else { + if ((*pp_page)->sector > sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= sector) { + if ((*pp_page)->option == 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + } + + err = VFiPFCACHE_ReadFATPage(p_vol, sector, pp_page); + if (err != 0) { + continue; + } + } else { + if (sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + offset &= (p_vol->bpb.bytes_per_sector - 1); + + if (offset == p_vol->bpb.bytes_per_sector - 1) { + *p_value = (*pp_page)->p_buf[offset]; + sector++; + + if ((*pp_page)->sector > sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= sector) { + if ((*pp_page)->option == 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + } + + err = VFiPFCACHE_ReadFATPage(p_vol, sector, pp_page); + if (err != 0) { + return err; + } + } else { + if (sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + *p_value += ((*pp_page)->p_buf[0] << 8); + } else { + *p_value = ((*pp_page)->p_buf[offset + 1] << 8) + (*pp_page)->p_buf[offset]; + } + } + break; + } while (1); + if (err != 0) { + *p_value = -1; + return err; + } + + if ((cluster & 1) != 0) { + *p_value >>= 4; + } else { + *p_value &= 0xFFF; + } + + return 0; +} + +s32 VFiPFFAT12_WriteFATEntry(PF_VOLUME* p_vol, u16 cluster, u16 value) { + long err; + u16 fat_offset; + u16 fat_sector; + u16 offset_in_sector; + u16 fat_sector2; + u16 offset_in_sector2; + u16 word; + u8 buf[2]; + + if (!p_vol) { + return 10; + } + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + fat_offset = (u16)(cluster + (cluster >> 1)); + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = (u16)(fat_offset & (p_vol->bpb.bytes_per_sector - 1)); + + if ((cluster & 1) != 0) { + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 1); + if (err != 0) { + return err; + } + word = (u16)((value << 4) + (buf[0] & 0xF)); + } else { + fat_sector2 = (u16)(p_vol->bpb.active_FAT_sector + ((fat_offset + 1) >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector2 = (u16)((fat_offset + 1) & (p_vol->bpb.bytes_per_sector - 1)); + + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector2, offset_in_sector2, 1); + if (err != 0) { + return err; + } + word = (u16)(((buf[0] << 8) & 0xF000) + (value & 0xFFF)); + } + + *(u16*)buf = SWAP16(word); + + if (offset_in_sector < p_vol->bpb.bytes_per_sector - 1) { + err = VFiPFSEC_WriteFAT(p_vol, buf, fat_sector, offset_in_sector, 2); + } else { + err = VFiPFSEC_WriteFAT(p_vol, buf, fat_sector, offset_in_sector, 1); + if (err == 0) { + err = VFiPFSEC_WriteFAT(p_vol, &buf[1], fat_sector + 1, 0, 1); + } + } + + return err; +} + +s32 VFiPFFAT12_WriteFATEntryPage(PF_VOLUME* p_vol, u16 cluster, u16 value, PF_CACHE_PAGE** pp_page) { + long err; + u32 fat_offset; + u32 fat_sector; + u16 offset_in_sector; + u32 current_fat; + long result; + + err = 0; + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + fat_offset = (u16)(cluster + (cluster >> 1)); + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = (u16)(fat_offset & (p_vol->bpb.bytes_per_sector - 1)); + + if ((*pp_page)->sector > fat_sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= fat_sector) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, fat_sector, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + } else { + if (fat_sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + if ((cluster & 1) != 0) { + (*pp_page)->p_buf[offset_in_sector] = (u8)(((*pp_page)->p_buf[offset_in_sector] & 0x0F) | ((value << 4) & 0xF0)); + VFiPFCACHE_UpdateModifiedSector(*pp_page); + + if (offset_in_sector == (u32)(p_vol->bpb.bytes_per_sector - 1)) { + if ((*pp_page)->sector > fat_sector + 1 || (*pp_page)->sector + p_vol->cache.fat_buff_size <= fat_sector + 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, fat_sector + 1, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check2; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check2:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + VFiPFCACHE_UpdateModifiedSector(*pp_page); + } else { + if (fat_sector + 1 != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + VFiPFCACHE_UpdateModifiedSector(*pp_page); + } + } + + (*pp_page)->p_buf[0] = (u8)(value >> 4); + } else { + (*pp_page)->p_buf[offset_in_sector + 1] = (u8)(value >> 4); + } + } else { + (*pp_page)->p_buf[offset_in_sector] = (u8)value; + VFiPFCACHE_UpdateModifiedSector(*pp_page); + + if (offset_in_sector == (u32)(p_vol->bpb.bytes_per_sector - 1)) { + if ((*pp_page)->sector > fat_sector + 1 || (*pp_page)->sector + p_vol->cache.fat_buff_size <= fat_sector + 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, fat_sector + 1, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check3; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check3:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + VFiPFCACHE_UpdateModifiedSector(*pp_page); + } else { + if (fat_sector + 1 != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + VFiPFCACHE_UpdateModifiedSector(*pp_page); + } + } + + (*pp_page)->p_buf[0] = ((*pp_page)->p_buf[0] & 0xF0) | (u8)(value >> 8); + } else { + (*pp_page)->p_buf[offset_in_sector + 1] = (u8)((value >> 8) | ((*pp_page)->p_buf[offset_in_sector + 1] & 0xF0)); + } + } + + return err; +} diff --git a/src/revolution/VF/pf_fat16.c b/src/revolution/VF/pf_fat16.c new file mode 100644 index 00000000..67bafbc9 --- /dev/null +++ b/src/revolution/VF/pf_fat16.c @@ -0,0 +1,217 @@ +#include + +s32 VFiPFFAT16_ReadFATEntry(PF_VOLUME* p_vol, u32 cluster, u32* p_value) { + u32 fat_offset; + u32 fat_sector; + u16 offset_in_sector; + u8 buf[2]; + s32 err; + u32 current_fat; + s32 result; + u16 tmp; + + if (!p_vol) { + *p_value = -1; + return 10; + } + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + *p_value = -1; + return 14; + } + + fat_offset = (s64)(cluster << 1); + + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = fat_offset & (p_vol->bpb.bytes_per_sector - 1); + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 2); + + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((s32(*)(s32))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < (u32)p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + *p_value = -1; + return err; + } + } + } + } while (err != 0); + + tmp = *(u16*)buf; + *p_value = SWAP16(tmp); + return 0; +} + +s32 VFiPFFAT16_ReadFATEntryPage(PF_VOLUME* p_vol, u32 cluster, u32* p_value, PF_CACHE_PAGE** pp_page) { + s32 err; + u32 offset; + u32 sector; + u32 current_fat; + s32 result; + u16 tmp; + + err = 0; + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + offset = cluster << 1; + sector = (u16)(p_vol->bpb.active_FAT_sector + (offset >> p_vol->bpb.log2_bytes_per_sector)); + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + if ((*pp_page)->sector > sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= sector) { + if ((*pp_page)->option == 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, sector, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((s32(*)(s32))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + } else { + if (sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + offset &= (p_vol->bpb.bytes_per_sector - 1); + tmp = *((u16*)((*pp_page)->p_buf + offset)); + *p_value = SWAP16(tmp); + + return err; +} + +s32 VFiPFFAT16_WriteFATEntry(PF_VOLUME* p_vol, u32 cluster, u32 value) { + s32 err; + u32 fat_offset; + u16 fat_sector; + u16 offset_in_sector; + u8 buf[2]; + + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + fat_offset = cluster << 1; + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = fat_offset & (p_vol->bpb.bytes_per_sector - 1); + + *(u16*)buf = SWAP16(value); + + err = VFiPFSEC_WriteFAT(p_vol, buf, fat_sector, offset_in_sector, 2); + + return err; +} + +s32 VFiPFFAT16_WriteFATEntryPage(PF_VOLUME* p_vol, u32 cluster, u32 value, PF_CACHE_PAGE** pp_page) { + s32 err; + u32 fat_offset; + u32 fat_sector; + u32 offset_in_sector; + u32 current_fat; + s32 result; + + err = 0; + if (!p_vol) { + return 10; + } + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + fat_offset = (s64)(cluster << 1); + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = (unsigned short)(fat_offset & (p_vol->bpb.bytes_per_sector - 1)); + + if ((*pp_page)->sector > fat_sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= fat_sector) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, fat_sector, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((s32(*)(s32))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + } else { + if (fat_sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + (*pp_page)->p_buf[offset_in_sector] = (u8)value; + (*pp_page)->p_buf[offset_in_sector + 1] = (u8)(value >> 8); + + VFiPFCACHE_UpdateModifiedSector((*pp_page)); + + return err; +} diff --git a/src/revolution/VF/pf_fat32.c b/src/revolution/VF/pf_fat32.c new file mode 100644 index 00000000..ef6e6058 --- /dev/null +++ b/src/revolution/VF/pf_fat32.c @@ -0,0 +1,246 @@ +#include + +long VFiPFSEC_ReadFAT(struct PF_VOLUME* p_vol, unsigned char* p_buf, unsigned long sector, unsigned short offset, unsigned short size); +long VFiPFCACHE_ReadFATPage(struct PF_VOLUME* p_vol, unsigned long sector, struct PF_CACHE_PAGE** pp_page); +long VFiPFFAT_UpdateFATEntry(struct PF_VOLUME* p_vol, struct PF_CACHE_PAGE* p_page); +long VFiPFSEC_WriteFAT(struct PF_VOLUME* p_vol, const unsigned char* p_buf, unsigned long sector, unsigned short offset, unsigned short size); +long VFiPFCACHE_UpdateModifiedSector(struct PF_CACHE_PAGE* p_page); + +long VFiPFFAT32_ReadFATEntry(struct PF_VOLUME* p_vol, unsigned long cluster, unsigned long* p_value) { + unsigned long fat_offset; + unsigned long fat_sector; + unsigned short offset_in_sector; + unsigned char buf[4]; + long err; + unsigned long current_fat; + long result; + unsigned long tmp; + + if (!p_vol) { + *p_value = -1; + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + *p_value = -1; + return 14; + } + + fat_offset = cluster << 2; + current_fat = 1; + + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = fat_offset & (p_vol->bpb.bytes_per_sector - 1); + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = p_vol->bpb.ext_flags & 7; + } + + do { + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 4); + + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + fat_sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + *p_value = -1; + return err; + } + } + } + } while (err != 0); + + tmp = *(unsigned long*)buf; + err = 0; + tmp = SWAP32(tmp); + *p_value = tmp & 0x0FFFFFFF; + + return err; +} + +long VFiPFFAT32_ReadFATEntryPage(struct PF_VOLUME* p_vol, unsigned long cluster, unsigned long* p_value, struct PF_CACHE_PAGE** pp_page) { + long err; + unsigned long offset; + unsigned long sector; + unsigned long current_fat; + long result; + unsigned long tmp; + + err = 0; + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + offset = cluster << 2; + sector = (u16)(p_vol->bpb.active_FAT_sector + (offset >> p_vol->bpb.log2_bytes_per_sector)); + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + if ((*pp_page)->sector > sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= sector) { + if ((*pp_page)->option == 1) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, sector, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + } else { + if (sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + offset &= (p_vol->bpb.bytes_per_sector - 1); + tmp = *((unsigned long*)((*pp_page)->p_buf + offset)); + tmp = SWAP32(tmp); + *p_value = tmp & 0x0FFFFFFF; + + return err; +} + +long VFiPFFAT32_WriteFATEntry(struct PF_VOLUME* p_vol, unsigned long cluster, unsigned long value) { + long err; + unsigned long fat_offset; + unsigned long fat_sector; + unsigned short offset_in_sector; + unsigned char buf[4]; + unsigned long dword; + unsigned long tmp; + + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + fat_offset = cluster << 2; + fat_sector = (u16)(p_vol->bpb.active_FAT_sector + (fat_offset >> p_vol->bpb.log2_bytes_per_sector)); + offset_in_sector = fat_offset & (p_vol->bpb.bytes_per_sector - 1); + + err = VFiPFSEC_ReadFAT(p_vol, buf, fat_sector, offset_in_sector, 4); + switch (err) { + case 0: { + tmp = *(unsigned long*)buf; + tmp = SWAP32(tmp); + tmp = (value & 0xFFFFFFF) | (tmp & 0xF0000000); + tmp = SWAP32(tmp); + *(unsigned long*)buf = tmp; + err = VFiPFSEC_WriteFAT(p_vol, buf, fat_sector, offset_in_sector, 4); + break; + } + default: + break; + } + + return err; +} + +long VFiPFFAT32_WriteFATEntryPage(struct PF_VOLUME* p_vol, unsigned long cluster, unsigned long value, struct PF_CACHE_PAGE** pp_page) { + long err; + unsigned long sector; + unsigned long offset; + unsigned long current_fat; + long result; + unsigned long tmp; + + err = 0; + if (!p_vol) { + return 10; + } + + if (!((cluster >= 2) && (cluster < p_vol->bpb.num_clusters + 2)) && (cluster != 0) && (cluster != 1)) { + return 14; + } + + offset = cluster << 2; + sector = (u16)(p_vol->bpb.active_FAT_sector + (offset >> p_vol->bpb.log2_bytes_per_sector)); + offset = (unsigned short)(offset & (p_vol->bpb.bytes_per_sector - 1)); + + if ((*pp_page)->sector > sector || (*pp_page)->sector + p_vol->cache.fat_buff_size <= sector) { + err = VFiPFFAT_UpdateFATEntry(p_vol, *pp_page); + if (err != 0) { + return err; + } + + if ((p_vol->bpb.ext_flags & 0x80) == 0) { + current_fat = 1; + } else { + current_fat = (p_vol->bpb.ext_flags) & 7; + } + + do { + err = VFiPFCACHE_ReadFATPage(p_vol, sector, pp_page); + if (err != 0x1000 || p_vol->p_callback == 0) { + goto check; + } + + result = ((long (*)(long))p_vol->p_callback)(p_vol->last_driver_error); + if (result != 0) { + if (result == 1 && p_vol->bpb.num_active_FATs >= 2 && current_fat < p_vol->bpb.num_active_FATs) { + current_fat++; + sector += p_vol->bpb.sectors_per_FAT; + } else { + check:; + if (err != 0) { + return err; + } + } + } + } while (err != 0); + + } else { + if (sector != (*pp_page)->sector + (((*pp_page)->p_buf - (*pp_page)->buffer) >> p_vol->bpb.log2_bytes_per_sector)) { + (*pp_page)->p_buf += p_vol->bpb.bytes_per_sector; + } + } + + tmp = *(unsigned long*)((*pp_page)->p_buf + offset); + tmp = SWAP32(tmp); + tmp = (value & 0xFFFFFFF) | (tmp & 0xF0000000); + tmp = SWAP32(tmp); + *(unsigned long*)((*pp_page)->p_buf + offset) = tmp; + + VFiPFCACHE_UpdateModifiedSector((*pp_page)); + + return err; +} diff --git a/src/revolution/VF/pf_fatfs.c b/src/revolution/VF/pf_fatfs.c new file mode 100644 index 00000000..c2e5788d --- /dev/null +++ b/src/revolution/VF/pf_fatfs.c @@ -0,0 +1,5 @@ +#include + +void VFiPFFATFS_initializeFATFS(void) { + VFiPFVOL_InitModule(); +} diff --git a/src/revolution/VF/pf_fclose.c b/src/revolution/VF/pf_fclose.c new file mode 100644 index 00000000..daae61ce --- /dev/null +++ b/src/revolution/VF/pf_fclose.c @@ -0,0 +1,5 @@ +#include + +s32 VFipf2_fclose(PF_FILE* p_file) { + return VFiPFAPI_convertReturnValue(VFiPFFILE_fclose(p_file)); +} diff --git a/src/revolution/VF/pf_filelock.c b/src/revolution/VF/pf_filelock.c new file mode 100644 index 00000000..9a470e41 --- /dev/null +++ b/src/revolution/VF/pf_filelock.c @@ -0,0 +1,11 @@ +#include + +static int lbl_804BF478 = 0; + +void VFiPF_InitLockFile() { + lbl_804BF478 = 0; +} + +long VFiPF_UnLockFile(void) { + return -1; +} diff --git a/src/revolution/VF/pf_finfo.c b/src/revolution/VF/pf_finfo.c new file mode 100644 index 00000000..485e89a9 --- /dev/null +++ b/src/revolution/VF/pf_finfo.c @@ -0,0 +1,5 @@ +#include + +s32 VFipf2_finfo(PF_FILE* p_file, PF_INFO* p_info) { + return VFiPFAPI_convertReturnValue(VFiPFFILE_finfo(p_file, p_info)); +} diff --git a/src/revolution/VF/pf_fopen.c b/src/revolution/VF/pf_fopen.c new file mode 100644 index 00000000..0669bceb --- /dev/null +++ b/src/revolution/VF/pf_fopen.c @@ -0,0 +1,34 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +void* VFiPFAPI_convertReturnValue2NULL(int err, void* p_stream); + +PF_FILE* VFipf2_fopen(const char* path, const char* mode) { + s32 open_mode; + PF_FILE* p_ofile; + + // TODO(Alex9303): + // Union forces 8-byte alignment, skipping 0xC and pushing stack to 0x30 + union { + PF_STR str; + s64 _align; + } path_str_u; + + s32 err; + + open_mode = VFiPFAPI_ParseOpenModeString(mode); + + if (open_mode == 0) { + VFipf_vol_set.last_error = 10; + return NULL; + } else { + err = VFiPFSTR_InitStr(&path_str_u.str, (const s8*)path, 1); + if (err == 0) { + err = VFiPFFILE_fopen(&path_str_u.str, open_mode, &p_ofile); + } else { + VFipf_vol_set.last_error = err; + } + } + return VFiPFAPI_convertReturnValue2NULL(err, p_ofile); +} diff --git a/src/revolution/VF/pf_fread.c b/src/revolution/VF/pf_fread.c new file mode 100644 index 00000000..55644416 --- /dev/null +++ b/src/revolution/VF/pf_fread.c @@ -0,0 +1,7 @@ +#include + +s32 VFipf2_fread(u8* p_buf, u32 size, u32 count, PF_FILE* p_file) { + u32 count_read; + VFiPFFILE_fread(p_buf, size, count, p_file, &count_read); + return count_read; +} diff --git a/src/revolution/VF/pf_fseek.c b/src/revolution/VF/pf_fseek.c new file mode 100644 index 00000000..0449a302 --- /dev/null +++ b/src/revolution/VF/pf_fseek.c @@ -0,0 +1,5 @@ +#include + +int VFipf2_fseek(PF_FILE* p_file, int lOffset, int nOrigin) { + return VFiPFAPI_convertReturnValue(VFiPFFILE_fseek(p_file, lOffset, nOrigin)); +} diff --git a/src/revolution/VF/pf_fwrite.c b/src/revolution/VF/pf_fwrite.c new file mode 100644 index 00000000..f829f465 --- /dev/null +++ b/src/revolution/VF/pf_fwrite.c @@ -0,0 +1,7 @@ +#include + +u32 VFipf2_fwrite(u8* p_buf, u32 size, u32 count, PF_FILE* p_file) { + u32 count_written; + VFiPFFILE_fwrite(p_buf, size, count, p_file, &count_written); + return count_written; +} diff --git a/src/revolution/VF/pf_getdev.c b/src/revolution/VF/pf_getdev.c new file mode 100644 index 00000000..96d8f10b --- /dev/null +++ b/src/revolution/VF/pf_getdev.c @@ -0,0 +1,6 @@ +#include + +s32 VFipf2_devinf(u8 drv_char, PF_DEV_INF* dev_inf) { + int result = VFiPFVOL_getdev((s8)drv_char, dev_inf); + return VFiPFAPI_convertReturnValue(result); +} diff --git a/src/revolution/VF/pf_init_prfile2.c b/src/revolution/VF/pf_init_prfile2.c new file mode 100644 index 00000000..99513894 --- /dev/null +++ b/src/revolution/VF/pf_init_prfile2.c @@ -0,0 +1,9 @@ +#include + +s32 VFipf2_init_prfile2(long config, void* param) { + s32 err = VFiPFFATFS_initializeFATFS(config, param); + if (err == 0) { + VFiPFSYS_initializeSYS(); + } + return VFiPFAPI_convertReturnValue(err); +} diff --git a/src/revolution/VF/pf_remove.c b/src/revolution/VF/pf_remove.c new file mode 100644 index 00000000..c7c30a58 --- /dev/null +++ b/src/revolution/VF/pf_remove.c @@ -0,0 +1,17 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +int VFipf2_remove(const char *path) { + long err; + PFSTR path_str; + + err = VFiPFSTR_InitStr(&path_str, (const s8*)path, 1); + if (err == 0) { + err = VFiPFFILE_remove(&path_str); + } else { + VFipf_vol_set.last_error = err; + } + + return VFiPFAPI_convertReturnValue(err); +} diff --git a/src/revolution/VF/pf_sector.c b/src/revolution/VF/pf_sector.c new file mode 100644 index 00000000..6be3d2f8 --- /dev/null +++ b/src/revolution/VF/pf_sector.c @@ -0,0 +1,225 @@ +#include + +struct PF_CACHE_PAGE* VFiPFCACHE_SearchDataCache(PF_VOLUME* p_vol, u32 sector); + +s32 VFiPFSEC_ReadFAT(PF_VOLUME* p_vol, u8* p_buf, u32 sector, u16 offset, u16 size) { + int err; + PF_CACHE_PAGE* p_page; + + if (!p_vol) { + return 10; + } + if (!p_buf) { + return 10; + } + if (((p_vol->flags & 1) == 0) || !VFiPFDRV_IsInserted(p_vol)) { + return 9; + } + err = VFiPFCACHE_ReadFATPage(p_vol, sector, &p_page); + if (err) { + return err; + } + + VFipf_memcpy(p_buf, &p_page->p_buf[offset], size); + return 0; +} + +s32 VFiPFSEC_ReadData(PF_VOLUME* p_vol, u8* p_buf, u32 sector, u16 offset, u32 size, u32* p_success_size, u32 set_sig) { + PF_CACHE_PAGE* p_page; + u32 num_success; + u32 num_sector; + u32 adjust_sector; + u32 rest_sector; + u32 cache_remaining_sectors; + s32 err; + + *p_success_size = 0; + if (!p_vol) { + return 10; + } + if (!p_buf) { + return 10; + } + if (((p_vol->flags & 1) == 0) || !VFiPFDRV_IsInserted(p_vol)) { + return 9; + } + if (offset != 0 || size < p_vol->bpb.bytes_per_sector) { + err = VFiPFCACHE_ReadDataPage(p_vol, sector, &p_page, set_sig); + if (err) { + return err; + } + VFipf_memcpy(p_buf, &p_page->p_buf[offset], size); + *p_success_size = size; + } else if (offset == 0 && (size & (p_vol->bpb.bytes_per_sector - 1)) == 0) { + err = VFiPFCACHE_ReadDataNumSector(p_vol, p_buf, sector, size >> p_vol->bpb.log2_bytes_per_sector, &num_success); + if (err) { + return err; + } + *p_success_size += num_success << p_vol->bpb.log2_bytes_per_sector; + if (num_success != (size >> p_vol->bpb.log2_bytes_per_sector)) { + return 17; + } + } else { + if (offset == 0) { + p_page = VFiPFCACHE_SearchDataCache(p_vol, sector); + if (p_page) { + cache_remaining_sectors = p_page->sector + p_page->size - sector; + num_sector = size >> p_vol->bpb.log2_bytes_per_sector; + if (cache_remaining_sectors <= num_sector) { + VFipf_memcpy(p_buf, p_page->p_buf, cache_remaining_sectors << p_vol->bpb.log2_bytes_per_sector); + *p_success_size += cache_remaining_sectors << p_vol->bpb.log2_bytes_per_sector; + sector += cache_remaining_sectors; + size -= cache_remaining_sectors << p_vol->bpb.log2_bytes_per_sector; + } else { + if (cache_remaining_sectors > num_sector) { + VFipf_memcpy(p_buf, p_page->p_buf, size); + *p_success_size += size; + size = 0; + } + } + } + if (size != 0) { + num_sector = size >> p_vol->bpb.log2_bytes_per_sector; + rest_sector = (sector + num_sector) % p_vol->cache.data_buff_size; + if (num_sector > rest_sector) { + adjust_sector = num_sector - rest_sector; + err = VFiPFCACHE_ReadDataNumSector(p_vol, p_buf + *p_success_size, sector, adjust_sector, &num_success); + if (err) { + return err; + } + *p_success_size += num_success << p_vol->bpb.log2_bytes_per_sector; + if (num_success != adjust_sector) { + return 17; + } + sector += adjust_sector; + num_sector -= adjust_sector; + } + if (num_sector != 0) { + err = VFiPFCACHE_ReadDataPage(p_vol, sector, &p_page, set_sig); + if (err) { + return err; + } + VFipf_memcpy(p_buf + *p_success_size, p_page->p_buf, num_sector << p_vol->bpb.log2_bytes_per_sector); + *p_success_size += num_sector << p_vol->bpb.log2_bytes_per_sector; + } + } + goto end; + } + return 10; + } +end: + return 0; +} + +s32 VFiPFSEC_WriteFAT(PF_VOLUME* p_vol, const u8* p_buf, u32 sector, u16 offset, u16 size) { + int err; + PF_CACHE_PAGE* p_page; + + if (!p_vol) { + return 10; + } + if (!p_buf) { + return 10; + } + if ((p_vol->flags & 1) == 0 || !VFiPFDRV_IsInserted(p_vol) || VFiPFDRV_IsWProtected(p_vol)) { + return 9; + } + err = VFiPFCACHE_ReadFATPage(p_vol, sector, &p_page); + if (err) { + return err; + } + + VFipf_memcpy(&p_page->p_buf[offset], (void*)p_buf, size); + err = VFiPFCACHE_WriteFATPage(p_vol, p_page); + if (err) { + return err; + } + + return 0; +} + +s32 VFiPFSEC_WriteData(PF_VOLUME* p_vol, const u8* p_buf, u32 sector, u16 offset, u32 size, u32* p_success_size, u32 set_sig, u32 is_direct) { + s32 err; + PF_CACHE_PAGE* p_page; + u32 num_success; + + *p_success_size = 0; + + if (!p_vol) { + return 10; + } + if (!p_buf) { + return 10; + } + if (((p_vol->flags & 1) == 0) || !VFiPFDRV_IsInserted(p_vol) || VFiPFDRV_IsWProtected(p_vol)) { + return 9; + } + if (offset != 0 || size < p_vol->bpb.bytes_per_sector) { + err = VFiPFCACHE_ReadDataPageAndFlushIfNeeded(p_vol, sector, &p_page, set_sig); + if (err) { + return err; + } + + VFipf_memcpy(&p_page->p_buf[offset], p_buf, size); + + err = VFiPFCACHE_WriteDataPage(p_vol, p_page, set_sig); + if (err) { + return err; + } + *p_success_size = size; + } else { + if ((offset == 0) && ((size & (p_vol->bpb.bytes_per_sector - 1)) == 0)) { + err = VFiPFCACHE_WriteDataNumSectorAndFreeIfNeeded(p_vol, p_buf, sector, size >> p_vol->bpb.log2_bytes_per_sector, &num_success); + if (err) { + return err; + } + + *p_success_size = num_success << p_vol->bpb.log2_bytes_per_sector; + if (num_success != (size >> p_vol->bpb.log2_bytes_per_sector)) { + return 17; + } + } else { + if (offset == 0) { + u32 num_sector = size >> p_vol->bpb.log2_bytes_per_sector; + u32 rest_sector = (sector + num_sector) % p_vol->cache.data_buff_size; + + if (num_sector > rest_sector) { + u32 adjust_sector = num_sector - rest_sector; + err = VFiPFCACHE_WriteDataNumSectorAndFreeIfNeeded(p_vol, p_buf, sector, adjust_sector, &num_success); + if (err) { + return err; + } + + *p_success_size = num_success << p_vol->bpb.log2_bytes_per_sector; + + if (num_success != adjust_sector) { + return 17; + } + + sector += adjust_sector; + num_sector -= adjust_sector; + } + + if (num_sector != 0) { + err = VFiPFCACHE_ReadDataPageAndFlushIfNeeded(p_vol, sector, &p_page, set_sig); + if (err) { + return err; + } + + VFipf_memcpy(p_page->p_buf, p_buf + *p_success_size, num_sector << p_vol->bpb.log2_bytes_per_sector); + + err = VFiPFCACHE_WriteDataPage(p_vol, p_page, set_sig); + if (err) { + return err; + } + + *p_success_size += num_sector << p_vol->bpb.log2_bytes_per_sector; + } + goto end; + } + return 10; + } + } +end: + return 0; +} diff --git a/src/revolution/VF/pf_service.c b/src/revolution/VF/pf_service.c new file mode 100644 index 00000000..58011cc1 --- /dev/null +++ b/src/revolution/VF/pf_service.c @@ -0,0 +1,15 @@ +#include + +u16 VFiPF_GET_LE_U16(const u8* val) { + return val[0] | val[1] << 8; +} + +void VFiPF_LE16_TO_U16_STR(u8* str, u32 n) { + u32 i; + + for (i = 0; i < n; i += sizeof(u16)) { + const u8 tmp = str[i]; + str[i] = str[i + 1]; + str[i + 1] = (0, tmp); + } +} diff --git a/src/revolution/VF/pf_str.c b/src/revolution/VF/pf_str.c new file mode 100644 index 00000000..c9a62000 --- /dev/null +++ b/src/revolution/VF/pf_str.c @@ -0,0 +1,188 @@ +#include + +extern PF_VOLUME_SET VFipf_vol_set; + +void VFiPFSTR_SetCodeMode(PFSTR* str, u32 mode) { + str->mode = (PFSTR_CodeMode)mode; +} + +u32 VFiPFSTR_GetCodeMode(const PFSTR* str) { + return str->mode; +} + +void VFiPFSTR_SetLocalStr(PFSTR* str, const wchar_t* data) { + if (str->mode == (u32)PFSTR_CODEMODE_OEM || (data == NULL)) { + str->local = str->begin; + } else { + str->local = data; + } +} + +s8* VFiPFSTR_GetStrPos(PFSTR* str, u32 target) { + s8* p_pos; + if (target == 1) { + p_pos = (s8*)str->begin; + } else if (target == 2) { + p_pos = (s8*)str->end; + } else { + p_pos = (s8*)str->local; + } + + return p_pos; +} + +void VFiPFSTR_MoveStrPos(PFSTR* str, s16 n) { + s16 i; + s16 dist = 0; + + if (VFiPFSTR_GetCodeMode(str) == PFSTR_CODEMODE_OEM) { + const char* data = (const char*)str->begin; + + for (; n != 0; dist++, n--) { + if (VFipf_vol_set.codeset.is_oem_mb_char(*data, PFSTR_CODEMODE_OEM)) { + dist++; + } + } + } else { + const char* data = (const char*)str->begin; + + for (i = 0; i < n; i++) { + const size_t width = VFipf_vol_set.codeset.unicode_char_width((u16*)data); + data += width * sizeof(wchar_t); + dist += (s16)width; + } + } + + str->begin = (u8*)str->begin + dist; +} + +s32 VFiPFSTR_InitStr(PFSTR* str, const void* s, u32 mode) { + if (str == NULL || s == NULL) { + return 10; + } + + if (mode == PFSTR_CODEMODE_OEM) { + str->begin = s; + str->end = (const u8*)s + VFipf_strlen((const char*)s); + } else if (mode == PFSTR_CODEMODE_UNICODE) { + str->begin = s; + str->end = (const u8*)s + (2 * VFipf_w_strlen((const wchar_t*)s)); + } else { + return 10; + } + + str->mode = (PFSTR_CodeMode)mode; + return 0; +} + +u16 VFiPFSTR_StrLen(PFSTR* str) { + return (u16)((u8*)str->end - (u8*)str->begin); +} + +u16 VFiPFSTR_StrNumChar(const PFSTR* str, u32 mode) { + const char* data; + size_t width; + u16 length; + + if (mode == PFSTR_CODEMODE_OEM) { + data = (const char*)str->begin; + } else { + data = (const char*)str->end; + } + + if (str->mode == (u32)PFSTR_CODEMODE_OEM) { + length = 0; + for (; *data != '\0'; data++, length++) { + if (VFipf_vol_set.codeset.is_oem_mb_char(*data, PFSTR_CODEMODE_OEM)) { + data++; + } + } + } else { + length = 0; + for (; data[0] != '\0' || data[1] != '\0'; data += width, length++) { + width = VFipf_vol_set.codeset.unicode_char_width((u16*)data); + } + } + + return length; +} + +int VFiPFSTR_StrCmp(const PFSTR* str, const char* cmp) { + const wchar_t* data; + wchar_t out; + + if (str->mode == (u32)PFSTR_CODEMODE_OEM) { + return VFipf_strcmp((const char*)str->begin, cmp); + } + + data = (const wchar_t*)str->begin; + do { + VFipf_vol_set.codeset.oem2unicode((s8*)cmp, &out); + cmp++; + } while (*data++ == out && data[-1] != L'\0' && out != L'\0'); + + return data[-1] - out; +} + +int VFiPFSTR_StrNCmp(PFSTR* str, const char* cmp, u32 mode, s16 pos, u16 n) { + const wchar_t* wdata; + const char* data; + wchar_t out; + + if (str->mode == (u32)PFSTR_CODEMODE_OEM || mode == PFSTR_CODEMODE_LOCAL) { + if (mode == PFSTR_CODEMODE_OEM) { + data = (const char*)str->begin + pos; + } else if (mode == PFSTR_CODEMODE_UNICODE) { + data = (const char*)str->end + pos; + } else { + data = (const char*)str->local + pos; + } + + return VFipf_strncmp(data, cmp, n); + } + + if (mode == PFSTR_CODEMODE_OEM) { + wdata = (const wchar_t*)((u8*)str->begin + pos * sizeof(wchar_t)); + } else { + wdata = (const wchar_t*)((u8*)str->end + pos * sizeof(wchar_t)); + } + + do { + VFipf_vol_set.codeset.oem2unicode((s8*)cmp, &out); + cmp++; + n--; + } while (*wdata++ == out && n > 0 && wdata[-1] != L'\0' && out != L'\0'); + + return wdata[-1] - out; +} + +void VFiPFSTR_ToUpperNStr(PFSTR* str, u16 n, char* out) { + const char* data; + const wchar_t* wdata; + int ch; + BOOL letter; + + if (str->mode == (u32)PFSTR_CODEMODE_OEM) { + for (data = (const char*)str->begin; n > 0 && *data != '\0'; data++, n--) { + *out++ = VFipf_toupper(*data); + } + } else { + for (wdata = (const wchar_t*)str->begin; n > 0 && *wdata != L'\0'; n--, wdata++) { + letter = *wdata >= L'a' && *wdata <= L'z'; + + if (letter) { + ch = *wdata - (L'a' - L'A'); + } else { + ch = *wdata; + } + + out[0] = (ch >> 0) & 0xFF; + out[1] = (ch >> 8) & 0xFF; + out += sizeof(wchar_t); + } + + *out = '\0'; + } + + *out = '\0'; +} diff --git a/src/revolution/VF/pf_system.c b/src/revolution/VF/pf_system.c new file mode 100644 index 00000000..8f6f2e9a --- /dev/null +++ b/src/revolution/VF/pf_system.c @@ -0,0 +1,22 @@ +#include + +void VFiPFSYS_initializeSYS() { + return; +} + +s32 VFiPFSYS_GetCurrentContextID(s32* context_id) { + *context_id = 0; + return 0; +} + +void VFiPFSYS_TimeStamp(PFDATE* date, PFTIME* time) { + date->year = 2000; + date->month = 4; + date->day = 1; + time->hour = 0; + time->minute = 0; + time->second = 0; + time->millisecond = 1; + dTM_GetNowTime(date, time); + time->millisecond = 1; +} diff --git a/src/revolution/VF/pf_unmount.c b/src/revolution/VF/pf_unmount.c new file mode 100644 index 00000000..308aef74 --- /dev/null +++ b/src/revolution/VF/pf_unmount.c @@ -0,0 +1,6 @@ +#include + +s32 VFipf2_unmount(s8 drv_char, u32 mode) { + int result = VFiPFVOL_unmount(drv_char, mode); + return VFiPFAPI_convertReturnValue4unmount(result); +} diff --git a/src/revolution/VF/pf_w_clib.c b/src/revolution/VF/pf_w_clib.c new file mode 100644 index 00000000..480674c1 --- /dev/null +++ b/src/revolution/VF/pf_w_clib.c @@ -0,0 +1,39 @@ +#include + +size_t VFipf_w_strlen(const wchar_t* str) { + const wchar_t* it = str; + ptrdiff_t diff; + + // Find end of string + while (*it != L'\0') { + it++; + } + + // Calculate size + diff = (uintptr_t)it - (uintptr_t)str; + return diff >> 1; +} + +int VFipf_w_strcpy(wchar_t* dest, const wchar_t* src) { + // Unconditional jump to the middle of the loop + goto jump; + while (*src != L'\0') { + src++; + dest++; + jump: + *dest = *src; + } +} + +int VFipf_w_strncmp(const wchar_t* s1, const wchar_t* s2, size_t n) { + while (n != 0) { + if (*s1 == L'\0' || *s2 == L'\0' || *s1 != *s2) { + return (int)(*s1 - *s2); + } + + s1++; + s2++; + n--; + } + return 0; +} diff --git a/src/revolution/VF/sd_drv.c b/src/revolution/VF/sd_drv.c new file mode 100644 index 00000000..a385ce19 --- /dev/null +++ b/src/revolution/VF/sd_drv.c @@ -0,0 +1,5 @@ +#include + +void VFi_InitSDWrok() { + return; +}