TempleOSTS_130315.ISO
This commit is contained in:
1 parent
e57428affb
commit
17b71f1a2d
958 files changed
+26043
-15907
No files matched your search
@@ -0,0 +1,14 @@
|
||||
#exe {OptOn(OPTf_KEEP_PRIVATE);};
|
||||
|
||||
#include "/TempleOS/Kernel/BootDefs.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1a.HPP"
|
||||
#exe {OptOn(OPTf_EXTERNS_TO_IMPORTS);};
|
||||
#include "/TempleOS/Compiler/CmpDefs.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1b.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1c.HPP"
|
||||
#exe {
|
||||
OptOff(OPTf_EXTERNS_TO_IMPORTS);
|
||||
OptOff(OPTf_KEEP_PRIVATE);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
#exe {ImportHashTable(adam_task->hash_table);};
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
//This is executed by Adam at boot.
|
||||
//See $LK,"Adam1 Start-up","FF:::/TempleOS/Kernel/KEnd.CPP,Adam1:2"$
|
||||
extern I8i OptEqu(I64i num,I8i val);
|
||||
OptEqu(0,0); //(0,0)=EchoOff (0,1)=EchoOn
|
||||
#include "/TempleOS/Kernel/BootDefs.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1a.HPP"
|
||||
#include "/TempleOS/Compiler/CmpDefs.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1b.HPP"
|
||||
#include "/TempleOS/Kernel/Adam1c.HPP"
|
||||
#include "/TempleOS/Compiler/Compiler.HPP"
|
||||
Cd("/TempleOS/Adam");;
|
||||
#include "Adam2"
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,302 @@
|
||||
/*
|
||||
In this file, syms defined Kernel assembly
|
||||
files are given C+ definitions. This file
|
||||
is included when you compile the kernel, after
|
||||
the assembly files have been assembled, making
|
||||
the C+ definitions available for the C+ Kernel
|
||||
files. It is also included as part of booting.
|
||||
|
||||
The assembly global labels are stored as HTT_EXPORT_SYS_SYM
|
||||
entries in the hash table. These symols are placed
|
||||
into the Kernel binary module and added to the
|
||||
sym hash table at boot before this file
|
||||
gets #included during boot.
|
||||
|
||||
See
|
||||
$LK,"Adam1b","FF:::/TempleOS/Kernel/Kernel.PRJ,Adam1b"$ for where it is included during compiling the kernel.
|
||||
$LK,"Adam1b","FF:::/TempleOS/Kernel/Adam1.CPP,Adam1b"$ for where it is included during boots.
|
||||
$LK,"LoadKernel","FF:::/TempleOS/Kernel/KEnd.CPP,LoadKernel"$ for where the Kernel syms are added to the hash tables.
|
||||
|
||||
*/
|
||||
|
||||
#help_index "Misc;Messages"
|
||||
public _extern SYS_FOCUS_TASK CTask *sys_focus_task;
|
||||
|
||||
#help_index "Graphics/Screen"
|
||||
//This is the INT 0x10 mode number.
|
||||
public _extern SYS_BIOS_GR_MODE U16 bios_gr_mode;
|
||||
#help_index "PCI"
|
||||
public _extern SYS_PCI_BUSSES U16 sys_pci_busses;
|
||||
#help_index "Misc"
|
||||
public _extern SYS_CTRL_ALT_FLAGS I64 sys_ctrl_alt_flags[1];
|
||||
public _extern SYS_COMPILE_TIME CDate sys_compile_time;
|
||||
|
||||
#help_index "Boot"
|
||||
_extern SYS_BOOT_BASE U32 sys_boot_base;
|
||||
_extern SYS_BOOT_CODE U32 sys_boot_code;
|
||||
_extern SYS_RUN_LEVEL U32 sys_run_level;
|
||||
_extern SYS_BOOT_PATCH_TABLE_BASE U32 sys_boot_patch_table_base;
|
||||
|
||||
#help_index "Misc/Progress Bars"
|
||||
public _extern SYS_PROGRESSES CProgress sys_progresses[NUM_PROGRESS_BARS];
|
||||
public _extern SYS_PROGRESS1 I64 progress1;
|
||||
public _extern SYS_PROGRESS1_MAX I64 progress1_max;
|
||||
public _extern SYS_PROGRESS1_DESC U8 progress1_desc[PROGRESS_DESC_LEN+1];
|
||||
public _extern SYS_PROGRESS2 I64 progress2;
|
||||
public _extern SYS_PROGRESS2_MAX I64 progress2_max;
|
||||
public _extern SYS_PROGRESS2_DESC U8 progress2_desc[PROGRESS_DESC_LEN+1];
|
||||
public _extern SYS_PROGRESS3 I64 progress3;
|
||||
public _extern SYS_PROGRESS3_MAX I64 progress3_max;
|
||||
public _extern SYS_PROGRESS3_DESC U8 progress3_desc[PROGRESS_DESC_LEN+1];
|
||||
public _extern SYS_PROGRESS4 I64 progress4;
|
||||
public _extern SYS_PROGRESS4_MAX I64 progress4_max;
|
||||
public _extern SYS_PROGRESS4_DESC U8 progress4_desc[PROGRESS_DESC_LEN+1];
|
||||
|
||||
#help_index "Bit"
|
||||
#help_file "::/TempleOS/Doc/Bit"
|
||||
public _intern IC_BT Bool Bt(U8 *bit_field,I64 bit);
|
||||
public _intern IC_BTS Bool Bts(U8 *bit_field,I64 bit);
|
||||
public _intern IC_BTR Bool Btr(U8 *bit_field,I64 bit);
|
||||
public _intern IC_BTC Bool Btc(U8 *bit_field,I64 bit);
|
||||
public _intern IC_BEQU Bool BEqu(U8 *bit_field,I64 bit,Bool val);
|
||||
|
||||
//Locked for (for multitple CPU's)
|
||||
public _intern IC_LBTS Bool LBts(U8 *bit_field,I64 bit);
|
||||
public _intern IC_LBTR Bool LBtr(U8 *bit_field,I64 bit);
|
||||
public _intern IC_LBTC Bool LBtc(U8 *bit_field,I64 bit);
|
||||
public _intern IC_LBEQU Bool LBEqu(U8 *bit_field,I64 bit,Bool val);
|
||||
|
||||
//Scan I64 sized item fwd for first set bit, starting at lowest.
|
||||
//Return -1 if not found.
|
||||
public _intern IC_BSF I64 Bsf(I64 bit_field_val);
|
||||
|
||||
//Scan I64 sized item reverse for first set bit, starting at highest.
|
||||
//Return -1 if not found.
|
||||
public _intern IC_BSR I64 Bsr(I64 bit_field_val);
|
||||
|
||||
public _extern _BIT_FIELD_OR_U32 U0 BFieldOrU32(
|
||||
U8 *bit_field,I64 bit,U32 pattern);
|
||||
public _extern _BIT_FIELD_EXTRACT_U32 U32 BFieldExtU32(
|
||||
U8 *bit_field,I64 bit,I64 size);
|
||||
|
||||
#help_index "Circular Queue"
|
||||
#help_file "::/TempleOS/Doc/Que"
|
||||
public _intern IC_QUE_INIT U0 QueInit(CQue *root);
|
||||
//Ins item into que after predicessor.
|
||||
public _intern IC_QUE_INS U0 QueIns(CQue *entry,CQue *pred);
|
||||
//Reversed insert into que. Ins
|
||||
//item into que before successor.
|
||||
public _intern IC_QUE_INS_REV U0 QueInsRev(CQue *entry,CQue *succ);
|
||||
//Remove item from que.
|
||||
public _intern IC_QUE_REM U0 QueRem(CQue *entry);
|
||||
|
||||
#help_index "Task"
|
||||
public _intern IC_PREEMPT Bool Preempt(Bool val);
|
||||
|
||||
#help_index "I/O;Processor/IO Port"
|
||||
public _intern IC_INU8 I64 InU8(I64 port);
|
||||
public _intern IC_INU16 I64 InU16(I64 port);
|
||||
public _intern IC_INU32 I64 InU32(I64 port);
|
||||
public _intern IC_OUTU8 U0 OutU8(I64 port, I64 val);
|
||||
public _intern IC_OUTU16 U0 OutU16(I64 port, I64 val);
|
||||
public _intern IC_OUTU32 U0 OutU32(I64 port, I64 val);
|
||||
public _extern _REP_IN_U8 U0 RepInU8(U8 *buf,I64 cnt,I64 port);
|
||||
public _extern _REP_IN_U16 U0 RepInU16(U8 *buf,I64 cnt,I64 port);
|
||||
public _extern _REP_IN_U32 U0 RepInU32(U8 *buf,I64 cnt,I64 port);
|
||||
public _extern _REP_OUT_U8 U0 RepOutU8(U8 *buf,I64 cnt,I64 port);
|
||||
public _extern _REP_OUT_U16 U0 RepOutU16(U8 *buf,I64 cnt,I64 port);
|
||||
public _extern _REP_OUT_U32 U0 RepOutU32(U8 *buf,I64 cnt,I64 port);
|
||||
|
||||
#help_index "Memory"
|
||||
|
||||
//Only goes fwd.
|
||||
public _intern IC_MEMCPY U0 MemCpy(U8 *dst,U8 *src,I64 cnt);
|
||||
public _intern IC_MEMSET U8 *MemSet(U8 *dst,I64 val,I64 cnt);
|
||||
public _intern IC_MEMSET U8 *MemSetU8(U8 *dst,I64 val,I64 U8cnt);
|
||||
public _intern IC_MEMSET_U16 U16 *MemSetU16(U8 *dst,I64 val,I64 U16cnt);
|
||||
public _intern IC_MEMSET_U32 U32 *MemSetU32(U8 *dst,I64 val,I64 U32cnt);
|
||||
public _intern IC_MEMSET_U64 U64 *MemSetU64(U8 *dst,I64 val,I64 U64cnt);
|
||||
public _extern SYS_CODE_BP CBlkPool *sys_code_bp;
|
||||
public _extern SYS_DATA_BP CBlkPool *sys_data_bp;
|
||||
public _extern SYS_HEAP_BASE U32 sys_heap_base;
|
||||
public _extern SYS_HEAP_LIMIT U32 sys_heap_limit;
|
||||
|
||||
_extern SYS_HEAP_INIT_FLAG U8 sys_heap_init_flag;
|
||||
_extern SYS_HEAP_INIT_VAL U8 sys_heap_init_val;
|
||||
_extern SYS_MEM_INIT_FLAG U8 sys_mem_init_flag;
|
||||
_extern SYS_MEM_INIT_VAL U8 sys_mem_init_val;
|
||||
_extern SYS_VAR_INIT_FLAG U8 sys_var_init_flag;
|
||||
_extern SYS_VAR_INIT_VAL U8 sys_var_init_val;
|
||||
_extern SYS_HEAP_DBG_FLAG U8 sys_heap_dbg;
|
||||
|
||||
#help_index "Char/Conversion"
|
||||
public _intern IC_TOUPPER I64 ToUpper(U8 ch);
|
||||
#help_index "Char/Operations"
|
||||
public _intern IC_STRLEN I64 StrLen(U8 *st);
|
||||
|
||||
#help_index "Processor"
|
||||
public _extern _CPUID U0 CPUId(U32 rax,CRAXRBCRCXRDX *result);
|
||||
public _intern IC_SET_RAX U0 SetRAX(I64 d);
|
||||
public _intern IC_GET_RAX I64 GetRAX();
|
||||
public _intern IC_CLI U0 Cli();
|
||||
public _intern IC_STI U0 Sti();
|
||||
public _intern IC_PUSHFD U0 PushFD();
|
||||
public _intern IC_POPFD U0 PopFD();
|
||||
public _intern IC_HLT U0 Hlt();
|
||||
public _extern _SYS_HLT U0 SysHlt(); //Loops
|
||||
|
||||
//This instruction hints to the processor
|
||||
//that a spin-loop is taking place.
|
||||
public _intern IC_PAUSE U0 Pause();
|
||||
|
||||
public _intern IC_POP I64 Pop();
|
||||
public _intern IC_PUSH U0 Push(I64 d);
|
||||
public _intern IC_CLD U0 Cld();
|
||||
public _intern IC_STD U0 Std();
|
||||
public _intern IC_GET_FLAGS I64 GetFlags();
|
||||
public _intern IC_CARRY I64 Carry();
|
||||
public _intern IC_SET_FLAGS U0 SetFlags(I64 d);
|
||||
public _intern IC_GET_STK_PTR U8 *GetStkPtr();
|
||||
public _intern IC_SET_STK_PTR U0 SetStkPtr(U8 *d);
|
||||
public _intern IC_GET_BASE_PTR U8 *GetBasePtr();
|
||||
public _intern IC_SET_BASE_PTR U0 SetBasePtr(U8 *d);
|
||||
public _extern SYS_CACHE_LINE_WIDTH I64 sys_cache_line_width;
|
||||
_extern SYS_GDTTAB U8 sys_gdttab[GDT_SIZE];
|
||||
public _extern _XCHG_U64 U64 XchgU64(U64 *dst,U64 d);
|
||||
public _extern _XCHG_U32 U64 XchgU32(U32 *dst,U32 d);
|
||||
public _extern _XCHG_U16 U64 XchgU16(U16 *dst,U16 d);
|
||||
public _extern _XCHG_U8 U64 XchgU8 (U8 *dst,U8 d);
|
||||
public _extern _LXCHG_U64 U64 LXchgU64(U64 *dst,U64 d);
|
||||
public _extern _LXCHG_U32 U64 LXchgU32(U32 *dst,U32 d);
|
||||
public _extern _LXCHG_U16 U64 LXchgU16(U16 *dst,U16 d);
|
||||
public _extern _LXCHG_U8 U64 LXchgU8(U8 *dst,U8 d);
|
||||
|
||||
//Model Specific REgisters
|
||||
//See $LK,"MSRs","MN:IA32_EFER"$
|
||||
public _extern _SET_MSR U0 SetMSR(I64 model_specific_reg,I64 val);
|
||||
|
||||
#help_index "Processor/Cache;Memory/Cache"
|
||||
public _intern IC_INVLPG U0 InvlPg(U8 *a);
|
||||
//Flush cache line.
|
||||
public _intern IC_CLFLUSH U0 CLFlush(U8 *a);
|
||||
|
||||
#help_index "MultiCore"
|
||||
#help_file "::/TempleOS/Doc/MultiCore"
|
||||
_extern _SET_GS_BASE U0 SetGs(CCPU *c);
|
||||
public _extern SYS_MP_CNT I64 mp_cnt;
|
||||
_extern SYS_MP_CNT_INITIAL I64 mp_cnt_initial; //only used during $LK,"MPStart","MN:MPStart"$
|
||||
_extern SYS_MP_CNT_LOCK I64 mp_cnt_lock;
|
||||
_extern SYS_TEMP_CPU0_STRUCT CCPU sys_temp_cpu0_struct;
|
||||
public _extern SYS_CPU_STRUCTS CCPU *cpu_structs;
|
||||
_extern SYS_SEMAS CSema sys_semas[NUM_SYS_SEMAS];
|
||||
|
||||
#help_index "MultiCore;Processor"
|
||||
//This pts to the current CPU structure.
|
||||
//It returns the val in the GS segment register.
|
||||
public _intern IC_GS CCPU *Gs();
|
||||
|
||||
#help_index "Time/CPU Cycles"
|
||||
public _intern IC_RDTSC I64 GetTimeStamp();
|
||||
|
||||
#help_index "Time/HPET"
|
||||
public _intern IC_HPET I64 HPET();
|
||||
|
||||
#help_index "Time/Jiffies"
|
||||
#help_file "::/TempleOS/Doc/TimeJiffy"
|
||||
_extern SYS_TIMER I64 sys_timer;
|
||||
public _extern SYS_JIFFIES I64 sys_jiffies;
|
||||
|
||||
#help_index "Math"
|
||||
public _intern IC_TO_I64 I64 ToI64(F64 d); //This truncates
|
||||
public _intern IC_TO_F64 F64 ToF64(I64 i);
|
||||
public _intern IC_TO_BOOL Bool ToBool(I64 i);
|
||||
public _intern IC_ABS_I64 I64 AbsI64(I64 i);
|
||||
public _intern IC_LIMIT_I64 I64 LimitI64(I64 p,I64 lo,I64 hi);
|
||||
public _intern IC_LIMIT_U64 U64 LimitU64(U64 p,U64 lo,U64 hi);
|
||||
public _intern IC_SIGN_I64 I64 SignI64(I64 i);
|
||||
public _intern IC_SQR_I64 I64 SqrI64(I64 i);
|
||||
public _intern IC_SQR_U64 U64 SqrU64(U64 i);
|
||||
public _intern IC_SWAP_U8 U0 SwapU8(U8 *n1,U8 *n2);
|
||||
public _intern IC_SWAP_U16 U0 SwapU16(U16 *n1,U16 *n2);
|
||||
public _intern IC_SWAP_U32 U0 SwapU32(U32 *n1,U32 *n2);
|
||||
public _intern IC_SWAP_U64 U0 SwapU64(U64 *n1,U64 *n2);
|
||||
public _intern IC_MIN_I64 I64 MinI64(I64 n1,I64 n2);
|
||||
public _intern IC_MAX_I64 I64 MaxI64(I64 n1,I64 n2);
|
||||
public _intern IC_MIN_U64 U64 MinU64(U64 n1,U64 n2);
|
||||
public _intern IC_MAX_U64 U64 MaxU64(U64 n1,U64 n2);
|
||||
public _intern IC_MOD_U64 U64 ModU64(U64 *q,U64 d);
|
||||
public _intern IC_SQR F64 Sqr(F64 d);
|
||||
public _intern IC_ABS F64 Abs(F64 d);
|
||||
public _intern IC_SQRT F64 Sqrt(F64 d);
|
||||
public _intern IC_SIN F64 Sin(F64 d);
|
||||
public _intern IC_COS F64 Cos(F64 d);
|
||||
public _intern IC_TAN F64 Tan(F64 d);
|
||||
public _intern IC_ATAN F64 ATan(F64 d);
|
||||
|
||||
public _extern _SIGN F64 Sign(F64 d);
|
||||
public _extern _ARG F64 Arg(F64 x,F64 y);
|
||||
public _extern _ROUND F64 Round(F64 d);
|
||||
public _extern _TRUNC F64 Trunc(F64 d);
|
||||
public _extern _FLOOR F64 Floor(F64 d);
|
||||
public _extern _CEIL F64 Ceil(F64 d);
|
||||
public _extern _POW F64 Pow(F64 base,F64 power);
|
||||
public _extern _POW10 F64 Pow10(F64 d);
|
||||
public _extern _LOG2 F64 Log2(F64 d);
|
||||
public _extern _LOG10 F64 Log10(F64 d);
|
||||
public _extern _LN F64 Ln(F64 d);
|
||||
public _extern _EXP F64 Exp(F64 d);
|
||||
_extern _FLDCW U0 Fldcw(U16 w);
|
||||
_extern _FCLEX U0 Fclex();
|
||||
_extern _FSTCW U16 Fstcw();
|
||||
_extern _FSTSW U16 Fstsw();
|
||||
_extern _FXSAVE U0 Fxsave(CFPU *fpu_mmx);
|
||||
_extern _FXRSTOR U0 Fxrstor(CFPU *fpu_mmx);
|
||||
_extern SYS_INIT_FPU_MMX CFPU sys_init_fpu_mmx;
|
||||
|
||||
#help_index "Math/CD3;ODE/CD3"
|
||||
#help_file "::/TempleOS/Doc/D3"
|
||||
public _extern _D3_EQU CD3 *D3Equ(CD3 *dst,F64 x,F64 y,F64 z);
|
||||
public _extern _D3_ZERO CD3 *D3Zero(CD3 *dst);
|
||||
public _extern _D3_COPY CD3 *D3Copy(CD3 *dst,CD3 *src);
|
||||
public _extern _D3_NORM F64 D3Norm(CD3 *d);
|
||||
public _extern _D3_SQR_NORM F64 D3SqrNorm(CD3 *d);
|
||||
public _extern _D3_ADD CD3 *D3Add(CD3 *d1,CD3 *d2,CD3 *sum);
|
||||
public _extern _D3_SUB CD3 *D3Sub(CD3 *d1,CD3 *d2,CD3 *diff);
|
||||
public _extern _D3_MUL CD3 *D3Mul(F64 c,CD3 *d,CD3 *prod);
|
||||
public _extern _D3_DIV CD3 *D3Div(F64 c,CD3 *d,CD3 *quot);
|
||||
public _extern _D3_ADD_EQU CD3 *D3AddEqu(CD3 *sum,CD3 *d);
|
||||
public _extern _D3_SUB_EQU CD3 *D3SubEqu(CD3 *diff,CD3 *d);
|
||||
public _extern _D3_MUL_EQU CD3 *D3MulEqu(CD3 *prod,F64 c);
|
||||
public _extern _D3_DIV_EQU CD3 *D3DivEqu(CD3 *quot,F64 c);
|
||||
public _extern _D3_DIST F64 D3Dist(CD3 *d1,CD3 *d2);
|
||||
public _extern _D3_SQR_DIST F64 D3SqrDist(CD3 *d1,CD3 *d2);
|
||||
//Dot Product
|
||||
public _extern _D3_DOT F64 D3Dot(CD3 *d1,CD3 *d2);
|
||||
//Cross Product
|
||||
public _extern _D3_CROSS CD3 *D3Cross(CD3 *d1,CD3 *d2,CD3 *prod);
|
||||
//Convert to unit vect
|
||||
public _extern _D3_UNIT CD3 *D3Unit(CD3 *d);
|
||||
|
||||
|
||||
#help_index "Task;Processor"
|
||||
//This pts to the current task record.
|
||||
//It returns the val in the FS segment register.
|
||||
public _intern IC_FS CTask *Fs();
|
||||
|
||||
#help_index "Call"
|
||||
public _extern _CALL I64 Call(U8 *s);
|
||||
|
||||
//fp_add can have any fixed number of arguments.
|
||||
public _extern _CALLIND I64 CallInd(/*argpop*/I64 (*fp_add)(...),...);
|
||||
|
||||
//This is just an array of ptrs to funs.
|
||||
//See $LK,"Extern Num Definitions","MN:EXT_TABLE_SIZE"$
|
||||
public _extern SYS_EXTERN_TABLE /*argpop*/ I64 (**ext)(...);
|
||||
//Can have any fixed number of arguments.
|
||||
public _extern _CALLEXTNUM I64 CallExtNum(I64 num,...);
|
||||
|
||||
//Search sym table for fun name and pass it args.
|
||||
//Can have any fixed number of arguments.
|
||||
public _extern _CALLEXTSTR I64 CallExtStr(/*argpop*/ U8 *name,...);
|
||||
|
||||
#help_index ""
|
||||
@@ -0,0 +1,831 @@
|
||||
#help_index "Time/CDate"
|
||||
#help_file "::/TempleOS/Doc/TimeDate"
|
||||
public extern CDate local_time_offset;
|
||||
|
||||
#help_index "Time/Jiffies"
|
||||
//18.33333*65536Hz (SYS_TIMER_FREQ)
|
||||
public extern I64 SysTimerRead();
|
||||
|
||||
#help_index "Task"
|
||||
extern U8 *sys_acct;
|
||||
extern CTask *sys_winmgr_task,*sys_task_being_screen_updated;
|
||||
public extern CTask *adam_task;
|
||||
public extern I64 sys_num_spawned_users,sys_num_task_inits;
|
||||
extern U0 TaskFinishOffDying();
|
||||
public _extern SYS_YIELD U0 Yield();
|
||||
public extern U0 TSSBusy(I64 tr,Bool val=OFF);
|
||||
_extern SYS_CONTEXT_RESTORE U0 TaskContextRestore();
|
||||
_extern SYS_TASK_END_NOW U0 TaskEndNow();
|
||||
|
||||
|
||||
#help_index "Time/CPU Cycles"
|
||||
#help_file "::/TempleOS/Doc/TimeCycles"
|
||||
public extern I64 time_stamp_freq,time_stamp_kHz_freq;
|
||||
public extern I64 TaskTotalTime();
|
||||
|
||||
//This is sampled once at boot time
|
||||
public extern I64 time_stamp_freq_initial;
|
||||
|
||||
#help_index "Time/HPET"
|
||||
#help_file "::/TempleOS/Doc/TimeHPET"
|
||||
public extern I64 HPET_freq,HPET_kHz_freq;
|
||||
|
||||
#help_index "Time/Seconds"
|
||||
public extern F64 tT(); //High freq
|
||||
public extern F64 tJ(); //From Jiffies.
|
||||
public extern F64 tS(); //From SysTimerFreq.
|
||||
public extern Bool Blink(F64 Hz=2.5);
|
||||
|
||||
#help_index "Snd"
|
||||
#help_file "::/TempleOS/Doc/Snd"
|
||||
public extern I64 snd_dev;
|
||||
public extern F64 snd_vol,snd_reverb_intensity,snd_reverb_delay;
|
||||
public extern U0 Snd(F64 freq,I64 waveform=WF_SQUARE,F64 amp=1.0);
|
||||
public extern Bool Mute(Bool val);
|
||||
public extern Bool IsMute();
|
||||
public extern F64 snd_freq;
|
||||
public extern U0 Beep(I64 freq=500,Bool busy=FALSE);
|
||||
public extern Bool IOSnd(Bool val);
|
||||
#help_index "Snd/Snd Files"
|
||||
public extern Bool snd_record;
|
||||
extern U0 (*fp_snd_record)(F64 freq,I64 waveform,F64 amp);
|
||||
#help_index "Snd/HDAudio"
|
||||
public extern U0 (*fp_snd)(F64 freq,I64 waveform,F64 amp);
|
||||
public extern U0 (*fp_snd_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num);
|
||||
public extern U0 (*fp_snd_copy_buf)(SND_IN_CONTAINER *buf,I64 buf_num);
|
||||
|
||||
#help_index "Processor"
|
||||
extern U8 *sys_fault_handlers_code;
|
||||
extern I64 *sys_idt;
|
||||
public extern U8 *IntEntryGet(I64 irq);
|
||||
public extern U8 *IntEntrySet(I64 irq,U0 (*fp_new_handler)(),I64 type=IDTET_IRQ,I64 dpl=0);
|
||||
extern CPCIDev sys_pci_dev_root;
|
||||
extern CMemRange sys_mem32_dev_root;
|
||||
|
||||
#help_index "Task/Delay;Time/CPU Cycles"
|
||||
public extern I64 TimeStampFreqCal();
|
||||
public extern U0 BusyWait(I64 æS); //Loosely timed
|
||||
public extern U0 SleepUntil(I64 wake_jiffy);
|
||||
public extern U0 Sleep(I64 mS);
|
||||
public extern U0 PortNop(); //On the order of 1uS
|
||||
#help_index "Task"
|
||||
public extern Bool IsPreempt();
|
||||
|
||||
#help_index "Debugging"
|
||||
#help_file "::/TempleOS/Doc/Dbg"
|
||||
extern CTask *sys_dbg_focus_task;
|
||||
extern U8 *sys_dbg_msg;
|
||||
extern I64 sys_dbg_msg_num;
|
||||
public extern Bool IsDbgTask();
|
||||
public extern Bool IsSysDbg();
|
||||
public extern Bool IsSysDeterministic();
|
||||
public extern Bool SysDbg(Bool val);
|
||||
public extern Bool SysDeterministic(Bool val);
|
||||
public extern Bool ChkPtr(U8 *ptr);
|
||||
public extern Bool ChkOnStk(U8 *ptr,CTask *task=NULL);
|
||||
public extern I64 UnusedStk(CTask *task=NULL);
|
||||
public extern U8 *Caller(I64 num=1);
|
||||
public extern U8 *TaskCaller(CTask *task=NULL,I64 num=0,Bool saved_context=FALSE);
|
||||
public extern Bool SingleUser(Bool val);
|
||||
public extern Bool IsSingleUser();
|
||||
#help_index "Debugging/Dump"
|
||||
public extern U0 D(U8 *add,I64 cnt=0x80,Bool show_offset=TRUE);
|
||||
public extern U0 Dm(U8 *add,I64 cnt=0x80);
|
||||
public extern U0 Da(U8 **add,I64 cnt=0x10);
|
||||
extern I64 *TaskRegAdd(CTask *task,I64 reg_num);
|
||||
public extern U0 Dr(CTask *task=NULL);
|
||||
public extern U0 StkRep(CTask *task=NULL);
|
||||
public extern U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL);
|
||||
#help_index "Debugging;Debugging/Debugger"
|
||||
public extern U0 Dbg(U8 *msg=NULL,I64 msg_num=0);
|
||||
#help_index "Debugging/Debugger"
|
||||
public extern Bool InDbg(Bool val);
|
||||
public extern Bool IsInDbg();
|
||||
public extern U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL);
|
||||
public extern U0 G2(U8 *ip=INVALID_PTR,CTask *task=NULL);
|
||||
public extern U0 S(U8 *ip=INVALID_PTR,CTask *task=NULL);
|
||||
public extern U0 E(U8 *add,I64 cnt=512,I64 ed_flags=0);
|
||||
extern CBpt *BptFind(U8 *add,CTask *task=NULL,Bool rem=FALSE);
|
||||
public extern Bool BptS(U8 *add,CTask *task=NULL,Bool live=TRUE);
|
||||
public extern Bool BptR(U8 *add,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE);
|
||||
public extern Bool B(U8 *add,CTask *task=NULL,Bool live=TRUE) //Toggle breakpoint
|
||||
public extern I64 B2(CTask *task=NULL,Bool live=TRUE);
|
||||
#help_index "Debugging/Raw Output"
|
||||
extern U0 RawDr(CTask *task=NULL);
|
||||
public extern U0 RawPutChar(I64 ch);
|
||||
public extern U0 VGAFlush();
|
||||
public extern Bool Raw(Bool val);
|
||||
public extern Bool IsRaw();
|
||||
public extern U0 DbgStr(U8 *st,I64 mS=100);
|
||||
public extern U0 DbgI64(I64 num,I64 mS=100);
|
||||
public extern U0 DbgF64(F64 d,I64 mS=100);
|
||||
public extern U0 DbgAdd(U8 *add,I64 mS=100);
|
||||
public extern U0 DbgD(U8 *add,I64 cnt=0x80,I64 mS=100);
|
||||
public extern U0 DbgDm(U8 *add,I64 cnt=0x80,I64 mS=100);
|
||||
|
||||
#help_index "Graphics/Color"
|
||||
extern U0 (*fp_set_std_palette)();
|
||||
public extern U8 *Color2Text(U8 *buf,CColorROPU32 c);
|
||||
|
||||
#help_index "Char"
|
||||
#help_file "::/TempleOS/Doc/Char"
|
||||
extern U0 (**fp_ctrl_alt_let_cbs)(I64 sc);
|
||||
extern I64 ctrl_alt_let_in_irq_flags;
|
||||
extern U8 **ctrl_alt_let_descs;
|
||||
extern I64 **ctrl_alt_let_ret_addr; //addr of ret add on stack in kbd irq
|
||||
extern CTaskCmd sys_macro_root;
|
||||
extern CKeyDev sys_put_key_root;
|
||||
extern CTask *sys_macro_util_task;
|
||||
extern I64 sys_raw_dc_col,sys_raw_dc_flags;
|
||||
extern U8 *sys_dc_screen_image;
|
||||
public extern Bool text_mode;
|
||||
|
||||
//Constants are defined for these to
|
||||
//optimize. See $LK-A,"::/TempleOS/Adam/Gr/GrCfg.CPP"$.
|
||||
public extern I64 text_rows,text_cols,gr_width,gr_height;
|
||||
public extern U8 *gr_font;
|
||||
|
||||
public extern CKeyDev *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE);
|
||||
public extern U0 KeyDevRem(CKeyDev *tempp);
|
||||
public extern U0 SetKeyDesc(U8 *fmt,...);
|
||||
public extern U0 SetCtrlAltLetCB(U8 ch,U0 (*fp_handler)(I64 sc),U8 *desc,Bool in_irq=FALSE);
|
||||
extern U8 key_desc[128];
|
||||
extern U8 *key_handler;
|
||||
|
||||
#help_index "Char/Output;Char/Define"
|
||||
public extern U0 PutDefineErr(U8 *st);
|
||||
public extern U0 PutDefineWarn(U8 *st);
|
||||
#help_index "Char/Output"
|
||||
public extern U0 PrintF(U8 *fmt,...);
|
||||
public extern U0 PrintFErr(U8 *fmt,...);
|
||||
public extern U0 PrintFWarn(U8 *fmt,...);
|
||||
public extern U0 NewLine(I64 cnt=1);
|
||||
public extern U0 Spaces(I64 cnt=1);
|
||||
public extern U0 PutErr(U8 *st=NULL);
|
||||
public extern U0 PutWarn(U8 *st=NULL);
|
||||
public extern U0 PutKey(I64 ch,I64 scancode);
|
||||
public extern U0 PutChar(I64 ch);
|
||||
public extern U0 PutS(U8 *st);
|
||||
public extern U8 *Bin2Hex(U8 *dst,I64 n;I64 width);
|
||||
public extern U0 PutHex(I64 n,I64 width);
|
||||
public extern Bool Silent(Bool val);
|
||||
public extern Bool IsSilent();
|
||||
public extern U0 GetOutOfDollar();
|
||||
#help_index "Char/Conversion"
|
||||
public extern I64 A2I(U8 *st,I64 radix=10,U8 **_end_ptr=NULL);
|
||||
#help_index "Input Pointer/Mouse"
|
||||
public extern I64 mouse_evt_time;
|
||||
extern I64 mouse_pkt_size;
|
||||
#help_index "Char/Input"
|
||||
public extern I64 kbd_evt_time;
|
||||
extern Bool kbd_irqs_working;
|
||||
public extern Bool PressAKey();
|
||||
public extern Bool ExitAllApplications();
|
||||
public extern Bool AreYouSure();
|
||||
public extern I64 GetKey(I64 *_scancode=NULL,Bool echo=FALSE,Bool raw_cursor=FALSE);
|
||||
public extern I64 GetChar(I64 *_scancode=NULL,Bool echo=TRUE,Bool raw_cursor=FALSE);
|
||||
public extern Bool ScanKey(I64 *_ch=NULL,I64 *_scancode=NULL,Bool echo=FALSE);
|
||||
public extern Bool YorN();
|
||||
public extern I64 GetS(U8 *buf,I64 size,Bool allow_ext=TRUE);
|
||||
public extern I64 KbdMouseEvtTime();
|
||||
|
||||
//Gets $LK,"Flags","MN:GETSF_SHIFT_ESC_EXIT"$
|
||||
public extern U8 *MGetS(I64 flags=0);
|
||||
extern U8 *(*fp_mgets)(I64 flags=0);
|
||||
extern U8 *GetFJoin(U8 *src,U8 *fmt,I64 argc,I64 *argv);
|
||||
public extern U8 *GetF(U8 *src,U8 *fmt,...);
|
||||
|
||||
#help_index "Char/Lists"
|
||||
public extern U8 *LstEntryPt(I64 entry_num, U8 *lst);
|
||||
public extern I64 LstEntryMatch(U8 *src, U8 *lst,I64 flags=0,I64 *_ambiguity_overkill=NULL);
|
||||
|
||||
#help_index "Char/Operations"
|
||||
public extern I64 StrOcc(U8 *src, U8 ch);
|
||||
public extern U8 *StrFirstOcc(U8 *src,U8 *marker);
|
||||
public extern U8 *StrLastOcc(U8 *src,U8 *marker);
|
||||
public extern I64 Spaces2Tabs(U8 *dst,U8 *src);
|
||||
public extern U8 *Tabs2Spaces(U8 *src);
|
||||
public extern U8 *ScaleIndent(U8 *src,F64 indent_scale_factor);
|
||||
public extern U8 *StrUtil(U8 *_src,I64 flags);
|
||||
public extern U8 *MStrUtil(U8 *src,I64 flags,F64 indent_scale_factor=0);
|
||||
public extern U8 *StrFirstRem(U8 *src,U8 *marker,U8 *dst=NULL);
|
||||
public extern U8 *StrLastRem(U8 *src,U8 *marker,U8 *dst=NULL);
|
||||
public extern Bool WildCardMatch(U8 *wild_st,U8 *src_st);
|
||||
public extern U8 *StrAdd(U8 *base,U8 *addition); //frees base arg
|
||||
public extern U8 *SearchStr(U8 *src,U8 *pattern,I64 flags=0);
|
||||
extern U8 *SPrintFJoin(U8 *dst,U8 *fmt,I64 argc,I64 *argv);
|
||||
public extern U8 *SPrintF(U8 *dst,U8 *fmt,...);
|
||||
public extern U8 *MSPrintF(U8 *fmt,...);
|
||||
|
||||
#help_index "Char/Define"
|
||||
#help_file "::/TempleOS/Doc/Define"
|
||||
public extern CHashDefineStr *DefineLoad(U8 *name,U8 *st,Bool replace=FALSE);
|
||||
public extern U0 DefinePrintF(U8 *name,U8 *src,...);
|
||||
public extern U8 *Define(U8 *name);
|
||||
public extern U0 PutDefine(U8 *name);
|
||||
#help_index "Char/Define;Char/Lists"
|
||||
public extern CHashDefineStr *DefineLstLoad(U8 *name,U8 *st,Bool replace=FALSE);
|
||||
public extern U8 *DefineSub(I64 sub,U8 *name);
|
||||
public extern I64 DefineSubCnt(U8 *name);
|
||||
public extern I64 DefineMatch(U8 *src,U8 *lst_name,I64 flags=0,I64 *_ambiguity_overkill=NULL);
|
||||
|
||||
#help_index "Memory"
|
||||
#help_file "::/TempleOS/Doc/Mem"
|
||||
public _extern _MEMCMP I64 MemCmp(U8 *ptr1,U8 *ptr2,I64 cnt);
|
||||
public extern I64 MemPageSize(U8 *a)
|
||||
public extern Bool MemPagePresentMark(U8 *a,Bool val);
|
||||
public extern Bool MemLowPagesProtect(Bool val);
|
||||
public extern U8 *MemBlks2MegAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL);
|
||||
public extern U8 *MemBlksUncachedAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL);
|
||||
public extern U8 *MemBlksWriteThroughAlloc(I64 *_pages2Meg,CBlkPool *bp=NULL);
|
||||
public extern U0 MemBlks2MegFree(CMemBlk *m,I64 pages2Meg,CBlkPool *bp=NULL);
|
||||
public extern U8 *MemBlksNonTaskAlloc(I64 *_pages512,CBlkPool *bp=NULL);
|
||||
public extern I64 *MemPtAtPageTableEntry(U8 *a);
|
||||
public extern U0 MemBlksNonTaskFree(CMemBlk *m,I64 pages512,CBlkPool *bp=NULL);
|
||||
public _extern _MALLOC U8 *MAlloc(I64 size,CTask *mem_task=NULL);
|
||||
public _extern _FREE U0 Free(U8 *add);
|
||||
public _extern _MSIZE I64 MSize(U8 *src); //size of heap object
|
||||
public _extern _MSIZE2 I64 MSize2(U8 *src); //Internal size
|
||||
public _extern _MHEAP_CTRL CHeapCtrl *MHeapCtrl(U8 *src);
|
||||
public extern U8 *CAlloc(I64 size,CTask *mem_task=NULL);
|
||||
public extern U8 *MAllocIdentical(U8 *src,CTask *mem_task=NULL);
|
||||
public extern U8 *MAllocAligned(I64 size,I64 alignment,CTask *mem_task=NULL,I64 misalignment=0);
|
||||
public extern U8 *CAllocAligned(I64 size,I64 alignment,CTask *mem_task=NULL,I64 misalignment=0);
|
||||
public extern U0 LinkedLstDel(U8 **_lst);
|
||||
public extern U8 *LinkedLstCopy(U8 **_lst,CTask *mem_task=NULL);
|
||||
public extern I64 LinkedLstCnt(U8 **_lst);
|
||||
public extern I64 LinkedLstSize(U8 **_lst);
|
||||
public extern I64 Scale2Mem(I64 min,I64 max,I64 limit=2*1024*1024*1024);
|
||||
#help_index "Memory;Circular Queue"
|
||||
public extern U0 QueDel(CQue *root,Bool querem=FALSE);
|
||||
public extern CQue *QueCopy(CQue *root,CTask *mem_task=NULL);
|
||||
public extern I64 QueCnt(CQue *root);
|
||||
public extern I64 QueSize(CQue *root);
|
||||
#help_index "Memory/Heap Ctrl"
|
||||
public extern U0 BlkPoolAdd(CBlkPool *bp,CMemBlk *m,I64 pages512);
|
||||
public extern U0 BlkPoolInit(CBlkPool *bp,I64 pages512);
|
||||
extern CHeapCtrl *TaskHeapCtrlNew(CTask *task,CBlkPool *bp);
|
||||
extern U0 TaskHeapCtrlDel(CHeapCtrl *hc);
|
||||
public extern CHeapCtrl *HeapCtrlIndependentInit(CBlkPool *bp,I64 pages512);
|
||||
#help_index "Memory/Adam Heap"
|
||||
public extern U8 *AMAlloc(I64 size);
|
||||
public extern U8 *AMAllocIdentical(U8 *src);
|
||||
public extern U8 *ACAlloc(I64 size);
|
||||
|
||||
#help_index "Char/Operations;Memory"
|
||||
public extern U8 *StrNew(U8 *buf,CTask *mem_task=NULL);
|
||||
#help_index "Char/Operations;Memory/Adam Heap"
|
||||
public extern U8 *AStrNew(U8 *buf);
|
||||
|
||||
#help_index "Device"
|
||||
public extern U8 *Mem32DevAlloc(I64 size,I64 alignment);
|
||||
public extern U8 *Mem64DevAlloc(I64 *_pages2Meg);
|
||||
public extern U0 Mem32DevFree(U8 *base);
|
||||
public extern U0 Mem64DevFree(U8 *base,I64 pages2Meg);
|
||||
public extern CHeapCtrl *sys_uncached_heap;
|
||||
|
||||
#help_index "Task"
|
||||
public extern U0 Exit();
|
||||
public extern U0 Kill(CTask *task,Bool wait=TRUE);
|
||||
public extern Bool Suspend(CTask *task=NULL,Bool state=TRUE);
|
||||
public extern Bool IsSuspended(CTask *task=NULL);
|
||||
public extern Bool TaskValidate(CTask *task);
|
||||
public extern CTask *Spawn(U0 (*fp_add)(U8 *data),U8 *data=NULL,
|
||||
U8 *task_name=NULL,
|
||||
CTask *parent=NULL, //NULL means adam
|
||||
I64 stk_size=0,I64 flags=SPAWNF_ADD_TO_QUE);
|
||||
public extern U0 TaskQueIns(CTask *task,CTask *pred=NULL);
|
||||
public extern U0 TaskQueRem(CTask *task);
|
||||
public extern U0 TaskWait(CTask *task=NULL);
|
||||
public extern U0 TaskInitExt(Bool from_dbg=FALSE);
|
||||
public extern U0 UserCmdLine();
|
||||
public extern U0 WinDerivedValsUpdate(CTask *task=NULL);
|
||||
public extern U0 TaskDerivedValsUpdate(CTask *task=NULL,Bool update_z_buf=TRUE);
|
||||
extern U0 (*fp_update_ctrls)(CTask *task);
|
||||
public extern CTask *SpawnUser(U8 *fmt=NULL,...);
|
||||
extern U0 TaskFinishOff(CTask *task);
|
||||
public extern U0 OverRideSingleUserSwap();
|
||||
|
||||
#help_index "Task/Requests"
|
||||
public extern U0 TaskRstAwaitingMsg(CTask *task=NULL);
|
||||
public extern CTaskCmd *
|
||||
TaskRqstQue(CTask *servant,CTask *master,
|
||||
U8 *data,I64 flags);
|
||||
public extern I64 ServantCmdsHandler(CTask *task=NULL);
|
||||
public extern I64 ServantUser(U8 *fmt,...);
|
||||
extern U0 ServantUserCmdLine();
|
||||
public extern Bool GetRqstResult(CTaskCmd *rqst=NULL,I64 *_result=NULL);
|
||||
public extern U0 ServantTaskCont();
|
||||
public extern I64 Adam(U8 *fmt,...);
|
||||
public extern U0 AdamLogExcept(I64 argc,I64 *argv);
|
||||
public extern U0 AdamLog(U8 *fmt,...);
|
||||
public extern U0 AdamErr(U8 *fmt,...);
|
||||
#help_index "Task/Text Input"
|
||||
public extern CTaskCmd *
|
||||
TextInputQue(CTask *servant,CTask *master,
|
||||
U8 *data,I64 flags);
|
||||
#help_index "Task/Text Input;Messages"
|
||||
public extern CTaskCmd *QueMsg(CTask *servant,CTask *master,
|
||||
I64 msg_code,I64 p1,I64 p2,I64 flags);
|
||||
public extern U0 PostMsg(CTask *task,I64 msg_code,I64 p1,I64 p2,I64 flags=0);
|
||||
public extern U0 SendMsg(CTask *task,I64 msg_code,I64 p1,I64 p2,I64 flags=0);
|
||||
public extern U0 Msg(I64 msg_code,I64 p1,I64 p2,I64 flags=0);
|
||||
|
||||
#help_index "Exceptions"
|
||||
//Exceptions are thrown through the following funcation call.
|
||||
//by convention, the first arg should be a type code.
|
||||
public extern U0 PutExcept();
|
||||
public extern U0 throw(...);
|
||||
public extern U0 throw_no_log(...);
|
||||
public extern I64 ExceptDepth(CTask *task=NULL);
|
||||
//The following are used internally and should not be called directly
|
||||
extern U0 SysTry(U8 *start_label,U8 *skip_label);
|
||||
extern U0 SysUntry();
|
||||
public extern U0 ThrowBreak(CTask *task=NULL);
|
||||
public extern Bool BreakLock(CTask *task=NULL);
|
||||
public extern Bool BreakUnlock(CTask *task=NULL);
|
||||
|
||||
#help_index "Compression/Piece by Piece"
|
||||
public extern U0 ArcCompressBuf(CArcCtrl *c);
|
||||
public extern U0 ArcFinishCompression(CArcCtrl *c);
|
||||
public extern U0 ArcExpandBuf(CArcCtrl *c);
|
||||
public extern CArcCtrl *ArcCtrlNew(Bool expand,Bool text_only);
|
||||
public extern U0 ArcCtrlDel(CArcCtrl *c);
|
||||
#help_index "Compression"
|
||||
public extern CArcCompress *
|
||||
CompressBuf(U8 *src,I64 size,I64 flags=0,CTask *mem_task=NULL);
|
||||
public extern U8 *ExpandBuf(CArcCompress *r,CTask *mem_task=NULL);
|
||||
//This is just an XOR checksum.
|
||||
extern I64 ArcXSum(U32 *buf,I64 size);
|
||||
|
||||
#help_index "AutoFile"
|
||||
#help_file "::/TempleOS/Doc/AutoFile"
|
||||
#help_index "Task/Text Input;AutoFile"
|
||||
public extern U0 Auto(U8 *fmt,...);
|
||||
public extern U0 AutoStr(U8 *fmt,...);
|
||||
public extern U0 AutoFile(U8 *filename);
|
||||
public extern U0 XTalk(CTask *task,U8 *fmt,...);
|
||||
public extern U0 XTalkWait(CTask *task,U8 *fmt,...);
|
||||
public extern U0 XTalkStr(CTask *task,U8 *fmt,...);
|
||||
public extern U0 XTalkStrWait(CTask *task,U8 *fmt,...);
|
||||
|
||||
#help_index "Misc/Progress Bars"
|
||||
public extern U0 ProgressBarsRst();
|
||||
|
||||
#help_index "Math"
|
||||
public extern U16 RandU16(); //With timestamp
|
||||
public extern U32 RandU32();
|
||||
public extern U64 RandU64();
|
||||
public extern I16 RandI16();
|
||||
public extern I32 RandI32();
|
||||
public extern I64 RandI64();
|
||||
public extern F64 Rand();
|
||||
public extern U16 Rand2U16(); //Without timestamp
|
||||
public extern U32 Rand2U32();
|
||||
public extern U64 Rand2U64();
|
||||
public extern I16 Rand2I16();
|
||||
public extern I32 Rand2I32();
|
||||
public extern I64 Rand2I64();
|
||||
public extern F64 Rand2();
|
||||
public extern U0 Randomize(I64 seed=0);
|
||||
public extern U64 FloorU64(U64 num,U64 to);
|
||||
public extern U64 CeilU64(U64 num,U64 to);
|
||||
public extern I64 RoundI64(I64 num,I64 to);
|
||||
public extern I64 FloorI64(I64 num,I64 to);
|
||||
public extern I64 CeilI64(I64 num,I64 to);
|
||||
|
||||
#help_index "Misc"
|
||||
public extern U0 QSortI64(I64 *base,I64 num, I64 (*fp_compare)(I64 e1,I64 e2));
|
||||
public extern U0 QSort(U8 *base,I64 num, I64 width,I64 (*fp_compare)(U8 *e1,U8 *e2));
|
||||
|
||||
public extern U16 EndianU16(U16 d);
|
||||
public extern U32 EndianU32(U32 d);
|
||||
public extern U64 EndianU64(U64 d);
|
||||
extern I64 sys_rnd_seed;
|
||||
|
||||
#help_index "Bit"
|
||||
public extern I64 BCnt(I64 d);
|
||||
public extern U8 *reverse_bits_table,*set_bits_table;
|
||||
|
||||
#help_index "Doc/Clipboard"
|
||||
public extern CDoc *sys_clipboard_doc;
|
||||
|
||||
#help_index "Time/CDate"
|
||||
public extern U16 mon_start_days1[12];
|
||||
public extern U16 mon_start_days2[12];
|
||||
public extern I64 YearStartDate(I64 year);
|
||||
public extern CDate CDateStruct2CDate(CDateStruct *_ds);
|
||||
public extern U0 CDate2CDateStruct(CDateStruct *_ds,CDate spdt);
|
||||
public extern I64 FirstDayOfMon(I64 i);
|
||||
public extern I64 LastDayOfMon(I64 i);
|
||||
public extern I64 FirstDayOfYear(I64 i);
|
||||
public extern I64 LastDayOfYear(I64 i);
|
||||
public extern I64 DayOfWeek(I64 i);
|
||||
public extern CDate GetCurTimeCDate();
|
||||
public extern U0 CDate2ISO1(CISO1Date *dst,CDate spdt);
|
||||
|
||||
#help_index "File/System"
|
||||
extern U8 sys_temp_filename[136];
|
||||
extern I64 sys_dsk_reads,sys_dsk_writes;
|
||||
|
||||
#help_index "File/System/Cache"
|
||||
extern CCacheBlk *sys_dsk_cache_base,*sys_dsk_cache_ctrl;
|
||||
extern CCacheBlk **sys_dsk_cache_hash_table;
|
||||
extern I64 sys_dsk_cache_size;
|
||||
|
||||
extern U0 DskCacheInit(I64 size_in_U8s);
|
||||
public extern U0 DskCacheInvalidate(CPrt *p);
|
||||
|
||||
#help_index "File/System/BlkDev"
|
||||
public extern CBlkDev *sys_blkdevs;
|
||||
|
||||
#help_index "File/System/Partitions"
|
||||
public extern CPrt *sys_prts;
|
||||
extern CPrt *drv_to_prt[32];
|
||||
|
||||
#help_index "PCI;Info;File/System/Hardware;Device"
|
||||
public extern I64 ATARep(Bool pmt=TRUE,Bool just_ide=FALSE,CATARep **_root=NULL);
|
||||
|
||||
#help_index "File/System/Hardware"
|
||||
public extern CATARep *ATAIDDrvs(CATARep *root,U8 _dft_drv,CATARep **_ata_drv,CATARep **_atapi_drv);
|
||||
extern CBlkDev *ATAMount(U8 first_drv_let,I64 type,I64 base0,I64 base1,I64 unit);
|
||||
public extern I64 sys_auto_mount_ide_cnt;
|
||||
public extern I64 AutoMountIDE();
|
||||
extern I64 ATAProbe(I64 base0,I64 base1,I64 unit);
|
||||
extern Bool ATAPIStartStop(CBlkDev *bdev,Bool start,F64 timeout);
|
||||
extern I64 BlkDevAdd(CBlkDev *bdev,Bool one_prt,Bool make_free);
|
||||
extern U0 ATAReadBlks(CBlkDev *bdev,U8 *buf, I64 blk, I64 cnt);
|
||||
extern U0 ATAWriteBlks(CBlkDev *bdev,U8 *buf, I64 blk, I64 cnt);
|
||||
|
||||
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
#help_file "::/TempleOS/Doc/CmdLine"
|
||||
public extern U0 ChgDsk(U8 drv_let=0);
|
||||
public extern Bool Drv(U8 drv_let);
|
||||
public extern Bool Cd(U8 *dirname,Bool make_dirs=FALSE);
|
||||
public extern Bool MapDrv(U8 drv_let,CPrt *p);
|
||||
public extern U0 Dir(U8 *wild="*",Bool full=FALSE);
|
||||
public extern I64 Del(U8 *wild,Bool print_msg=TRUE);
|
||||
public extern Bool MkDir(U8 *filename);
|
||||
|
||||
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);File/Install Related;Install"
|
||||
public extern U0 PrtRep();
|
||||
|
||||
#help_index "File/Program Routines/Low Level"
|
||||
extern CDirEntry *SysFilesFind(U8 *files_find_mask,I64 fuf_flags);
|
||||
extern I64 SysDel(U8 *wild,Bool make_mask); //this is dangerous
|
||||
extern Bool CopySingle(U8 *f1,U8 *f2); //Just one file
|
||||
extern U0 CleanMAPBuf(CPrt *p);
|
||||
extern U0 FAT32FreeClusters(CPrt *p,I64 c);
|
||||
extern U0 NativeFSFreeClusters(CPrt *p,I64 c,I64 cnt);
|
||||
public extern Bool BlkDevLock(CBlkDev *bdev);
|
||||
public extern Bool PrtLock(CPrt *p);
|
||||
public extern Bool BlkDevUnlock(CBlkDev *bdev,Bool rst=FALSE);
|
||||
public extern Bool PrtUnlock(CPrt *p,Bool rst=FALSE);
|
||||
public extern U0 BlkDevsRelease();
|
||||
public extern CPrt *PrtMakeFree(U8 drv_let);
|
||||
public extern CPrt *PrtNextFree(U8 first_drv_let='C');
|
||||
public extern CBlkDev *BlkDevNextFree(U8 first_drv_let,I64 type);
|
||||
public extern U0 PrtsRelease();
|
||||
public extern I64 ClusterNumNext(CPrt *p,I64 c,I64 cnt=1);
|
||||
public extern I64 Cluster2Blk(CPrt *p,I64 c);
|
||||
public extern I64 RClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks);
|
||||
public extern I64 RClusters(CPrt *p,U8 *buf,I64 c,I64 cnt);
|
||||
public extern I64 WClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks);
|
||||
public extern I64 WClusters(CPrt *p,U8 *buf,I64 c,I64 cnt);
|
||||
public extern I64 ClusersAlloc(CPrt *p,I64 c=0,I64 cnt=1,Bool contiguous=FALSE);
|
||||
public extern Bool RBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt);
|
||||
public extern Bool WBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt);
|
||||
public extern U0 WZeroBlks(CPrt *p,I64 blk,I64 cnt);
|
||||
public extern U0 PrtChk(CPrt *p);
|
||||
public extern U0 BlkDevChk(CBlkDev *bdev);
|
||||
public extern U8 Prt2Drv(CPrt *p=NULL);
|
||||
public extern CPrt *Drv2Prt(U8 drv_let=0);
|
||||
public extern CBlkDev *Drv2BlkDev(U8 drv_let=0);
|
||||
extern I64 Name2DirCluster(CPrt *p,U8 *dirname);
|
||||
extern I64 Name2ParentDirCluster(CPrt *p,U8 *dirname);
|
||||
public extern U8 *DrvSerialNum(U8 drv_let=0);
|
||||
public extern U8 *DrvModelNum(U8 drv_let=0);
|
||||
|
||||
#help_index "File/Program Routines/CFile"
|
||||
public extern CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0);
|
||||
public extern I64 FSize(CFile *f);
|
||||
public extern U0 FClose(CFile *f);
|
||||
public extern Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
|
||||
public extern Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1);
|
||||
|
||||
#help_index "File/CD DVD"
|
||||
public extern U0 CDImageRead(U8 cd_drv_let,U8 *out_name);
|
||||
public extern U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD);
|
||||
public extern U8 *sys_dft_iso_name;
|
||||
|
||||
#help_index "File/FileNames"
|
||||
public extern Bool FilesFindMatch(U8 *files_find_mask,U8 *filename,I64 fuf_flags=0);
|
||||
public extern Bool IsDotZ(U8 *filename);
|
||||
public extern Bool IsDotC(U8 *filename);
|
||||
public extern U8 *FileExtDot(U8 *src);
|
||||
public extern U8 *FileExtRem(U8 *src,U8 *dst=NULL);
|
||||
public extern U0 PutFileLink(U8 *filename,I64 line=0,Bool plain_text=FALSE);
|
||||
public extern U0 PutDirLink(U8 *dirname);
|
||||
public extern U8 *CurDir(CTask *task=NULL,CTask *mem_task=NULL);
|
||||
public extern U8 *DirNameAbs(U8 *dirname);
|
||||
public extern U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL);
|
||||
public extern U8 *ToggleZorNotZ(U8 *name);
|
||||
public extern U8 *FileNameAbs(U8 *filename,I64 fuf_flags=0);
|
||||
public extern Bool FileNameChk(U8 *filename);
|
||||
public extern U8 *ChgExt(U8 *filename,U8 *extension);
|
||||
public extern U8 *DftExt(U8 *filename,U8 *extension);
|
||||
public extern Bool IsDir(U8 *dir_name);
|
||||
public extern Bool IsDrvWritable(U8 drv_let=0);
|
||||
extern CDirEntry *CdDir(CDirEntry *tempm,U8 *abs_name);
|
||||
|
||||
#help_index "File/Program Routines/Utils"
|
||||
public extern U0 GetFFlags(U8 *f,U8 *lst,U8 *st);
|
||||
public extern U8 *SPrintFFlags(U8 *dst,U8 *lst,I64 flags);
|
||||
public extern U0 FileAccessDel(CFileAccess *fa);
|
||||
public extern CFileAccess *FileAccessNew(U8 *mask,Bool make_mask=FALSE,Bool make_dirs=FALSE);
|
||||
extern I64 FileAttr(U8 *name,I64 old_attr=0);
|
||||
public extern U0 CDirEntryDel(CDirEntry *tempm);
|
||||
public extern U0 CDirEntryDel2(CDirEntry *tempm);
|
||||
public extern U0 CDirLstDel(CDirEntry *tempm);
|
||||
public extern U0 CDirLstDel2(CDirEntry *tempm);
|
||||
public extern Bool CDirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempm,Bool free_old_chain=TRUE);
|
||||
|
||||
#help_index "File/Program Routines"
|
||||
public extern CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0);
|
||||
public extern I64 FileSize(U8 *filename,I64 fuf_flags=0);
|
||||
public extern I64 FileSizeExpanded(U8 *filename,I64 fuf_flags=0);
|
||||
public extern Bool FileFind(U8 *filename,CDirEntry *de=NULL,I64 fuf_flags=0);
|
||||
public extern U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE);
|
||||
public extern U8 *TextFileRead(U8 *filename,I64 *_attr=NULL);
|
||||
public extern I64 FileWrite(U8 *filename,U8 *fbuf,
|
||||
I64 size,CDate spdt=0,I64 attr=0,Bool raw=FALSE);
|
||||
public extern U0 TextFileWrite(U8 *filename,U8 *st,I64 attr=0);
|
||||
|
||||
#help_index "Install;File/Install Related;File/Cmd Line (Typically);Cmd Line (Typically);"
|
||||
public extern U0 Mount(Bool repartition=FALSE);
|
||||
|
||||
#help_index "Install;File/Install Related"
|
||||
extern CATARep *ATARepFind(CATARep *root,I64 num);
|
||||
public extern Bool DrvEnable(U8 drv_let,Bool val);
|
||||
public extern U0 Fmt(U8 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=PT_FAT32);
|
||||
extern U0 DrvDftSelect();
|
||||
public extern U8 dft_drv,sys_first_hd_drv_let,sys_first_cd_drv_let;
|
||||
extern Bool boot_drv_pmt;
|
||||
|
||||
#help_index "Hash"
|
||||
#help_file "::/TempleOS/Doc/Hash"
|
||||
public _extern _HASH_STR I64 HashStr(U8 *st);
|
||||
public _extern _HASH_FIND CHash *
|
||||
HashFind(U8 *st,CHashTable *table,I64 mask,I64 instance=1);
|
||||
public _extern _HASH_SINGLE_TABLE_FIND CHash *
|
||||
HashSingleTableFind(U8 *st,CHashTable *table,I64 mask,I64 instance=1);
|
||||
public _extern _HASH_BUCKET_FIND CHash **
|
||||
HashBucketFind(U8 *st,CHashTable *table);
|
||||
public _extern _HASH_ADD U0 HashAdd(CHash *temph,CHashTable *table);
|
||||
public _extern _HASH_ADD_AFTER U0 HashAddAfter(CHash *temph,CHash *pred,CHashTable *table);
|
||||
public _extern _HASH_REPLACE U0 HashReplace(CHash *temph,CHashTable *table,
|
||||
I64 instance=1);//instance must match temph's
|
||||
public _extern _HASH_REM_DEL Bool HashRemDel(CHash *temph,CHashTable *table,
|
||||
I64 instance=1);//instance must match temph's
|
||||
public _extern _EXT_FIND U8 *ExtFind(U8 *st,I64 instance=1);
|
||||
public extern CHashGeneric *HashGenericAdd(U8 *name,I64 type,I64 val=0,I64 u8=0,I64 u16=0,CTask *task=NULL);
|
||||
public extern I64 HashTypeNum(CHash *temph);
|
||||
public extern CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL);
|
||||
public extern U0 HashDel(CHashSrcSym *temph);
|
||||
public extern U0 HashTableDel(CHashTable *table);
|
||||
extern U0 SysSymImportsResolve(U8 *sptr,I64 ld_flags=0);
|
||||
|
||||
#help_index "Hash/Named Frame"
|
||||
#help_file "::/TempleOS/Doc/NamedFrame"
|
||||
public extern I64 NamedFramePtr(U8 *name,CTask *task=NULL);
|
||||
public extern CHashGeneric *NamedFramePtrAdd(U8 *name,I64 val,CTask *task=NULL);
|
||||
public extern I64 NamedFramePtrSet(U8 *name,I64 val,CTask *task=NULL);
|
||||
public extern I64 NamedFramePtrDel(U8 *name,CTask *task=NULL);
|
||||
|
||||
#help_index "Compiler;Cmd Line (Typically)"
|
||||
public extern U8 *Load(U8 *filename,I64 ld_flags=0,
|
||||
CBinFile *bfh_addr=INVALID_PTR); //INVALID_PTR means don't care what load addr.
|
||||
|
||||
extern I64 sys_num_installed_compilers;
|
||||
#help_index "Compiler"
|
||||
extern U0 (*fp_prs_stream_blk)(CLex *lx);
|
||||
|
||||
#help_index "Boot"
|
||||
public extern U0 Reboot();
|
||||
|
||||
#help_index "MultiCore"
|
||||
extern CMPCmdCtrl *mp_ctrl;
|
||||
extern U8 mp_apic_ids[MP_MAX_PROCESSORS];
|
||||
extern CMPCrash *mp_crash;
|
||||
public extern U0 MPInt(U8 num,I64 cpu_num=1);
|
||||
public extern U0 IntEOI(); //signal end of interrupt
|
||||
public extern U0 MPIntAll(U8 num);
|
||||
public extern U0 MPWake(I64 target_cpu_mask);
|
||||
extern U0 MPSethServerTask();
|
||||
extern CMPCmd *MPQueJob(I64 (*fp_add)(U8 *data),U8 *data=NULL,
|
||||
U8 *desc=NULL,
|
||||
I64 flags=1<<MPCf_FREE_ON_COMPLETE,
|
||||
Bool spawn=FALSE,I64 target_cpu_mask=ALL_MASK);
|
||||
public extern CMPCmd *MPJob(I64 (*fp_add)(U8 *data),U8 *data=NULL,
|
||||
I64 target_cpu=1,I64 flags=1<<MPCf_FREE_ON_COMPLETE);
|
||||
public extern I64 MPJobResult(CMPCmd *tempm);
|
||||
public extern CTask *MPSpawn(U0 (*fp_add)(U8 *data),U8 *data=NULL,U8 *name=NULL,I64 target_cpu=1);
|
||||
public extern U0 MPNMInt();
|
||||
public extern U0 MPStart();
|
||||
#help_index "MultiCore;Boot"
|
||||
public extern U0 MPHalt();
|
||||
|
||||
#help_index "Math"
|
||||
public extern F64 Limit(F64 p,F64 lo,F64 hi);
|
||||
public extern F64 Min(F64 n1,F64 n2);
|
||||
public extern F64 Max(F64 n1,F64 n2);
|
||||
public extern F64 Pow10I64(I64 i);
|
||||
|
||||
#help_index "PCI"
|
||||
public extern U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg);
|
||||
public extern U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg);
|
||||
public extern U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg);
|
||||
public extern U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
|
||||
public extern U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
|
||||
public extern U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val);
|
||||
public extern I64 PCIClassFind(I64 class_code,I64 n);
|
||||
|
||||
//These are far call routines in the BIOS
|
||||
public _extern SYS_BIOS32_SERVICE_DIR U32 sys_BIOS32_service_dir;
|
||||
public _extern SYS_PCI_SERVICES U32 sys_pci_services;
|
||||
|
||||
#help_index "PCI;Call"
|
||||
public _extern C32_EAX U32 c32_eax;
|
||||
public _extern C32_EBX U32 c32_ebx;
|
||||
public _extern C32_ECX U32 c32_ecx;
|
||||
public _extern C32_EDX U32 c32_edx;
|
||||
public _extern C32_ESI U32 c32_esi;
|
||||
public _extern C32_EDI U32 c32_edi;
|
||||
public _extern C32_EFLAGS U32 c32_eflags;
|
||||
//Not reentrant
|
||||
public _extern _FAR_CALL32 Bool FarCall32(U0 (*fp_add)());
|
||||
|
||||
#help_index "Call"
|
||||
//fp_add can have any fixed number of arguments.
|
||||
public argpop extern I64 CallStkGrow(I64 stk_size_threshold,I64 stk_size,/*argpop*/I64 (*fp_add)(...),...);
|
||||
|
||||
#help_index "Fifo"
|
||||
public extern CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL);
|
||||
public extern U0 FifoU8Del(CFifoU8 *f);
|
||||
public extern Bool FifoU8Ins(CFifoU8 *f,U8 b);
|
||||
public extern Bool FifoU8Rem(CFifoU8 *f,U8 *_b);
|
||||
public extern Bool FifoU8Peek(CFifoU8 *f,U8 *_b);
|
||||
public extern U0 FifoU8Flush(CFifoU8 *f);
|
||||
public extern I64 FifoU8Cnt(CFifoU8 *f);
|
||||
public extern CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL);
|
||||
public extern U0 FifoI64Del(CFifoI64 *f);
|
||||
public extern Bool FifoI64Ins(CFifoI64 *f,I64 q);
|
||||
public extern Bool FifoI64Rem(CFifoI64 *f,I64 *_q);
|
||||
public extern Bool FifoI64Peek(CFifoI64 *f,I64 *_q);
|
||||
public extern U0 FifoI64Flush(CFifoI64 *f);
|
||||
public extern I64 FifoI64Cnt(CFifoI64 *f);
|
||||
|
||||
#help_index "Char/Operations"
|
||||
public _extern _STRCMP I64 StrCmp(U8 *st1,U8 *st2);
|
||||
public _extern _STRICMP I64 StrICmp(U8 *st1,U8 *st2);
|
||||
public _extern _STRNCMP I64 StrNCmp(U8 *st1,U8 *st2,I64 n);
|
||||
public _extern _STRNICMP I64 StrNICmp(U8 *st1,U8 *st2,I64 n);
|
||||
public _extern _STRSTR U8 *StrStr(U8 *st,U8 *pattern);
|
||||
public _extern _STRISTR U8 *StrIStr(U8 *st,U8 *pattern);
|
||||
public _extern _STRCPY U0 StrCpy(U8 *dst,U8 *src);
|
||||
public _extern _STRCAT U0 StrCat(U8 *dst,U8 *src);
|
||||
|
||||
#help_index "Char/Input"
|
||||
public extern I64 sys_key_cnt;
|
||||
public extern U0 SetTypeMatic(U8 delay);
|
||||
extern U0 KbdInit();
|
||||
extern I64 KbdQueMsgs();
|
||||
extern U0 KbdMouseVarsInit();
|
||||
extern Bool MouseDriverInstall();
|
||||
extern U0 KbdMouseHandler(Bool poll_kbd,Bool poll_mouse);
|
||||
public extern U32 key_down_bitmap[8],key_down_bitmap2[8];
|
||||
|
||||
#help_index "Char/BitMaps"
|
||||
public extern U32 alpha_bitmap[16];
|
||||
public extern U32 alpha_numeric_bitmap[16];
|
||||
public extern U32 alpha_numeric_no_at_bitmap[16];
|
||||
public extern U32 word_bitmap[16];
|
||||
public extern U32 dec_numeric_bitmap[16];
|
||||
public extern U32 hex_numeric_bitmap[16];
|
||||
public extern U32 white_space_bitmap[16];
|
||||
public extern U32 non_eol_white_space_bitmap[16];
|
||||
public extern U32 zero_cr_nl_cursor_bitmap[16];
|
||||
public extern U32 zero_tab_ff_cr_nl_cursor_bitmap[16];
|
||||
public extern U32 zero_tab_ff_cr_nl_cursor_dollar_bitmap[16];
|
||||
public extern U32 getkey_chars_bitmap[16];
|
||||
public extern U32 printable_chars_bitmap[16];
|
||||
public extern U32 displayable_chars_bitmap[16];
|
||||
public extern U32 safe_dollar_chars_bitmap[16];
|
||||
public extern U32 filename_chars_bitmap[16];
|
||||
public extern U32 non_eol_chars_bitmap[16];
|
||||
|
||||
#help_index "Char/Conversion"
|
||||
public extern I64 A2ScanCode(I64 ch,I64 sc_flags=0);
|
||||
public extern U8 ScanCode2A(I64 sc);
|
||||
public extern U8 *A2KeyName(I64 ch,Bool include_ctrl=TRUE);
|
||||
public extern U8 *ScanCode2KeyName(I64 sc);
|
||||
|
||||
#help_index "Input Pointer/Mouse"
|
||||
public extern F64 mxx_scale,myy_scale,mzz_scale;
|
||||
|
||||
//These are the coordinates before
|
||||
//they get scaled.
|
||||
public extern I64 mxx_prescale,myy_prescale,mzz_prescale;
|
||||
public extern I64 mxx,myy,mzz;
|
||||
public extern F64 mouse_speed;
|
||||
extern I64 old_mxx,old_myy,old_mzz;
|
||||
public extern Bool mouse_buttons[5];
|
||||
extern Bool mouse_installed;
|
||||
extern I64 mouse_install_attempts,
|
||||
mouse_last_evt_time;
|
||||
extern Bool mouse_has_wheel;
|
||||
extern Bool mouse_has_ext_buttons;
|
||||
extern Bool mouse_evt;
|
||||
extern Bool mouse_install_attempt_in_progress;
|
||||
extern CFifoI64 *scan_code_fifo;
|
||||
extern I64 sys_last_down_scan_code;
|
||||
extern Bool kbdmouse_rst;
|
||||
extern Bool mouse_irqs_working;
|
||||
|
||||
#help_index "Input Pointer"
|
||||
#help_file "::/TempleOS/Doc/InputPointer"
|
||||
public extern I64 ipx,ipy,ipz,ip_throttle;
|
||||
public extern I64 ipx_offset,ipy_offset,ipz_offset;
|
||||
public extern F64 ipx_scale,ipy_scale,ipz_scale;
|
||||
public extern F64 ip_speed;
|
||||
public extern I64 ip_dev;
|
||||
public extern I64 iptx,ipty;
|
||||
public extern Bool ip_lb,ip_cb,ip_rb;
|
||||
extern Bool ip_lb_last,ip_cb_last,ip_rb_last;
|
||||
public extern Bool ip_has_wheel;
|
||||
extern F64 ip_last_move_time;
|
||||
extern CSnap ip_snap_last;
|
||||
public extern U0 SetIP(I64 x=MAX_I64,I64 y=MAX_I64,I64 z=MAX_I64,I64 l=MAX_I64,I64 r=MAX_I64,I64 c=MAX_I64);
|
||||
#help_index "Input Pointer/Displayed Image"
|
||||
public extern Bool ip_on; //Show or hide cursor
|
||||
extern U0 IPVarsUpdate(I64 x,I64 y,I64 z,Bool l,Bool c,Bool r);
|
||||
extern U0 IPVarsInit();
|
||||
#help_index "Input Pointer/Snap"
|
||||
public extern I64 ipx_presnap,ipy_presnap,ipz_presnap;
|
||||
extern CSnap *SnapCur();
|
||||
public extern U0 GetSnap(CSnap *s);
|
||||
public extern U0 SetSnap(CSnap *s,I64 i=0,F64 d=0);
|
||||
|
||||
#help_index "Messages"
|
||||
extern U0 InputFilterTask();
|
||||
public extern I64 ScanMsg(I64 *_p1=NULL,I64 *_p2=NULL,I64 mask=~1,CTask *task=NULL);
|
||||
public extern I64 FlushMsgs(CTask *task=NULL);
|
||||
public extern I64 GetMsg(I64 *_p1=NULL,I64 *_p2=NULL,I64 mask=~1,CTask *task=NULL);
|
||||
public extern I64 ScanChar();
|
||||
|
||||
#help_index "Misc;Messages"
|
||||
public extern I64 sys_cur_scan_code;
|
||||
|
||||
#help_index "Doc/Task"
|
||||
extern CDoc *(*fp_doc_cur)(CTask *task=NULL);
|
||||
|
||||
#help_index "Char/Conversion"
|
||||
public extern F64 A2F64(U8 *src,U8 **_end_ptr=NULL);
|
||||
|
||||
#help_index "Time/CDate"
|
||||
public extern U8 *date_fmt_map,*time_fmt_map;
|
||||
public extern U0 DateTimeFmtMapsRst();
|
||||
|
||||
#help_index "Char/Conversion;Time/CDate"
|
||||
public extern CDate A2CDate(U8 *src);
|
||||
|
||||
#help_index "Debugging/PSect;Hash"
|
||||
public extern CHash *PSectFind(U8 *add,I64 *_offset);
|
||||
extern CPSectCache *psect_cache;
|
||||
extern I64 psect_cache_index;
|
||||
#help_index "Debugging/PSect"
|
||||
public extern I64 SrcLineNum(U8 *add,I64 cnt=1);
|
||||
public extern U8 *SrcFileName(U8 *add,I64 cnt=1,CTask *mem_task=NULL);
|
||||
public extern U8 *SrcEdLink(U8 *add,I64 cnt=1,CTask *mem_task=NULL);
|
||||
public extern Bool PutSrcLink(U8 *add,I64 cnt=1,U8 *buf=NULL);
|
||||
|
||||
#help_index "Debugging;Debugging/Debugger"
|
||||
public extern U0 EdLite(U8 *filename,I64 num=1);
|
||||
extern U8 *sys_fix_file_line;
|
||||
public extern U0 SetFix(U8 *filename,I64 line);
|
||||
public extern U0 Fix();
|
||||
extern U0 EdLiteFileLine(U8 *_fl_file_line);
|
||||
#help_index "Debugging/Debugger;Doc/Cmd Line (Typically);Cmd Line (Typically);Training"
|
||||
public extern U0 Man(U8 *st);
|
||||
|
||||
#help_index "Exceptions"
|
||||
public extern U0 CatchAll();
|
||||
|
||||
#help_index "Task/Requests;Compiler"
|
||||
public extern U0 UserTaskCont();
|
||||
public extern I64 ExeCmdLine(CLex *lx);
|
||||
|
||||
#help_index "Training;Debugging/Debugger"
|
||||
public extern U0 Help();
|
||||
|
||||
#help_index ""
|
||||
@@ -0,0 +1,296 @@
|
||||
asm {
|
||||
USE32
|
||||
|
||||
SYS_BIOS32_SERVICE_DIR:: DU32 0;
|
||||
SYS_PCI_SERVICES:: DU32 0;
|
||||
|
||||
SYS_FIND_BIOS32_SERVICE_DIR::
|
||||
MOV ESI,0xE0000
|
||||
MOV ECX,(0x100000-0xE0000)/4
|
||||
@@05: CMP U32 [ESI],'_32_'
|
||||
JNE @@20
|
||||
PUSH ECX
|
||||
XOR ECX,ECX
|
||||
MOV CL,U8 9[ESI]
|
||||
SHL ECX,4
|
||||
@@10: MOV EDI,ESI
|
||||
XOR EAX,EAX
|
||||
XOR EDX,EDX
|
||||
@@15: MOV DL,U8 [EDI]
|
||||
ADD EAX,EDX
|
||||
INC EDI
|
||||
DEC ECX
|
||||
JNZ @@15
|
||||
POP ECX
|
||||
OR AL,AL
|
||||
JNZ @@20
|
||||
MOV U32 [SYS_BIOS32_SERVICE_DIR],ESI
|
||||
MOV ESI,U32 4[ESI]
|
||||
MOV U32 [SYS_BIOS32_SERVICE_CALL],ESI
|
||||
RET
|
||||
|
||||
@@20: ADD ESI,4
|
||||
LOOP @@05
|
||||
MOV U32 [SYS_BIOS32_SERVICE_DIR],0
|
||||
RET
|
||||
|
||||
SYS_FIND_PCI_SERVICES::
|
||||
MOV ESI,U32 [SYS_BIOS32_SERVICE_DIR]
|
||||
OR ESI,ESI
|
||||
JNZ @@05
|
||||
MOV U32 [SYS_PCI_SERVICES],0
|
||||
RET
|
||||
@@05: MOV EAX,'$$PCI'
|
||||
XOR EBX,EBX
|
||||
DU8 0x9A; //CALL GDT_CS_SEL:BIOS32_SERVICE
|
||||
SYS_BIOS32_SERVICE_CALL:: DU32 0;
|
||||
DU16 GDT_CS_SEL;
|
||||
OR AL,AL
|
||||
JNZ @@05
|
||||
LEA ESI,U32 [EBX+EDX]
|
||||
MOV U32 [SYS_PCI_SERVICES],ESI
|
||||
RET
|
||||
|
||||
@@05: MOV U32 [SYS_PCI_SERVICES],0
|
||||
RET
|
||||
|
||||
|
||||
|
||||
|
||||
USE64
|
||||
C32_EAX:: DU32 0;
|
||||
C32_EBX:: DU32 0;
|
||||
C32_ECX:: DU32 0;
|
||||
C32_EDX:: DU32 0;
|
||||
C32_ESI:: DU32 0;
|
||||
C32_EDI:: DU32 0;
|
||||
C32_EFLAGS:: DU32 0;
|
||||
|
||||
C32_RSP:: DU64 0;
|
||||
|
||||
_FAR_CALL32::
|
||||
//This calls a 32-bit mode routine.
|
||||
//(We must switch from 64-bit mode to do it.)
|
||||
//
|
||||
//NON REENTRANT
|
||||
//
|
||||
ENTER 0
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
OR RAX,RAX
|
||||
JNZ @@05
|
||||
LEAVE
|
||||
RET1 8 //return FALSE
|
||||
@@05: MOV U32 [C32_ADD],EAX
|
||||
PUSH_REGS
|
||||
PUSHFD
|
||||
XOR RAX,RAX
|
||||
PUSH U64 FS:CTask.addr[RAX]
|
||||
PUSH U64 GS:CCPU.addr[RAX]
|
||||
MOV U64 [C32_RSP],RSP
|
||||
PUSH U32 GDT_ZERO_DS_SEL //STKSEG
|
||||
PUSH U32 0x9C000 //STK
|
||||
PUSH U32 0 //FLAGS--interrupts off
|
||||
PUSH U32 GDT_CS_SEL
|
||||
LEA RAX,[@@15]
|
||||
PUSH RAX
|
||||
IRET
|
||||
USE32
|
||||
@@15:
|
||||
WBINVD
|
||||
//disable paging
|
||||
MOV_EAX_CR0
|
||||
BTR EAX,31
|
||||
MOV_CR0_EAX
|
||||
|
||||
MOV ECX,IA32_EFER
|
||||
XOR EDX,EDX
|
||||
XOR EAX,EAX
|
||||
WRMSR
|
||||
|
||||
MOV AX,GDT_ZERO_DS_SEL
|
||||
MOV FS,AX
|
||||
MOV GS,AX
|
||||
//SS already set
|
||||
|
||||
MOV EAX,U32 [C32_EAX]
|
||||
MOV EBX,U32 [C32_EBX]
|
||||
MOV ECX,U32 [C32_ECX]
|
||||
MOV EDX,U32 [C32_EDX]
|
||||
MOV ESI,U32 [C32_ESI]
|
||||
MOV EDI,U32 [C32_EDI]
|
||||
MOV U32 [C32_EFLAGS],0
|
||||
|
||||
DU8 0x9A; //CALL GDT_CS_SEL:[C32_ADD]
|
||||
C32_ADD:: DU32 0;
|
||||
DU16 GDT_CS_SEL;
|
||||
|
||||
PUSHFD
|
||||
POP U32 [C32_EFLAGS]
|
||||
|
||||
MOV U32 [C32_EAX],EAX
|
||||
MOV U32 [C32_EBX],EBX
|
||||
MOV U32 [C32_ECX],ECX
|
||||
MOV U32 [C32_EDX],EDX
|
||||
MOV U32 [C32_ESI],ESI
|
||||
MOV U32 [C32_EDI],EDI
|
||||
|
||||
CALL INIT_EM64T
|
||||
USE64
|
||||
MOV AX,GDT_ZERO_DS_SEL
|
||||
MOV DS,AX
|
||||
MOV ES,AX
|
||||
MOV SS,AX
|
||||
|
||||
MOV RSP,U64 [C32_RSP]
|
||||
|
||||
//GS ALREADY ON STK
|
||||
CALL _SET_GS_BASE
|
||||
POP RAX
|
||||
CALL SET_FS_BASE
|
||||
|
||||
POPFD
|
||||
POP_REGS
|
||||
XOR RAX,RAX
|
||||
MOV AL,TRUE
|
||||
LEAVE
|
||||
RET1 8
|
||||
}
|
||||
|
||||
_extern C32_EAX U32 c32_eax;
|
||||
_extern C32_EBX U32 c32_ebx;
|
||||
_extern C32_ECX U32 c32_ecx;
|
||||
_extern C32_EDX U32 c32_edx;
|
||||
_extern C32_ESI U32 c32_esi;
|
||||
_extern C32_EDI U32 c32_edi;
|
||||
_extern C32_EFLAGS U32 c32_eflags;
|
||||
_extern SYS_PCI_SERVICES U32 sys_pci_services;
|
||||
|
||||
//Not reentrant--used to call BIOS32
|
||||
//Takes like, 250uS.
|
||||
_extern _FAR_CALL32 Bool FarCall32(U0 (*fp_add)());
|
||||
|
||||
U8 PCIReadU8(I64 bus,I64 dev,I64 fun,I64 rg)
|
||||
{
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB108;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
if (FarCall32(sys_pci_services))
|
||||
result=c32_ecx.u8[0];
|
||||
else
|
||||
result=0xFF;
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
U16 PCIReadU16(I64 bus,I64 dev,I64 fun,I64 rg)
|
||||
{
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB109;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
if (FarCall32(sys_pci_services))
|
||||
result=c32_ecx.u16[0];
|
||||
else
|
||||
result=0xFFFF;
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
U32 PCIReadU32(I64 bus,I64 dev,I64 fun,I64 rg)
|
||||
{
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB10A;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
if (FarCall32(sys_pci_services))
|
||||
result=c32_ecx;
|
||||
else
|
||||
result=0xFFFFFFFF;
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 PCIWriteU8(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB10B;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
c32_ecx=val;
|
||||
FarCall32(sys_pci_services);
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
}
|
||||
|
||||
U0 PCIWriteU16(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB10C;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
c32_ecx=val;
|
||||
FarCall32(sys_pci_services);
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
}
|
||||
|
||||
U0 PCIWriteU32(I64 bus,I64 dev,I64 fun,I64 rg,I64 val)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB10D;
|
||||
c32_ebx=bus<<8+dev<<3+fun;
|
||||
c32_edi=rg;
|
||||
c32_ecx=val;
|
||||
FarCall32(sys_pci_services);
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
}
|
||||
|
||||
I64 PCIClassFind(I64 class_code,I64 n)
|
||||
{
|
||||
//class_code is low three bytes
|
||||
//n is index starting at zero
|
||||
//Returns: -1 not found
|
||||
// else bus,dev,fun.
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_FAR_CALL32],0))
|
||||
Yield;
|
||||
c32_eax=0xB103;
|
||||
c32_esi=n;
|
||||
c32_ecx=class_code;
|
||||
if (FarCall32(sys_pci_services) && !c32_eax.u8[1])
|
||||
result=c32_ebx.u8[1]<<16+(c32_ebx&0xF8)<<5+c32_ebx&7;
|
||||
else
|
||||
result=-1;
|
||||
LBtr(&sys_semas[SYS_SEMA_FAR_CALL32],0);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
//See $LK,"MP_VECT_ADDR","FF:::/TempleOS/Kernel/Adam1a.HPP,MP_VECT_ADDR"$ for something
|
||||
//else used in low RAM.
|
||||
//See $LK-A,"::/TempleOS/Doc/Mem.TXT"$.
|
||||
|
||||
//At least $LK,"DFT_CACHE_LINE_WIDTH","MN:DFT_CACHE_LINE_WIDTH"$ alignment.
|
||||
#define BOOT_RAM_BASE 0x07C00
|
||||
#define BOOT_RAM_LIMIT 0x80000
|
||||
|
||||
//9FC00 is EBDA BIOS area
|
||||
#define VGA_GRAPHIC_MEM_BASE 0xA0000
|
||||
#define VGA_TEXT_MEM_BASE 0xB8000
|
||||
|
||||
#define BLK_SIZE_BITS 9
|
||||
#define BLK_SIZE (1<<BLK_SIZE_BITS)
|
||||
#define CD_BLK_SIZE (4*BLK_SIZE)
|
||||
#define CD_FILE_OFFSET 80
|
||||
|
||||
#define CD_BOOT_LOADER_SIZE CD_BLK_SIZE*1 //Max 4 CDBlks, I think
|
||||
|
||||
//These are the cfguration settings
|
||||
//for a standard production CD-Image
|
||||
#define STD_DISTRO_CDROM_CFG "b1Scale2Mem(2048,0x40000)\nt3 \n\n\n\n\n"
|
||||
#define SAFE_CDROM_CFG "b1Scale2Mem(2048,0x40000)\nt3 \n\n\n\nDontProbe\n\n"
|
||||
|
||||
#define BOOT_STK_SIZE BLK_SIZE
|
||||
|
||||
#define BOOT_CODE_RAM 1
|
||||
#define BOOT_CODE_HARDDRV 2
|
||||
#define BOOT_CODE_CDROM 3
|
||||
|
||||
@@ -0,0 +1,324 @@
|
||||
//See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (4).
|
||||
//See $LK,"CArcCompress","MN:CArcCompress"$, $LK,"CArcEntry","MN:CArcEntry"$, and $LK,"CArcCtrl","MN:CArcCtrl"$
|
||||
|
||||
asm {
|
||||
USE64
|
||||
/****
|
||||
U0 ArcGetEntry(CArcCtrl *c)
|
||||
{
|
||||
I64 i;
|
||||
CArcEntry *temp,*temp1;
|
||||
|
||||
if (c->entry_used) {
|
||||
i=c->free_index;
|
||||
|
||||
c->entry_used=FALSE;
|
||||
c->cur_entry=c->next_entry;
|
||||
c->cur_bits_in_use=c->next_bits_in_use;
|
||||
if (c->next_bits_in_use<ARC_MAX_BITS) {
|
||||
c->next_entry = &c->compress[i++];
|
||||
if (i==c->free_limit) {
|
||||
c->next_bits_in_use++;
|
||||
c->free_limit=1<<c->next_bits_in_use;
|
||||
}
|
||||
} else {
|
||||
do if (++i==c->free_limit)
|
||||
i=c->min_table_entry;
|
||||
while (c->hash[i]);
|
||||
temp=&c->compress[i];
|
||||
c->next_entry=temp;
|
||||
temp1=&c->hash[temp->basecode];
|
||||
while (temp1) {
|
||||
if (temp1->next==temp) {
|
||||
temp1->next=temp->next;
|
||||
break;
|
||||
} else
|
||||
temp1=temp1->next;
|
||||
}
|
||||
}
|
||||
c->free_index=i;
|
||||
}
|
||||
}
|
||||
****/
|
||||
_ARC_GET_ENTRY::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
BTR U64 CArcCtrl.entry_used[RSI],0
|
||||
JNC I32 @@30
|
||||
MOV RDX,U64 CArcCtrl.free_index[RSI]
|
||||
MOV RAX,U64 CArcCtrl.next_entry[RSI]
|
||||
MOV U64 CArcCtrl.cur_entry[RSI],RAX
|
||||
MOV RCX,U64 CArcCtrl.next_bits_in_use[RSI]
|
||||
MOV U64 CArcCtrl.cur_bits_in_use[RSI],RCX
|
||||
CMP RCX,ARC_MAX_BITS
|
||||
JAE @@05
|
||||
MOV RAX,RDX
|
||||
SHL RAX,4
|
||||
LEA RAX,U64 CArcCtrl.compress[RSI+RAX]
|
||||
MOV U64 CArcCtrl.next_entry[RSI],RAX
|
||||
INC RDX
|
||||
CMP U64 CArcCtrl.free_limit[RSI],RDX
|
||||
JNE @@25
|
||||
INC RCX
|
||||
MOV U64 CArcCtrl.next_bits_in_use[RSI],RCX
|
||||
MOV RAX,1
|
||||
SHL RAX,CL
|
||||
MOV U64 CArcCtrl.free_limit[RSI],RAX
|
||||
JMP @@25
|
||||
@@05: INC RDX
|
||||
CMP U64 CArcCtrl.free_limit[RSI],RDX
|
||||
JNE @@10
|
||||
MOV RDX,U64 CArcCtrl.min_table_entry[RSI]
|
||||
@@10: MOV RAX,U64 CArcCtrl.hash[RSI+RDX*8]
|
||||
OR RAX,RAX
|
||||
JNZ @@05
|
||||
MOV RDI,RDX
|
||||
SHL RDI,4
|
||||
LEA RDI,U64 CArcCtrl.compress[RSI+RDI]
|
||||
MOV U32 CArcCtrl.next_entry[RSI],EDI
|
||||
MOVZX RBX,U16 CArcEntry.basecode[RDI]
|
||||
LEA RCX,U64 CArcCtrl.hash[RSI+RBX*8]
|
||||
@@15: OR RCX,RCX
|
||||
JZ @@25
|
||||
MOV RAX,U64 CArcEntry.next[RCX]
|
||||
CMP RDI,RAX
|
||||
JNE @@20
|
||||
MOV RAX,U64 CArcEntry.next[RDI]
|
||||
MOV U64 CArcEntry.next[RCX],RAX
|
||||
JMP @@25
|
||||
@@20: MOV RCX,RAX
|
||||
JMP @@15
|
||||
@@25: MOV U64 CArcCtrl.free_index[RSI],RDX
|
||||
@@30: POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 8
|
||||
}
|
||||
|
||||
_extern _ARC_GET_ENTRY
|
||||
U0 ArcGetEntry(CArcCtrl *c);
|
||||
|
||||
|
||||
I64 ArcXSum(U32 *src,I64 size)
|
||||
{
|
||||
I64 result=0;
|
||||
size>>=2;
|
||||
while (size--)
|
||||
result^=*src++;
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 ArcDetermineCompressionType(U8 *src,I64 size)
|
||||
{
|
||||
while (size--)
|
||||
if (*src++&0x80)
|
||||
return CT_8_BIT;
|
||||
return CT_7_BIT;
|
||||
}
|
||||
|
||||
U0 ArcCompressBuf(CArcCtrl *c)
|
||||
//Use $LK,"CompressBuf","MN:CompressBuf"$() unless you are doing
|
||||
//more than one buffer.
|
||||
{
|
||||
CArcEntry *temp,*temp1;
|
||||
I64 basecode;
|
||||
U8 *src_ptr,*src_limit,ch;
|
||||
|
||||
src_ptr=c->src_buf+c->src_pos;
|
||||
src_limit=c->src_buf+c->src_size;
|
||||
|
||||
if (c->saved_basecode==MAX_U32)
|
||||
basecode=*src_ptr++;
|
||||
else
|
||||
basecode=c->saved_basecode;
|
||||
|
||||
while (src_ptr<src_limit &&
|
||||
c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
|
||||
ArcGetEntry(c);
|
||||
|
||||
arc_start_loop1:
|
||||
if (src_ptr>=src_limit) goto arc_done_compression;
|
||||
ch=*src_ptr++;
|
||||
if (temp=c->hash[basecode])
|
||||
do {
|
||||
if (temp->ch==ch) {
|
||||
basecode=temp-&c->compress[0];
|
||||
goto arc_start_loop1;
|
||||
}
|
||||
} while (temp=temp->next);
|
||||
|
||||
BFieldOrU32(c->dst_buf,c->dst_pos,basecode);
|
||||
c->dst_pos+=c->cur_bits_in_use;
|
||||
|
||||
c->entry_used=TRUE;
|
||||
temp=c->cur_entry;
|
||||
temp->basecode=basecode;
|
||||
temp->ch=ch;
|
||||
temp1=&c->hash[basecode];
|
||||
temp->next=temp1->next;
|
||||
temp1->next=temp;
|
||||
|
||||
basecode=ch;
|
||||
}
|
||||
arc_done_compression:
|
||||
c->saved_basecode=basecode;
|
||||
c->src_pos=src_ptr-c->src_buf;
|
||||
}
|
||||
|
||||
U0 ArcFinishCompression(CArcCtrl *c)
|
||||
{
|
||||
if (c->dst_pos+c->cur_bits_in_use<=c->dst_size) {
|
||||
BFieldOrU32(c->dst_buf,c->dst_pos,c->saved_basecode);
|
||||
c->dst_pos+=c->next_bits_in_use;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ArcExpandBuf(CArcCtrl *c)
|
||||
//Use $LK,"ExpandBuf","MN:ExpandBuf"$() unless you know what
|
||||
//you're doing.
|
||||
{
|
||||
U8 *dst_ptr,*dst_limit;
|
||||
I64 basecode,lastcode,code;
|
||||
CArcEntry *temp,*temp1;
|
||||
|
||||
dst_ptr=c->dst_buf+c->dst_pos;
|
||||
dst_limit=c->dst_buf+c->dst_size;
|
||||
|
||||
while (dst_ptr<dst_limit &&
|
||||
c->stk_ptr!=c->stk_base)
|
||||
*dst_ptr++ = * -- c->stk_ptr;
|
||||
|
||||
if (c->stk_ptr==c->stk_base && dst_ptr<dst_limit) {
|
||||
if (c->saved_basecode==MAX_U32) {
|
||||
lastcode=BFieldExtU32(c->src_buf,c->src_pos,
|
||||
c->next_bits_in_use);
|
||||
c->src_pos+=c->next_bits_in_use;
|
||||
*dst_ptr++=lastcode;
|
||||
ArcGetEntry(c);
|
||||
c->last_ch=lastcode;
|
||||
} else
|
||||
lastcode=c->saved_basecode;
|
||||
while (dst_ptr<dst_limit &&
|
||||
c->src_pos+c->next_bits_in_use<=c->src_size) {
|
||||
basecode=BFieldExtU32(c->src_buf,c->src_pos,
|
||||
c->next_bits_in_use);
|
||||
c->src_pos+=c->next_bits_in_use;
|
||||
if (c->cur_entry==&c->compress[basecode]) {
|
||||
*c->stk_ptr++=c->last_ch;
|
||||
code=lastcode;
|
||||
} else
|
||||
code=basecode;
|
||||
while (code>=c->min_table_entry) {
|
||||
*c->stk_ptr++=c->compress[code].ch;
|
||||
code=c->compress[code].basecode;
|
||||
}
|
||||
*c->stk_ptr++=code;
|
||||
c->last_ch=code;
|
||||
|
||||
c->entry_used=TRUE;
|
||||
temp=c->cur_entry;
|
||||
temp->basecode=lastcode;
|
||||
temp->ch=c->last_ch;
|
||||
temp1=&c->hash[lastcode];
|
||||
temp->next=temp1->next;
|
||||
temp1->next=temp;
|
||||
|
||||
ArcGetEntry(c);
|
||||
while (dst_ptr<dst_limit && c->stk_ptr!=c->stk_base)
|
||||
*dst_ptr++ = * -- c->stk_ptr;
|
||||
lastcode=basecode;
|
||||
}
|
||||
c->saved_basecode=lastcode;
|
||||
}
|
||||
c->dst_pos=dst_ptr-c->dst_buf;
|
||||
}
|
||||
|
||||
CArcCtrl *ArcCtrlNew(Bool expand,Bool text_only)
|
||||
{
|
||||
CArcCtrl *c;
|
||||
c=CAlloc(sizeof(CArcCtrl));
|
||||
if (expand) {
|
||||
c->stk_base=MAlloc(ARC_MAX_ENTRY+1);
|
||||
c->stk_ptr=c->stk_base;
|
||||
}
|
||||
if (text_only)
|
||||
c->min_bits=7;
|
||||
else
|
||||
c->min_bits=8;
|
||||
c->min_table_entry=1<<c->min_bits;
|
||||
c->free_index=c->min_table_entry;
|
||||
c->next_bits_in_use=c->min_bits+1;
|
||||
c->free_limit=1<<c->next_bits_in_use;
|
||||
c->saved_basecode=MAX_U32;
|
||||
c->entry_used=TRUE;
|
||||
ArcGetEntry(c);
|
||||
c->entry_used=TRUE;
|
||||
return c;
|
||||
}
|
||||
|
||||
U0 ArcCtrlDel(CArcCtrl *c)
|
||||
{
|
||||
Free(c->stk_base);
|
||||
Free(c);
|
||||
}
|
||||
|
||||
|
||||
CArcCompress *CompressBuf(U8 *src,I64 size,
|
||||
I64 flags=0,CTask *mem_task=NULL)
|
||||
{
|
||||
CArcCompress *result;
|
||||
I64 size_out;
|
||||
Bool text_only=ArcDetermineCompressionType(src,size)==CT_7_BIT;
|
||||
CArcCtrl *c=ArcCtrlNew(FALSE,text_only);
|
||||
c->src_size=size;
|
||||
c->src_buf=src;
|
||||
c->dst_size=(size+sizeof(CArcCompress))<<3;
|
||||
c->dst_buf=CAlloc(c->dst_size>>3);
|
||||
c->dst_pos=sizeof(CArcCompress)<<3;
|
||||
ArcCompressBuf(c);
|
||||
ArcFinishCompression(c);
|
||||
if (c->src_pos==c->src_size) {
|
||||
size_out=(c->dst_pos+7)>>3;
|
||||
result=MAlloc(size_out,mem_task);
|
||||
MemCpy(result,c->dst_buf,size_out);
|
||||
result->compression_type=text_only ? CT_7_BIT:CT_8_BIT;
|
||||
result->compressed_size=size_out;
|
||||
} else {
|
||||
result=MAlloc(size+sizeof(CArcCompress),mem_task);
|
||||
MemCpy(&result->body,src,size);
|
||||
result->compression_type=CT_NONE;
|
||||
result->compressed_size=size+sizeof(CArcCompress);
|
||||
}
|
||||
result->expanded_size=size;
|
||||
result->flags=flags;
|
||||
Free(c->dst_buf);
|
||||
ArcCtrlDel(c);
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *ExpandBuf(CArcCompress *r,CTask *mem_task=NULL)
|
||||
{
|
||||
CArcCtrl *c;
|
||||
Bool text_only;
|
||||
U8 *result=MAlloc(r->expanded_size+1,mem_task);
|
||||
result[r->expanded_size]=0; //terminate
|
||||
text_only= r->compression_type==CT_7_BIT;
|
||||
if (r->compression_type==CT_NONE) {
|
||||
MemCpy(result,&r->body,r->expanded_size);
|
||||
goto expand_end;
|
||||
}
|
||||
c=ArcCtrlNew(TRUE,text_only);
|
||||
c->src_size=r->compressed_size<<3;
|
||||
c->src_pos=sizeof(CArcCompress)<<3;
|
||||
c->src_buf=r;
|
||||
c->dst_size=r->expanded_size;
|
||||
c->dst_buf=result;
|
||||
c->dst_pos=0;
|
||||
ArcExpandBuf(c);
|
||||
ArcCtrlDel(c);
|
||||
expand_end:
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,483 @@
|
||||
//See $LK-A,"::/TempleOS/Doc/TimeDate.TXT"$
|
||||
|
||||
U16 mon_start_days1[12]={
|
||||
0,31,59,90,120,151,181,212,243,273,304,334};
|
||||
U16 mon_start_days2[12]={
|
||||
0,31,60,91,121,152,182,213,244,274,305,335};
|
||||
|
||||
I64 YearStartDate(I64 year)
|
||||
{
|
||||
I64 y1=year-1,yd4000=y1/4000,yd400=y1/400,yd100=y1/100,yd4=y1/4;
|
||||
return year*365+yd4-yd100+yd400-yd4000;
|
||||
}
|
||||
|
||||
CDate CDateStruct2CDate(CDateStruct *_ds)
|
||||
{
|
||||
CDate spdt;
|
||||
I64 i1,i2;
|
||||
i1=YearStartDate(_ds->year);
|
||||
i2=YearStartDate(_ds->year+1);
|
||||
if (i2-i1==365)
|
||||
i1+=mon_start_days1[_ds->mon-1];
|
||||
else
|
||||
i1+=mon_start_days2[_ds->mon-1];
|
||||
spdt.date=i1+_ds->day_of_mon-1;
|
||||
spdt.time=(_ds->sec10000+100*(_ds->sec100+100*(_ds->sec+60*(_ds->min+60*_ds->hour))))<<21/(15*15*3*625);
|
||||
return spdt;
|
||||
}
|
||||
|
||||
I64 DayOfWeek(I64 i)
|
||||
{
|
||||
i+=CDATE_BASE_DAY_OF_WEEK;
|
||||
if (i>=0)
|
||||
return i % 7;
|
||||
else
|
||||
return 6-(6-i)%7;
|
||||
}
|
||||
|
||||
U0 CDate2CDateStruct(CDateStruct *_ds,CDate spdt)
|
||||
{
|
||||
I64 i,k,date=spdt.date;
|
||||
_ds->day_of_week=DayOfWeek(date);
|
||||
_ds->year=(date+1)*100000/CDATE_YEAR_DAYS_INT;
|
||||
i=YearStartDate(_ds->year);
|
||||
while (i>date) {
|
||||
_ds->year--;
|
||||
i=YearStartDate(_ds->year);
|
||||
}
|
||||
date-=i;
|
||||
if (YearStartDate(_ds->year+1)-i==365) {
|
||||
k=0;
|
||||
while (date>=mon_start_days1[k+1] && k<11)
|
||||
k++;
|
||||
date-=mon_start_days1[k];
|
||||
} else {
|
||||
k=0;
|
||||
while (date>=mon_start_days2[k+1] && k<11)
|
||||
k++;
|
||||
date-=mon_start_days2[k];
|
||||
}
|
||||
_ds->mon=k+1;
|
||||
_ds->day_of_mon=date+1;
|
||||
k=(625*15*15*3*spdt.time)>>21+1;
|
||||
_ds->sec10000=ModU64(&k,100);
|
||||
_ds->sec100=ModU64(&k,100);
|
||||
_ds->sec=ModU64(&k,60);
|
||||
_ds->min=ModU64(&k,60);
|
||||
_ds->hour =k;
|
||||
}
|
||||
|
||||
I64 FirstDayOfMon(I64 i)
|
||||
{
|
||||
CDateStruct ds;
|
||||
CDate spdt=0;
|
||||
spdt.date=i;
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
ds.day_of_mon=1;
|
||||
spdt=CDateStruct2CDate(&ds);
|
||||
return spdt.date;
|
||||
}
|
||||
|
||||
I64 LastDayOfMon(I64 i)
|
||||
{
|
||||
CDateStruct ds;
|
||||
CDate spdt=0;
|
||||
spdt.date=i;
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
ds.mon++;
|
||||
if (ds.mon==13) {
|
||||
ds.mon=0;
|
||||
ds.year++;
|
||||
}
|
||||
ds.day_of_mon=1;
|
||||
spdt=CDateStruct2CDate(&ds);
|
||||
return spdt.date-1;
|
||||
}
|
||||
|
||||
I64 FirstDayOfYear(I64 i)
|
||||
{
|
||||
CDateStruct ds;
|
||||
CDate spdt=0;
|
||||
spdt.date=i;
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
ds.day_of_mon=1;
|
||||
ds.mon=1;
|
||||
spdt=CDateStruct2CDate(&ds);
|
||||
return spdt.date;
|
||||
}
|
||||
|
||||
I64 LastDayOfYear(I64 i)
|
||||
{
|
||||
CDateStruct ds;
|
||||
CDate spdt=0;
|
||||
spdt.date=i;
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
ds.day_of_mon=1;
|
||||
ds.mon=1;
|
||||
ds.year++;
|
||||
spdt=CDateStruct2CDate(&ds);
|
||||
return spdt.date-1;
|
||||
}
|
||||
|
||||
|
||||
I64 Bcd2Bin(U64 b)
|
||||
{
|
||||
I64 i,result=0;
|
||||
for (i=0;i<16;i++) {
|
||||
result=result*10+b>>60;
|
||||
b<<=4;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
U0 GetCurTimeCDateStruct(CDateStruct *_ds)
|
||||
{
|
||||
I64 i;
|
||||
U8 *b=_ds;
|
||||
Bool is_bcd;
|
||||
|
||||
MemSet(_ds,0,sizeof(CDateStruct));
|
||||
PushFD;
|
||||
Cli;
|
||||
while (LBts(&sys_semas[SYS_SEMA_SYS_DATE],0))
|
||||
Pause;
|
||||
|
||||
OutU8(0x70,0x0A);
|
||||
do {
|
||||
while (InU8(0x71) & 0x80)
|
||||
Pause;
|
||||
|
||||
OutU8(0x70,0);
|
||||
b[2]=InU8(0x71);
|
||||
OutU8(0x70,2);
|
||||
b[3]=InU8(0x71);
|
||||
OutU8(0x70,4);
|
||||
b[4]=InU8(0x71);
|
||||
|
||||
OutU8(0x70,6);
|
||||
b[5]=InU8(0x71);
|
||||
OutU8(0x70,7);
|
||||
b[6]=InU8(0x71);
|
||||
OutU8(0x70,8);
|
||||
b[7]=InU8(0x71);
|
||||
OutU8(0x70,9);
|
||||
b[8]=InU8(0x71);
|
||||
|
||||
OutU8(0x70,0x0A);
|
||||
} while (InU8(0x71) & 0x80);
|
||||
|
||||
OutU8(0x70,0x0B);
|
||||
if (InU8(0x71) & 4)
|
||||
is_bcd=FALSE;
|
||||
else
|
||||
is_bcd=TRUE;
|
||||
|
||||
LBtr(&sys_semas[SYS_SEMA_SYS_DATE],0);
|
||||
PopFD;
|
||||
if (is_bcd)
|
||||
for (i=2;i<9;i++)
|
||||
b[i]=Bcd2Bin(b[i]);
|
||||
|
||||
if (_ds->year>255) _ds->year=255;
|
||||
_ds->year+=2000;
|
||||
if (_ds->mon>12) _ds->mon=12;
|
||||
if (_ds->day_of_mon>31) _ds->day_of_mon=31;
|
||||
if (_ds->day_of_week>6) _ds->day_of_week=6;
|
||||
if (_ds->hour>23) _ds->hour=23;
|
||||
if (_ds->min>59) _ds->min=59;
|
||||
if (_ds->sec>59) _ds->sec=59;
|
||||
}
|
||||
|
||||
CDate GetCurTimeCDate()
|
||||
{
|
||||
CDateStruct ds;
|
||||
GetCurTimeCDateStruct(&ds);
|
||||
return CDateStruct2CDate(&ds)-local_time_offset;
|
||||
}
|
||||
|
||||
U0 DateTimeFmtMapsRst()
|
||||
{
|
||||
I64 i;
|
||||
for (i=0;i<DF_NUM;i++)
|
||||
date_fmt_map[i]=i;
|
||||
for (i=0;i<TF_NUM;i++)
|
||||
time_fmt_map[i]=i;
|
||||
}
|
||||
|
||||
U8 *MSPrintFTime(CDate spdt,I64 sub_fmt)
|
||||
{
|
||||
CDateStruct ds;
|
||||
if (sub_fmt<TF_NUM)
|
||||
sub_fmt=time_fmt_map[sub_fmt];
|
||||
switch (sub_fmt) {
|
||||
case TF_HH24_MM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d:%02d",ds.hour,ds.min);
|
||||
case TF_HH12_MM_SS_AM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
if (ds.hour>=12)
|
||||
return MSPrintF("%02d:%02d:%02d pm",ds.hour-12,ds.min,ds.sec);
|
||||
else
|
||||
return MSPrintF("%02d:%02d:%02d am",ds.hour,ds.min,ds.sec);
|
||||
case TF_HH12_MM_AM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
if (ds.hour>=12)
|
||||
return MSPrintF("%02d:%02d pm",ds.hour-12,ds.min);
|
||||
else
|
||||
return MSPrintF("%02d:%02d am",ds.hour,ds.min);
|
||||
case TF_HH12_MM_SSA:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
if (ds.hour>=12)
|
||||
return MSPrintF("%02d:%02d:%02dp",ds.hour-12,ds.min,ds.sec);
|
||||
else
|
||||
return MSPrintF("%02d:%02d:%02da",ds.hour,ds.min,ds.sec);
|
||||
case TF_HH12_MMA:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
if (ds.hour>=12)
|
||||
return MSPrintF("%02d:%02dp",ds.hour-12,ds.min);
|
||||
else
|
||||
return MSPrintF("%02d:%02da",ds.hour,ds.min);
|
||||
case TF_H_M:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dh %02dm",ds.hour+spdt.date*24,ds.min);
|
||||
case TF_H_M_S:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dh %02dm %02ds",ds.hour+spdt.date*24,ds.min,ds.sec);
|
||||
case TF_D_H_M:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dd %02dh %02dm",spdt.date,ds.hour,ds.min);
|
||||
case TF_D_H_M_S:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dd %02dh %02dm %02ds",spdt.date,ds.hour,ds.min,ds.sec);
|
||||
case TF_D_H_M_Sh:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dd %02dh %02dm %02d.%02ds",spdt.date,ds.hour,ds.min,ds.sec,ds.sec100);
|
||||
case TF_H_M_Sh:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dh %02dm %02d.%02ds",ds.hour+spdt.date*24,ds.min,ds.sec,ds.sec100);
|
||||
case TF_Sh:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%d.%02d",60*((spdt.date*24+ds.hour)*60+ds.min)+ds.sec,ds.sec100);
|
||||
case TF_M_Sh:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%02d:%02d.%02d",60*(spdt.date*24+ds.hour)+ds.min,ds.sec,ds.sec100);
|
||||
case TF_H_M_Sh2:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%02d:%02d:%02d.%02d",spdt.date*24+ds.hour,ds.min,ds.sec,ds.sec100);
|
||||
case TF_D_H_M_Sht:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dd %02dh %02dm %02d.%04ds",spdt.date,ds.hour,ds.min,ds.sec,100*ds.sec100+ds.sec10000);
|
||||
case TF_H_M_Sht:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%dh %02dm %02d.%04ds",ds.hour+spdt.date*24,ds.min,ds.sec,100*ds.sec100+ds.sec10000);
|
||||
case TF_Sht:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%d.%04d",60*((spdt.date*24+ds.hour)*60+ds.min)+ds.sec,100*ds.sec100+ds.sec10000);
|
||||
case TF_M_Sht:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%02d:%02d.%04d",60*(spdt.date*24+ds.hour)+ds.min,ds.sec,100*ds.sec100+ds.sec10000);
|
||||
case TF_H_M_Sht2:
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
return MSPrintF("%02d:%02d:%02d.%04d",spdt.date*24+ds.hour,ds.min,ds.sec,100*ds.sec100+ds.sec10000);
|
||||
case TF_HH24:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d",ds.hour);
|
||||
case TF_MM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d",ds.min);
|
||||
case TF_SS:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d",ds.sec);
|
||||
case TF_HH24_MM_SS:
|
||||
default:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d:%02d:%02d",ds.hour,ds.min,ds.sec);
|
||||
}
|
||||
}
|
||||
|
||||
U8 *MSPrintFDate(CDate spdt,I64 sub_fmt)
|
||||
{
|
||||
CDateStruct ds;
|
||||
if (sub_fmt<DF_NUM)
|
||||
sub_fmt=date_fmt_map[sub_fmt];
|
||||
switch (sub_fmt) {
|
||||
case DF_MM_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d",ds.mon,ds.day_of_mon);
|
||||
case DF_wek_MM_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon,ds.day_of_mon);
|
||||
case DF_wek_MM_DD_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d/%02d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon,ds.day_of_mon,ds.year%100);
|
||||
case DF_MM_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d/%d",ds.mon,ds.day_of_mon,ds.year);
|
||||
case DF_wek_MM_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d/%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon,ds.day_of_mon,ds.year);
|
||||
case DF_mon_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d",ds.mon-1,"ST_MONTHS",ds.day_of_mon);
|
||||
case DF_wek_mon_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ, %3tZ %02d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon-1,"ST_MONTHS",ds.day_of_mon);
|
||||
case DF_mon_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d,%04d",ds.mon-1,"ST_MONTHS",ds.day_of_mon,ds.year);
|
||||
case DF_wek_mon_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ, %3tZ %02d,%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon-1,"ST_MONTHS",ds.day_of_mon,ds.year);
|
||||
case DF_month_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z %d",ds.mon-1,"ST_MONTHS",ds.day_of_mon);
|
||||
case DF_week_month_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z, %Z %d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon-1,"ST_MONTHS",ds.day_of_mon);
|
||||
case DF_month_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z %d,%d",ds.mon-1,"ST_MONTHS",ds.day_of_mon,ds.year);
|
||||
case DF_week_month_DD_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z, %Z %d,%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.mon-1,"ST_MONTHS",ds.day_of_mon,ds.year);
|
||||
case DF_DD_MM_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d/%02d",ds.day_of_mon,ds.mon,ds.year%100);
|
||||
case DF_DD_MM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d",ds.day_of_mon,ds.mon);
|
||||
case DF_wek_DD_MM:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon);
|
||||
case DF_wek_DD_MM_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d/%02d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon,ds.year%100);
|
||||
case DF_DD_MM_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d/%d",ds.day_of_mon,ds.mon,ds.year);
|
||||
case DF_wek_DD_MM_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d/%02d/%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon,ds.year);
|
||||
case DF_DD_mon:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d %3tZ",ds.day_of_mon,ds.mon-1,"ST_MONTHS");
|
||||
case DF_wek_DD_mon:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ, %02d %3tZ",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon-1,"ST_MONTHS");
|
||||
case DF_DD_mon_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d %3tZ,%04d",ds.day_of_mon,ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_wek_DD_mon_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ, %02d %3tZ,%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_DD_month:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d %Z",ds.day_of_mon,ds.mon-1,"ST_MONTHS");
|
||||
case DF_week_DD_month:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z, %d %Z",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon-1,"ST_MONTHS");
|
||||
case DF_DD_month_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d %Z,%d",ds.day_of_mon,ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_week_DD_month_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z, %d %Z,%d",ds.day_of_week,"ST_DAYS_OF_WEEK",
|
||||
ds.day_of_mon,ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_YY_MM_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d/%02d",ds.year%100,ds.mon,ds.day_of_mon);
|
||||
case DF_YYYY_MM_DD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d/%02d/%02d",ds.year,ds.mon,ds.day_of_mon);
|
||||
case DF_YYMMDD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d%02d%02d",ds.year%100,ds.mon,ds.day_of_mon);
|
||||
case DF_YYYYMMDD:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d%02d%02d",ds.year,ds.mon,ds.day_of_mon);
|
||||
case DF_MMDDYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d%02d%02d",ds.mon,ds.day_of_mon,ds.year%100);
|
||||
case DF_MMDDYYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d%02d%d",ds.mon,ds.day_of_mon,ds.year);
|
||||
case DF_wek:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ",ds.day_of_week,"ST_DAYS_OF_WEEK");
|
||||
case DF_week:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z",ds.day_of_week,"ST_DAYS_OF_WEEK");
|
||||
case DF_mon:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ",ds.mon-1,"ST_MONTHS");
|
||||
case DF_month:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z",ds.mon-1,"ST_MONTHS");
|
||||
case DF_YYYY_mon:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d %3tZ",ds.year,ds.mon-1,"ST_MONTHS");
|
||||
case DF_YYYY_month:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d %Z",ds.year,ds.mon-1,"ST_MONTHS");
|
||||
case DF_YY_mon:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d %3tZ",ds.year%100,ds.mon-1,"ST_MONTHS");
|
||||
case DF_YY_month:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d %Z",ds.year%100,ds.mon-1,"ST_MONTHS");
|
||||
case DF_mon_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %d",ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_month_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z %d",ds.mon-1,"ST_MONTHS",ds.year);
|
||||
case DF_mon_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%3tZ %02d",ds.mon-1,"ST_MONTHS",ds.year%100);
|
||||
case DF_month_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%Z %02d",ds.mon-1,"ST_MONTHS",ds.year%100);
|
||||
case DF_YY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d",ds.year%100);
|
||||
case DF_YYYY:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%d",ds.year);
|
||||
case DF_D:
|
||||
return MSPrintF("%d days",spdt.date);
|
||||
case DF_M:
|
||||
return MSPrintF("%d mons",ToI64(spdt/(CDATE_YEAR_DAYS/12))>>32);
|
||||
case DF_Y:
|
||||
return MSPrintF("%d years",ToI64(spdt/CDATE_YEAR_DAYS)>>32);
|
||||
case DF_D2:
|
||||
return MSPrintF("%d",spdt.date);
|
||||
case DF_M2:
|
||||
return MSPrintF("%d",ToI64(spdt/(CDATE_YEAR_DAYS/12))>>32);
|
||||
case DF_Y2:
|
||||
return MSPrintF("%d",ToI64(spdt/CDATE_YEAR_DAYS)>>32);
|
||||
case DF_D3:
|
||||
return MSPrintF("%0.1f",spdt/ToF64(MAX_U32+1));
|
||||
case DF_M3:
|
||||
return MSPrintF("%0.1f",spdt/ToF64(MAX_U32+1)/(CDATE_YEAR_DAYS/12));
|
||||
case DF_Y3:
|
||||
return MSPrintF("%0.1f",spdt/ToF64(MAX_U32+1)/CDATE_YEAR_DAYS);
|
||||
case DF_MM_DD_YY:
|
||||
default:
|
||||
CDate2CDateStruct(&ds,spdt+local_time_offset);
|
||||
return MSPrintF("%02d/%02d/%02d",ds.mon,ds.day_of_mon,ds.year%100);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,701 @@
|
||||
Bool IsDbgTask()
|
||||
{
|
||||
CTask *task=Fs->parent_task;
|
||||
if (TaskValidate(task) && task->dbg_task==Fs)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool ChkPtr(U8 *ptr)
|
||||
{
|
||||
if (sys_heap_base<=ptr<=MAPPED_MEM_SPACE) {
|
||||
if (*MemPtAtPageTableEntry(ptr)&1)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
} else if (ptr<sys_boot_base)
|
||||
return FALSE;
|
||||
else if (ptr<VGA_GRAPHIC_MEM_BASE)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool ChkOnStk(U8 *ptr,CTask *task=NULL)
|
||||
{
|
||||
Bool result=FALSE;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (task) {
|
||||
if (&task->stk->stk_base<=ptr<=(&task->stk->stk_base)(U8 *)+task->stk->stk_size)
|
||||
result=TRUE;
|
||||
} else if (sys_heap_base<=ptr<=sys_heap_limit)
|
||||
result=TRUE;
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 UnusedStk(CTask *task=NULL)
|
||||
{
|
||||
I64 result;
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (task==Fs)
|
||||
result=GetStkPtr()(U8 *)-(&task->stk->stk_base)(U8 *);
|
||||
else
|
||||
result=task->rsp(U8 *)-(&task->stk->stk_base)(U8 *);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *Caller(I64 num=1)
|
||||
//Returns the addr of the fun
|
||||
//which called this one, or the caller
|
||||
//of the caller, etc.
|
||||
{
|
||||
U8 **rbp=GetBasePtr,**ptr;
|
||||
while (num--) {
|
||||
if (rbp>=*rbp)
|
||||
return NULL;
|
||||
rbp=*rbp;
|
||||
if (!ChkOnStk(rbp,Fs))
|
||||
return NULL;
|
||||
}
|
||||
ptr=rbp+1;
|
||||
return *ptr;
|
||||
}
|
||||
|
||||
U8 *TaskCaller(CTask *task=NULL,I64 num=0,Bool saved_context=FALSE)
|
||||
{
|
||||
U8 **ptr,**rbp,**rsp;
|
||||
if (!task) task=Fs;
|
||||
if (!saved_context && task==Fs)
|
||||
return Caller(num+1);
|
||||
if (!TaskValidate(task))
|
||||
return NULL;
|
||||
rbp=task->rbp;
|
||||
rsp=task->rsp;
|
||||
if (num) {
|
||||
while (ChkOnStk(rbp,task)) {
|
||||
ptr=rbp+1;
|
||||
if (! --num)
|
||||
return *ptr;
|
||||
if (rbp>=*rbp)
|
||||
break;
|
||||
rbp=*rbp;
|
||||
}
|
||||
return NULL;
|
||||
} else {
|
||||
if (task->rip==SYS_RET)
|
||||
return *rsp;
|
||||
else
|
||||
return task->rip;
|
||||
}
|
||||
}
|
||||
#define STK_REP_LEN 32
|
||||
|
||||
U0 StkRep(CTask *task=NULL)
|
||||
//Reports whats on the stk
|
||||
{
|
||||
I64 i,j,add,
|
||||
**rbp,**rsp,*my_rsp[STK_REP_LEN];
|
||||
CHashTable *old_hash=Fs->hash_table;
|
||||
if (!task) task=Fs;
|
||||
if (!TaskValidate(task))
|
||||
return;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (task==Fs) {
|
||||
rbp=GetBasePtr;
|
||||
rsp=rbp+3;
|
||||
rbp=*rbp;
|
||||
} else {
|
||||
rsp=task->rsp;
|
||||
rbp=task->rbp;
|
||||
}
|
||||
if (task->rip==SYS_RET)
|
||||
add=*rsp;
|
||||
else
|
||||
add=task->rip;
|
||||
MemCpy(my_rsp,rsp,STK_REP_LEN*sizeof(U8 *));
|
||||
PopFD;
|
||||
Fs->hash_table=task->hash_table;
|
||||
for (i=0;i<STK_REP_LEN;i++) {
|
||||
"%08X [RSP+%04X]: %016X ",rsp+i,
|
||||
i*sizeof(U8 *),my_rsp[i];
|
||||
while (TRUE) {
|
||||
if (!(&task->stk->stk_base<=rbp<(&task->stk->stk_base)(U8 *)+task->stk->stk_size))
|
||||
break;
|
||||
j=rbp-rsp;
|
||||
if (j>=i)
|
||||
break;
|
||||
add=my_rsp[j+1];
|
||||
if (rbp>=my_rsp[j])
|
||||
break;
|
||||
rbp=my_rsp[j];
|
||||
}
|
||||
if (my_rsp[i]==add)
|
||||
"$$FG,RED$$";
|
||||
"%P$$FG$$\n",my_rsp[i];
|
||||
}
|
||||
NewLine;
|
||||
Fs->hash_table=old_hash;
|
||||
}
|
||||
|
||||
U0 CallerRep(U8 **rbp=NULL,CTask *task=NULL)
|
||||
//Prints a report of calling routines
|
||||
{
|
||||
I64 **ptr;
|
||||
if (!task) task=Fs;
|
||||
if (!rbp) {
|
||||
if (task==Fs)
|
||||
rbp=GetBasePtr;
|
||||
else
|
||||
rbp=task->rbp;
|
||||
}
|
||||
"CallerRep:\n";
|
||||
while (ChkOnStk(rbp,task)) {
|
||||
ptr=rbp+1;
|
||||
"%08X:%08tX:%P\n",ptr,*ptr,*ptr;
|
||||
if (rbp>=*rbp)
|
||||
break;
|
||||
rbp=*rbp;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DbgStr(U8 *st,I64 mS=100)
|
||||
//Shows a string using
|
||||
//$LK,"Raw","MN:Raw"$ screen output for a fixed length
|
||||
//of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
"DbgStr(";
|
||||
"" st;
|
||||
')';
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 DbgI64(I64 num,I64 mS=100)
|
||||
//Shows a hex num using
|
||||
//$LK,"Raw","MN:Raw"$ screen output for a fixed length
|
||||
//of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
"DbgI64(%016X)",num;
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 DbgF64(F64 d,I64 mS=100)
|
||||
//Shows a floating-point val using
|
||||
//$LK,"Raw","MN:Raw"$ screen output for a fixed length
|
||||
//of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
"DbgF64(%15e)",d;
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 DbgAdd(U8 *add,I64 mS=100)
|
||||
//Shows an addr using $LK,"Raw","MN:Raw"$ screen
|
||||
//output for a length of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
"DbgAdd(%P)",add;
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 DbgD(U8 *add,I64 cnt=0x80,I64 mS=100)
|
||||
//Dumps a block of mem using $LK,"Raw","MN:Raw"$
|
||||
//screen output for a fixed length
|
||||
//of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
D(add,cnt);
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 DbgDm(U8 *add,I64 cnt=0x80,I64 mS=100)
|
||||
//Dumps a block of mem using $LK,"Raw","MN:Raw"$
|
||||
//screen output for a fixed length
|
||||
//of time.
|
||||
{
|
||||
Bool old_raw,old_input_filter;
|
||||
PushFD;
|
||||
Cli;
|
||||
old_raw=Raw(ON);
|
||||
old_input_filter=LBtr(&Fs->task_flags,TASKf_INPUT_FILTER_TASK);
|
||||
Dm(add,cnt);
|
||||
BusyWait(mS<<10);
|
||||
PopFD;
|
||||
LBEqu(&Fs->task_flags,TASKf_INPUT_FILTER_TASK,old_input_filter);
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 D(U8 *add,I64 cnt=0x80,Bool show_offset=TRUE)
|
||||
//Dump mem, showing offsets.
|
||||
//See $LK,"DocD","MN:DocD"$() for a live dump.
|
||||
{
|
||||
I64 i,j,ch;
|
||||
U8 *ptr=add;
|
||||
while (cnt) {
|
||||
if (show_offset)
|
||||
"%08X ",ptr-add;
|
||||
else
|
||||
"%010X ",ptr;
|
||||
j=cnt>16 ? 16:cnt;
|
||||
for (i=0;i<j;i++)
|
||||
"%02X ",ptr[i];
|
||||
for (;i<16;i++)
|
||||
" ";
|
||||
for (i=0;i<j;i++) {
|
||||
ch=ptr[i];
|
||||
if (ch<CH_SHIFT_SPACE || ch==CH_BACKSPACE)
|
||||
ch='.';
|
||||
'' ch;
|
||||
if (ch=='$$')
|
||||
'' ch;
|
||||
}
|
||||
NewLine;
|
||||
cnt-=j;
|
||||
ptr+=j;
|
||||
}
|
||||
}
|
||||
|
||||
U0 Dm(U8 *add,I64 cnt=0x80)
|
||||
//Show mem addr, not offsets
|
||||
{
|
||||
D(add,cnt,FALSE);
|
||||
}
|
||||
|
||||
U0 Da(U8 **add,I64 cnt=0x10)
|
||||
//Dump mem, showing symbolic addresses
|
||||
{
|
||||
while (cnt-->0) {
|
||||
"%08X:%08X,%P\n",add,*add,*add;
|
||||
add++;
|
||||
}
|
||||
}
|
||||
|
||||
I64 *TaskRegAdd(CTask *task,I64 reg_num)
|
||||
{
|
||||
switch (reg_num) {
|
||||
case CREG_RAX: return &task->rax;
|
||||
case CREG_RCX: return &task->rcx;
|
||||
case CREG_RDX: return &task->rdx;
|
||||
case CREG_RBX: return &task->rbx;
|
||||
case CREG_RSP: return &task->rsp;
|
||||
case CREG_RBP: return &task->rbp;
|
||||
case CREG_RSI: return &task->rsi;
|
||||
case CREG_RDI: return &task->rdi;
|
||||
case 8 : return &task->r8;
|
||||
case 9 : return &task->r9;
|
||||
case 10: return &task->r10;
|
||||
case 11: return &task->r11;
|
||||
case 12: return &task->r12;
|
||||
case 13: return &task->r13;
|
||||
case 14: return &task->r14;
|
||||
case 15: return &task->r15;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#define RAWDR_COL 40
|
||||
|
||||
U0 RawDr(CTask *task=NULL)
|
||||
{
|
||||
I64 i,j,old_col=sys_raw_dc_col;
|
||||
Bool old_raw=Raw(ON);
|
||||
U8 buf[200];
|
||||
|
||||
if (!task) task=Fs;
|
||||
|
||||
for (i=0;i<16;i++) {
|
||||
sys_raw_dc_col=i*text_cols+RAWDR_COL;
|
||||
"º%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAdd(task,i);
|
||||
}
|
||||
|
||||
sys_raw_dc_col=i++*text_cols+RAWDR_COL;
|
||||
"ºRIP:%016X\n",task->rip;
|
||||
|
||||
sys_raw_dc_col=i++*text_cols+RAWDR_COL;
|
||||
"º%-*tT\n",text_cols-(RAWDR_COL+1)-1,Fs->rip;
|
||||
|
||||
sys_raw_dc_col=i++*text_cols+RAWDR_COL;
|
||||
'º';
|
||||
if (Bt(&sys_run_level,RLf_COMPILER)) {
|
||||
j=Fs->rip;
|
||||
Ui(buf,&j,,,TRUE);
|
||||
"" buf;
|
||||
} else
|
||||
NewLine;
|
||||
|
||||
sys_raw_dc_col=i*text_cols+RAWDR_COL;
|
||||
'È';
|
||||
for (j=0;j<text_cols-RAWDR_COL-1;j++)
|
||||
'Í';
|
||||
|
||||
sys_raw_dc_col=old_col;
|
||||
Raw(old_raw);
|
||||
}
|
||||
|
||||
U0 Dr(CTask *task=NULL)
|
||||
{//Dump registers
|
||||
I64 i;
|
||||
if (!task) task=Fs;
|
||||
for (i=0;i<16;i++)
|
||||
"%3Z:%016X\n",i,"ST_U64_REGS",*TaskRegAdd(task,i);
|
||||
"RIP:%016X\n",task->rip;
|
||||
}
|
||||
|
||||
U0 OverRideSingleUserSwap()
|
||||
{
|
||||
Bool old_single=SingleUser(OFF);
|
||||
Yield;
|
||||
SingleUser(old_single);
|
||||
}
|
||||
|
||||
U8 *SysMGetS(I64)
|
||||
{
|
||||
U8 buf[512];
|
||||
GetS(buf,512,FALSE);
|
||||
return StrNew(buf);
|
||||
}
|
||||
|
||||
CBpt *BptFind(U8 *add,CTask *task=NULL,Bool rem=FALSE)
|
||||
{
|
||||
CBpt *result=NULL,*tempb,*tempb1,*tempb2;
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
tempb1=&task->bpt_lst;
|
||||
tempb=task->bpt_lst;
|
||||
while (tempb) {
|
||||
tempb2=tempb->next;
|
||||
if (tempb->addr==add) {
|
||||
result=tempb;
|
||||
if (rem)
|
||||
tempb1->next=tempb2;
|
||||
else
|
||||
tempb1=&tempb->next;
|
||||
} else
|
||||
tempb1=&tempb->next;
|
||||
tempb=tempb2;
|
||||
}
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool BptS(U8 *add,CTask *task=NULL,Bool live=TRUE)
|
||||
{//Set breakpoint
|
||||
CBpt *tempb;
|
||||
Bool result=TRUE;
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (!(tempb=BptFind(add,task,FALSE))) {
|
||||
tempb=CAlloc(sizeof(CBpt),task);
|
||||
tempb->addr=add;
|
||||
tempb->val=*add;
|
||||
result=FALSE;
|
||||
tempb->next=task->bpt_lst;
|
||||
task->bpt_lst=tempb;
|
||||
if (task==Fs && live)
|
||||
*add=OC_BPT;
|
||||
}
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool BptR(U8 *add,CTask *task=NULL,Bool live=TRUE,Bool rem=TRUE)
|
||||
{//Rem breakpoint
|
||||
CBpt *tempb;
|
||||
Bool result=FALSE;
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (tempb=BptFind(add,task,rem)) {
|
||||
if (task==Fs && live)
|
||||
*tempb->addr=tempb->val;
|
||||
result=TRUE;
|
||||
if (rem)
|
||||
Free(tempb);
|
||||
}
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool B(U8 *add,CTask *task=NULL,Bool live=TRUE)
|
||||
{//Toggle breakpoint
|
||||
//Returns TRUE if removed
|
||||
Bool result=FALSE;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (BptFind(add,task,FALSE)) {
|
||||
BptR(add,task,live,TRUE);
|
||||
result=TRUE;
|
||||
} else
|
||||
BptS(add,task,live);
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 B2(CTask *task=NULL,Bool live=TRUE)
|
||||
{ //Rem all breakpoints
|
||||
//Returns cnt of removed
|
||||
I64 result=0;
|
||||
CBpt *tempb,*tempb1;
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
tempb=task->bpt_lst;
|
||||
task->bpt_lst=NULL;
|
||||
while (tempb) {
|
||||
tempb1=tempb->next;
|
||||
if (task==Fs && live)
|
||||
*tempb->addr=tempb->val;
|
||||
Free(tempb);
|
||||
tempb=tempb1;
|
||||
result++;
|
||||
}
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 G(U8 *ip=INVALID_PTR,CTask *task=NULL)
|
||||
//Go
|
||||
{
|
||||
if (!task) task=Fs;
|
||||
if (ip!=INVALID_PTR) task->rip=ip;
|
||||
if (BptFind(task->rip,task))
|
||||
"\nDo one of the following, first:\n"
|
||||
">S;\t\t\t//Single step\n"
|
||||
">B2;\t\t\t//Clear all break points\n"
|
||||
">G2;\t\t\t//Clear all break points and Go\n\n"
|
||||
"After resuming, <CTRL-ALT-T> changes focus task\n"
|
||||
"After resuming, <CTRL-ALT-F> flushes screen VGA cache\n";
|
||||
else {
|
||||
LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
|
||||
LBtr(&task->rflags,RFLAGf_TRAP);//No single step
|
||||
Suspend(task,FALSE);
|
||||
if (task==Fs) {
|
||||
if (IsInDbg && task->next_lex!=&task->next_lex) {
|
||||
"Exit Dbg\n";
|
||||
Btr(&task->last_lex->flags,Lf_PMT);
|
||||
}
|
||||
} else
|
||||
Exit;
|
||||
}
|
||||
}
|
||||
|
||||
U0 G2(U8 *ip=INVALID_PTR,CTask *task=NULL)
|
||||
//Rem all breakpoints and Go.
|
||||
{
|
||||
if (!task) task=Fs;
|
||||
B2(task);
|
||||
if (ext[EXT_WIN_FOCUS])
|
||||
CallExtNum(EXT_WIN_FOCUS,sys_dbg_focus_task);
|
||||
VGAFlush;
|
||||
G(ip,task);
|
||||
}
|
||||
|
||||
public U0 S(U8 *ip=INVALID_PTR,CTask *task=NULL) //Single-step.
|
||||
{ //Single step
|
||||
if (!task) task=Fs;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (ip!=INVALID_PTR) task->rip=ip;
|
||||
LBts(&task->task_flags,TASKf_DISABLE_BPTS);
|
||||
LBts(&task->rflags,RFLAGf_TRAP);
|
||||
Suspend(task,FALSE);
|
||||
if (task==Fs) {
|
||||
if (IsInDbg) {
|
||||
if (task->next_lex!=&task->next_lex)
|
||||
Btr(&task->last_lex->flags,Lf_PMT);
|
||||
}
|
||||
} else
|
||||
Exit;
|
||||
PopFD;
|
||||
}
|
||||
|
||||
U0 DbgHelp()
|
||||
{
|
||||
"\n"
|
||||
"The cmd line is basically the same as normal. Here are some common\n"
|
||||
"debugging commands.\n\n"
|
||||
">EdLite(\"FileName\");\t\t//Edit file.\n"
|
||||
">D(0x100000);\t\t\t//Dump page tables.\n"
|
||||
">Dm(0x100000);\t\t\t//Dump page tables.\n"
|
||||
">Dm(Fs,sizeof(CTask));\t\t//Dump current task record.\n"
|
||||
">ClassRep(\"CTask\",Fs,1);\t//Dump current task record.\n"
|
||||
">CallerRep;\t\t\t//Stack trace report.\n"
|
||||
">Da(_RSP);\t\t\t//Dump stk.\n"
|
||||
">Dr;\t\t\t\t//Dump Registers.\n"
|
||||
">1+2*3+&PutS;\t\t\t//Show calculation result.\n"
|
||||
">*(0x70000)(I64 *)=0x123456789;\t//Assign value to 0x70000-0x70007.\n"
|
||||
">_RAX=0x1234;\t\t\t//Set RAX to 0x1234.\n"
|
||||
">_RIP=&SysThrowBreak;\t\t//Set RIP.\n"
|
||||
">I64 i;\t\t\t\t//Declare variable.\n"
|
||||
">i=_RCX+_RDX;\t\t\t//Assign to variable.\n"
|
||||
">U(&PrintF+0x8);\t\t//Unassemble PrintF.\n"
|
||||
">Uf(\"PutS\");\t\t\t//Unassembler function \"PutS\".\n"
|
||||
">Man(\"PutS\");\t\t\t//Edit Src for \"PutS\".\n"
|
||||
">E(_RIP);\t\t\t//Edit Src Code.\n"
|
||||
">Fix;\t\t\t\t//Edit Last Err Src Code.\n"
|
||||
">B(&Main+0x20);\t\t\t//Toggle break point.\n"
|
||||
">B2;\t\t\t\t//Clear all break points.\n"
|
||||
">S;\t\t\t\t//Single step.\n"
|
||||
">G;\t\t\t\t//Resume execution.\n"
|
||||
">G2;\t\t\t\t//B2;VGAFlush;WinFocus;G;\n"
|
||||
">Exit;\t\t\t\t//Exit (kill) task.\n\n"
|
||||
"After resuming, <CTRL-ALT-T> changes focus task.\n"
|
||||
"After resuming, <CTRL-ALT-F> flushes screen VGA cache.\n\n";
|
||||
}
|
||||
|
||||
U0 Dbg2()
|
||||
{
|
||||
Bool old_user_task,old_waiting_msg;
|
||||
I64 i,old_dbg_mgets;
|
||||
U8 buf[200];
|
||||
if (IsRaw) {
|
||||
i=Fs->rip;
|
||||
Ui(buf,&i);
|
||||
"" buf;
|
||||
} else
|
||||
U(Fs->rip,1);
|
||||
|
||||
old_waiting_msg=LBtr(&Fs->task_flags,TASKf_AWAITING_MSG);
|
||||
old_user_task =LBts(&Fs->task_flags,TASKf_USER);
|
||||
TaskInitExt(TRUE);
|
||||
sys_focus_task=Fs;
|
||||
sys_cur_scan_code=0;
|
||||
old_dbg_mgets=fp_mgets;
|
||||
fp_mgets=&SysMGetS;
|
||||
while (!mouse_install_attempts)
|
||||
OverRideSingleUserSwap;
|
||||
UserTaskCont;
|
||||
fp_mgets=old_dbg_mgets;
|
||||
LBEqu(&Fs->task_flags,TASKf_USER,old_user_task);
|
||||
LBEqu(&Fs->task_flags,TASKf_AWAITING_MSG,old_waiting_msg);
|
||||
}
|
||||
|
||||
U0 Fault3(I64 fault_num,I64 fault_err_code)
|
||||
{
|
||||
nounusedwarn fault_err_code;
|
||||
Bool was_in_dbg;
|
||||
PushFD;
|
||||
Cli;
|
||||
was_in_dbg=InDbg(ON);
|
||||
if (Gs->num && mp_crash) {
|
||||
mp_cnt=1;
|
||||
mp_crash->cpu_num=Gs->num;
|
||||
mp_crash->task=Fs;
|
||||
mp_crash->msg=sys_dbg_msg;
|
||||
mp_crash->msg_num=sys_dbg_msg_num;
|
||||
MPInt(I_MP_CRASH,0);
|
||||
SysHlt;
|
||||
}
|
||||
"\n\tTempleOS Debugger\n\n"
|
||||
">Help;\t//For help.\n\n";
|
||||
Beep(500,TRUE);
|
||||
if (fault_num==I_DBG) {
|
||||
if (sys_dbg_msg) {
|
||||
"\n!!! %s",sys_dbg_msg;
|
||||
if (sys_dbg_msg_num)
|
||||
"%016X",sys_dbg_msg_num;
|
||||
" !!!\n\n";
|
||||
}
|
||||
}
|
||||
CallerRep;
|
||||
Dbg2;
|
||||
InDbg(was_in_dbg);
|
||||
PopFD;
|
||||
}
|
||||
|
||||
U0 Fault2(I64 fault_num,I64 fault_err_code) //Called from $LK,"Fault2","FF:::/TempleOS/Kernel/Interrupts.CPP,Fault2"$
|
||||
{
|
||||
//$BK,1$Be careful not to swap-out and ruin the saved context$BK,0$
|
||||
Bool was_raw,was_single_user,was_silent;
|
||||
I64 i,old_dc_flags=sys_raw_dc_flags;
|
||||
if (fault_num==I_DIVIDE_BY_ZERO)
|
||||
throw(EXCEPT_DIVIDE_BY_ZERO,Fs->rip);
|
||||
was_single_user=SingleUser(ON);
|
||||
if (!IsInDbg)
|
||||
sys_dbg_focus_task=sys_focus_task;
|
||||
sys_focus_task=NULL;
|
||||
if (fault_num==I_BPT)
|
||||
Fs->rip--;
|
||||
if (Fs->dbg_task)
|
||||
CallExtNum(EXT_RESUME_DBG); //See $LK,"IDEResumeDbg","FF:::/TempleOS/Adam/Doc/DocIDE.CPP,IDEResumeDbg"$
|
||||
else {
|
||||
was_raw=Raw(ON);
|
||||
was_silent=Silent(OFF);
|
||||
sys_raw_dc_flags|=RDCF_SHOW_DOLLAR|RDCF_SCROLL;
|
||||
"Task \"";
|
||||
"" Fs->task_title;
|
||||
"\"\n";
|
||||
"Fault:0x%02X %Z\t\tErr Code:%08X\n",fault_num,fault_num,"ST_INT_NAMES",fault_err_code;
|
||||
"RIP:%08X",Fs->rip; //Sometimes crashes on %P, so do this first
|
||||
":%P RSP:%08X\n",Fs->rip,Fs->rsp;
|
||||
if (fault_num==I_PAGE_FAULT) {
|
||||
asm { MOV_RAX_CR2 }
|
||||
i=GetRAX;
|
||||
"Fault Addr:%08X:%P\n",i,i;
|
||||
}
|
||||
Fault3(fault_num,fault_err_code);
|
||||
Silent(was_silent);
|
||||
Raw(was_raw);
|
||||
sys_raw_dc_flags=old_dc_flags;
|
||||
}
|
||||
SingleUser(was_single_user);
|
||||
if (LBtr(&Fs->task_flags,TASKf_KILL_AFTER_DBG))
|
||||
Exit;
|
||||
}
|
||||
|
||||
U0 Dbg(U8 *msg=NULL,I64 msg_num=0)
|
||||
//Enters the debugger. Can be used as a panic.
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
sys_dbg_msg=msg;
|
||||
sys_dbg_msg_num=msg_num;
|
||||
asm {INT 0x32};
|
||||
#assert I_DBG==0x32
|
||||
PopFD;
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
//These provide an option for different
|
||||
//languages. Not all strings are done this way
|
||||
//See $LK,"Char/Define","HI:Char/Define"$.
|
||||
|
||||
U0 LoadSysStrs()
|
||||
{
|
||||
DefineLoad("ST_UNDEFINED_EXTERN","Undefined Extern\n");
|
||||
DefineLoad("ST_FILE_NOT_FOUND","File not found.\n");
|
||||
DefineLoad("ST_INVALID_FILENAME","Invalid File Name.\n");
|
||||
DefineLoad("ST_PRESS_A_KEY","$$BK,1$$PRESS A KEY$$BK,0$$\n");
|
||||
DefineLoad("ST_EXIT_ALL_APPLICATIONS","$$FG,RED$$Exit all other applications.$$FG$$\n");
|
||||
DefineLoad("ST_GOING_TO_PROBE_HARDWARE","\nWe're going to probe hardware.\n");
|
||||
DefineLoad("ST_ARE_YOU_SURE","ARE YOU SURE ");
|
||||
DefineLoad("ST_NOT_NATIVE","Not Native Partition\n");
|
||||
DefineLoad("ST_NOT_FAT32","Not FAT32 Partition\n");
|
||||
DefineLoad("ST_NOT_ISO9660","Not ISO9660 Partition\n");
|
||||
DefineLoad("ST_NOT_ISO13346","Not ISO13346 Partition\n");
|
||||
DefineLoad("ST_UNSUPPORTED_FILE_SYSTEM","File System Not Supported\n");
|
||||
DefineLoad("ST_NOT_WRITABLE","Not Writable\n");
|
||||
DefineLoad("ST_DELETE","Del ");
|
||||
DefineLoad("ST_INVALID_DRV","Invalid Drive\n");
|
||||
DefineLoad("ST_NO_MATCHING_ENTRIES","No matching entries\n");
|
||||
DefineLstLoad("ST_OFF_ON","Off\0On\0");
|
||||
DefineLstLoad("ST_HTT_TYPES","ExportSysSym\0ImportSysSym\0DefineStr\0GlbVar\0Class\0"
|
||||
"IntType\0Funct\0Word\0DictWord\0KeyWord\0AsmKeyWord\0OpCode\0Reg\0"
|
||||
"File\0Module\0HelpFile\0Frame Ptr\0Private\0"
|
||||
"Public\0Export\0Import\0Lit\0Unres\0Local\0");
|
||||
DefineLstLoad("ST_DAYS_OF_WEEK","Sunday\0Monday\0Tuesday\0Wednesday\0"
|
||||
"Thursday\0Friday\0Saturday\0");
|
||||
DefineLstLoad("ST_MONTHS","January\0February\0March\0April\0May\0"
|
||||
"June\0July\0August\0September\0October\0November\0December\0");
|
||||
DefineLstLoad("ST_EXCEPT_TYPES","Local\0Break\0Out of Mem\0Divide by Zero\0"
|
||||
"Floating\0Compiler\0Undefined Define\0"
|
||||
"Undefined Extern\0File\0File Xsum\0"
|
||||
"Partition error\0Blk Dev error\0"
|
||||
"Graphics\0SPrintF\0GetF\0Bin Module\0"
|
||||
"MultiCore\0FUF\0Flags\0");
|
||||
|
||||
DefineLstLoad("ST_FILE_ATTRS","R\0H\0S\0V\0D\0A\0 \0 \0X\0Y\0T\0Z\0C\0F\0");
|
||||
DefineLstLoad("ST_FILE_UTIL_FLAGS","r\0d\0i\0a\0c\0R\0p\0m\0D\0F\0T\0S\0A\0J\0G\0Z\0P\0f\0l\0lf\0lb\0");
|
||||
DefineLstLoad("ST_BLKDEV_TYPES","NULL\0RAM\0ATA\0ATAPI\0");
|
||||
DefineLstLoad("ST_PRT_TYPES","NULL\0NATIVE\0FAT32\0ISO9660\0ISO13490\0ISO13346\0NTFS\0UNKNOWN\0");
|
||||
|
||||
DefineLoad("ST_MOUNT_INTRO",
|
||||
"\n\n\n$$BK,1$$$$FG,PURPLE$$Mount drives so they will "
|
||||
"be present when you boot.$$FG$$$$BK,0$$\n");
|
||||
DefineLoad("ST_MOUNT_FIRST_DRV_LET",
|
||||
"\n****** Mount Drives ******\n"
|
||||
"The first drive letter is the letter\n"
|
||||
"of the first partition. If adding\n"
|
||||
"a hard drive, you should pick 'C'.\n"
|
||||
"If more than one partition is present\n"
|
||||
"they will be lettered in sequence.\n"
|
||||
"\n"
|
||||
"First Drive Letter($$FG,PURPLE$$<ENTER>$$FG$$ to exit):");
|
||||
DefineLoad("ST_MOUNT_DRV_TYPE",
|
||||
"\t$$FG,PURPLE$$1$$FG$$=RAM\n\t$$FG,PURPLE$$2$$FG$$=ATA(Harddisk)\n"
|
||||
"\t$$FG,PURPLE$$3$$FG$$=ATAPI(CD-ROM)\n"
|
||||
"Type:");
|
||||
DefineLoad("ST_MOUNT_BLKS",
|
||||
"Blks of 512 bytes:");
|
||||
DefineLoad("ST_MOUNT_UNIT",
|
||||
"\t$$FG,PURPLE$$0$$FG$$=Master\n\t$$FG,PURPLE$$1$$FG$$=Slave\nUnit:");
|
||||
DefineLoad("ST_MOUNT_FMT_WHOLE_DRV",
|
||||
"\nReformat WHOLE drive!");
|
||||
DefineLoad("ST_MOUNT_BOOTED_CDROM",
|
||||
"<ENTER> to use booted CD-ROM\n");
|
||||
DefineLoad("ST_INCLUDE_0X",
|
||||
"Include $$FG,PURPLE$$0x$$FG$$ prefix\n");
|
||||
DefineLoad("ST_MOUNT_BASE0",
|
||||
"Include $$FG,PURPLE$$0x$$FG$$ prefix.\n"
|
||||
"I/O Port Base0:\n");
|
||||
DefineLoad("ST_MOUNT_BASE0_HINT",
|
||||
"Enter dev number or\n"
|
||||
"port with $$FG,PURPLE$$0x$$FG$$ prefix.\n"
|
||||
"I/O Port Base0:\n");
|
||||
DefineLoad("ST_MOUNT_BASE1",
|
||||
"I/O Port Base1:\n");
|
||||
|
||||
DefineLoad("ST_CDROM_PORTS_PMT1",
|
||||
"\nDon't worry. This is not a product\n"
|
||||
"registration. TempleOS just needs the\n"
|
||||
"I/O port numbers for the CD-ROM.\n\n"
|
||||
"Retry the ports above or check Windows\n"
|
||||
"system information under I/O ports for\n"
|
||||
"'IDE', 'ATA' or 'SATA'.\n\n"
|
||||
"\nEnter 4-digit hex I/O Port number.\n"
|
||||
"CD-ROM I/O Port Base0: 0x");
|
||||
|
||||
DefineLoad("ST_CDROM_PORTS_PMT2",
|
||||
"\n\nTry again with different port numbers if\n"
|
||||
"it hangs for more than 2 minutes.\n\n");
|
||||
|
||||
DefineLoad("ST_FAILED","\n\n$$BK,1$$$$FG,RED$$Operation Failed$$BK,0$$$$FG$$\n\n");
|
||||
|
||||
DefineLstLoad("ST_COLORS","BLACK\0BLUE\0GREEN\0CYAN\0"
|
||||
"RED\0PURPLE\0BROWN\0LTGRAY\0DKGRAY\0LTBLUE\0LTGREEN\0"
|
||||
"LTSCYAN\0LTRED\0LTPURPLE\0YELLOW\0WHITE\0");
|
||||
DefineLstLoad("ST_INT_NAMES",
|
||||
"Divide Error\0SingleStep\0NMI\0Breakpoint\0Overflow\0BOUND Range Exceeded\0Invalid Opcode\0No Math Coprocessor\0"
|
||||
"Double Fault\0Coprocessor Segment Fault\0Invalid TASK\0Segment Not Present\0Stk Segment Fault\0General Protection\0Page Fault\0 \0"
|
||||
|
||||
"Math Fault\0Alignment Check\0Machine Check\0SIMD Exception\0 \0 \0 \0 \0"
|
||||
" \0 \0 \0 \0 \0 \0 \0 \0"
|
||||
|
||||
" \0 \0 \0 \0 \0 \0 \0 \0"
|
||||
" \0 \0 \0 \0 \0 \0 \0 \0"
|
||||
|
||||
"MP Crash\0Wake\0Dbg\0");
|
||||
|
||||
|
||||
$AN,"Anchor for inserting OS Define","OS_DEFINE"$
|
||||
|
||||
}
|
||||
|
||||
U8 *Color2Text(U8 *buf,CColorROPU32 c)
|
||||
{
|
||||
if (0<=c.c0.color<16)
|
||||
StrCpy(buf,DefineSub(c.c0.color,"ST_COLORS"));
|
||||
else if (c.c0.color==COLOR_TRANSPARENT)
|
||||
StrCpy(buf,"TRANSPARENT");
|
||||
else
|
||||
StrCpy(buf,"INVALID");
|
||||
if (c&ROPF_DITHER) {
|
||||
StrCat(buf,"/");
|
||||
if (0<=c.c1.color<16)
|
||||
StrCat(buf,DefineSub(c.c1.color,"ST_COLORS"));
|
||||
else if (c.c1.color==COLOR_TRANSPARENT)
|
||||
StrCat(buf,"TRANSPARENT");
|
||||
else
|
||||
StrCat(buf,"INVALID");
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
U0 RawPutChar(I64 ch)
|
||||
{
|
||||
/* This is for RAW output during boot
|
||||
before the window mgr is running
|
||||
and for the debugger.
|
||||
|
||||
See $LK,"GrUpdateForegroundOfText","MN:GrUpdateForegroundOfText"$ for
|
||||
the normal screen text output routine.
|
||||
|
||||
See also $LK,"GrUpdateScreen","MN:GrUpdateScreen"$().
|
||||
|
||||
*/
|
||||
Bool old_preempt=Preempt(OFF);
|
||||
I64 i,row,col;
|
||||
U8 *ptr,*ptr1,*ptr2;
|
||||
|
||||
if (!(sys_raw_dc_flags&RDCF_SHOW_DOLLAR)) {
|
||||
if (ch=='$$') {
|
||||
if (sys_raw_dc_flags&RDCF_IN_DOLLAR) {
|
||||
sys_raw_dc_flags&=~RDCF_IN_DOLLAR;
|
||||
if (!(sys_raw_dc_flags & RDCF_LAST_DOLLAR)) {
|
||||
sys_raw_dc_flags&=~RDCF_LAST_DOLLAR;
|
||||
Preempt(old_preempt);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
sys_raw_dc_flags|=RDCF_IN_DOLLAR|RDCF_LAST_DOLLAR;
|
||||
Preempt(old_preempt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
sys_raw_dc_flags&=~RDCF_LAST_DOLLAR;
|
||||
if (sys_raw_dc_flags&RDCF_IN_DOLLAR) {
|
||||
Preempt(old_preempt);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (ch=='\t') {
|
||||
RawPutChar(CH_SPACE);
|
||||
while (sys_raw_dc_col & 7)
|
||||
RawPutChar(CH_SPACE);
|
||||
} else if (ch==CH_BACKSPACE) {
|
||||
sys_raw_dc_col--;
|
||||
RawPutChar(CH_SPACE);
|
||||
sys_raw_dc_col--;
|
||||
} else if (ch=='\n') {
|
||||
RawPutChar(CH_SPACE);
|
||||
while (sys_raw_dc_col % text_cols)
|
||||
RawPutChar(CH_SPACE);
|
||||
|
||||
} else if (Bt(displayable_chars_bitmap,ch)) {
|
||||
row=sys_raw_dc_col/text_cols%text_rows;
|
||||
col=sys_raw_dc_col%text_cols;
|
||||
if (text_mode) {
|
||||
if (sys_raw_dc_flags&RDCF_SCROLL && sys_raw_dc_col && !row && !col) {
|
||||
MemCpy(VGA_TEXT_MEM_BASE,VGA_TEXT_MEM_BASE+text_cols,
|
||||
text_cols*(text_rows-1)*2);
|
||||
MemSet(VGA_TEXT_MEM_BASE+text_cols*(text_rows-1)*2,0,text_cols*2);
|
||||
sys_raw_dc_col-=text_cols;
|
||||
row=text_rows-1;
|
||||
}
|
||||
ptr=VGA_TEXT_MEM_BASE+(row*text_cols+col)*2;
|
||||
ptr[0]=ch;
|
||||
ptr[1]=BLACK<<4+WHITE;
|
||||
} else {
|
||||
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
|
||||
OutU8(VGA_SC_DATA,0x0F); //All planes -- WHITE
|
||||
if (sys_raw_dc_flags&RDCF_SCROLL && sys_raw_dc_col && !row && !col) {
|
||||
//Scroll cached image
|
||||
MemCpy(sys_dc_screen_image,sys_dc_screen_image+gr_width*FONT_HEIGHT>>3,
|
||||
gr_width*(gr_height-FONT_HEIGHT)>>3);
|
||||
MemSet(sys_dc_screen_image+gr_width*(gr_height-FONT_HEIGHT)>>3,0,gr_width*FONT_HEIGHT>>3);
|
||||
|
||||
MemCpy(VGA_GRAPHIC_MEM_BASE,sys_dc_screen_image,gr_width*gr_height>>3);
|
||||
sys_raw_dc_col-=text_cols;
|
||||
row=text_rows-1;
|
||||
}
|
||||
PushFD;
|
||||
Cli;
|
||||
ptr=ptr1=col+row*gr_width;
|
||||
ptr+=VGA_GRAPHIC_MEM_BASE;
|
||||
ptr1+=sys_dc_screen_image; //Write to cached image as well
|
||||
ptr2=&gr_font[ch.u8[0]*FONT_HEIGHT];
|
||||
for (i=0;i<FONT_HEIGHT;i++) {
|
||||
*ptr=*ptr1=reverse_bits_table[*ptr2++];
|
||||
ptr+=gr_width>>3;
|
||||
ptr1+=gr_width>>3;
|
||||
}
|
||||
PopFD;
|
||||
}
|
||||
sys_raw_dc_col++;
|
||||
}
|
||||
Preempt(old_preempt);
|
||||
}
|
||||
|
||||
U0 VGAFlush()
|
||||
{
|
||||
LBts(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0);
|
||||
}
|
||||
|
||||
U0 WinDerivedValsUpdate(CTask *task=NULL)
|
||||
{
|
||||
if (!task) task=Fs;
|
||||
|
||||
//Assert: This is called with TASKLf_TASK_LOCK set
|
||||
PushFD;
|
||||
Cli;
|
||||
task->win_width =task->win_right-task->win_left+1;
|
||||
task->win_height=task->win_bottom-task->win_top+1;
|
||||
|
||||
//Inside the Border
|
||||
task->win_pixel_left =FONT_WIDTH*task->win_left;
|
||||
task->win_pixel_right =FONT_WIDTH*(task->win_right+1)-1;
|
||||
task->win_pixel_width =task->win_pixel_right-task->win_pixel_left+1;
|
||||
task->win_pixel_top =FONT_HEIGHT*task->win_top;
|
||||
task->win_pixel_bottom=FONT_HEIGHT*(task->win_bottom+1)-1;
|
||||
task->win_pixel_height=task->win_pixel_bottom-task->win_pixel_top+1;
|
||||
|
||||
//Outside the border
|
||||
if (Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
|
||||
task->win_border_pixel_left =task->win_pixel_left;
|
||||
task->win_border_pixel_right =task->win_pixel_right;
|
||||
task->win_border_pixel_top =task->win_pixel_top;
|
||||
task->win_border_pixel_bottom=task->win_pixel_bottom;
|
||||
} else {
|
||||
task->win_border_pixel_left =task->win_pixel_left-FONT_WIDTH;
|
||||
task->win_border_pixel_right =task->win_pixel_right+FONT_WIDTH;
|
||||
task->win_border_pixel_top =task->win_pixel_top-FONT_HEIGHT;
|
||||
task->win_border_pixel_bottom=task->win_pixel_bottom+FONT_HEIGHT;
|
||||
}
|
||||
PopFD;
|
||||
}
|
||||
|
||||
Bool AKDRawDisplayPutKey(I64 ch,I64)
|
||||
{
|
||||
if (IsRaw) {
|
||||
RawPutChar(ch);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool AKDRawDisplayPutS(U8 *st)
|
||||
{
|
||||
U8 ch;
|
||||
if (IsRaw) {
|
||||
while (ch=*st++)
|
||||
RawPutChar(ch);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool AKDInputFilterPutKey(I64 ch,I64 scancode)
|
||||
{
|
||||
Bool old_preempt;
|
||||
if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
|
||||
old_preempt=Preempt(OFF);
|
||||
Msg(MSG_KEY_DOWN,ch,scancode);
|
||||
Preempt(old_preempt);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool AKDInputFilterPutS(U8 *st)
|
||||
{
|
||||
U8 ch;
|
||||
Bool old_preempt;
|
||||
if (Bt(&Fs->task_flags,TASKf_INPUT_FILTER_TASK)) {
|
||||
old_preempt=Preempt(OFF);
|
||||
while (ch=*st++)
|
||||
Msg(MSG_KEY_DOWN,ch,0);
|
||||
Preempt(old_preempt);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 PutKey(I64 ch,I64 sc)
|
||||
{ //See $LK,"PutKeyHandling","FA:::/TempleOS/Doc/KeyBoard.TXT,PutKeyHandling"$
|
||||
CKeyDev *tempp=sys_put_key_root.next;
|
||||
if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
|
||||
if (sys_cur_scan_code & SCF_SCROLL) {
|
||||
if (sys_focus_task==Fs) {
|
||||
while (sys_cur_scan_code & SCF_SCROLL)
|
||||
Yield;
|
||||
}
|
||||
}
|
||||
while (tempp!=&sys_put_key_root) {
|
||||
if (!(sc & SCF_KEY_DESC) || tempp->flags & KDF_HAS_DESCS) {
|
||||
if ((*tempp->put_key)(ch,sc))
|
||||
break;
|
||||
}
|
||||
tempp=tempp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 PutChar(I64 ch)
|
||||
{
|
||||
PutKey(ch,0);
|
||||
}
|
||||
|
||||
U0 PutS(U8 *st)
|
||||
{ //See $LK,"PutKeyHandling","FA:::/TempleOS/Doc/KeyBoard.TXT,PutKeyHandling"$
|
||||
U8 ch,*ptr;
|
||||
Bool cont=TRUE;
|
||||
if (!st) return;
|
||||
CKeyDev *tempp=sys_put_key_root.next;
|
||||
if (!Bt(&Fs->display_flags,DISPLAYf_SILENT)) {
|
||||
if (sys_cur_scan_code & SCF_SCROLL) {
|
||||
if (sys_focus_task==Fs) {
|
||||
while (sys_cur_scan_code & SCF_SCROLL)
|
||||
Yield;
|
||||
}
|
||||
}
|
||||
while (cont && tempp!=&sys_put_key_root) {
|
||||
if (tempp->put_s) {
|
||||
if ((*tempp->put_s)(st))
|
||||
break;
|
||||
} else {
|
||||
ptr=st;
|
||||
while (ch=*ptr++)
|
||||
if ((*tempp->put_key)(ch,0))
|
||||
cont=FALSE;
|
||||
}
|
||||
tempp=tempp->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 SetKeyDesc(U8 *fmt,...)
|
||||
{
|
||||
I64 i;
|
||||
U8 *buf=SPrintFJoin(NULL,fmt,argc,argv);
|
||||
StrCpy(key_desc,buf);
|
||||
key_handler=Caller;
|
||||
Free(buf);
|
||||
for (i=0;i<5;i++)
|
||||
Yield; //This makes KeyMap work better
|
||||
}
|
||||
|
||||
U0 SetCtrlAltLetCB(U8 ch,U0 (*fp_handler)(I64 sc),U8 *desc,Bool in_irq=FALSE)
|
||||
{
|
||||
ch=ToUpper(ch)-'A';
|
||||
if (ch<26) {
|
||||
fp_ctrl_alt_let_cbs[ch]=fp_handler;
|
||||
Free(ctrl_alt_let_descs[ch]);
|
||||
ctrl_alt_let_descs[ch]=AStrNew(desc);
|
||||
BEqu(&ctrl_alt_let_in_irq_flags,ch,in_irq);
|
||||
}
|
||||
}
|
||||
|
||||
CKeyDev *KeyDevAdd(Bool (*fp_put_key)(I64 ch,I64 sc),Bool (*fp_puts)(U8 *st),I64 priority,Bool key_descs=FALSE)
|
||||
//Places hook in StdOut chain
|
||||
{ //See $LK,"PutKeyHandling","FA:::/TempleOS/Doc/KeyBoard.TXT,PutKeyHandling"$
|
||||
Bool old_preempt=Preempt(OFF);
|
||||
CKeyDev *tempp,*tempp1=sys_put_key_root.last;
|
||||
tempp=ACAlloc(sizeof(CKeyDev));
|
||||
tempp->put_key=fp_put_key;
|
||||
tempp->put_s=fp_puts;
|
||||
tempp->priority=priority;
|
||||
if (key_descs)
|
||||
tempp->flags|=KDF_HAS_DESCS;
|
||||
while (tempp1->priority>priority)
|
||||
tempp1=tempp1->last;
|
||||
QueIns(tempp,tempp1);
|
||||
Preempt(old_preempt);
|
||||
return tempp;
|
||||
}
|
||||
|
||||
U0 KeyDevRem(CKeyDev *tempp)
|
||||
{
|
||||
Bool old_preempt=Preempt(OFF);
|
||||
QueRem(tempp);
|
||||
Preempt(old_preempt);
|
||||
Free(tempp);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
//See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (2).
|
||||
|
||||
#define ATA_NOP 0x00
|
||||
#define ATA_DEV_RST 0x08
|
||||
#define ATA_PACKET 0xA0
|
||||
#define ATA_READ_NATIVE_MAX 0xF8
|
||||
#define ATA_READ_NATIVE_MAX_EXT 0x27
|
||||
#define ATA_SET_MAX 0xF9
|
||||
#define ATA_SET_MAX_EXT 0x37
|
||||
#define ATA_READ_MULTI 0xC4
|
||||
#define ATA_READ_MULTI_EXT 0x29
|
||||
#define ATA_WRITE_MULTI 0xC5
|
||||
#define ATA_WRITE_MULTI_EXT 0x39
|
||||
#define ATA_ID_DEV 0xEC
|
||||
|
||||
#define ATAS_ERR 0x01
|
||||
#define ATAS_DRQ 0x08
|
||||
#define ATAS_DF 0x20
|
||||
#define ATAS_DRDY 0x40
|
||||
#define ATAS_BSY 0x80
|
||||
|
||||
#define ATAR0_DATA 0
|
||||
#define ATAR0_FEAT 1
|
||||
#define ATAR0_NSECT 2
|
||||
#define ATAR0_SECT 3
|
||||
#define ATAR0_LCYL 4
|
||||
#define ATAR0_HCYL 5
|
||||
#define ATAR0_SELECT 6
|
||||
#define ATAR0_STAT 7
|
||||
#define ATAR0_CMD 7
|
||||
#define ATAR1_CTRL 2
|
||||
@@ -0,0 +1,729 @@
|
||||
Bool BlkDevLock(CBlkDev *bdev)
|
||||
{
|
||||
BlkDevChk(bdev);
|
||||
while (bdev->lock_fwding)
|
||||
bdev=bdev->lock_fwding;
|
||||
if (!Bt(&bdev->locked_flags,BDlf_LOCKED) || bdev->owning_task!=Fs) {
|
||||
while (LBts(&bdev->locked_flags,BDlf_LOCKED))
|
||||
Yield;
|
||||
bdev->owning_task=Fs;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool PrtLock(CPrt *p)
|
||||
{
|
||||
PrtChk(p);
|
||||
BlkDevLock(p->bdev);
|
||||
if (!Bt(&p->locked_flags,Plf_LOCKED) || p->owning_task!=Fs) {
|
||||
while (LBts(&p->locked_flags,Plf_LOCKED))
|
||||
Yield;
|
||||
p->owning_task=Fs;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool BlkDevUnlock(CBlkDev *bdev,Bool rst=FALSE)
|
||||
{
|
||||
BlkDevChk(bdev);
|
||||
while (bdev->lock_fwding)
|
||||
bdev=bdev->lock_fwding;
|
||||
if (Bt(&bdev->locked_flags,BDlf_LOCKED) && bdev->owning_task==Fs) {
|
||||
if (rst) {
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(0);
|
||||
bdev->flags&=~(BDF_INITIALIZED|BDF_INIT_IN_PROGRESS);
|
||||
}
|
||||
bdev->owning_task=0;
|
||||
LBtr(&bdev->locked_flags,BDlf_LOCKED);
|
||||
Yield; //Prevent deadlock
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool PrtUnlock(CPrt *p,Bool rst=FALSE)
|
||||
{
|
||||
PrtChk(p);
|
||||
if (Bt(&p->locked_flags,Plf_LOCKED) && p->owning_task==Fs) {
|
||||
BlkDevUnlock(p->bdev,rst);
|
||||
p->owning_task=0;
|
||||
LBtr(&p->locked_flags,Plf_LOCKED);
|
||||
Yield; //Prevent deadlock
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool BlkDevInit(CBlkDev *bdev)
|
||||
{
|
||||
CPrt *p=Drv2Prt(bdev->first_drv_let);
|
||||
Bool old_preempt=Preempt(OFF),result=FALSE;
|
||||
|
||||
if (!LBts(&bdev->flags,BDf_INITIALIZED)) {
|
||||
bdev->flags|=BDF_INIT_IN_PROGRESS;
|
||||
switch(bdev->type) {
|
||||
case BDT_RAM:
|
||||
bdev->RAM_dsk=AMAlloc((bdev->max_blk+1)<<BLK_SIZE_BITS);
|
||||
bdev->max_blk=MSize(bdev->RAM_dsk)>>BLK_SIZE_BITS-1;
|
||||
p->type=PT_NATIVE;
|
||||
if (sys_boot_code.u8[0]!=BOOT_CODE_RAM ||
|
||||
!NativeFSDrvValidate(bdev->first_drv_let))
|
||||
NativeFSFmt(bdev->first_drv_let);
|
||||
else {
|
||||
p->size=bdev->max_blk+1;
|
||||
NativeFSPrtInit(p);
|
||||
}
|
||||
result=TRUE;
|
||||
break;
|
||||
case BDT_ATA:
|
||||
bdev->max_reads=128;
|
||||
bdev->max_writes=1;
|
||||
bdev->read_freq=2000;
|
||||
bdev->write_freq=500;
|
||||
result=ATAInit(bdev);
|
||||
break;
|
||||
case BDT_ATAPI:
|
||||
//0xFFFF*4 is too big for my taste
|
||||
bdev->max_reads=0x800*4;
|
||||
//max of maybe a quarter of disk cache
|
||||
if (bdev->max_reads>sys_dsk_cache_size/BLK_SIZE/4)
|
||||
bdev->max_reads=sys_dsk_cache_size/BLK_SIZE/4 & ~3;
|
||||
if (bdev->max_reads<128)
|
||||
bdev->max_reads=128;
|
||||
bdev->max_writes=0xFFFF*4;
|
||||
bdev->read_freq=1000;
|
||||
bdev->write_freq=250;
|
||||
if (result=ATAInit(bdev))
|
||||
p->size=bdev->max_blk+1;
|
||||
break;
|
||||
}
|
||||
if (result && bdev->flags & BDF_READ_CACHE)
|
||||
DskCacheInvalidate(p);
|
||||
bdev->flags&=~BDF_INIT_IN_PROGRESS;
|
||||
} else
|
||||
result=TRUE;
|
||||
Preempt(old_preempt);
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 BlkDevsRelease()
|
||||
{
|
||||
I64 i;
|
||||
CBlkDev *bdev;
|
||||
for (i=0;i<NUM_BLKDEVS;i++) {
|
||||
bdev=&sys_blkdevs[i];
|
||||
if (bdev->bd_signature==BD_SIGNATURE_VAL &&
|
||||
Bt(&bdev->locked_flags,BDlf_LOCKED) && bdev->owning_task==Fs)
|
||||
BlkDevUnlock(bdev,TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
U0 PrtsRelease()
|
||||
{
|
||||
I64 i;
|
||||
CPrt *p;
|
||||
for (i=0;i<NUM_PRTS;i++) {
|
||||
p=&sys_prts[i];
|
||||
if (Bt(&p->locked_flags,Plf_LOCKED) && p->owning_task==Fs)
|
||||
PrtUnlock(p,TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
CPrt *PrtMakeFree(U8 drv_let)
|
||||
{//!!! drv is not a remapped prt.
|
||||
I64 i=ToUpper(drv_let)-'A';
|
||||
CPrt *result;
|
||||
if (!(0<=i<NUM_PRTS))
|
||||
throw(EXCEPT_PRT,8);
|
||||
result=&sys_prts[i];
|
||||
MemSet(result,0,sizeof(CPrt));
|
||||
result->drv_let='A'+i;
|
||||
return result;
|
||||
}
|
||||
|
||||
CPrt *PrtNextFree(U8 first_drv_let='C')
|
||||
{//!!! first_drv_let is not a remapped prt.
|
||||
I64 i=ToUpper(first_drv_let)-'A';
|
||||
if (!(0<=i<NUM_PRTS))
|
||||
throw(EXCEPT_PRT,8);
|
||||
do
|
||||
if (sys_prts[i].pt_signature!=PRT_SIGNATURE_VAL)
|
||||
return PrtMakeFree(i+'A');
|
||||
while (++i<NUM_PRTS);
|
||||
throw(EXCEPT_PRT,9);
|
||||
return NULL; //never gets here
|
||||
}
|
||||
|
||||
CBlkDev *BlkDevNextFree(U8 first_drv_let,I64 type)
|
||||
{
|
||||
I64 i=0;
|
||||
CBlkDev *result;
|
||||
do {
|
||||
result=&sys_blkdevs[i];
|
||||
if (result->bd_signature!=BD_SIGNATURE_VAL) {
|
||||
MemSet(result,0,sizeof(CBlkDev));
|
||||
result->first_drv_let=first_drv_let;
|
||||
result->type=type;
|
||||
if (type==BDT_ATAPI)
|
||||
result->flags=BDF_REMOVABLE;
|
||||
else
|
||||
result->flags=0;
|
||||
if (type!=BDT_RAM)
|
||||
result->flags|=BDF_READ_CACHE;
|
||||
|
||||
if (type==BDT_ATAPI) {
|
||||
result->blk_size=CD_BLK_SIZE;
|
||||
result->flags|=BDF_READ_ONLY;
|
||||
} else
|
||||
result->blk_size=BLK_SIZE;
|
||||
|
||||
result->max_blk=0xEFFFFFFF;
|
||||
return result;
|
||||
}
|
||||
} while (++i<NUM_BLKDEVS);
|
||||
throw(EXCEPT_BLKDEV,9);
|
||||
return NULL; //never gets here
|
||||
}
|
||||
|
||||
U0 MapBufAlloc(CPrt *p,I64 num_blks)
|
||||
{
|
||||
PrtChk(p);
|
||||
Free(p->cur_map_blk);
|
||||
Free(p->buffered_map_dirty_bits);
|
||||
p->num_buffered_map_blks=num_blks;
|
||||
p->cur_map_blk=AMAlloc(num_blks<<BLK_SIZE_BITS);
|
||||
p->buffered_map_dirty_bits=ACAlloc((num_blks+7)>>3);
|
||||
p->cur_map_blk_num=0;
|
||||
RBlks(p,p->cur_map_blk,p->map1,p->num_buffered_map_blks);
|
||||
}
|
||||
|
||||
|
||||
U0 CleanMAPBuf(CPrt *p,I64 MAP_select=-1)
|
||||
{
|
||||
I64 i;
|
||||
if ((MAP_select==-1 || !MAP_select) && p->map1!=p->map2)
|
||||
for (i=0;i<p->num_buffered_map_blks;i++)
|
||||
if (Bt(p->buffered_map_dirty_bits,i))
|
||||
WBlks(p,p->cur_map_blk(I64)+i<<BLK_SIZE_BITS,p->map1+i+p->cur_map_blk_num,1);
|
||||
if (MAP_select==-1 || MAP_select==1 || p->map1==p->map2)
|
||||
for (i=0;i<p->num_buffered_map_blks;i++)
|
||||
if (LBtr(p->buffered_map_dirty_bits,i))
|
||||
WBlks(p,p->cur_map_blk(I64)+i<<BLK_SIZE_BITS,p->map2+i+p->cur_map_blk_num,1);
|
||||
}
|
||||
|
||||
U0 SetNativeBuf(CPrt *p,I64 c,I64 map_select=-1)
|
||||
{
|
||||
I64 MAP_blk_num;
|
||||
if (c==INVALID_CLUSTER)
|
||||
throw(EXCEPT_PRT,1);
|
||||
if (p->type==PT_FAT32)
|
||||
MAP_blk_num=c/(BLK_SIZE>>2);
|
||||
else
|
||||
MAP_blk_num=c>>(BLK_SIZE_BITS+3);
|
||||
if (MAP_blk_num!=p->cur_map_blk_num) {
|
||||
CleanMAPBuf(p,map_select);
|
||||
p->cur_map_blk_num=MAP_blk_num;
|
||||
if (map_select==-1 || !map_select)
|
||||
RBlks(p,p->cur_map_blk,p->map1+p->cur_map_blk_num,1);
|
||||
else
|
||||
RBlks(p,p->cur_map_blk,p->map2+p->cur_map_blk_num,1);
|
||||
}
|
||||
}
|
||||
|
||||
#define ZERO_BUF_SIZE 2048
|
||||
U0 WZeroBlks(CPrt *p,I64 blk,I64 cnt)
|
||||
{
|
||||
I64 n;
|
||||
U8 *z=CAlloc(ZERO_BUF_SIZE<<BLK_SIZE_BITS);
|
||||
Bool show_progress;
|
||||
if (cnt>ZERO_BUF_SIZE && p->bdev->type!=BDT_RAM) {
|
||||
progress1=0; progress1_max=cnt;
|
||||
StrCpy(progress1_desc,"Zeroing");
|
||||
show_progress=TRUE;
|
||||
} else
|
||||
show_progress=FALSE;
|
||||
while (cnt>0) {
|
||||
n=cnt;
|
||||
if (n>ZERO_BUF_SIZE)
|
||||
n=ZERO_BUF_SIZE;
|
||||
WBlks(p,z,blk,n);
|
||||
blk+=n;
|
||||
cnt-=n;
|
||||
if (show_progress)
|
||||
progress1+=n;
|
||||
Yield; //Prevent locking
|
||||
}
|
||||
Free(z);
|
||||
if (show_progress) {
|
||||
*progress1_desc=0;
|
||||
progress1=progress1_max=0;
|
||||
}
|
||||
}
|
||||
|
||||
//Very dangerous
|
||||
Bool SetDrvType(U8 drv_let,I64 type=PT_NATIVE)
|
||||
{
|
||||
I64 i,j,ext_base,prt_num,offset,cur_type;
|
||||
CMasterBoot mbr;
|
||||
CBlkDev *bdev=Drv2BlkDev(drv_let);
|
||||
prt_num=bdev->first_drv_let-'A';
|
||||
switch (bdev->type) {
|
||||
case BDT_ATA:
|
||||
offset=0;
|
||||
ext_base=INVALID_CLUSTER;
|
||||
while (TRUE) {
|
||||
ATAReadBlks(bdev,&mbr,offset,1);
|
||||
j=-1;
|
||||
for (i=0;i<4;i++) {
|
||||
cur_type=mbr.p[i].type;
|
||||
if (cur_type) {
|
||||
if (cur_type==5 || cur_type==15)
|
||||
j=i;
|
||||
else {
|
||||
if (prt_num+'A'==ToUpper(drv_let)) {
|
||||
switch (type) {
|
||||
case PT_NATIVE:
|
||||
mbr.p[i].type=MBR_PT_NATIVE;
|
||||
break;
|
||||
case PT_FAT32:
|
||||
mbr.p[i].type=MBR_PT_FAT32a;
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
mbr.p[i].active=0x80;
|
||||
ATAWriteBlks(bdev,&mbr,offset,1);
|
||||
return TRUE;
|
||||
}
|
||||
prt_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j<0)
|
||||
break;
|
||||
if (!mbr.p[j].offset)
|
||||
break;
|
||||
if (ext_base==INVALID_CLUSTER) {
|
||||
offset=mbr.p[j].offset;
|
||||
ext_base=offset;
|
||||
} else
|
||||
offset=mbr.p[j].offset+ext_base;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Bool RBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
Bool result=TRUE,unlock;
|
||||
CBlkDev *bdev=p->bdev;
|
||||
PrtChk(p);
|
||||
if (cnt<=0) return result;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
BlkDevInit(bdev);
|
||||
if (p->offset && blk<p->offset || blk+cnt>p->offset+p->size)
|
||||
throw(EXCEPT_PRT,2);
|
||||
blk+=bdev->offset;
|
||||
|
||||
if (bdev->flags & BDF_READ_CACHE)
|
||||
RCache(p,&buf,&blk,&cnt);
|
||||
if (cnt>0) {
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(bdev->read_freq);
|
||||
result=(*p->rblks)(p,buf,blk,cnt);
|
||||
bdev->last_time=tS;
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(0);
|
||||
if (bdev->flags & BDF_READ_CACHE)
|
||||
DskCacheAdd(p,buf,blk,cnt);
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool WBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
Bool result=TRUE,unlock;
|
||||
CBlkDev *bdev=p->bdev;
|
||||
PrtChk(p);
|
||||
if (cnt<=0) return result;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
BlkDevInit(bdev);
|
||||
if (bdev->flags&BDF_READ_ONLY &&
|
||||
!(bdev->flags & BDF_READ_ONLY_OVERRIDE))
|
||||
throw(EXCEPT_BLKDEV,0);
|
||||
if (p->offset && blk<p->offset || blk+cnt>p->offset+p->size)
|
||||
throw(EXCEPT_PRT,3);
|
||||
blk+=bdev->offset;
|
||||
if (cnt>0) {
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(bdev->write_freq);
|
||||
result=(*p->wblks)(p,buf,blk,cnt);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(0);
|
||||
bdev->last_time=tS;
|
||||
if (bdev->flags & BDF_READ_CACHE)
|
||||
DskCacheAdd(p,buf,blk,cnt);
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
U0 DskCacheInvalidate(CPrt *p)
|
||||
{
|
||||
Bool unlock;
|
||||
CBlkDev *bdev=p->bdev;
|
||||
PrtChk(p);
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
BlkDevInit(bdev);
|
||||
if (bdev->flags & BDF_READ_CACHE)
|
||||
DskCacheInvalidate2(p);
|
||||
if (p->type==PT_ISO9660) {
|
||||
if (!(bdev->flags & BDF_READ_ONLY_OVERRIDE))
|
||||
ISOPrtInit(p,(32767/bdev->blk_size+1)*
|
||||
bdev->blk_size>>BLK_SIZE_BITS);
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
|
||||
U0 ChgDsk(U8 drv_let=0)
|
||||
{ //This is needed for removable media
|
||||
CPrt *p=Drv2Prt(drv_let);
|
||||
CBlkDev *bdev=p->bdev;
|
||||
Bool old_preempt=Preempt(OFF);
|
||||
if (!(bdev->flags&BDF_INITIALIZED))
|
||||
BlkDevInit(bdev);
|
||||
else if (bdev->flags&BDF_REMOVABLE)
|
||||
DskCacheInvalidate(p);
|
||||
Drv(drv_let);
|
||||
NativeFSFreeFreeLst(p);
|
||||
Preempt(old_preempt);
|
||||
}
|
||||
|
||||
U8 *DrvSerialNum(U8 drv_let=0)
|
||||
{ //20 bytes max.
|
||||
CBlkDev *bdev=Drv2BlkDev(drv_let);
|
||||
U16 *st,*result=NULL;
|
||||
I64 i;
|
||||
if (bdev->dev_id_record) {
|
||||
st=CAlloc(20+1);
|
||||
for (i=0;i<10;i++)
|
||||
st[i]=EndianU16(bdev->dev_id_record[10+i]);
|
||||
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
|
||||
Free(st);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *DrvModelNum(U8 drv_let=0)
|
||||
{ //40 bytes max.
|
||||
CBlkDev *bdev=Drv2BlkDev(drv_let);
|
||||
U16 *st,*result=NULL;
|
||||
I64 i;
|
||||
if (bdev->dev_id_record) {
|
||||
st=CAlloc(40+1);
|
||||
for (i=0;i<20;i++)
|
||||
st[i]=EndianU16(bdev->dev_id_record[27+i]);
|
||||
result=MStrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
|
||||
Free(st);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 PrtRep()
|
||||
{ //Partition report
|
||||
CPrt *p;
|
||||
CBlkDev *bdev;
|
||||
I64 i;
|
||||
U8 *st,drv_let;
|
||||
"\nDefined Partitions:\n\n";
|
||||
p=sys_prts;
|
||||
for (i=0;i<NUM_PRTS;i++,p++) {
|
||||
if (p->pt_signature==PRT_SIGNATURE_VAL) {
|
||||
bdev=p->bdev;
|
||||
drv_let=Prt2Drv(p);
|
||||
if (Bt(&p->type,PTf_DISABLE))
|
||||
"$$FG,RED$$X";
|
||||
else if (drv_let==dft_drv)
|
||||
"$$FG,GREEN$$:";
|
||||
else
|
||||
'' CH_SPACE;
|
||||
"$$FG,PURPLE$$%C %-8Z %-9Z %04X %04X %02X$$FG$$\n",
|
||||
drv_let,p->type.u16[0],"ST_PRT_TYPES",
|
||||
bdev->type,"ST_BLKDEV_TYPES",bdev->base0,bdev->base1,bdev->unit;
|
||||
if (st=DrvModelNum(drv_let)) {
|
||||
" $$FG,CYAN$$Model# :%s$$FG$$\n",st;
|
||||
Free(st);
|
||||
}
|
||||
if (st=DrvSerialNum(drv_let)) {
|
||||
" $$FG,CYAN$$Serial#:%s$$FG$$\n",st;
|
||||
Free(st);
|
||||
}
|
||||
" %016X-%016X\n",
|
||||
p->offset,p->offset+p->size-1;
|
||||
p->offset,p->offset+p->size-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
I64 ClusterNumNext(CPrt *p,I64 c,I64 cnt=1)
|
||||
{
|
||||
Bool unlock;
|
||||
PrtChk(p);
|
||||
if (cnt<=0) return c;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
switch (p->type) {
|
||||
case PT_ISO9660:
|
||||
case PT_NATIVE:
|
||||
c+=cnt;
|
||||
break;
|
||||
case PT_FAT32:
|
||||
while (cnt-->0 && 0<c<0x0FFFFFF8) {
|
||||
SetNativeBuf(p,c);
|
||||
c=p->cur_map_blk[c & (BLK_SIZE/4-1)];
|
||||
}
|
||||
if (!(0<c<0x0FFFFFF8))
|
||||
c=INVALID_CLUSTER;
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
I64 Cluster2Blk(CPrt *p,I64 c)
|
||||
{
|
||||
PrtChk(p);
|
||||
return p->data+c*p->spc;
|
||||
}
|
||||
|
||||
I64 RClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks)
|
||||
{ //This accepts blk count, so padding on last cluster is not read.
|
||||
I64 i;
|
||||
Bool unlock;
|
||||
PrtChk(p);
|
||||
if (blks<=0) return c;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
switch (p->type) {
|
||||
case PT_ISO9660:
|
||||
case PT_NATIVE:
|
||||
RBlks(p,buf,p->data+c*p->spc,blks);
|
||||
c+=(blks+p->spc-1)/p->spc;
|
||||
break;
|
||||
case PT_FAT32:
|
||||
while (blks && 0<c<0x0FFFFFF8) {
|
||||
i=blks;
|
||||
if (i>p->spc)
|
||||
i=p->spc;
|
||||
RBlks(p,buf,p->data+c*p->spc,i);
|
||||
buf+=i<<BLK_SIZE_BITS;
|
||||
c=ClusterNumNext(p,c,1);
|
||||
blks-=i;
|
||||
}
|
||||
if (blks)
|
||||
Dbg;
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
I64 RClusters(CPrt *p,U8 *buf,I64 c,I64 cnt)
|
||||
{
|
||||
return RClustersBlks(p,buf,c,cnt*p->spc);
|
||||
}
|
||||
|
||||
Bool CFileNameTo(U8 *dst,U8 *src)
|
||||
{
|
||||
MemSet(dst,0,CDIR_FILENAME_LEN);
|
||||
if (!FileNameChk(src))
|
||||
return FALSE;
|
||||
StrCpy(dst,src);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
I64 Name2DirCluster(CPrt *p,U8 *dirname)
|
||||
{
|
||||
Bool cont=TRUE,unlock;
|
||||
I64 cur_dir_cluster;
|
||||
CDirEntry de;
|
||||
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
|
||||
PrtChk(p);
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
cur_dir_cluster=p->root_cluster;
|
||||
while (*buf && cont) {
|
||||
StrFirstRem(buf,"/",buf2);
|
||||
if (*buf2) {
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
cont=NativeFSFileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
cont=FAT32FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
cont=ISO1FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
cur_dir_cluster=de.cluster;
|
||||
}
|
||||
}
|
||||
if (!cont) {
|
||||
"%s ",dirname;
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
cur_dir_cluster=0;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
Free(buf);
|
||||
Free(buf2);
|
||||
return cur_dir_cluster;
|
||||
}
|
||||
|
||||
I64 Name2ParentDirCluster(CPrt *p,U8 *dirname)
|
||||
{
|
||||
Bool cont=TRUE,unlock;
|
||||
I64 cur_dir_cluster,cur_dir_cluster2;
|
||||
CDirEntry de;
|
||||
U8 *buf=StrNew(dirname),*buf2=StrNew(dirname);
|
||||
PrtChk(p);
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
cur_dir_cluster=p->root_cluster;
|
||||
cur_dir_cluster2=p->root_cluster;
|
||||
while (*buf && cont) {
|
||||
cur_dir_cluster2=cur_dir_cluster;
|
||||
StrFirstRem(buf,"/",buf2);
|
||||
if (*buf2) {
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
cont=NativeFSFileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
cont=FAT32FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
cont=ISO1FileFind(p,cur_dir_cluster,buf2,&de,FUF_JUST_DIRS);
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
cur_dir_cluster=de.cluster;
|
||||
}
|
||||
}
|
||||
if (!cont) {
|
||||
"%s ",dirname;
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
cur_dir_cluster2=0;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
Free(buf);
|
||||
Free(buf2);
|
||||
return cur_dir_cluster2;
|
||||
}
|
||||
|
||||
|
||||
I64 WClustersBlks(CPrt *p,U8 *buf,I64 c,I64 blks)
|
||||
{ //This accepts blk count, so padding on last cluster is not written.
|
||||
I64 i;
|
||||
Bool unlock;
|
||||
PrtChk(p);
|
||||
if (blks<=0) return c;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
WBlks(p,buf,p->data+c*p->spc,blks);
|
||||
c=0;
|
||||
break;
|
||||
case PT_FAT32:
|
||||
while (blks) {
|
||||
if (!(0<c<0x0FFFFFF8))
|
||||
Dbg;
|
||||
i=blks;
|
||||
if (i>p->spc)
|
||||
i=p->spc;
|
||||
WBlks(p,buf,p->data+c*p->spc,i);
|
||||
buf+=i<<BLK_SIZE_BITS;
|
||||
c=ClusterNumNext(p,c);
|
||||
blks-=i;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
return c;
|
||||
}
|
||||
|
||||
I64 WClusters(CPrt *p,U8 *buf,I64 c,I64 cnt)
|
||||
{
|
||||
return WClustersBlks(p,buf,c,cnt*p->spc);
|
||||
}
|
||||
|
||||
//c=0 means first cluster in chain
|
||||
I64 ClusersAlloc(CPrt *p,I64 c=0,I64 cnt=1,Bool contiguous=FALSE)
|
||||
{
|
||||
PrtChk(p);
|
||||
if (cnt<=0) return c;
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
return NativeFSAllocClusters(p,cnt);
|
||||
case PT_FAT32:
|
||||
if (contiguous) {
|
||||
if (c) throw(EXCEPT_FILE,3);
|
||||
return FAT32AllocContiguousClusters(p,cnt);
|
||||
} else
|
||||
return FAT32AllocClusters(p,c,cnt);
|
||||
default:
|
||||
Dbg;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,517 @@
|
||||
Bool MapDrv(U8 drv_let,CPrt *p)
|
||||
{
|
||||
drv_let=ToUpper(drv_let);
|
||||
if ('A'<=drv_let<='Z') {
|
||||
drv_to_prt[drv_let-'A']=p;
|
||||
p->drv_let=drv_let;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool Drv(U8 drv_let)
|
||||
{
|
||||
CPrt *p=Drv2Prt(drv_let);
|
||||
CBlkDev *bdev=p->bdev;
|
||||
BlkDevChk(bdev);
|
||||
if (p!=Fs->cur_prt) {
|
||||
if ( bdev->flags & BDF_REMOVABLE &&
|
||||
!(bdev->flags & BDF_INITIALIZED) )
|
||||
ChgDsk(Prt2Drv(p));
|
||||
if (bdev->type==BDT_RAM)
|
||||
BlkDevInit(bdev);
|
||||
}
|
||||
Fs->cur_prt=p;
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=StrNew("/");
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
case PT_FAT32:
|
||||
case PT_ISO9660:
|
||||
return TRUE;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool Cd(U8 *dirname,Bool make_dirs=FALSE)
|
||||
{//Optionally, will create the directories if they don't exist.
|
||||
I64 maxlen,cur_dir_cluster=0;
|
||||
U8 *chg_to_buf,*new_cur_dir,*buf;
|
||||
CPrt *p;
|
||||
Bool result=TRUE;
|
||||
if (!*dirname) return TRUE;
|
||||
if (dirname[1]==':') {
|
||||
if (*dirname==':') {
|
||||
if (Fs->cur_prt->drv_let!=dft_drv)
|
||||
if (!Drv(*dirname)) return FALSE;
|
||||
} else {
|
||||
if (Fs->cur_prt!=
|
||||
Drv2Prt(*dirname))
|
||||
if (!Drv(*dirname)) return FALSE;
|
||||
}
|
||||
dirname+=2;
|
||||
}
|
||||
if (*dirname=='/' || !*dirname || !Fs->cur_dir) {
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=StrNew("/");
|
||||
if (*dirname=='/')
|
||||
dirname++;
|
||||
}
|
||||
chg_to_buf=MStrUtil(dirname,
|
||||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||||
maxlen=StrLen(Fs->cur_dir)+1+StrLen(chg_to_buf)+1;
|
||||
new_cur_dir=MAlloc(maxlen);
|
||||
buf=MAlloc(maxlen);
|
||||
StrCpy(new_cur_dir,Fs->cur_dir);
|
||||
while (*chg_to_buf && result) {
|
||||
StrFirstRem(chg_to_buf,"/",buf);
|
||||
if (!*buf)
|
||||
StrCpy(new_cur_dir,"/");
|
||||
else if (!StrCmp(buf,"..")) {
|
||||
StrLastRem(new_cur_dir,"/");
|
||||
if (!*new_cur_dir)
|
||||
StrCpy(new_cur_dir,"/");
|
||||
} else if (!StrCmp(buf,".")) {
|
||||
;
|
||||
} else if (*buf) {
|
||||
if (!StrCmp(buf,"HOME")) {
|
||||
result=Cd(sys_acct);
|
||||
Free(new_cur_dir);
|
||||
new_cur_dir=MAlloc(maxlen+StrLen(sys_acct));
|
||||
StrCpy(new_cur_dir,sys_acct+2);
|
||||
} else {
|
||||
p=Fs->cur_prt;
|
||||
cur_dir_cluster=Name2DirCluster(p,new_cur_dir);
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSCd(buf,cur_dir_cluster);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32Cd(buf,cur_dir_cluster);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1Cd(buf,cur_dir_cluster);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
result=FALSE;
|
||||
}
|
||||
if (!result && make_dirs) {
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=StrNew(new_cur_dir);
|
||||
result=MkDir(buf);
|
||||
}
|
||||
if (result) {
|
||||
if (StrCmp(new_cur_dir,"/"))
|
||||
StrCat(new_cur_dir,"/");
|
||||
StrCat(new_cur_dir,buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=StrNew(new_cur_dir);
|
||||
Free(buf);
|
||||
Free(chg_to_buf);
|
||||
Free(new_cur_dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 FileAccessDel(CFileAccess *fa)
|
||||
{
|
||||
CBlkDev *bdev;
|
||||
if (!fa) return;
|
||||
bdev=fa->old_prt->bdev;
|
||||
if (!(bdev->flags & BDF_INIT_IN_PROGRESS)) {
|
||||
if (fa->old_dir) {
|
||||
Drv(Prt2Drv(fa->old_prt));
|
||||
Cd(fa->old_dir);
|
||||
}
|
||||
} else {
|
||||
Fs->cur_prt=fa->old_prt;
|
||||
Free(Fs->cur_dir);
|
||||
Fs->cur_dir=StrNew("/");
|
||||
}
|
||||
Free(fa->old_dir);
|
||||
Free(fa->mask);
|
||||
Free(fa);
|
||||
}
|
||||
|
||||
CFileAccess *FileAccessNew(U8 *_mask,Bool make_mask=FALSE,Bool make_dirs=FALSE)
|
||||
{
|
||||
Bool valid=TRUE,old_silent;
|
||||
U8 *buf,*mask,*temp_mask;
|
||||
CFileAccess *fa=CAlloc(sizeof(CFileAccess));
|
||||
mask=MStrUtil(_mask,
|
||||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||||
temp_mask=mask;
|
||||
fa->old_dir=StrNew(Fs->cur_dir);
|
||||
fa->old_prt=Fs->cur_prt;
|
||||
if (*mask && mask[1]==':') {
|
||||
if (Fs->cur_prt!=Drv2Prt(*mask))
|
||||
if (!Drv(*mask)) valid=FALSE;
|
||||
mask+=2;
|
||||
}
|
||||
if (StrStr(mask,"HOME") && Fs->cur_prt!=Drv2Prt(*sys_acct))
|
||||
Drv(*sys_acct);
|
||||
fa->p=Fs->cur_prt;
|
||||
PrtChk(fa->p);
|
||||
buf=MAlloc(StrLen(mask)+2);
|
||||
StrCpy(buf,mask);
|
||||
fa->mask=MAlloc(StrLen(mask)+2);
|
||||
StrLastRem(buf,"/",fa->mask);
|
||||
if (*mask=='/' && !*buf)
|
||||
StrCpy(buf,"/");
|
||||
//If began with Dir, change to Dir.
|
||||
if (*buf && !Cd(buf,make_dirs))
|
||||
valid=FALSE;
|
||||
if (valid && make_mask) {
|
||||
if (!*fa->mask) {
|
||||
Free(fa->mask);
|
||||
fa->mask=StrNew("*");
|
||||
} else {
|
||||
if (!make_dirs || FileNameChk(fa->mask)) {
|
||||
old_silent=Silent(ON);
|
||||
//Try mask to see if Dir. If Dir, change to dir and set to "*".
|
||||
if (Cd(fa->mask,make_dirs)) {
|
||||
Free(fa->mask);
|
||||
fa->mask=StrNew("*");
|
||||
}
|
||||
Silent(old_silent);
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
Free(temp_mask);
|
||||
if (!valid) {
|
||||
FileAccessDel(fa);
|
||||
fa=NULL;
|
||||
// throw(EXCEPT_FILE);
|
||||
}
|
||||
return fa;
|
||||
}
|
||||
|
||||
CDirEntry *FilesFind(U8 *files_find_mask,I64 fuf_flags=0)
|
||||
{
|
||||
/*
|
||||
Flags:
|
||||
$LK,"FUF_RECURSE","MN:FUF_RECURSE"$ +r Recurse
|
||||
$LK,"FUF_FLATTEN_TREE","MN:FUF_FLATTEN_TREE"$ +f $BK,1$be sure to use this along with '+F'$BK,0$.
|
||||
$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$ +D just directories
|
||||
$LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$ +F just files
|
||||
$LK,"FUF_JUST_TXT_FILES","MN:FUF_JUST_TXT_FILES"$ +T just text files: $LK,"FILENAME_MASK_TXT","MN:FILENAME_MASK_TXT"$
|
||||
$LK,"FUF_JUST_SRC_FILES","MN:FUF_JUST_SRC_FILES"$ +S just src files : $LK,"FILENAME_MASK_SRC","MN:FILENAME_MASK_SRC"$
|
||||
See $LK,"ST_FILE_UTIL_FLAGS","MN:ST_FILE_UTIL_FLAGS"$ when used in calling program taking text flags.
|
||||
*/
|
||||
CDirEntry *result;
|
||||
CFileAccess *fa;
|
||||
if (fuf_flags&~FUG_FILES_FIND)
|
||||
throw(EXCEPT_FUF,4);
|
||||
if (fa=FileAccessNew(files_find_mask,TRUE)) {
|
||||
result=SysFilesFind(fa->mask,fuf_flags);
|
||||
FileAccessDel(fa);
|
||||
} else
|
||||
result=NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool IsDir(U8 *dir_name)
|
||||
{
|
||||
U8 *mask=MSPrintF("%s/*",dir_name);
|
||||
Bool result,old_silent=Silent(ON);
|
||||
CFileAccess *fa;
|
||||
if (fa=FileAccessNew(mask)) {
|
||||
FileAccessDel(fa);
|
||||
result=TRUE;
|
||||
} else
|
||||
result=FALSE;
|
||||
Free(mask);
|
||||
Silent(old_silent);
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 Dir(U8 *files_find_mask="*",Bool full=FALSE)
|
||||
{
|
||||
CFileAccess *fa;
|
||||
if (fa=FileAccessNew(files_find_mask,TRUE)) {
|
||||
Dir2(fa->mask,0,full);
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
I64 Del(U8 *files_find_mask,Bool print_msg=TRUE)
|
||||
{
|
||||
I64 result=0;
|
||||
CFileAccess *fa;
|
||||
if (fa=FileAccessNew(files_find_mask)) {
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,FALSE,print_msg);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *FileRead(U8 *filename,I64 *_size=NULL,I64 *_attr=NULL,Bool raw=FALSE)
|
||||
{
|
||||
CHashGeneric *temph;
|
||||
U8 *absname,*altname,*curname,*result=NULL;
|
||||
I64 i,size=0,attr=0;
|
||||
CFileAccess *fa;
|
||||
CArcCompress *ac=NULL;
|
||||
if (_attr) *_attr=0;
|
||||
absname=FileNameAbs(filename);
|
||||
altname=ToggleZorNotZ(absname);
|
||||
if (!raw && ((temph=HashFind(absname,adam_task->hash_table,HTT_FILE))||
|
||||
(temph=HashFind(altname,adam_task->hash_table,HTT_FILE)))) {
|
||||
if (FileAttr(absname) & _ATTR_COMPRESSED) {
|
||||
ac=temph->user_data0;
|
||||
if (_size) *_size=ac->expanded_size;
|
||||
if (_attr) *_attr=FileAttr(absname,*_attr);
|
||||
result=ExpandBuf(ac);
|
||||
} else {
|
||||
result=MAlloc(temph->user_data1+1);
|
||||
MemCpy(result,temph->user_data0,temph->user_data1);
|
||||
result[temph->user_data1]=0; //Terminate
|
||||
if (_size) *_size=temph->user_data1;
|
||||
}
|
||||
} else {
|
||||
for (i=0;i<2 && !result;i++) {//Try name, then altname
|
||||
if (!i)
|
||||
curname=absname;
|
||||
else
|
||||
curname=altname;
|
||||
if (fa=FileAccessNew(curname)) {
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
}
|
||||
|
||||
//Search parent directories.
|
||||
for (i=0;i<2 && !result;i++) {//Try name, then altname
|
||||
if (!i)
|
||||
curname=absname;
|
||||
else
|
||||
curname=altname;
|
||||
if (fa=FileAccessNew(curname)) {
|
||||
while (!result && StrCmp(Fs->cur_dir,"/")) {
|
||||
Cd("..");
|
||||
switch (Fs->cur_prt->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1FileRead(fa->p,Fs->cur_dir,fa->mask,&size,&attr,raw,&ac);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
}
|
||||
if (!result) {
|
||||
"%s ",filename;
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
}
|
||||
if (_size) *_size=size;
|
||||
if (_attr) *_attr=attr;
|
||||
if (result && !raw && attr & _ATTR_RESIDENT)
|
||||
HashGenericAdd(curname,HTT_FILE,AMAllocIdentical(ac),size,0,adam_task);
|
||||
Free(ac);
|
||||
}
|
||||
Free(absname);
|
||||
Free(altname);
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *TextFileRead(U8 *filename,I64 *_attr=NULL)
|
||||
{
|
||||
return FileRead(filename,NULL,_attr);
|
||||
}
|
||||
|
||||
|
||||
Bool FileFind(U8 *filename,CDirEntry *rde=NULL,I64 fuf_flags=0)
|
||||
{ //$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$, $LK,"FUF_Z_OR_NOT_Z","MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS","MN:FUF_SCAN_PARENTS"$
|
||||
//If you pass rde, you must Free(rde->full_name);
|
||||
I64 i,j,cur_dir_cluster;
|
||||
U8 *altname,*curname,*full_name=NULL;
|
||||
CDirEntry de;
|
||||
CFileAccess *fa;
|
||||
Bool result=FALSE;
|
||||
if (fuf_flags&~FUG_FILE_FIND)
|
||||
throw(EXCEPT_FUF,5);
|
||||
if (!filename) return FALSE;
|
||||
altname=ToggleZorNotZ(filename);
|
||||
if (fuf_flags&FUF_Z_OR_NOT_Z)
|
||||
j=2;
|
||||
else
|
||||
j=1;
|
||||
for (i=0;i<j && !result;i++) {
|
||||
if (!i)
|
||||
curname=filename;
|
||||
else
|
||||
curname=altname;
|
||||
if (fa=FileAccessNew(curname)) {
|
||||
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
if (result && rde)
|
||||
full_name=MSPrintF("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name);
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
}
|
||||
for (i=0;i<j && !result && fuf_flags&FUF_SCAN_PARENTS;i++) {
|
||||
if (!i)
|
||||
curname=filename;
|
||||
else
|
||||
curname=altname;
|
||||
if (fa=FileAccessNew(curname)) {
|
||||
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
|
||||
while (!result && StrCmp(Fs->cur_dir,"/")) {
|
||||
Cd("..");
|
||||
cur_dir_cluster=Name2DirCluster(fa->p,Fs->cur_dir);
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1FileFind(fa->p,cur_dir_cluster,fa->mask,&de,fuf_flags);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
}
|
||||
if (result && rde)
|
||||
full_name=MSPrintF("%C:%s/%s",Fs->cur_prt->drv_let,Fs->cur_dir,de.name);
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
}
|
||||
if (rde) {
|
||||
if (result) {
|
||||
MemCpy(rde,&de,sizeof(CDirEntry));
|
||||
rde->full_name=full_name;
|
||||
} else
|
||||
MemSet(rde,0,sizeof(CDirEntry));
|
||||
}
|
||||
Free(altname);
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 FileSize(U8 *filename,I64 fuf_flags=0)
|
||||
{ //$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$, $LK,"FUF_Z_OR_NOT_Z","MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS","MN:FUF_SCAN_PARENTS"$
|
||||
CDirEntry de;
|
||||
if (FileFind(filename,&de,fuf_flags)) {
|
||||
Free(de.full_name);
|
||||
return de.size;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 FileSizeExpanded(U8 *filename,I64 fuf_flags=0)
|
||||
{ //$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$, $LK,"FUF_Z_OR_NOT_Z","MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS","MN:FUF_SCAN_PARENTS"$
|
||||
U8 buf[BLK_SIZE];
|
||||
CPrt *p;
|
||||
CDirEntry de;
|
||||
if (FileFind(filename,&de,fuf_flags)) {
|
||||
p=Drv2Prt(*de.full_name);
|
||||
Free(de.full_name);
|
||||
if (p->type==PT_NATIVE && de.expanded_size)
|
||||
return de.expanded_size;
|
||||
else {
|
||||
if (de.size && FileAttr(de.name) & _ATTR_COMPRESSED) {
|
||||
RBlks(p,buf,Cluster2Blk(p,de.cluster),1);
|
||||
return (&buf)(CArcCompress *)->expanded_size;
|
||||
} else
|
||||
return de.size;
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 FileWrite(U8 *filename,U8 *fbuf,
|
||||
I64 size,CDate spdt=0,I64 attr=0,Bool raw=FALSE)
|
||||
{
|
||||
I64 c=0;
|
||||
CHashGeneric *temph;
|
||||
CFileAccess *fa;
|
||||
CArcCompress *ac=NULL;
|
||||
U8 *absname=FileNameAbs(filename);
|
||||
if (fa=FileAccessNew(filename,FALSE,TRUE)) {
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
c=NativeFSFileWrite(fa->p,Fs->cur_dir,fa->mask,
|
||||
fbuf,size,spdt,attr,raw,&ac);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
c=FAT32FileWrite(fa->p,Fs->cur_dir,fa->mask,
|
||||
fbuf,size,spdt,attr,raw,&ac);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
if (temph=HashFind(absname,adam_task->hash_table,HTT_FILE)) {
|
||||
if (!raw && ac && attr & _ATTR_RESIDENT) {
|
||||
Free(temph->user_data0);
|
||||
temph->user_data0=AMAllocIdentical(ac);
|
||||
temph->user_data1=size;
|
||||
} else
|
||||
HashRemDel(temph,adam_task->hash_table);
|
||||
} else if (!raw && ac && attr & _ATTR_RESIDENT)
|
||||
HashGenericAdd(absname,HTT_FILE,AMAllocIdentical(ac),size,0,adam_task);
|
||||
Free(ac);
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
Free(absname);
|
||||
return c;
|
||||
}
|
||||
|
||||
U0 TextFileWrite(U8 *filename,U8 *st,I64 attr=0)
|
||||
{
|
||||
FileWrite(filename,st,StrLen(st),0,attr);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
U0 DrvDftSelect()
|
||||
{
|
||||
Fs->cur_prt=INVALID_PTR; //Null screws-up cache
|
||||
Fs->cur_dir=StrNew("/");
|
||||
ChgDsk(':');
|
||||
}
|
||||
|
||||
Bool CopySingleZ(U8 *f1,U8 *f2) //Just one file
|
||||
{
|
||||
U8 *file_buf=NULL;
|
||||
I64 size,attr=0,c;
|
||||
CDirEntry de;
|
||||
if (FileFind(f1,&de,FUF_JUST_FILES)) {
|
||||
Free(de.full_name);
|
||||
file_buf=FileRead(f1,&size,&attr);
|
||||
attr=FileAttr(f2,attr);
|
||||
if (file_buf) {
|
||||
"Copying %s to %s\n",f1,f2;
|
||||
c=FileWrite(f2,file_buf,size,de.datetime,attr);
|
||||
Free(file_buf);
|
||||
return ToBool(c);
|
||||
} else
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
} else
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define COPY_BUF_BLKS 0x80
|
||||
Bool CopySingle(U8 *f1,U8 *f2) //Just one file
|
||||
{
|
||||
U8 *absf1=FileNameAbs(f1),*absf2=FileNameAbs(f2),*buf;
|
||||
I64 cnt,n,size,attr1=FileAttr(f1),attr2=FileAttr(f2),
|
||||
xsum=NATIVE_XSUM,i,j;
|
||||
CFile *in_file=NULL,*out_file=NULL;
|
||||
|
||||
if (!StrCmp(absf1,absf2)) { //onto self?
|
||||
Free(absf1);
|
||||
Free(absf2);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Free(absf1);
|
||||
Free(absf2);
|
||||
if (attr1!=attr2)
|
||||
return CopySingleZ(f1,f2);
|
||||
buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
if (attr1 & _ATTR_CONTIGUOUS)
|
||||
in_file=FOpen(f1,"rc");
|
||||
else
|
||||
in_file=FOpen(f1,"r");
|
||||
if (in_file) {
|
||||
size=FSize(in_file);
|
||||
cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
if (attr2 & _ATTR_CONTIGUOUS)
|
||||
out_file=FOpen(f2,"wc",cnt);
|
||||
else
|
||||
out_file=FOpen(f2,"w",cnt);
|
||||
if (out_file) {
|
||||
"Copying %s to %s\n",f1,f2;
|
||||
j=size;
|
||||
while (cnt>0) {
|
||||
if (cnt>COPY_BUF_BLKS) {
|
||||
n=COPY_BUF_BLKS;
|
||||
i=n<<BLK_SIZE_BITS;
|
||||
} else {
|
||||
n=cnt;
|
||||
i=j;
|
||||
}
|
||||
FRBlks(in_file, buf,FFB_NEXT_BLK,n);
|
||||
xsum^=ArcXSum(buf,i);
|
||||
FWBlks(out_file,buf,FFB_NEXT_BLK,n);
|
||||
cnt-=n;
|
||||
j-=n<<BLK_SIZE_BITS;
|
||||
}
|
||||
if (in_file->de.xsum &&
|
||||
in_file->de.xsum!=xsum)
|
||||
throw(EXCEPT_ARC_XSUM);
|
||||
out_file->de.xsum=xsum;
|
||||
out_file->flags|=FF_USE_OLD_DATETIME;
|
||||
out_file->de.datetime=in_file->de.datetime;
|
||||
out_file->de.size=size;
|
||||
out_file->de.expanded_size=in_file->de.expanded_size;
|
||||
out_file->de.attr=FileAttr(f2,in_file->de.attr);
|
||||
FClose(out_file);
|
||||
FClose(in_file);
|
||||
Free(buf);
|
||||
return TRUE;
|
||||
} else PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
FClose(in_file);
|
||||
} else PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
Free(buf);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool MkDir(U8 *filename)
|
||||
{
|
||||
U8 *name;
|
||||
CFileAccess *fa;
|
||||
Bool result=FALSE;
|
||||
if (FileFind(filename,,FUF_JUST_DIRS))
|
||||
return FALSE;
|
||||
if (fa=FileAccessNew(filename)) {
|
||||
if (*fa->mask) {
|
||||
if (!FileNameChk(fa->mask))
|
||||
PutDefineErr("ST_INVALID_FILENAME");
|
||||
else {
|
||||
"Make Directory:";
|
||||
"" filename;
|
||||
NewLine;
|
||||
name=MStrUtil(fa->mask,
|
||||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSMkDir(fa->p,Fs->cur_dir,name);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32MkDir(fa->p,Fs->cur_dir,name);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
Free(name);
|
||||
}
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 SysDel(U8 *wild,Bool make_mask) //this is dangerous
|
||||
{
|
||||
I64 result=0;
|
||||
CFileAccess *fa;
|
||||
if (fa=FileAccessNew(wild,make_mask)) {
|
||||
switch (fa->p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FilesDel(fa->p,Fs->cur_dir,fa->mask,0,TRUE,TRUE);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 Fmt(I64 drv_let,Bool quick=TRUE,Bool confirm=TRUE,I64 type=PT_FAT32)
|
||||
{//See $LK,"PT_FAT32","MN:PT_FAT32"$ for a lst of supported file system types.
|
||||
|
||||
CPrt *p=Drv2Prt(drv_let);
|
||||
Bool old_silent=IsSilent;
|
||||
if (confirm) {
|
||||
if (!AreYouSure)
|
||||
return;
|
||||
}
|
||||
if (!p) {
|
||||
PutDefineErr("ST_INVALID_DRV");
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case PT_NATIVE:
|
||||
Silent(ON);
|
||||
Drv(drv_let);
|
||||
Silent(old_silent);
|
||||
NativeFSFmt(drv_let,quick);
|
||||
DskCacheInvalidate(Drv2Prt(drv_let));
|
||||
Drv(drv_let);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
Silent(ON);
|
||||
Drv(drv_let);
|
||||
Silent(old_silent);
|
||||
FAT32Fmt(drv_let,quick);
|
||||
DskCacheInvalidate(Drv2Prt(drv_let));
|
||||
Drv(drv_let);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U0 CDImageRead(U8 cd_drv_let,U8 *out_name)
|
||||
{
|
||||
CBlkDev *bdev=Drv2BlkDev(cd_drv_let);
|
||||
CPrt *p=Drv2Prt(cd_drv_let);
|
||||
U8 *buf=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS),
|
||||
*out_name2=DftExt(out_name,"ISO");
|
||||
CFile *f=FOpen(out_name2,"w");
|
||||
I64 n,spc=bdev->blk_size>>BLK_SIZE_BITS,blk=0,cnt,retry;
|
||||
BlkDevInit(bdev);
|
||||
if (bdev->type!=BDT_ATAPI)
|
||||
throw(EXCEPT_BLKDEV,3);
|
||||
if (!out_name)
|
||||
out_name=sys_dft_iso_name;
|
||||
cnt=CeilU64(p->size,spc);
|
||||
while (cnt>0) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>bdev->max_reads)
|
||||
n=bdev->max_reads;
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(bdev->read_freq);
|
||||
|
||||
retry=4;
|
||||
while (--retry)
|
||||
if (ATAPIReadBlks2(bdev,buf,blk/spc,n/spc,TRUE,
|
||||
//n is 0x800 if max_reads. Up to 8 additional seconds
|
||||
tS+7.0+0.004*n/spc))
|
||||
break;
|
||||
|
||||
if (!retry)
|
||||
ATAPIReadBlks2(bdev,buf,blk/spc,n/spc,TRUE,0);
|
||||
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(0);
|
||||
FWBlks(f,buf,blk,n);
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
}
|
||||
FClose(f);
|
||||
Free(buf);
|
||||
Free(out_name2);
|
||||
}
|
||||
|
||||
class CDualBuf
|
||||
{
|
||||
U8 *buf0,*buf1;
|
||||
I64 in_buf,out_buf,cnt;
|
||||
U8 *filename;
|
||||
CBlkDev *CD_bdev;
|
||||
};
|
||||
|
||||
|
||||
U0 CDImageWriteTask(CDualBuf *d)
|
||||
{
|
||||
U8 *buf;
|
||||
I64 n,blk=0,cnt=d->cnt;
|
||||
CFile *f;
|
||||
if (!IsSysDeterministic)
|
||||
Preempt(ON);
|
||||
TaskInitExt; //needed for disk access
|
||||
if (FileAttr(d->filename)&_ATTR_CONTIGUOUS)
|
||||
f=FOpen(d->filename,"rc");
|
||||
else
|
||||
f=FOpen(d->filename,"r");
|
||||
while (cnt>0) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>d->CD_bdev->max_writes)
|
||||
n=d->CD_bdev->max_writes;
|
||||
buf=d->in_buf&1 ? d->buf1:d->buf0;
|
||||
while (d->in_buf>d->out_buf+1)
|
||||
Yield;
|
||||
FRBlks(f,buf,blk,n);
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(d->CD_bdev->write_freq);
|
||||
d->in_buf++;
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
}
|
||||
FClose(f);
|
||||
}
|
||||
|
||||
U0 CDImageWrite(U8 cd_drv_let,U8 *in_name=NULL,I64 media_type=MT_CD)
|
||||
{
|
||||
CDualBuf *d=CAlloc(sizeof(CDualBuf));
|
||||
U8 *buf,*in_name2,*in_name3;
|
||||
I64 i,n,spc,blk=0,cnt;
|
||||
CPrt *p=Drv2Prt(cd_drv_let);
|
||||
CBlkDev *bdev=p->bdev,*bdev2;
|
||||
CTask *task;
|
||||
Bool old_preempt;
|
||||
CFile *f;
|
||||
|
||||
if (!in_name)
|
||||
in_name=sys_dft_iso_name;
|
||||
in_name3=DftExt(in_name,"ISO");
|
||||
in_name2=FileNameAbs(in_name3);
|
||||
f=FOpen(in_name2,"r");
|
||||
if (!f) {
|
||||
Free(d);
|
||||
return;
|
||||
}
|
||||
|
||||
cnt=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
FClose(f);
|
||||
if (bdev->type!=BDT_ATAPI)
|
||||
throw(EXCEPT_BLKDEV,4);
|
||||
bdev2=Drv2BlkDev(*in_name2);
|
||||
while (bdev2->lock_fwding)
|
||||
bdev2=bdev2->lock_fwding;
|
||||
if ((bdev2->type==BDT_ATA || bdev2->type==BDT_ATAPI) &&
|
||||
bdev2->base0==bdev->base0) {
|
||||
"Can't Burn CD on same ATA ctrller as File.\n\n";
|
||||
throw(EXCEPT_BLKDEV,5);
|
||||
}
|
||||
|
||||
bdev->flags|=BDF_READ_ONLY_OVERRIDE;
|
||||
BlkDevInit(bdev);
|
||||
spc=bdev->blk_size>>BLK_SIZE_BITS;
|
||||
if (p->size<cnt)
|
||||
p->size=cnt;
|
||||
|
||||
d->filename=in_name2;
|
||||
d->CD_bdev=bdev;
|
||||
d->buf0=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
d->buf1=MAlloc(COPY_BUF_BLKS<<BLK_SIZE_BITS);
|
||||
d->cnt=cnt;
|
||||
|
||||
old_preempt=Preempt(OFF);
|
||||
task=Spawn(&CDImageWriteTask,d,"Write CD");
|
||||
|
||||
while (d->in_buf<=d->out_buf)
|
||||
Yield;
|
||||
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(bdev->write_freq);
|
||||
BlkDevLock(bdev);
|
||||
ATAPIWaitReady(bdev,0);
|
||||
|
||||
progress1=0; progress1_max=cnt;
|
||||
StrCpy(progress1_desc,"Writing");
|
||||
while (cnt>0) {
|
||||
if (cnt>COPY_BUF_BLKS)
|
||||
n=COPY_BUF_BLKS;
|
||||
else
|
||||
n=cnt;
|
||||
if (n>bdev->max_writes)
|
||||
n=bdev->max_writes;
|
||||
buf=d->out_buf&1 ? d->buf1:d->buf0;
|
||||
while (d->in_buf<=d->out_buf)
|
||||
Yield;
|
||||
ATAPIWriteBlks(bdev,buf,blk/spc,(n+spc-1)/spc);
|
||||
d->out_buf++;
|
||||
cnt-=n;
|
||||
blk+=n;
|
||||
progress1+=n;
|
||||
}
|
||||
ATAPISync(bdev);
|
||||
|
||||
progress1=0; progress1_max=2;
|
||||
StrCpy(progress1_desc,"Closing");
|
||||
for (i=0;i<2;i++) {
|
||||
ATAPIClose(bdev,0x100,i); //Close tracks
|
||||
progress1++;
|
||||
}
|
||||
|
||||
ATAPISync(bdev);
|
||||
|
||||
ATAPIClose(bdev,0x200); //close disk
|
||||
ATAPISync(bdev);
|
||||
if (media_type==MT_DVD) {
|
||||
ATAPIClose(bdev,0x300);
|
||||
ATAPISync(bdev);
|
||||
}
|
||||
|
||||
*progress1_desc=0;
|
||||
progress1=progress1_max=0;
|
||||
|
||||
if (!Bt(&sys_semas[SYS_SEMA_NO_IO_SND],0))
|
||||
Snd(0);
|
||||
bdev->flags&=~BDF_READ_ONLY_OVERRIDE;
|
||||
BlkDevUnlock(bdev);
|
||||
Free(d->buf0);
|
||||
Free(d->buf1);
|
||||
Free(in_name2);
|
||||
Free(in_name3);
|
||||
Preempt(old_preempt);
|
||||
Free(d);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,954 @@
|
||||
U0 ATABlkSelect(CBlkDev *bdev,I64 blk,I64 cnt)
|
||||
{
|
||||
if (bdev->type!=BDT_ATAPI && bdev->base1)
|
||||
OutU8(bdev->base1+ATAR1_CTRL,0x8);
|
||||
if (bdev->flags & BDF_EXT_SIZE) {
|
||||
OutU8(bdev->base0+ATAR0_NSECT,cnt.u8[1]);
|
||||
OutU8(bdev->base0+ATAR0_SECT,blk.u8[3]);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,blk.u8[4]);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,blk.u8[5]);
|
||||
OutU8(bdev->base0+ATAR0_NSECT,cnt);
|
||||
OutU8(bdev->base0+ATAR0_SECT,blk);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,blk.u8[1]);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,blk.u8[2]);
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
} else {
|
||||
OutU8(bdev->base0+ATAR0_NSECT,cnt);
|
||||
OutU8(bdev->base0+ATAR0_SECT,blk);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,blk.u8[1]);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,blk.u8[2]);
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4|blk.u8[3]);
|
||||
}
|
||||
}
|
||||
|
||||
Bool ATAWaitNotBUSY(CBlkDev *bdev,F64 timeout)
|
||||
{
|
||||
while (TRUE) {
|
||||
if (timeout && tS>timeout)
|
||||
return FALSE;
|
||||
if (InU8(bdev->base0+ATAR0_STAT)&ATAS_BSY)
|
||||
Yield;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool ATAWaitDRQ(CBlkDev *bdev,F64 timeout)
|
||||
{
|
||||
while (TRUE) {
|
||||
if (timeout && tS>timeout)
|
||||
return FALSE;
|
||||
if (!(InU8(bdev->base0+ATAR0_STAT)&ATAS_DRQ))
|
||||
Yield;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool ATANop(CBlkDev *bdev,F64 timeout)
|
||||
{
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_FEAT,0);
|
||||
OutU8(bdev->base0+ATAR0_CMD,ATA_NOP);
|
||||
return ATAWaitNotBUSY(bdev,timeout);
|
||||
}
|
||||
|
||||
U0 ATACmd(CBlkDev *bdev,U8 cmd)
|
||||
{
|
||||
OutU8(bdev->base0+ATAR0_FEAT,0);
|
||||
OutU8(bdev->base0+ATAR0_CMD,cmd);
|
||||
bdev->last_time=tS;
|
||||
PortNop;
|
||||
}
|
||||
|
||||
Bool ATAGetResult(CBlkDev *bdev,U8 *buf,I64 cnt,I64 _avail,Bool one_read,F64 timeout=0)
|
||||
{
|
||||
I64 avail,overflow;
|
||||
bdev->flags&=~BDF_LAST_WAS_WRITE;
|
||||
MemSet(buf,0,cnt);
|
||||
while (cnt>0) {
|
||||
if (!ATAWaitDRQ(bdev,timeout))
|
||||
return FALSE;
|
||||
if (_avail)
|
||||
avail=_avail;
|
||||
else
|
||||
avail=InU8(bdev->base0+ATAR0_HCYL)<<8+InU8(bdev->base0+ATAR0_LCYL);
|
||||
if (avail) {
|
||||
if (avail>cnt) {
|
||||
overflow=avail-cnt;
|
||||
avail=cnt;
|
||||
} else
|
||||
overflow=0;
|
||||
if (avail&2)
|
||||
RepInU16(buf,avail>>1,bdev->base0+ATAR0_DATA);
|
||||
else
|
||||
RepInU32(buf,avail>>2,bdev->base0+ATAR0_DATA);
|
||||
cnt-=avail;
|
||||
buf+=avail;
|
||||
while (overflow>0) {
|
||||
if (timeout && tS>timeout)
|
||||
return FALSE;
|
||||
InU16(bdev->base0+ATAR0_DATA);
|
||||
overflow-=2;
|
||||
}
|
||||
if (one_read)
|
||||
break;
|
||||
} else
|
||||
Yield;
|
||||
}
|
||||
return ATAWaitNotBUSY(bdev,timeout);
|
||||
}
|
||||
|
||||
Bool ATAPIWritePktWord(CBlkDev *bdev,U16 w,F64 timeout=0)
|
||||
{
|
||||
if (!ATAWaitDRQ(bdev,timeout))
|
||||
return FALSE;
|
||||
OutU16(bdev->base0+ATAR0_DATA,EndianU16(w));
|
||||
bdev->last_time=tS;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool ATAPISetMaxSpeed(CBlkDev *bdev)
|
||||
{
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,0);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,0);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0xBB00); //Set speed
|
||||
ATAPIWritePktWord(bdev,0xFFFF); //read at max
|
||||
ATAPIWritePktWord(bdev,0xFFFF); //write at max
|
||||
ATAPIWritePktWord(bdev,0);
|
||||
ATAPIWritePktWord(bdev,0);
|
||||
ATAPIWritePktWord(bdev,0);
|
||||
return ATAWaitNotBUSY(bdev,0);
|
||||
}
|
||||
|
||||
|
||||
Bool ATAPISeek(CBlkDev *bdev,I64 native_blk)
|
||||
{
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,0);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,0);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x2B00); //Seek
|
||||
ATAPIWritePktWord(bdev,native_blk>>16);
|
||||
ATAPIWritePktWord(bdev,native_blk);
|
||||
ATAPIWritePktWord(bdev,0);
|
||||
ATAPIWritePktWord(bdev,0);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
return ATAWaitNotBUSY(bdev,0);
|
||||
}
|
||||
|
||||
Bool ATAPIStartStop(CBlkDev *bdev,Bool start,F64 timeout)
|
||||
{
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
|
||||
//Start/Stop
|
||||
if (!ATAPIWritePktWord(bdev,0x1B00,timeout)) return FALSE;
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) return FALSE;
|
||||
if (start) {
|
||||
if (!ATAPIWritePktWord(bdev,0x0100,timeout)) return FALSE;
|
||||
} else {
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) return FALSE;
|
||||
}
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) return FALSE;
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) return FALSE;
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) return FALSE;
|
||||
return ATAWaitNotBUSY(bdev,timeout);
|
||||
}
|
||||
|
||||
I64 ATAGetDevId(CBlkDev *bdev,U16 **_id_record,F64 timeout)
|
||||
{
|
||||
U16 *id_record;
|
||||
if (_id_record) *_id_record=NULL;
|
||||
if (bdev->type!=BDT_ATAPI && bdev->base1)
|
||||
OutU8(bdev->base1+ATAR1_CTRL,0x8);
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
ATACmd(bdev,ATA_ID_DEV);
|
||||
if (!ATAWaitNotBUSY(bdev,timeout))
|
||||
return BDT_NULL;
|
||||
if (InU8(bdev->base0+ATAR0_STAT)&ATAS_ERR)
|
||||
return BDT_ATAPI;
|
||||
id_record=ACAlloc(512);
|
||||
if (!ATAGetResult(bdev,id_record,512,512,FALSE,timeout)) {
|
||||
Free(id_record);
|
||||
return BDT_NULL;
|
||||
}
|
||||
if (_id_record) *_id_record=id_record;
|
||||
return BDT_ATA;
|
||||
}
|
||||
|
||||
I64 ATAReadNativeMax(CBlkDev *bdev,F64 timeout)
|
||||
{ //returns zero on err
|
||||
I64 result=0;
|
||||
Bool okay=TRUE;
|
||||
|
||||
if (bdev->type==BDT_ATAPI) {
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
ATACmd(bdev,ATA_DEV_RST);
|
||||
if (!ATAWaitNotBUSY(bdev,0))
|
||||
okay=FALSE;
|
||||
} else {
|
||||
while (InU8(bdev->base0+ATAR0_STAT) & ATAS_BSY) {
|
||||
if (timeout && tS>timeout)
|
||||
return FALSE;
|
||||
if (bdev->flags&BDF_LAST_WAS_WRITE)
|
||||
OutU16(bdev->base0+ATAR0_DATA,0);
|
||||
else
|
||||
InU16(bdev->base0+ATAR0_DATA);
|
||||
Yield;
|
||||
}
|
||||
|
||||
Free(bdev->dev_id_record);
|
||||
if (ATAGetDevId(bdev,&bdev->dev_id_record,timeout)==BDT_NULL)
|
||||
okay=FALSE;
|
||||
else
|
||||
BEqu(&bdev->flags,BDf_EXT_SIZE,Bt(&bdev->dev_id_record[86],10));
|
||||
}
|
||||
if (okay) {
|
||||
if (bdev->flags & BDF_EXT_SIZE && bdev->base1) {
|
||||
OutU8(bdev->base1+ATAR1_CTRL,0x8);
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
ATACmd(bdev,ATA_READ_NATIVE_MAX_EXT);
|
||||
if (ATAWaitNotBUSY(bdev,timeout)) {
|
||||
result.u8[0]=InU8(bdev->base0+ATAR0_SECT);
|
||||
result.u8[1]=InU8(bdev->base0+ATAR0_LCYL);
|
||||
result.u8[2]=InU8(bdev->base0+ATAR0_HCYL);
|
||||
|
||||
OutU8(bdev->base1+ATAR1_CTRL,0x80);
|
||||
result.u8[3]=InU8(bdev->base0+ATAR0_SECT);
|
||||
result.u8[4]=InU8(bdev->base0+ATAR0_LCYL);
|
||||
result.u8[5]=InU8(bdev->base0+ATAR0_HCYL);
|
||||
|
||||
if (result>>24==result&0xFFFFFF) {//Kludge to make qemu-kvm work
|
||||
bdev->flags&=~BDF_EXT_SIZE;
|
||||
result&=0xFFFFFF;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (bdev->type!=BDT_ATAPI && bdev->base1)
|
||||
OutU8(bdev->base1+ATAR1_CTRL,0x8);
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
ATACmd(bdev,ATA_READ_NATIVE_MAX);
|
||||
if (ATAWaitNotBUSY(bdev,timeout)) {
|
||||
result.u8[0]=InU8(bdev->base0+ATAR0_SECT);
|
||||
result.u8[1]=InU8(bdev->base0+ATAR0_LCYL);
|
||||
result.u8[2]=InU8(bdev->base0+ATAR0_HCYL);
|
||||
result.u8[3]=InU8(bdev->base0+ATAR0_SELECT) & 0xF;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bdev->max_blk=result;
|
||||
}
|
||||
|
||||
I64 ATAPIReadCapacity(CBlkDev *bdev,I64 *_blk_size=NULL)
|
||||
{ //Supposedly this can return a result +/- 75 sects.
|
||||
//Error might just be for music.
|
||||
Bool unlock=BlkDevLock(bdev);
|
||||
U32 buf[2];
|
||||
if (ATAWaitNotBUSY(bdev,0)) {
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,8);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,0);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x2500); //Read Capacity
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
if (!ATAGetResult(bdev,buf,8,0,TRUE))
|
||||
buf[0]=buf[1]=0;
|
||||
} else
|
||||
buf[0]=buf[1]=0;
|
||||
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
if (_blk_size) *_blk_size=EndianU32(buf[1]);
|
||||
return EndianU32(buf[0]);
|
||||
}
|
||||
|
||||
CATAPITrack *ATAPIReadTrackInfo(CBlkDev *bdev,I64 blk)
|
||||
{
|
||||
CATAPITrack *result=CAlloc(sizeof(CATAPITrack));
|
||||
Bool unlock=BlkDevLock(bdev);
|
||||
if (ATAWaitNotBUSY(bdev,0)) {
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,sizeof(CATAPITrack)&0xFF);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,sizeof(CATAPITrack)>>8);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x5200); //Read Track Info
|
||||
ATAPIWritePktWord(bdev,blk.u16[1]);
|
||||
ATAPIWritePktWord(bdev,blk.u16[0]);
|
||||
ATAPIWritePktWord(bdev,(sizeof(CATAPITrack)&0xFF00)>>8);
|
||||
ATAPIWritePktWord(bdev,(sizeof(CATAPITrack)&0x00FF)<<8);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
if (!ATAGetResult(bdev,result,sizeof(CATAPITrack),0,TRUE)) {
|
||||
Free(result);
|
||||
result=NULL;
|
||||
}
|
||||
} else {
|
||||
Free(result);
|
||||
result=NULL;
|
||||
}
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool ATAInit(CBlkDev *bdev)
|
||||
{
|
||||
Bool unlock=BlkDevLock(bdev),okay=FALSE;
|
||||
|
||||
if (bdev->type==BDT_ATAPI)
|
||||
bdev->flags&=~BDF_EXT_SIZE;
|
||||
else
|
||||
bdev->flags|=BDF_EXT_SIZE;
|
||||
|
||||
if (ATAReadNativeMax(bdev,tS+0.1)) {
|
||||
|
||||
ATABlkSelect(bdev,bdev->max_blk,0);
|
||||
if (bdev->flags&BDF_EXT_SIZE)
|
||||
ATACmd(bdev,ATA_SET_MAX_EXT);
|
||||
else
|
||||
ATACmd(bdev,ATA_SET_MAX);
|
||||
if (ATAWaitNotBUSY(bdev,0)) {
|
||||
okay=TRUE;
|
||||
if (bdev->type==BDT_ATAPI) {
|
||||
if (ATAPIStartStop(bdev,TRUE,0)) {
|
||||
if(!ATAPISetMaxSpeed(bdev))
|
||||
okay=FALSE;
|
||||
} else
|
||||
okay=FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
return okay;
|
||||
}
|
||||
|
||||
Bool ATAPIWaitReady(CBlkDev *bdev,F64 timeout)
|
||||
{
|
||||
while (TRUE) {
|
||||
if (!ATAWaitNotBUSY(bdev,timeout) ||
|
||||
!ATANop(bdev,timeout) ||
|
||||
!ATAPIStartStop(bdev,TRUE,timeout))
|
||||
return FALSE;
|
||||
if (InU8(bdev->base0+ATAR0_STAT) & ATAS_DRDY &&
|
||||
!InU8(bdev->base0+ATAR0_FEAT));
|
||||
return TRUE;
|
||||
if (timeout && tS>timeout)
|
||||
return FALSE;
|
||||
ATAInit(bdev);
|
||||
Yield;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ATAReadBlks(CBlkDev *bdev,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
I64 retries=3;
|
||||
Bool unlock=BlkDevLock(bdev);
|
||||
|
||||
retry:
|
||||
ATABlkSelect(bdev,blk,cnt);
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
ATACmd(bdev,ATA_READ_MULTI_EXT);
|
||||
else
|
||||
ATACmd(bdev,ATA_READ_MULTI);
|
||||
if (!ATAGetResult(bdev,buf,cnt*bdev->blk_size,BLK_SIZE,FALSE,tS+1.0)) {
|
||||
if (retries--) {
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
goto retry;
|
||||
} else
|
||||
throw(EXCEPT_BLKDEV,6);
|
||||
}
|
||||
|
||||
sys_dsk_reads+=(cnt*bdev->blk_size)>>BLK_SIZE_BITS;
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
}
|
||||
|
||||
I64 ATAProbe(I64 base0,I64 base1,I64 unit)
|
||||
{
|
||||
CBlkDev bdev;
|
||||
MemSet(&bdev,0,sizeof(CBlkDev));
|
||||
bdev.type=BDT_ATAPI;
|
||||
bdev.base0=base0;
|
||||
bdev.base1=base1;
|
||||
bdev.unit=unit;
|
||||
bdev.blk_size=CD_BLK_SIZE;
|
||||
return ATAGetDevId(&bdev,NULL,tS+0.1);
|
||||
}
|
||||
|
||||
Bool ATAPIReadBlks2(CBlkDev *bdev,U8 *buf, I64 native_blk, I64 cnt,Bool lock,F64 timeout)
|
||||
{
|
||||
Bool result,unlock;
|
||||
if (cnt<=0)
|
||||
return FALSE;
|
||||
if (lock)
|
||||
unlock=BlkDevLock(bdev);
|
||||
if (!ATAPIWaitReady(bdev,timeout)) goto arb_false_done;
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,bdev->blk_size);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,bdev->blk_size.u8[1]);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
if (!ATAPIWritePktWord(bdev,0xA800,timeout)) goto arb_false_done;
|
||||
if (!ATAPIWritePktWord(bdev,native_blk.u16[1],timeout)) goto arb_false_done;
|
||||
if (!ATAPIWritePktWord(bdev,native_blk,timeout)) goto arb_false_done;
|
||||
if (!ATAPIWritePktWord(bdev,cnt.u16[1],timeout)) goto arb_false_done;
|
||||
if (!ATAPIWritePktWord(bdev,cnt,timeout)) goto arb_false_done;
|
||||
if (!ATAPIWritePktWord(bdev,0x0000,timeout)) goto arb_false_done;
|
||||
if (!ATAGetResult(bdev,buf,cnt*bdev->blk_size,0,FALSE,timeout)) {
|
||||
arb_false_done:
|
||||
result=FALSE;
|
||||
} else {
|
||||
sys_dsk_reads+=(cnt*bdev->blk_size)>>BLK_SIZE_BITS;
|
||||
result=TRUE;
|
||||
}
|
||||
// ATAPIStartStop(bdev,FALSE,0);
|
||||
if (lock && unlock) BlkDevUnlock(bdev);
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 ATAPIReadBlks(CBlkDev *bdev,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
CPrt *p=Drv2Prt(bdev->first_drv_let);
|
||||
I64 retry,spc=bdev->blk_size>>BLK_SIZE_BITS,n,blk2,
|
||||
l2=bdev->max_reads<<1+spc<<1;
|
||||
U8 *cd_buf=MAlloc(l2<<BLK_SIZE_BITS);
|
||||
if (cnt>0) {
|
||||
if (blk<=bdev->max_reads)
|
||||
blk2=0;
|
||||
else
|
||||
blk2=FloorU64(blk-bdev->max_reads,spc);
|
||||
if (blk2+l2>p->size)
|
||||
l2=p->size-blk2;
|
||||
n=(l2+spc-1)/spc;
|
||||
|
||||
retry=4;
|
||||
while (--retry)
|
||||
if (ATAPIReadBlks2(bdev,cd_buf,blk2/spc,n,TRUE,
|
||||
//n is 0x800 if max_reads. Up to 8 additional seconds
|
||||
tS+7.0+0.004*n))
|
||||
break;
|
||||
if (!retry)
|
||||
ATAPIReadBlks2(bdev,cd_buf,blk2/spc,n,TRUE,0);
|
||||
if (bdev->flags & BDF_READ_CACHE)
|
||||
DskCacheAdd(p,cd_buf,blk2,n*spc);
|
||||
MemCpy(buf,cd_buf+(blk-blk2)<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
|
||||
}
|
||||
Free(cd_buf);
|
||||
}
|
||||
|
||||
U0 ATARBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
I64 n;
|
||||
CBlkDev *bdev=p->bdev;
|
||||
BlkDevChk(bdev);
|
||||
while (cnt>0) {
|
||||
n=cnt;
|
||||
if (n>bdev->max_reads)
|
||||
n=bdev->max_reads;
|
||||
if (bdev->type==BDT_ATAPI)
|
||||
ATAPIReadBlks(bdev,buf,blk,n);
|
||||
else
|
||||
ATAReadBlks(bdev,buf,blk,n);
|
||||
buf+=n<<BLK_SIZE_BITS;
|
||||
blk+=n;
|
||||
cnt-=n;
|
||||
}
|
||||
}
|
||||
|
||||
//This is for low level disk access
|
||||
//Call WBlks() instead
|
||||
U0 ATAWriteBlks(CBlkDev *bdev,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
I64 i,U32s_avail,sects_avail,retries=3;
|
||||
F64 timeout;
|
||||
Bool unlock=BlkDevLock(bdev);
|
||||
retry:
|
||||
ATABlkSelect(bdev,blk,cnt);
|
||||
if (bdev->flags&BDF_EXT_SIZE)
|
||||
ATACmd(bdev,ATA_WRITE_MULTI_EXT);
|
||||
else
|
||||
ATACmd(bdev,ATA_WRITE_MULTI);
|
||||
bdev->flags|=BDF_LAST_WAS_WRITE;
|
||||
while (cnt>0) {
|
||||
timeout=tS+1.0;
|
||||
while (TRUE) {
|
||||
i=InU8(bdev->base0+ATAR0_STAT);
|
||||
if (!(i & ATAS_DRDY)||!(i & ATAS_DRQ)) {
|
||||
Yield;
|
||||
} else
|
||||
break;
|
||||
if (/* i&ATAS_ERR||*/ tS>timeout) {
|
||||
if (retries--) {
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
goto retry;
|
||||
} else
|
||||
throw(EXCEPT_BLKDEV,7);
|
||||
}
|
||||
}
|
||||
sects_avail=1;
|
||||
U32s_avail=sects_avail<<BLK_SIZE_BITS>>2;
|
||||
RepOutU32(buf,U32s_avail,bdev->base0+ATAR0_DATA);
|
||||
buf+=U32s_avail<<2;
|
||||
cnt-=sects_avail;
|
||||
retries=3;
|
||||
}
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
}
|
||||
|
||||
Bool ATAPISync(CBlkDev *bdev)
|
||||
{
|
||||
Bool okay=TRUE;
|
||||
if (!ATAWaitNotBUSY(bdev,0))
|
||||
okay=FALSE;
|
||||
else {
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,0);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,0);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x3500); //Sync
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
if (!ATAWaitNotBUSY(bdev,0))
|
||||
okay=FALSE;
|
||||
}
|
||||
return okay;
|
||||
}
|
||||
|
||||
U0 ATAPIClose(CBlkDev *bdev,I64 close_field=0x200,I64 track=0)
|
||||
{
|
||||
//0x200 CD/DVD part 1
|
||||
//0x300 DVD part 2
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,0);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,0);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x5B00); //Close
|
||||
ATAPIWritePktWord(bdev,close_field);
|
||||
ATAPIWritePktWord(bdev,track);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
}
|
||||
|
||||
U0 ATAPIWriteBlks(CBlkDev *bdev,U8 *buf, I64 native_blk, I64 cnt)
|
||||
{
|
||||
I64 U32s_avail;
|
||||
U8 *buf2;
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
ATAPISeek(bdev,native_blk);
|
||||
|
||||
OutU8(bdev->base0+ATAR0_FEAT,0);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,bdev->blk_size);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,bdev->blk_size.u8[1]);
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_CMD,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0x0400); //FMT
|
||||
ATAPIWritePktWord(bdev,native_blk.u16[1]);
|
||||
ATAPIWritePktWord(bdev,native_blk);
|
||||
ATAPIWritePktWord(bdev,cnt.u16[1]);
|
||||
ATAPIWritePktWord(bdev,cnt);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
bdev->flags|=BDF_LAST_WAS_WRITE;
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
|
||||
ATAPISeek(bdev,native_blk);
|
||||
|
||||
if (bdev->flags & BDF_EXT_SIZE)
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xEF|bdev->unit<<4);
|
||||
else
|
||||
OutU8(bdev->base0+ATAR0_SELECT,0xE0|bdev->unit<<4);
|
||||
OutU8(bdev->base0+ATAR0_LCYL,bdev->blk_size);
|
||||
OutU8(bdev->base0+ATAR0_HCYL,bdev->blk_size.u8[1]);
|
||||
ATACmd(bdev,ATA_PACKET);
|
||||
ATAPIWritePktWord(bdev,0xAA00); //Write
|
||||
ATAPIWritePktWord(bdev,native_blk.u16[1]);
|
||||
ATAPIWritePktWord(bdev,native_blk);
|
||||
ATAPIWritePktWord(bdev,cnt.u16[1]);
|
||||
ATAPIWritePktWord(bdev,cnt);
|
||||
ATAPIWritePktWord(bdev,0x0000);
|
||||
buf2=buf+bdev->blk_size*cnt;
|
||||
while (buf<buf2) {
|
||||
ATAWaitDRQ(bdev,0);
|
||||
U32s_avail=(InU8(bdev->base0+ATAR0_HCYL)<<8+InU8(bdev->base0+ATAR0_LCYL))>>2;
|
||||
if (buf+U32s_avail<<2>buf2)
|
||||
U32s_avail=(buf2-buf)>>2;
|
||||
if (U32s_avail) {
|
||||
RepOutU32(buf,U32s_avail,bdev->base0+ATAR0_DATA);
|
||||
buf+=U32s_avail<<2;
|
||||
sys_dsk_writes+=U32s_avail>>(BLK_SIZE_BITS-2);
|
||||
}
|
||||
}
|
||||
ATAWaitNotBUSY(bdev,0);
|
||||
}
|
||||
|
||||
U0 ATAWBlks(CPrt *p,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
I64 n,spc;
|
||||
CBlkDev *bdev=p->bdev;
|
||||
Bool unlock;
|
||||
BlkDevChk(bdev);
|
||||
spc=bdev->blk_size>>BLK_SIZE_BITS;
|
||||
if (bdev->type==BDT_ATAPI) {
|
||||
unlock=BlkDevLock(bdev);
|
||||
ATAPIWaitReady(bdev,0);
|
||||
}
|
||||
while (cnt>0) {
|
||||
n=cnt;
|
||||
if (n>bdev->max_writes)
|
||||
n=bdev->max_writes;
|
||||
if (bdev->type==BDT_ATAPI)
|
||||
ATAPIWriteBlks(bdev,buf,blk/spc,(n+spc-1)/spc);
|
||||
else
|
||||
ATAWriteBlks(bdev,buf,blk,n);
|
||||
buf+=n<<BLK_SIZE_BITS;
|
||||
blk+=n;
|
||||
cnt-=n;
|
||||
sys_dsk_writes+=n;
|
||||
}
|
||||
if (bdev->type==BDT_ATAPI) {
|
||||
ATAPISync(bdev);
|
||||
// ATAPIStartStop(bdev,FALSE,0);
|
||||
if (unlock) BlkDevUnlock(bdev);
|
||||
}
|
||||
}
|
||||
|
||||
Bool BootCdProbe(CBlkDev *bdev)
|
||||
{
|
||||
CKernel *img=CAlloc(CD_BLK_SIZE);
|
||||
I64 i;
|
||||
Bool result=FALSE;
|
||||
"Port: %04X,%04X Unit: %02X ",bdev->base0,bdev->base1,bdev->unit;
|
||||
if (ATAProbe(bdev->base0,bdev->base1,bdev->unit)==BDT_ATAPI) {
|
||||
//After preboot + BootCD.BIN.Z comes Kernel.BIN.C
|
||||
//See $LK,"CDBOOT","FA:::/TempleOS/Adam/Dsk/DskCDDVD.CPP,CDBOOT"$, See $LK,"CD Boot Blk","FF:::/TempleOS/Adam/Boot/BootCD.CPP,BOOT_CODE_CDROM"$
|
||||
" ATAPI";
|
||||
if (ATAPIStartStop(bdev,TRUE,tS+5.0)) {
|
||||
" Started";
|
||||
for (i=0;i<2;i++) { //Retry
|
||||
if (ATAPIReadBlks2(bdev,img,sys_boot_code.u16[1],1,FALSE,tS+7.0)) {
|
||||
if (img->compile_time==sys_compile_time) {
|
||||
" Found";
|
||||
return TRUE;
|
||||
} else
|
||||
" Read";
|
||||
} else
|
||||
" NoRead";
|
||||
}
|
||||
}
|
||||
}
|
||||
" Nope\n";
|
||||
Free(img);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool BootCdProbeAll(CBlkDev *bdev)
|
||||
{
|
||||
I64 i,j,k;
|
||||
U32 d1,d2;
|
||||
|
||||
bdev->base1=0;
|
||||
for (k=0;k<256;k++) {
|
||||
i=-1;
|
||||
while (TRUE) {
|
||||
j=PCIClassFind(0x010100+k,++i);
|
||||
if (j<0)
|
||||
break;
|
||||
"Subcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
|
||||
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
|
||||
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
|
||||
if (d1&1 && d2&1) {
|
||||
if (bdev->base0=d1&-8) {
|
||||
bdev->unit=0;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
bdev->unit=1;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
|
||||
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
|
||||
if (d1&1 && d2&1) {
|
||||
if (bdev->base0=d1&-8) {
|
||||
bdev->unit=0;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
bdev->unit=1;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
d1=0x1F0;
|
||||
d2=0x3F6;
|
||||
if (bdev->base0=d1&-8) {
|
||||
bdev->unit=0;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
bdev->unit=1;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
d1=0x170;
|
||||
d2=0x376;
|
||||
if (bdev->base0=d1&-8) {
|
||||
bdev->unit=0;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
bdev->unit=1;
|
||||
if (BootCdProbe(bdev))
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ATARepEntry(I64 base0,I64 base1,I64 unit,I64 irq,U8 *msg,CATARep **_root,I64 *num_hints)
|
||||
{
|
||||
I64 type;
|
||||
base0&=-8;
|
||||
base1&=-4;
|
||||
CATARep *tempha;
|
||||
if (type=ATAProbe(base0,base1,unit)) {
|
||||
*num_hints+=1;
|
||||
"\n\n$$FG,PURPLE$$ $$BT-LE+LM+X,\"%d\",\"%d\\n\"$$$$FG$$$$LM,4$$",*num_hints,*num_hints;
|
||||
if (type==BDT_ATA)
|
||||
"$$FG,RED$$ATA ";
|
||||
else
|
||||
"$$FG,RED$$ATAPI ";
|
||||
"$$FG,LTBLUE$$%s$$FG$$\nBase0:0x%04X Base1:0x%04X\nIrq:0x%02X Unit:%d$$LM,0$$\n",msg,base0,base1,irq,unit;
|
||||
if (_root) {
|
||||
tempha=CAlloc(sizeof(CATARep));
|
||||
tempha->next=*_root;
|
||||
*_root=tempha;
|
||||
tempha->num=*num_hints;
|
||||
tempha->type=type;
|
||||
tempha->base0=base0;
|
||||
tempha->base1=base1;
|
||||
tempha->unit=unit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bool hint_ata_disable=FALSE;
|
||||
|
||||
U0 ATARepExitAllApplications()
|
||||
{
|
||||
I64 ch;
|
||||
PutDefine("ST_GOING_TO_PROBE_HARDWARE");
|
||||
PutDefine("ST_EXIT_ALL_APPLICATIONS");
|
||||
PutDefine("ST_PRESS_A_KEY");
|
||||
"Press '$$FG,PURPLE$$p$$FG$$' to probe or '$$FG,PURPLE$$s$$FG$$' to skip.\n";
|
||||
ch=ToUpper(GetChar(NULL,FALSE));
|
||||
if (ch=='S')
|
||||
hint_ata_disable=TRUE;
|
||||
else
|
||||
hint_ata_disable=FALSE;
|
||||
}
|
||||
|
||||
public I64 ATARep(Bool pmt=TRUE,Bool just_ide=FALSE,CATARep **_root=NULL)
|
||||
{
|
||||
U32 d1,d2;
|
||||
U8 d3;
|
||||
I64 i,j,k,cnt=0,unlock_flags=0,num_hints=0;
|
||||
#assert NUM_BLKDEVS<=64
|
||||
Bool old_preempt;
|
||||
|
||||
if (_root) *_root=NULL;
|
||||
|
||||
if (pmt)
|
||||
ATARepExitAllApplications;
|
||||
if (hint_ata_disable)
|
||||
return 0;
|
||||
|
||||
old_preempt=Preempt(OFF);
|
||||
for (i=0;i<NUM_BLKDEVS;i++)
|
||||
if (sys_blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
|
||||
BEqu(&unlock_flags,i,
|
||||
BlkDevLock(&sys_blkdevs[i]));
|
||||
|
||||
if (!just_ide)
|
||||
for (k=0;k<256;k++) {
|
||||
i=-1;
|
||||
while (TRUE) {
|
||||
j=PCIClassFind(0x010100+k,++i);
|
||||
if (j<0)
|
||||
break;
|
||||
|
||||
"\nSubcode:0x%X Bus:0x%X Dev:0x%X Fun:0x%X\n",k,j.u8[2],j.u8[1],j.u8[0];
|
||||
cnt++;
|
||||
|
||||
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x10);
|
||||
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x14);
|
||||
d3=PCIReadU8(j.u8[2],j.u8[1],j.u8[0],0x3C);
|
||||
if (d1&1 && d2&1) {
|
||||
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
|
||||
} else {
|
||||
d1=0x1F0;
|
||||
d2=0x3F6;
|
||||
d3=14;
|
||||
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
|
||||
}
|
||||
d1=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x18);
|
||||
d2=PCIReadU32(j.u8[2],j.u8[1],j.u8[0],0x1C);
|
||||
if (d1&1 && d2&1) {
|
||||
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
|
||||
} else {
|
||||
d1=0x170;
|
||||
d2=0x376;
|
||||
d3=15;
|
||||
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cnt) {
|
||||
d1=0x1F0;
|
||||
d2=0x3F6;
|
||||
d3=14;
|
||||
ATARepEntry(d1,d2,0,d3,"Primary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Primary IDE",_root,&num_hints);
|
||||
|
||||
d1=0x170;
|
||||
d2=0x376;
|
||||
d3=15;
|
||||
ATARepEntry(d1,d2,0,d3,"Secondary IDE",_root,&num_hints);
|
||||
ATARepEntry(d1,d2,1,d3,"Secondary IDE",_root,&num_hints);
|
||||
}
|
||||
NewLine(2);
|
||||
for (i=0;i<NUM_BLKDEVS;i++)
|
||||
if (Bt(&unlock_flags,i))
|
||||
BlkDevUnlock(&sys_blkdevs[i]);
|
||||
Preempt(old_preempt);
|
||||
return num_hints;
|
||||
}
|
||||
|
||||
CATARep *ATAIDDrvs(CATARep *root,U8 _dft_drv,CATARep **_ata_drv,CATARep **_atapi_drv)
|
||||
{
|
||||
CATARep *result=NULL,*tempha=root,*ata_drv=NULL,*atapi_drv=NULL;
|
||||
CBlkDev *bdev;
|
||||
Bool was_silent=Silent(ON);
|
||||
try
|
||||
bdev=Drv2BlkDev(_dft_drv);
|
||||
catch {
|
||||
Fs->catch_except=TRUE;
|
||||
bdev=NULL;
|
||||
}
|
||||
Silent(was_silent);
|
||||
while (tempha) {
|
||||
if (!result && bdev && bdev->type==tempha->type) {
|
||||
if (bdev->type==BDT_ATAPI &&
|
||||
bdev->base0==tempha->base0 && bdev->unit==tempha->unit)
|
||||
result=atapi_drv=tempha;
|
||||
else if (bdev->type==BDT_ATA && bdev->base0==tempha->base0 &&
|
||||
bdev->base1==tempha->base1 && bdev->unit==tempha->unit)
|
||||
result=ata_drv=tempha;
|
||||
}
|
||||
if (!result || result->type!=tempha->type) {
|
||||
if (tempha->type==BDT_ATA) {
|
||||
if (!ata_drv || tempha->unit<ata_drv->unit ||
|
||||
tempha->unit==ata_drv->unit && tempha->num<ata_drv->num)
|
||||
ata_drv=tempha;
|
||||
} else if (tempha->type==BDT_ATAPI) {
|
||||
if (!atapi_drv || tempha->unit<atapi_drv->unit ||
|
||||
tempha->unit==atapi_drv->unit && tempha->num<atapi_drv->num)
|
||||
atapi_drv=tempha;
|
||||
}
|
||||
}
|
||||
tempha=tempha->next;
|
||||
}
|
||||
if (_ata_drv) *_ata_drv =ata_drv;
|
||||
if (_atapi_drv) *_atapi_drv=atapi_drv;
|
||||
return result;
|
||||
}
|
||||
|
||||
CBlkDev *ATAMount(U8 first_drv_let,I64 type,I64 base0,I64 base1,I64 unit)
|
||||
{
|
||||
CBlkDev *result;
|
||||
if (0<=first_drv_let-'A'<NUM_PRTS && (type==BDT_ATA || type==BDT_ATAPI) &&
|
||||
0<=unit<=1) {
|
||||
result=BlkDevNextFree(first_drv_let,type);
|
||||
result->unit=unit;
|
||||
result->base0=base0;
|
||||
result->base1=base1;
|
||||
if (BlkDevAdd(result,FALSE,FALSE))
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
I64 AutoMountIDE()
|
||||
{
|
||||
I64 result=0;
|
||||
CATARep *root=NULL,*ata_drv=NULL,*atapi_drv=NULL,*tempha;
|
||||
ATARep(FALSE,TRUE,&root);
|
||||
ATAIDDrvs(root,dft_drv,&ata_drv,&atapi_drv);
|
||||
if (ata_drv && ATAMount(sys_first_hd_drv_let,BDT_ATA,
|
||||
ata_drv->base0,ata_drv->base1,ata_drv->unit))
|
||||
result++;
|
||||
if (atapi_drv && ATAMount(sys_first_cd_drv_let,BDT_ATAPI,
|
||||
atapi_drv->base0,atapi_drv->base1,atapi_drv->unit))
|
||||
result++;
|
||||
tempha=root;
|
||||
while (tempha) {
|
||||
if (tempha!=ata_drv && tempha!=atapi_drv) {
|
||||
if (tempha->type==BDT_ATA && ATAMount(sys_first_hd_drv_let,BDT_ATA,
|
||||
tempha->base0,tempha->base1,tempha->unit))
|
||||
result++;
|
||||
else if (tempha->type==BDT_ATAPI && ATAMount(sys_first_cd_drv_let,BDT_ATAPI,
|
||||
tempha->base0,tempha->base1,tempha->unit))
|
||||
result++;
|
||||
}
|
||||
tempha=tempha->next;
|
||||
}
|
||||
LinkedLstDel(root);
|
||||
sys_auto_mount_ide_cnt=result;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,318 @@
|
||||
U0 SetBlkDevLockFwding(CBlkDev *bdev)
|
||||
{
|
||||
CBlkDev *bdev1;
|
||||
I64 i;
|
||||
switch (bdev->type) {
|
||||
case BDT_RAM:
|
||||
break;
|
||||
case BDT_ATA:
|
||||
case BDT_ATAPI:
|
||||
for (i=0;i<NUM_BLKDEVS;i++) {
|
||||
bdev1=&sys_blkdevs[i];
|
||||
if (bdev1->bd_signature==BD_SIGNATURE_VAL && bdev!=bdev1 &&
|
||||
(bdev1->type==BDT_ATAPI || bdev1->type==BDT_ATA) &&
|
||||
bdev1->base0==bdev->base0) {
|
||||
bdev->lock_fwding=bdev1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
I64 BlkDevAdd(CBlkDev *bdev,Bool one_prt,Bool make_free)
|
||||
{
|
||||
I64 i,j,ext_base,offset,result=0;
|
||||
CPrt *p;
|
||||
CBootStruct br;
|
||||
CMasterBoot mbr;
|
||||
|
||||
bdev->bd_signature=BD_SIGNATURE_VAL;
|
||||
if (make_free)
|
||||
p=PrtMakeFree(bdev->first_drv_let+result);
|
||||
else
|
||||
p=PrtNextFree(bdev->first_drv_let);
|
||||
p->bdev=bdev;
|
||||
p->size=bdev->max_blk+1;
|
||||
switch (bdev->type) {
|
||||
case BDT_RAM:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
p->type=PT_NATIVE;
|
||||
p->rblks=&RAMRBlks;
|
||||
p->wblks=&RAMWBlks;
|
||||
//This is to force creation of a RAM
|
||||
//drive during boot, so it is probably
|
||||
//MAlloced to the same addr and can
|
||||
//be assumed to be already formatted.
|
||||
//If this line is removed, RAM Drives
|
||||
//will be allocated on a just-in-time
|
||||
//basis.
|
||||
if (BlkDevInit(bdev))
|
||||
result++;
|
||||
else
|
||||
p->pt_signature=0;
|
||||
break;
|
||||
case BDT_ATA:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL; //Temporarily validate
|
||||
if (!BlkDevInit(bdev))
|
||||
p->pt_signature=0; //Revoke validation
|
||||
else {
|
||||
p->pt_signature=0; //Revoke validation
|
||||
if (one_prt) {
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
p->type=PT_NATIVE;
|
||||
p->rblks=&ATARBlks;
|
||||
p->wblks=&ATAWBlks;
|
||||
p->size=bdev->max_blk+1;
|
||||
//The following read is a test read.
|
||||
//if it hangs, the drive is not supported.
|
||||
ATAReadBlks(bdev,&mbr,0,1);
|
||||
break;
|
||||
}
|
||||
offset=0;
|
||||
ext_base=INVALID_CLUSTER;
|
||||
while (TRUE) {
|
||||
ATAReadBlks(bdev,&mbr,offset,1);
|
||||
if (mbr.signature!=0xAA55)
|
||||
break;
|
||||
j=-1;
|
||||
for (i=0;i<4;i++) {
|
||||
if (mbr.p[i].type) {
|
||||
if (make_free)
|
||||
p=PrtMakeFree(bdev->first_drv_let+result);
|
||||
else
|
||||
p=PrtNextFree(bdev->first_drv_let);
|
||||
p->bdev=bdev;
|
||||
p->rblks=&ATARBlks;
|
||||
p->wblks=&ATAWBlks;
|
||||
p->offset=mbr.p[i].offset+offset;
|
||||
p->size =mbr.p[i].size;
|
||||
switch (mbr.p[i].type) {
|
||||
case MBR_PT_NATIVE:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
p->type=PT_NATIVE;
|
||||
NativeFSPrtInit(p);
|
||||
break;
|
||||
case MBR_PT_FAT32a:
|
||||
case MBR_PT_FAT32b:
|
||||
case MBR_PT_FAT32c:
|
||||
case MBR_PT_FAT32d:
|
||||
case MBR_PT_FAT32e:
|
||||
case MBR_PT_FAT32f:
|
||||
ATAReadBlks(bdev,&br,p->offset,1);
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
if (br.signature==MBR_PT_NATIVE) {
|
||||
p->type=PT_NATIVE;
|
||||
NativeFSPrtInit(p);
|
||||
} else {
|
||||
p->type=PT_FAT32;
|
||||
FAT32PrtInit(p);
|
||||
}
|
||||
break;
|
||||
case MBR_PT_NTFS:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
p->type=PT_NTFS;
|
||||
break;
|
||||
case 5:
|
||||
case 15:
|
||||
j=i;
|
||||
break;
|
||||
default:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
p->type=PT_UNKNOWN;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (j<0)
|
||||
break;
|
||||
if (!mbr.p[j].offset)
|
||||
break;
|
||||
if (ext_base==INVALID_CLUSTER) {
|
||||
offset=mbr.p[j].offset;
|
||||
ext_base=offset;
|
||||
} else
|
||||
offset=mbr.p[j].offset+ext_base;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case BDT_ATAPI:
|
||||
p->pt_signature=PRT_SIGNATURE_VAL;
|
||||
result++;
|
||||
p->type=PT_ISO9660; //Start with this
|
||||
p->rblks=&ATARBlks;
|
||||
p->wblks=&ATAWBlks;
|
||||
p->size =0;
|
||||
break;
|
||||
}
|
||||
if (result)
|
||||
SetBlkDevLockFwding(bdev);
|
||||
else
|
||||
MemSet(bdev,0,sizeof(CBlkDev));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Bool DrvEnable(U8 drv_let,Bool val)
|
||||
{//This can be used to unmount a drive or remount,
|
||||
//but not mount the first time.
|
||||
CPrt *p;
|
||||
Bool result=FALSE;
|
||||
try {
|
||||
p=Drv2Prt(drv_let);
|
||||
result=!LBEqu(&p->type,PTf_DISABLE,!val);
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
CATARep *ATARepFind(CATARep *root,I64 num)
|
||||
{
|
||||
CATARep *tempha=root;
|
||||
while (tempha) {
|
||||
if (tempha->num==num)
|
||||
return tempha;
|
||||
tempha=tempha->next;
|
||||
}
|
||||
return tempha;
|
||||
}
|
||||
|
||||
U0 Mount(Bool repartition=FALSE)
|
||||
{
|
||||
CBlkDev *bdev;
|
||||
I64 first_prt_num,type,unit,num_hints;
|
||||
U8 blks_buf[32],base0_buf[128],base1_buf[128];
|
||||
Bool add;
|
||||
CATARep *root,*tempha;
|
||||
|
||||
do {
|
||||
PrtRep;
|
||||
PutDefine("ST_MOUNT_FIRST_DRV_LET");
|
||||
first_prt_num=ToUpper(GetChar)-'A';
|
||||
NewLine;
|
||||
if (0<=first_prt_num<NUM_PRTS) {
|
||||
PutDefine("ST_MOUNT_DRV_TYPE");
|
||||
type=GetChar-'0';
|
||||
NewLine;
|
||||
|
||||
unit=0;
|
||||
if (type==BDT_ATA || type==BDT_ATAPI) {
|
||||
num_hints=ATARep(TRUE,,&root);
|
||||
do {
|
||||
if (num_hints)
|
||||
PutDefine("ST_MOUNT_BASE0_HINT");
|
||||
else
|
||||
PutDefine("ST_MOUNT_BASE0");
|
||||
GetS(base0_buf,128);
|
||||
} while (!A2I(base0_buf));
|
||||
if (1<=A2I(base0_buf)<=num_hints) {
|
||||
tempha=ATARepFind(root,A2I(base0_buf));
|
||||
SPrintF(base0_buf,"0x%X",tempha->base0);
|
||||
SPrintF(base1_buf,"0x%X",tempha->base1);
|
||||
unit=tempha->unit;
|
||||
} else {
|
||||
if (type==BDT_ATAPI)
|
||||
StrCpy(base1_buf,"0");
|
||||
else
|
||||
do {
|
||||
PutDefine("ST_MOUNT_BASE1");
|
||||
GetS(base1_buf,128);
|
||||
} while (!A2I(base1_buf));
|
||||
do {
|
||||
PutDefine("ST_MOUNT_UNIT");
|
||||
unit=GetChar-'0';
|
||||
} while (!(0<=unit<=1));
|
||||
NewLine;
|
||||
}
|
||||
LinkedLstDel(root);
|
||||
}
|
||||
if (type==BDT_RAM) {
|
||||
PutDefine("ST_MOUNT_BLKS");
|
||||
GetS(blks_buf,32);
|
||||
}
|
||||
|
||||
if (BDT_NULL<type<BDT_NUM_TYPES && 0<=unit<=1) {
|
||||
bdev=BlkDevNextFree(first_prt_num+'A',type);
|
||||
bdev->unit=unit;
|
||||
if (type==BDT_RAM)
|
||||
bdev->max_blk=A2I(blks_buf)-1;
|
||||
if (type==BDT_ATA ||
|
||||
type==BDT_ATAPI) {
|
||||
bdev->base0=A2I(base0_buf);
|
||||
bdev->base1=A2I(base1_buf);
|
||||
}
|
||||
add=TRUE;
|
||||
if (type==BDT_ATA && repartition) {
|
||||
PutDefine("ST_MOUNT_FMT_WHOLE_DRV");
|
||||
if (YorN) {
|
||||
if (!BlkDevAdd(bdev,TRUE,TRUE))
|
||||
PutDefine("ST_FAILED");
|
||||
else
|
||||
CallExtStr("PrtDsk",bdev->first_drv_let);
|
||||
add=FALSE;
|
||||
}
|
||||
}
|
||||
if (add && !BlkDevAdd(bdev,FALSE,TRUE))
|
||||
PutDefine("ST_FAILED");
|
||||
} else
|
||||
PutDefine("ST_FAILED");
|
||||
}
|
||||
} while (0<=first_prt_num<NUM_PRTS);
|
||||
}
|
||||
|
||||
I64 SysPmtI64()
|
||||
{
|
||||
U8 st[136];
|
||||
StrCpy(st,"0x");
|
||||
GetS(st+2,134,FALSE);
|
||||
return A2I(st);
|
||||
}
|
||||
|
||||
Bool PmtBaseUnit(CBlkDev *bdev)
|
||||
{
|
||||
I64 ch;
|
||||
Bool probe;
|
||||
" TempleOS\n\n\n";
|
||||
#exe {
|
||||
if (kernel_cfg->opts[CFG_DONT_PROBE])
|
||||
StreamPutS("probe=FALSE;");
|
||||
else
|
||||
StreamPutS("probe=TRUE;");
|
||||
};
|
||||
if (!probe || !BootCdProbeAll(bdev)) {
|
||||
PutDefine("ST_CDROM_PORTS_PMT1");
|
||||
bdev->base0=SysPmtI64;
|
||||
bdev->base1=0;
|
||||
"\nUnit (0 or 1): ";
|
||||
do ch=GetChar(NULL,FALSE);
|
||||
while (!('0'<=ch<='1'));
|
||||
'' ch;
|
||||
bdev->unit=ch-'0';
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 BlkDevsInitAll()
|
||||
{
|
||||
CBlkDev *bdev;
|
||||
I64 i;
|
||||
sys_blkdevs=CAlloc(sizeof(CBlkDev)*NUM_BLKDEVS);
|
||||
sys_prts=CAlloc(sizeof(CPrt)*NUM_PRTS);
|
||||
for (i=0;i<NUM_PRTS;i++)
|
||||
drv_to_prt[i]=&sys_prts[i];
|
||||
sys_raw_dc_col=0;
|
||||
#exe {
|
||||
if (kernel_cfg->opts[CFG_AUTO_MOUNT_IDE])
|
||||
StreamPutS("AutoMountIDE;");
|
||||
StreamPutS("#exe {OptOff(OPTf_WARN_PAREN);}");
|
||||
StreamDoc(kernel_cfg->add_dev);
|
||||
StreamPutS("#exe {OptOn(OPTf_WARN_PAREN);}");
|
||||
};
|
||||
PrtRep;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
I64 FSize(CFile *f)
|
||||
{
|
||||
if (f)
|
||||
return f->de.size;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
CFile *FOpen(U8 *filename,U8 *flags,I64 cnt=0)
|
||||
{ //allows flags "r","w","w+". Include a "c" for contiguous.
|
||||
CFile *f=CAlloc(sizeof(CFile));
|
||||
CFileAccess *fa;
|
||||
U8 *full_name;
|
||||
Bool contiguous=StrOcc(flags,'c');
|
||||
|
||||
f->cluster=INVALID_CLUSTER;
|
||||
f->fblk_num=0;
|
||||
if (cnt>0)
|
||||
f->max_blk=cnt-1;
|
||||
else
|
||||
f->max_blk=MAX_I64;
|
||||
f->file_cluster_num=INVALID_CLUSTER;
|
||||
full_name=FileNameAbs(filename);
|
||||
f->p=Drv2Prt(*full_name);
|
||||
if (f->p->type==PT_NATIVE)
|
||||
contiguous=TRUE;
|
||||
if (contiguous) {
|
||||
f->flags|=FF_CONTIGUOUS;
|
||||
if (f->p->type!=PT_NATIVE) {
|
||||
if (!(FileAttr(filename) & _ATTR_CONTIGUOUS))
|
||||
throw(EXCEPT_FILE,2);
|
||||
}
|
||||
}
|
||||
f->cluster_buf=CAlloc(f->p->spc<<BLK_SIZE_BITS);
|
||||
if (StrOcc(flags,'w')) {
|
||||
f->flags=f->flags|FF_WRITE|FF_NEEDS_WRITE;
|
||||
if (StrOcc(flags,'+')) {
|
||||
if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
|
||||
Free(full_name);
|
||||
if (contiguous)
|
||||
f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
|
||||
return f;
|
||||
}
|
||||
} else
|
||||
Del(full_name,FALSE);
|
||||
f->de.full_name=full_name;
|
||||
f->flags|=FF_NEW_FILE;
|
||||
if (fa=FileAccessNew(full_name)) {
|
||||
StrCpy(f->de.name,fa->mask);
|
||||
if (cnt>0) { //We pre-alloc the whole thing.
|
||||
f->de.cluster=ClusersAlloc(f->p,0,
|
||||
(cnt+f->p->spc-1)/f->p->spc,contiguous);
|
||||
f->de.expanded_size=f->de.size=cnt<<BLK_SIZE_BITS;
|
||||
CDirNew(fa->p,Fs->cur_dir,&f->de,TRUE);
|
||||
f->flags&=~FF_NEW_FILE;
|
||||
}
|
||||
FileAccessDel(fa);
|
||||
if (!contiguous || cnt>0)
|
||||
return f;
|
||||
}
|
||||
} else {
|
||||
if (FileFind(full_name,&f->de,FUF_JUST_FILES)) {
|
||||
Free(full_name);
|
||||
f->max_blk=(FSize(f)+BLK_SIZE-1)>>BLK_SIZE_BITS-1;
|
||||
return f;
|
||||
}
|
||||
}
|
||||
Free(f->cluster_buf);
|
||||
Free(full_name);
|
||||
Free(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 FClose(CFile *f)
|
||||
{
|
||||
CFileAccess *fa;
|
||||
if (f) {
|
||||
if (f->flags & FF_BUF_DIRTY) {
|
||||
WClusters(f->p,f->cluster_buf,f->cluster,1);
|
||||
f->flags&=~FF_BUF_DIRTY;
|
||||
}
|
||||
if (f->flags & FF_NEEDS_WRITE) {
|
||||
if (fa=FileAccessNew(f->de.full_name)) {
|
||||
if (!(f->flags & FF_USE_OLD_DATETIME))
|
||||
f->de.datetime=GetCurTimeCDate;
|
||||
if (f->flags & FF_NEW_FILE)
|
||||
CDirNew(fa->p,Fs->cur_dir,&f->de,TRUE);
|
||||
else
|
||||
CDirNew(fa->p,Fs->cur_dir,&f->de,FALSE);
|
||||
FileAccessDel(fa);
|
||||
} else
|
||||
throw(EXCEPT_FILE,1);
|
||||
}
|
||||
Free(f->cluster_buf);
|
||||
Free(f->de.full_name);
|
||||
Free(f);
|
||||
}
|
||||
}
|
||||
|
||||
I64 FSetCluster(CFile *f,I64 c,I64 blk,Bool read)
|
||||
{
|
||||
CPrt *p=f->p;
|
||||
I64 i;
|
||||
if (f->cluster!=c) {
|
||||
if (f->flags & FF_BUF_DIRTY) {
|
||||
i=p->spc;
|
||||
if (f->max_blk!=MAX_I64) {
|
||||
i=f->max_blk+1-f->file_cluster_num*p->spc;
|
||||
if (i>p->spc)
|
||||
i=p->spc;
|
||||
}
|
||||
WClustersBlks(p,f->cluster_buf,f->cluster,i);
|
||||
f->flags=f->flags & ~FF_BUF_DIRTY;
|
||||
}
|
||||
f->cluster=c;
|
||||
f->file_cluster_num=blk/p->spc;
|
||||
if (read) {
|
||||
i=p->spc;
|
||||
if (f->max_blk!=MAX_I64) {
|
||||
i=f->max_blk+1-f->file_cluster_num*p->spc;
|
||||
if (i>p->spc)
|
||||
i=p->spc;
|
||||
}
|
||||
c=RClustersBlks(p,f->cluster_buf,c,i);
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
Bool FRBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
|
||||
{
|
||||
CPrt *p=f->p;
|
||||
I64 spc=p->spc,i,j,c=f->de.cluster;
|
||||
if (!f || !p) return FALSE;
|
||||
if (blk==FFB_NEXT_BLK)
|
||||
blk=f->fblk_num;
|
||||
if (blk+cnt-1>f->max_blk)
|
||||
return FALSE;
|
||||
if (cnt<=0) return TRUE;
|
||||
|
||||
if (f->flags & FF_CONTIGUOUS) {
|
||||
RBlks(p,buf,Cluster2Blk(p,c)+blk,cnt);
|
||||
blk+=cnt;
|
||||
} else {
|
||||
i=blk/spc;
|
||||
if (0<=f->file_cluster_num<=i) {
|
||||
c=f->cluster;
|
||||
i-=f->file_cluster_num;
|
||||
}
|
||||
if (i>0)
|
||||
c=ClusterNumNext(p,c,i);
|
||||
|
||||
if (i=blk%spc) {
|
||||
c=FSetCluster(f,c,blk,TRUE);
|
||||
j= cnt<spc-i ? cnt:spc-i;
|
||||
MemCpy(buf,f->cluster_buf+i<<BLK_SIZE_BITS,j<<BLK_SIZE_BITS);
|
||||
buf+=j<<BLK_SIZE_BITS;
|
||||
cnt-=j;
|
||||
blk+=j;
|
||||
}
|
||||
while (cnt>=spc) {
|
||||
c=FSetCluster(f,c,blk,TRUE);
|
||||
MemCpy(buf,f->cluster_buf,spc<<BLK_SIZE_BITS);
|
||||
buf+=spc<<BLK_SIZE_BITS;
|
||||
cnt-=spc;
|
||||
blk+=spc;
|
||||
}
|
||||
if (cnt>0) {
|
||||
c=FSetCluster(f,c,blk,TRUE);
|
||||
MemCpy(buf,f->cluster_buf,cnt<<BLK_SIZE_BITS);
|
||||
buf+=cnt<<BLK_SIZE_BITS;
|
||||
blk+=cnt;
|
||||
}
|
||||
}
|
||||
f->fblk_num=blk;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool FWBlks(CFile *f,U8 *buf,I64 blk=FFB_NEXT_BLK,I64 cnt=1)
|
||||
{
|
||||
CPrt *p=f->p;
|
||||
I64 spc=p->spc,i,j,c=f->de.cluster,c1;
|
||||
if (!f || !p) return FALSE;
|
||||
if (blk==FFB_NEXT_BLK)
|
||||
blk=f->fblk_num;
|
||||
if (blk+cnt-1>f->max_blk)
|
||||
return FALSE;
|
||||
if (!(f->flags & FF_WRITE))
|
||||
return FALSE;
|
||||
if (cnt<=0) return TRUE;
|
||||
if (f->flags & FF_CONTIGUOUS) {
|
||||
WBlks(p,buf,Cluster2Blk(p,c)+blk,cnt);
|
||||
blk+=cnt;
|
||||
} else {
|
||||
if (!c) {
|
||||
c=ClusersAlloc(p,0,1,FALSE);
|
||||
f->file_cluster_num=0;
|
||||
f->cluster=c;
|
||||
f->de.cluster=c;
|
||||
f->flags|=FF_NEEDS_WRITE|FF_NEW_FILE;
|
||||
}
|
||||
i=blk/spc;
|
||||
if (0<=f->file_cluster_num<=i) {
|
||||
c=f->cluster;
|
||||
i-=f->file_cluster_num;
|
||||
}
|
||||
while (i>0) {
|
||||
c1=c;
|
||||
c=ClusterNumNext(p,c1,1);
|
||||
if (c==INVALID_CLUSTER) {
|
||||
c=ClusersAlloc(p,c1,i,FALSE);
|
||||
if (i>1)
|
||||
c=ClusterNumNext(p,c,i-1);
|
||||
break;
|
||||
} else
|
||||
i--;
|
||||
}
|
||||
|
||||
if (i=blk%spc) {
|
||||
FSetCluster(f,c,blk,TRUE);
|
||||
j=cnt<spc-i ? cnt:spc-i;
|
||||
MemCpy(f->cluster_buf+BLK_SIZE*i,buf,j<<BLK_SIZE_BITS);
|
||||
f->flags|=FF_BUF_DIRTY;
|
||||
buf+=j<<BLK_SIZE_BITS;
|
||||
cnt-=j;
|
||||
blk+=j;
|
||||
if (cnt>0) {
|
||||
c1=c;
|
||||
c=ClusterNumNext(p,c1,1);
|
||||
if (c==INVALID_CLUSTER)
|
||||
c=ClusersAlloc(p,c1,1,FALSE);
|
||||
}
|
||||
}
|
||||
while (cnt>=spc) {
|
||||
FSetCluster(f,c,blk,FALSE);
|
||||
MemCpy(f->cluster_buf,buf,spc<<BLK_SIZE_BITS);
|
||||
f->flags|=FF_BUF_DIRTY;
|
||||
buf+=spc<<BLK_SIZE_BITS;
|
||||
cnt-=spc;
|
||||
blk+=spc;
|
||||
if (cnt>0) {
|
||||
c1=c;
|
||||
c=ClusterNumNext(p,c1,1);
|
||||
if (c==INVALID_CLUSTER)
|
||||
c=ClusersAlloc(p,c1,1,FALSE);
|
||||
}
|
||||
}
|
||||
if (cnt>0) {
|
||||
FSetCluster(f,c,blk,TRUE);
|
||||
MemCpy(f->cluster_buf,buf,cnt<<BLK_SIZE_BITS);
|
||||
f->flags|=FF_BUF_DIRTY;
|
||||
buf+=cnt<<BLK_SIZE_BITS;
|
||||
blk+=cnt;
|
||||
}
|
||||
if (f->de.size<blk<<BLK_SIZE_BITS)
|
||||
f->de.size=blk<<BLK_SIZE_BITS;
|
||||
if (f->de.expanded_size<blk<<BLK_SIZE_BITS)
|
||||
f->de.expanded_size=blk<<BLK_SIZE_BITS;
|
||||
}
|
||||
f->fblk_num=blk;
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
U0 DskCacheInit(I64 size_in_U8s)
|
||||
{
|
||||
CCacheBlk *tempc;
|
||||
I64 i,cnt;
|
||||
|
||||
while (LBts(&sys_semas[SYS_SEMA_DSK_CACHE],0))
|
||||
Yield;
|
||||
Free(sys_dsk_cache_ctrl);
|
||||
Free(sys_dsk_cache_base);
|
||||
Free(sys_dsk_cache_hash_table);
|
||||
if (size_in_U8s<0x2000) {
|
||||
sys_dsk_cache_ctrl=NULL;
|
||||
sys_dsk_cache_base=NULL;
|
||||
sys_dsk_cache_hash_table=NULL;
|
||||
} else {
|
||||
sys_dsk_cache_ctrl=ACAlloc(offset(CCacheBlk.body));
|
||||
sys_dsk_cache_base=AMAlloc(size_in_U8s);
|
||||
QueInit(sys_dsk_cache_ctrl);
|
||||
|
||||
cnt=MSize(sys_dsk_cache_base)/sizeof(CCacheBlk);
|
||||
sys_dsk_cache_size=cnt*BLK_SIZE;
|
||||
for (i=0;i<cnt;i++) {
|
||||
tempc=sys_dsk_cache_base+i;
|
||||
QueIns(tempc,sys_dsk_cache_ctrl->last_lru);
|
||||
tempc->next_hash=tempc->last_hash=tempc;
|
||||
tempc->p=NULL;
|
||||
tempc->blk=0;
|
||||
}
|
||||
|
||||
sys_dsk_cache_hash_table=AMAlloc(DSK_CACHE_HASH_SIZE*sizeof(U8 *)*2);
|
||||
for (i=0;i<DSK_CACHE_HASH_SIZE;i++) {
|
||||
tempc=sys_dsk_cache_hash_table(U8 *)+i*sizeof(U8 *)*2-offset(CCacheBlk.next_hash);
|
||||
tempc->next_hash=tempc->last_hash=tempc;
|
||||
}
|
||||
}
|
||||
LBtr(&sys_semas[SYS_SEMA_DSK_CACHE],0);
|
||||
}
|
||||
|
||||
I64 DskCacheHash(I64 blk)
|
||||
{
|
||||
I64 i=blk & (DSK_CACHE_HASH_SIZE-1);
|
||||
return sys_dsk_cache_hash_table(U8 *)+i<<4-offset(CCacheBlk.next_hash);
|
||||
}
|
||||
|
||||
U0 DskCacheQueRem(CCacheBlk *tempc)
|
||||
{
|
||||
QueRem(tempc);
|
||||
tempc->next_hash->last_hash=tempc->last_hash;
|
||||
tempc->last_hash->next_hash=tempc->next_hash;
|
||||
}
|
||||
|
||||
U0 DskCacheQueIns(CCacheBlk *tempc)
|
||||
{
|
||||
CCacheBlk *temp_n,*temp_l;
|
||||
QueIns(tempc,sys_dsk_cache_ctrl->last_lru);
|
||||
temp_l=DskCacheHash(tempc->blk);
|
||||
temp_n=temp_l->next_hash;
|
||||
tempc->last_hash=temp_l;
|
||||
tempc->next_hash=temp_n;
|
||||
temp_l->next_hash=temp_n->last_hash=tempc;
|
||||
}
|
||||
|
||||
CCacheBlk *DskCacheFind(CPrt *p,I64 blk)
|
||||
{
|
||||
CCacheBlk *tempc,*tempc1=DskCacheHash(blk);
|
||||
tempc=tempc1->next_hash;
|
||||
while (tempc!=tempc1) {
|
||||
if (tempc->p==p && tempc->blk==blk)
|
||||
return tempc;
|
||||
tempc=tempc->next_hash;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 DskCacheAdd(CPrt *p,U8 *buf, I64 blk, I64 cnt)
|
||||
{
|
||||
CCacheBlk *tempc;
|
||||
if (sys_dsk_cache_base) {
|
||||
while (LBts(&sys_semas[SYS_SEMA_DSK_CACHE],0))
|
||||
Yield;
|
||||
while (cnt-->0) {
|
||||
if (!(tempc=DskCacheFind(p,blk)))
|
||||
tempc=sys_dsk_cache_ctrl->next_lru;
|
||||
DskCacheQueRem(tempc);
|
||||
MemCpy(&tempc->body,buf,BLK_SIZE);
|
||||
tempc->p=p;
|
||||
tempc->blk=blk;
|
||||
DskCacheQueIns(tempc);
|
||||
blk++;
|
||||
buf+=BLK_SIZE;
|
||||
}
|
||||
LBtr(&sys_semas[SYS_SEMA_DSK_CACHE],0);
|
||||
}
|
||||
}
|
||||
|
||||
U0 DskCacheInvalidate2(CPrt *p)
|
||||
{
|
||||
CCacheBlk *tempc,*tempc1;
|
||||
if (sys_dsk_cache_base) {
|
||||
while (LBts(&sys_semas[SYS_SEMA_DSK_CACHE],0))
|
||||
Yield;
|
||||
tempc=sys_dsk_cache_ctrl->last_lru;
|
||||
while (tempc!=sys_dsk_cache_ctrl) {
|
||||
tempc1=tempc->last_lru;
|
||||
if (tempc->p==p) {
|
||||
DskCacheQueRem(tempc);
|
||||
tempc->p=NULL;
|
||||
tempc->blk=0;
|
||||
tempc->next_hash=tempc->last_hash=tempc;
|
||||
QueIns(tempc,sys_dsk_cache_ctrl->last_lru);
|
||||
}
|
||||
tempc=tempc1;
|
||||
}
|
||||
LBtr(&sys_semas[SYS_SEMA_DSK_CACHE],0);
|
||||
}
|
||||
}
|
||||
|
||||
U0 RCache(CPrt *p,U8 **_buf, I64 *_blk, I64 *_cnt)
|
||||
{
|
||||
CCacheBlk *tempc;
|
||||
if (sys_dsk_cache_base) {
|
||||
while (LBts(&sys_semas[SYS_SEMA_DSK_CACHE],0))
|
||||
Yield;
|
||||
//fetch leading blks from cache
|
||||
while (*_cnt>0) {
|
||||
if (tempc=DskCacheFind(p,*_blk)) {
|
||||
MemCpy(*_buf,&tempc->body,BLK_SIZE);
|
||||
*_cnt-=1;
|
||||
*_buf+=BLK_SIZE;
|
||||
*_blk+=1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
//fetch trailing blks from cache
|
||||
while (*_cnt>0) {
|
||||
if (tempc=DskCacheFind(p,*_blk+*_cnt-1)) {
|
||||
MemCpy(*_buf+(*_cnt-1)<<BLK_SIZE_BITS,&tempc->body,BLK_SIZE);
|
||||
*_cnt-=1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
LBtr(&sys_semas[SYS_SEMA_DSK_CACHE],0);
|
||||
}
|
||||
}
|
||||
|
||||
Bool RAMRBlks(CPrt *p,U8 *buf,I64 blk,I64 cnt)
|
||||
{
|
||||
CBlkDev *bdev=p->bdev;
|
||||
BlkDevChk(bdev);
|
||||
MemCpy(buf,bdev->RAM_dsk+blk<<BLK_SIZE_BITS,cnt<<BLK_SIZE_BITS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool RAMWBlks(CPrt *p,U8 *buf,I64 blk,I64 cnt)
|
||||
{
|
||||
CBlkDev *bdev=p->bdev;
|
||||
BlkDevChk(bdev);
|
||||
MemCpy(bdev->RAM_dsk+blk<<BLK_SIZE_BITS,buf,cnt<<BLK_SIZE_BITS);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -0,0 +1,268 @@
|
||||
Bool CDirNew(CPrt *p,U8 *cur_dir,CDirEntry *tempm,Bool free_old_chain=TRUE)
|
||||
{
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
return NativeFSDirNew(p,cur_dir,tempm,free_old_chain);
|
||||
case PT_FAT32:
|
||||
return FAT32DirNew(p,cur_dir,tempm,free_old_chain);
|
||||
case PT_ISO9660:
|
||||
PutDefineErr("ST_NOT_WRITABLE");
|
||||
return FALSE;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 CDirEntryDel(CDirEntry *tempm)
|
||||
{ //Doesn't Free user_data
|
||||
if (tempm) {
|
||||
Free(tempm->full_name);
|
||||
Free(tempm);
|
||||
}
|
||||
}
|
||||
|
||||
U0 CDirEntryDel2(CDirEntry *tempm)
|
||||
{ //Frees user_data
|
||||
if (tempm) {
|
||||
Free(tempm->full_name);
|
||||
Free(tempm->user_data);
|
||||
Free(tempm);
|
||||
}
|
||||
}
|
||||
|
||||
U0 CDirLstDel(CDirEntry *tempm)
|
||||
{ //Doesn't Free user_data
|
||||
CDirEntry *tempm2;
|
||||
while (tempm) {
|
||||
tempm2=tempm->next;
|
||||
if (tempm->sub)
|
||||
CDirLstDel(tempm->sub);
|
||||
CDirEntryDel(tempm);
|
||||
tempm=tempm2;
|
||||
}
|
||||
}
|
||||
|
||||
U0 CDirLstDel2(CDirEntry *tempm)
|
||||
{ //Frees user_data
|
||||
CDirEntry *tempm2;
|
||||
while (tempm) {
|
||||
tempm2=tempm->next;
|
||||
if (tempm->sub)
|
||||
CDirLstDel2(tempm->sub);
|
||||
CDirEntryDel2(tempm);
|
||||
tempm=tempm2;
|
||||
}
|
||||
}
|
||||
|
||||
I64 CDirEntryCompare(CDirEntry *e1,CDirEntry *e2)
|
||||
{
|
||||
U8 buf1[CDIR_FILENAME_LEN],buf2[CDIR_FILENAME_LEN],
|
||||
buf3[CDIR_FILENAME_LEN],buf4[CDIR_FILENAME_LEN];
|
||||
I64 d1=0,d2=0;
|
||||
if (e1->attr & _ATTR_DIR)
|
||||
d1=1;
|
||||
if (e2->attr & _ATTR_DIR)
|
||||
d2=1;
|
||||
if (d1!=d2)
|
||||
return d2-d1;
|
||||
else {
|
||||
StrCpy(buf1,e1->name);
|
||||
StrCpy(buf2,e2->name);
|
||||
FileExtRem(buf1,buf3);
|
||||
FileExtRem(buf2,buf4);
|
||||
if (d1=StrCmp(buf3,buf4))
|
||||
return d1;
|
||||
return StrCmp(buf1,buf2);
|
||||
}
|
||||
}
|
||||
|
||||
U0 CDirFilesSort(CDirEntry **_tempm)
|
||||
{
|
||||
I64 i,cnt=0;
|
||||
CDirEntry *tempm=*_tempm,*tempm1,**sort_buf;
|
||||
if (tempm) {
|
||||
tempm1=tempm;
|
||||
while (tempm1) {
|
||||
cnt++;
|
||||
tempm1=tempm1->next;
|
||||
}
|
||||
if (cnt>1) {
|
||||
sort_buf=MAlloc(cnt*sizeof(U8 *));
|
||||
i=0;
|
||||
tempm1=tempm;
|
||||
while (tempm1) {
|
||||
sort_buf[i++]=tempm1;
|
||||
tempm1=tempm1->next;
|
||||
}
|
||||
QSortI64(sort_buf,cnt,&CDirEntryCompare);
|
||||
tempm=sort_buf[0];
|
||||
*_tempm=tempm;
|
||||
for (i=0;i<cnt-1;i++) {
|
||||
tempm1=sort_buf[i];
|
||||
tempm1->next=sort_buf[i+1];
|
||||
}
|
||||
tempm1=sort_buf[i];
|
||||
tempm1->next=NULL;
|
||||
Free(sort_buf);
|
||||
|
||||
tempm1=tempm;
|
||||
while (tempm1) {
|
||||
if (tempm1->sub)
|
||||
CDirFilesSort(&tempm1->sub);
|
||||
tempm1=tempm1->next;
|
||||
}
|
||||
} else
|
||||
if (tempm->sub)
|
||||
CDirFilesSort(&tempm->sub);
|
||||
}
|
||||
}
|
||||
|
||||
CDirEntry *CDirFilesFlatten(CDirEntry *tempm,CDirEntry **_result,I64 fuf_flags)
|
||||
{ //returns last node
|
||||
CDirEntry *tempm1;
|
||||
Bool del;
|
||||
if (tempm)
|
||||
while (TRUE) {
|
||||
tempm1=tempm->next;
|
||||
if (!(tempm->attr&_ATTR_DIR)||!(fuf_flags&FUF_JUST_FILES)) {
|
||||
_result=*_result=tempm;
|
||||
del=FALSE;
|
||||
} else
|
||||
del=TRUE;
|
||||
if (tempm->sub) {
|
||||
_result=CDirFilesFlatten(tempm->sub,_result,fuf_flags);
|
||||
tempm->sub=NULL;
|
||||
}
|
||||
if (del)
|
||||
CDirEntryDel(tempm);
|
||||
if (tempm1)
|
||||
tempm=tempm1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
*_result=NULL;
|
||||
return _result;
|
||||
}
|
||||
|
||||
CDirEntry *SysFilesFind(U8 *files_find_mask,I64 fuf_flags)
|
||||
{
|
||||
CPrt *p=Fs->cur_prt;
|
||||
CDirEntry *result=NULL;
|
||||
PrtChk(p);
|
||||
switch (p->type) {
|
||||
case PT_NATIVE:
|
||||
result=NativeFSFilesFind(files_find_mask,fuf_flags);
|
||||
break;
|
||||
case PT_FAT32:
|
||||
result=FAT32FilesFind(files_find_mask,fuf_flags);
|
||||
break;
|
||||
case PT_ISO9660:
|
||||
result=ISO1FilesFind(files_find_mask,fuf_flags);
|
||||
break;
|
||||
default:
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
result=NULL;
|
||||
}
|
||||
if (result) {
|
||||
CDirFilesSort(&result);
|
||||
if (fuf_flags&(FUF_FLATTEN_TREE|FUF_JUST_FILES))
|
||||
CDirFilesFlatten(result,&result,fuf_flags);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 PutFileLink(U8 *filename,I64 line=0,Bool plain_text=FALSE)
|
||||
{
|
||||
U8 *buf;
|
||||
if (!filename) return;
|
||||
if (IsRaw) {
|
||||
if (line)
|
||||
"%s,%04d",filename,line;
|
||||
else
|
||||
"" filename;
|
||||
} else {
|
||||
buf=FileNameAbs(filename);
|
||||
if (plain_text) {
|
||||
if (line)
|
||||
"$$LK,\"%s,%04d\",\"PL:%s,%d\"$$",filename,line,buf,line;
|
||||
else
|
||||
"$$LK,\"%s\",\"PI:%s\"$$",filename,buf;
|
||||
} else {
|
||||
if (line)
|
||||
"$$LK,\"%s,%04d\",\"FL:%s,%d\"$$",filename,line,buf,line;
|
||||
else
|
||||
"$$LK,\"%s\",\"FI:%s\"$$",filename,buf;
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
U0 PutDirLink(U8 *dirname)
|
||||
{
|
||||
U8 *buf;
|
||||
if (!dirname) return;
|
||||
if (IsRaw)
|
||||
"" dirname;
|
||||
else {
|
||||
buf=DirNameAbs(dirname);
|
||||
"$$MA+A,\"%s\",\"Cd(\\\"%s\\\");Dir;\n\"$$",dirname,buf;
|
||||
Free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
U0 Dir2(U8 *files_find_mask,I64 fuf_flags,Bool full)
|
||||
{
|
||||
CDirEntry *tempm1=NULL,*tempm2;
|
||||
U8 *st;
|
||||
I64 csize=0xFFFF,esize=0xFFFF,c=0xFFFF;
|
||||
tempm1=SysFilesFind(files_find_mask,fuf_flags);
|
||||
|
||||
if (!(st=CurDir))
|
||||
PutDefine("ST_INVALID_DRV");
|
||||
else {
|
||||
if (tempm1) {
|
||||
//Find max columns
|
||||
tempm2=tempm1;
|
||||
while (tempm2) {
|
||||
if (tempm2->size>csize)
|
||||
csize=tempm2->size;
|
||||
if (tempm2->expanded_size>esize)
|
||||
esize=tempm2->expanded_size;
|
||||
if (tempm2->cluster>c)
|
||||
c=tempm2->cluster;
|
||||
tempm2=tempm2->next;
|
||||
}
|
||||
csize=Bsr(csize)/4+1;
|
||||
esize=Bsr(esize)/4+1;
|
||||
c=Bsr(c)/4+1;
|
||||
|
||||
"$$MA+A,\"Directory \",\"PopUpCd;Dir;\n\"$$ of %s\n",st;
|
||||
if (full)
|
||||
"__DATE__ __TIME__ %*ts %*ts %*ts\n",
|
||||
csize,"SIZE",esize,"UNCMPSIZE",c,"CLUSTER";
|
||||
else
|
||||
"DATE_ TIME_ %*ts\n",csize,"SIZE";
|
||||
while (tempm1) {
|
||||
tempm2=tempm1->next;
|
||||
if (full)
|
||||
"%D %T %0*tX %0*tX %0*tX ",tempm1->datetime,tempm1->datetime,
|
||||
csize,tempm1->size,esize,tempm1->expanded_size,
|
||||
c, tempm1->cluster;
|
||||
else
|
||||
"%h1D %h1T %0*tX ",tempm1->datetime,tempm1->datetime,
|
||||
csize,tempm1->size;
|
||||
if (tempm1->attr & _ATTR_DIR)
|
||||
PutDirLink(tempm1->name);
|
||||
else
|
||||
PutFileLink(tempm1->name);
|
||||
|
||||
NewLine;
|
||||
CDirEntryDel(tempm1);
|
||||
tempm1=tempm2;
|
||||
}
|
||||
} else
|
||||
PutDefine("ST_NO_MATCHING_ENTRIES");
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,373 @@
|
||||
U8 *FileExtDot(U8 *src)
|
||||
{
|
||||
U8 ch;
|
||||
while (ch=*src++)
|
||||
if (ch=='.' && *src!='/' && *src!='.')
|
||||
return src-1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U8 *FileExtRem(U8 *src,U8 *dst=NULL)
|
||||
{
|
||||
U8 *ptr;
|
||||
if (ptr=FileExtDot(src)) {
|
||||
if (dst)
|
||||
StrCpy(dst,ptr+1);
|
||||
*ptr=0;
|
||||
} else if (dst)
|
||||
*dst=0;
|
||||
return dst;
|
||||
}
|
||||
|
||||
Bool IsDotZ(U8 *filename)
|
||||
{
|
||||
I64 i=StrLen(filename);
|
||||
if (i>6 && filename[i-1]=='Z' && filename[i-2]=='.' && filename[i-6]=='.')
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool IsDotC(U8 *filename)
|
||||
{
|
||||
I64 i=StrLen(filename);
|
||||
if (i>6 && filename[i-1]=='C' && filename[i-2]=='.' && filename[i-6]=='.')
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool FilesFindMatch(U8 *files_find_mask,U8 *filename,I64 fuf_flags=0)
|
||||
{
|
||||
U8 *st1=StrNew(files_find_mask),
|
||||
*st2=MAlloc(StrLen(files_find_mask)+1);
|
||||
Bool result=FALSE;
|
||||
while (TRUE) {
|
||||
StrFirstRem(st1,";",st2);
|
||||
if (*st2) {
|
||||
if (*st2=='~') {
|
||||
if (WildCardMatch(st2+1,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (WildCardMatch(st2,filename)) {
|
||||
if (Bt(&fuf_flags,FUf_JUST_TXT_FILES) && !FilesFindMatch(FILENAME_MASK_TXT,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
} else if (Bt(&fuf_flags,FUf_JUST_SRC_FILES) && !FilesFindMatch(FILENAME_MASK_SRC,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
} else if (Bt(&fuf_flags,FUf_JUST_AOT_FILES) && !FilesFindMatch(FILENAME_MASK_AOT,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
} else if (Bt(&fuf_flags,FUf_JUST_JIT_FILES) && !FilesFindMatch(FILENAME_MASK_JIT,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
} else if (Bt(&fuf_flags,FUf_JUST_GRA_FILES) && !FilesFindMatch(FILENAME_MASK_GRA,filename)) {
|
||||
result=FALSE;
|
||||
break;
|
||||
} else
|
||||
result=TRUE;
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
}
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 PrtChk(CPrt *p)
|
||||
{
|
||||
if (!p || p->pt_signature!=PRT_SIGNATURE_VAL)
|
||||
throw(EXCEPT_PRT,4);
|
||||
}
|
||||
|
||||
U8 Prt2Drv(CPrt *p=NULL)
|
||||
{
|
||||
if (!p)
|
||||
p=Fs->cur_prt;
|
||||
PrtChk(p);
|
||||
return p->drv_let;
|
||||
}
|
||||
|
||||
CPrt *Drv2Prt(U8 drv_let=0)
|
||||
{
|
||||
CPrt *p;
|
||||
if (!drv_let)
|
||||
p=Fs->cur_prt;
|
||||
else {
|
||||
if (drv_let==':')
|
||||
drv_let=dft_drv;
|
||||
p=drv_to_prt[ToUpper(drv_let)-'A'];
|
||||
}
|
||||
PrtChk(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
U0 BlkDevChk(CBlkDev *bdev)
|
||||
{
|
||||
if (!bdev || bdev->bd_signature!=BD_SIGNATURE_VAL)
|
||||
throw(EXCEPT_BLKDEV,1);
|
||||
if (!(BDT_NULL<bdev->type<BDT_NUM_TYPES))
|
||||
throw(EXCEPT_BLKDEV,2);
|
||||
}
|
||||
|
||||
CBlkDev *Drv2BlkDev(U8 drv_let=0)
|
||||
{
|
||||
CPrt *p=Drv2Prt(drv_let);
|
||||
CBlkDev *bdev=p->bdev;
|
||||
BlkDevChk(bdev);
|
||||
return bdev;
|
||||
}
|
||||
|
||||
Bool IsDrvWritable(U8 drv_let=0)
|
||||
{
|
||||
CBlkDev *bdev=Drv2BlkDev(drv_let);
|
||||
if (bdev->flags & BDF_READ_ONLY)
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U8 *CurDir(CTask *task=NULL,CTask *mem_task=NULL)
|
||||
{
|
||||
U8 *st;
|
||||
if (!task) task=Fs;
|
||||
if (!task->cur_dir)
|
||||
return NULL;
|
||||
st=MAlloc(StrLen(task->cur_dir)+3,mem_task);
|
||||
*st=Prt2Drv;
|
||||
st[1]=':';
|
||||
StrCpy(st+2,task->cur_dir);
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *DirNameAbs(U8 *_dirname)
|
||||
{
|
||||
I64 maxlen;
|
||||
U8 drv[3],*cur_dir,*buf2,*buf3,*buf,*dirname,*temp_name;
|
||||
if (!Fs->cur_dir || !*Fs->cur_dir)
|
||||
return StrNew(_dirname);
|
||||
dirname=MStrUtil(_dirname,
|
||||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||||
temp_name=dirname;
|
||||
*drv=Prt2Drv;
|
||||
drv[1]=':';
|
||||
drv[2]=0;
|
||||
if (*dirname && dirname[1]==':') {
|
||||
if (*dirname==':')
|
||||
*drv=dft_drv;
|
||||
else
|
||||
*drv=*dirname;
|
||||
dirname=dirname+2;
|
||||
cur_dir=StrNew("/");
|
||||
} else
|
||||
cur_dir=StrNew(Fs->cur_dir);
|
||||
if (*dirname=='/') {
|
||||
Free(cur_dir);
|
||||
cur_dir=StrNew("/");
|
||||
dirname++;
|
||||
}
|
||||
|
||||
buf2=StrNew(dirname);
|
||||
maxlen=StrLen(cur_dir)+1+StrLen(buf2)+1;
|
||||
buf3=MAlloc(maxlen);
|
||||
buf =MAlloc(maxlen);
|
||||
StrCpy(buf3,cur_dir);
|
||||
while (*buf2) {
|
||||
StrFirstRem(buf2,"/",buf);
|
||||
if (!*buf)
|
||||
StrCpy(buf3,"/");
|
||||
else if (!StrCmp(buf,"..")) {
|
||||
StrLastRem(buf3,"/");
|
||||
if (!*buf3)
|
||||
StrCpy(buf3,"/");
|
||||
} else if (!StrCmp(buf,".")) {
|
||||
;
|
||||
} else if (*buf) {
|
||||
if (!StrCmp(buf,"HOME")) {
|
||||
Free(buf3);
|
||||
buf3=MAlloc(maxlen+StrLen(sys_acct));
|
||||
StrCpy(buf3,sys_acct+2);
|
||||
*drv=*sys_acct;
|
||||
} else {
|
||||
if (StrCmp(buf3,"/"))
|
||||
StrCat(buf3,"/");
|
||||
StrCat(buf3,buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(cur_dir);
|
||||
cur_dir=MAlloc(StrLen(buf3)+3);
|
||||
StrCpy(cur_dir,drv);
|
||||
StrCpy(cur_dir+2,buf3);
|
||||
Free(buf);
|
||||
Free(buf2);
|
||||
Free(buf3);
|
||||
Free(temp_name);
|
||||
return cur_dir;
|
||||
}
|
||||
|
||||
U8 *FileNameAbs(U8 *_filename,I64 fuf_flags=0)
|
||||
{//$LK,"FUF_Z_OR_NOT_Z","MN:FUF_Z_OR_NOT_Z"$, $LK,"FUF_SCAN_PARENTS","MN:FUF_SCAN_PARENTS"$
|
||||
U8 *buf,*buf2,*buf3,*filename,*temp_name,*temp_buf;
|
||||
CDirEntry de;
|
||||
filename=MStrUtil(_filename,
|
||||
SUF_REM_LEADING|SUF_REM_TRAILING|SUF_REM_CTRL_CHARS);
|
||||
temp_name=filename;
|
||||
buf=StrNew(filename);
|
||||
temp_buf=buf;
|
||||
if (*buf && buf[1]==':') {
|
||||
buf+=2;
|
||||
filename+=2;
|
||||
}
|
||||
buf2=MAlloc(StrLen(temp_name)+1);
|
||||
StrLastRem(buf,"/",buf2);
|
||||
if (*filename=='/' && !*buf)
|
||||
StrCpy(buf,"/");
|
||||
buf3=DirNameAbs(temp_buf);
|
||||
Free(temp_buf);
|
||||
buf=MAlloc(StrLen(buf3)+1+StrLen(buf2)+1);
|
||||
StrCpy(buf,buf3);
|
||||
if (buf[StrLen(buf)-1]!='/')
|
||||
StrCat(buf,"/");
|
||||
StrCat(buf,buf2);
|
||||
Free(buf2);
|
||||
Free(buf3);
|
||||
Free(temp_name);
|
||||
if (fuf_flags&&FileFind(buf,&de,fuf_flags|FUF_JUST_FILES)) {
|
||||
Free(buf);
|
||||
buf=de.full_name;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
U8 *ChgExt(U8 *filename,U8 *extension)
|
||||
{//Change file name extension
|
||||
U8 *result=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
|
||||
StrCpy(result,filename);
|
||||
if (FileExtDot(filename))
|
||||
FileExtRem(result);
|
||||
StrCat(result,".");
|
||||
StrCat(result,extension);
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *DftExt(U8 *filename,U8 *extension)
|
||||
{//Give extension if has none.
|
||||
U8 *result=MAlloc(StrLen(filename)+1+StrLen(extension)+1);
|
||||
StrCpy(result,filename);
|
||||
if (!FileExtDot(filename)) {
|
||||
StrCat(result,".");
|
||||
StrCat(result,extension);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CDirEntry *CdDir(CDirEntry *tempm,U8 *abs_name)
|
||||
{
|
||||
I64 i;
|
||||
while (tempm) {
|
||||
i=StrLen(tempm->full_name);
|
||||
if (StrNCmp(tempm->full_name,abs_name,i))
|
||||
tempm=tempm->next;
|
||||
else
|
||||
if (StrLen(abs_name)==i)
|
||||
return tempm;
|
||||
else
|
||||
return CdDir(tempm->sub,abs_name);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
I64 FileAttr(U8 *name,I64 attr=0)
|
||||
{
|
||||
if (IsDotZ(name))
|
||||
attr|=_ATTR_COMPRESSED;
|
||||
else
|
||||
attr&=~_ATTR_COMPRESSED;
|
||||
if (IsDotC(name))
|
||||
attr|=_ATTR_CONTIGUOUS;
|
||||
return attr;
|
||||
}
|
||||
|
||||
Bool FileNameChk(U8 *filename)
|
||||
{
|
||||
U8 *ptr=filename;
|
||||
if (!filename) return FALSE;
|
||||
if (!*ptr) return FALSE;
|
||||
if (*ptr=='.') {
|
||||
if (!ptr[1]) return TRUE;
|
||||
if (ptr[1]=='.' && !ptr[2]) return TRUE;
|
||||
}
|
||||
if (StrLen(filename)>=CDIR_FILENAME_LEN) return FALSE;
|
||||
while (*ptr)
|
||||
if (!Bt(filename_chars_bitmap,*ptr++))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
U8 *DirFile(U8 *dirname,U8 *name=NULL,U8 *_extension=NULL)
|
||||
{/*
|
||||
Strips file from dirname, scans for file upward until found or returns default.
|
||||
|
||||
("/TempleOS/Kernel/Hash1a.CPP.Z",NULL,NULL) returns "D:/TempleOS/Kernel"
|
||||
("/TempleOS/Kernel",NULL,"PRJ.Z") returns "D:/TempleOS/Kernel/Kernel.PRJ.Z"
|
||||
("/TempleOS/Kernel/Dsk",NULL,"PRJ.Z") returns "D:/TempleOS/Kernel/Kernel.PRJ.Z"
|
||||
("/TempleOS/Apps/MusicOrgan","Load","CPP.Z") returns "D:/TempleOS/Apps/MusicOrgan/Load.CPP.Z"
|
||||
*/
|
||||
U8 *st=DirNameAbs(dirname),*st2,*st3,*result,*dft=NULL,*ext;
|
||||
if (_extension && *_extension) {
|
||||
if (*_extension=='.')
|
||||
ext=StrNew(_extension);
|
||||
else
|
||||
ext=MSPrintF(".%s",_extension);
|
||||
} else
|
||||
ext=StrNew("");
|
||||
while (StrOcc(st,'/')&&!IsDir(st))
|
||||
StrLastRem(st,"/");
|
||||
while (StrOcc(st,'/')) {
|
||||
st2=StrNew(st);
|
||||
st3=StrNew(st);
|
||||
StrLastRem(st2,"/",st3);
|
||||
|
||||
if (name)
|
||||
result=MSPrintF("%s/%s%s",st,name,ext);
|
||||
else {
|
||||
if (*ext)
|
||||
result=MSPrintF("%s/%s%s",st,st3,ext);
|
||||
else
|
||||
result=StrNew(st);
|
||||
}
|
||||
if (!dft)
|
||||
dft=StrNew(result);
|
||||
if (!*ext&&(!name||!*name)||FileFind(result)) {
|
||||
Free(st3);
|
||||
Free(st2);
|
||||
Free(st);
|
||||
Free(dft);
|
||||
Free(ext);
|
||||
return result;
|
||||
}
|
||||
Free(st);
|
||||
st=st2;
|
||||
Free(st3);
|
||||
}
|
||||
Free(st);
|
||||
Free(ext);
|
||||
return dft;
|
||||
}
|
||||
|
||||
U8 *ToggleZorNotZ(U8 *name)
|
||||
{
|
||||
U8 *result;
|
||||
if (IsDotZ(name)) {
|
||||
result=StrNew(name);
|
||||
result[StrLen(name)-2]=0;
|
||||
} else
|
||||
result=MSPrintF("%s.Z",name);
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,314 @@
|
||||
//ISO1 is ISO9660
|
||||
//ISO2 is ISO13490
|
||||
//ISO3 is ISO13346
|
||||
|
||||
Bool ISOPrtInit(CPrt *p,I64 blk)
|
||||
{
|
||||
CBlkDev *bdev=p->bdev;
|
||||
I64 spc=bdev->blk_size>>BLK_SIZE_BITS,i=blk/spc;
|
||||
CISO1PriDesc *iso=MAlloc(bdev->blk_size);
|
||||
CISO1DirEntry *de;
|
||||
Bool unlock,result=FALSE;
|
||||
U8 buf[8];
|
||||
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
p->type=PT_ISO9660; //default
|
||||
p->spc=spc;
|
||||
p->offset=p->data=p->root_cluster=p->size=0;
|
||||
while (TRUE) {
|
||||
p->size=MaxI64(p->size,(i+1)*spc);
|
||||
RBlks(p,iso,i*spc,spc);
|
||||
buf[0](U32)=iso->id[0](U32);
|
||||
buf[4](U16)=iso->id[4](U8);
|
||||
switch (LstEntryMatch(buf,"CD001\0CDW02\0BEA01\0BOOT2\0NSR02\0NSR03\0TEA01\0",LEF_EXACT)) {
|
||||
case 0:
|
||||
p->type=PT_ISO9660;
|
||||
switch (iso->type) {
|
||||
case ISO1T_SUPPLEMENTARY_DESC:
|
||||
p->data=0;
|
||||
de=&iso->root_dir_record;
|
||||
p->root_cluster=de->loc.little;
|
||||
p->size=iso->vol_space_size.little*bdev->blk_size>>BLK_SIZE_BITS;
|
||||
result=TRUE;
|
||||
goto ipi_done;
|
||||
case ISO1T_TERMINATOR:
|
||||
throw(EXCEPT_PRT,5);
|
||||
}
|
||||
break;
|
||||
default: //Its normal for ISO13346 to read NULL blk as terminator
|
||||
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
|
||||
throw(EXCEPT_PRT,6);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
ipi_done:
|
||||
Free(iso);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch {
|
||||
p->type=PT_ISO9660;
|
||||
p->spc=spc;
|
||||
p->offset=p->data=p->root_cluster=0;
|
||||
Free(iso);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 CDate2ISO1(CISO1Date *dst,CDate spdt)
|
||||
{
|
||||
CDateStruct ds;
|
||||
CDate2CDateStruct(&ds,spdt);
|
||||
dst->year=ds.year-ISO1_BASE_YEAR;
|
||||
dst->mon=ds.mon;
|
||||
dst->day=ds.day_of_mon;
|
||||
dst->hour=ds.hour;
|
||||
dst->min=ds.min;
|
||||
dst->sec=ds.sec;
|
||||
dst->sec100=ds.sec100;
|
||||
}
|
||||
|
||||
CDate ISO1DateStruct2CDate(CISO1Date *dt)
|
||||
{
|
||||
CDateStruct ds;
|
||||
MemSet(&ds,0,sizeof(CDateStruct));
|
||||
ds.day_of_mon=dt->day;
|
||||
ds.mon=dt->mon;
|
||||
ds.year=dt->year+ISO1_BASE_YEAR;
|
||||
ds.sec100=dt->sec100;
|
||||
ds.sec=dt->sec;
|
||||
ds.min=dt->min;
|
||||
ds.hour=dt->hour;
|
||||
return CDateStruct2CDate(&ds);
|
||||
}
|
||||
|
||||
Bool ISO1FromName(U8 *dst,U8 *src)
|
||||
{
|
||||
I64 i,j,n;
|
||||
MemSet(dst,0,CDIR_FILENAME_LEN);
|
||||
n=*src++;
|
||||
if (n==1 && !*src) {
|
||||
*dst='.';
|
||||
} else if (n==1 && *src==1) {
|
||||
*dst='.';
|
||||
dst[1]='.';
|
||||
} else {
|
||||
n>>=1;
|
||||
j=0;
|
||||
for (i=0;i<n;i++) {
|
||||
src++;
|
||||
if (*src==';')
|
||||
break;
|
||||
if (Bt(filename_chars_bitmap,*src)) {
|
||||
if (j>=CDIR_FILENAME_LEN-1)
|
||||
return FALSE;
|
||||
dst[j++]=*src++;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return FileNameChk(dst);
|
||||
}
|
||||
|
||||
Bool ISO1CDirFill(CPrt *p,CDirEntry *tempm,CISO1DirEntry *de)
|
||||
{
|
||||
Bool result;
|
||||
CArcCompress *buf;
|
||||
MemSet(tempm,0,sizeof(CDirEntry));
|
||||
result=ISO1FromName(tempm->name,&de->name_len);
|
||||
tempm->cluster=de->loc.little;
|
||||
tempm->size=de->size.little;
|
||||
tempm->attr=FileAttr(tempm->name);
|
||||
if (de->flags & ISO1_ATTR_DIR)
|
||||
tempm->attr|=_ATTR_DIR;
|
||||
tempm->datetime=ISO1DateStruct2CDate(&de->date);
|
||||
if (tempm->attr & _ATTR_COMPRESSED) {
|
||||
buf=MAlloc(BLK_SIZE);
|
||||
RClustersBlks(p,buf,tempm->cluster,1);
|
||||
tempm->expanded_size=buf->expanded_size;
|
||||
Free(buf);
|
||||
} else
|
||||
tempm->expanded_size=tempm->size;
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool ISO1FileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
|
||||
{ //$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$
|
||||
CISO1DirEntry *isoptr,*buf;
|
||||
U8 dname[CDIR_FILENAME_LEN];
|
||||
Bool result=FALSE,unlock;
|
||||
I64 i;
|
||||
if (fuf_flags&~FUG_FILE_FIND)
|
||||
throw(EXCEPT_FUF,8);
|
||||
PrtChk(p);
|
||||
if (p->type!=PT_ISO9660)
|
||||
PutDefineErr("ST_NOT_ISO9660");
|
||||
else {
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
isoptr=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(Fs->cur_prt,isoptr,cur_dir_cluster,1);
|
||||
if (isoptr->name_len==1 && !isoptr->name) { //curdir
|
||||
i=(isoptr->size.little+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS;
|
||||
buf=MAlloc(p->spc<<BLK_SIZE_BITS*i);
|
||||
RClusters(Fs->cur_prt,buf,cur_dir_cluster,i);
|
||||
Free(isoptr);
|
||||
} else {
|
||||
buf=isoptr;
|
||||
i=1;
|
||||
}
|
||||
i*=p->spc<<BLK_SIZE_BITS;
|
||||
isoptr=buf;
|
||||
while (i>0) {
|
||||
if (!isoptr->len) {
|
||||
isoptr(U8 *)++;
|
||||
i--;
|
||||
} else {
|
||||
ISO1FromName(dname,&isoptr->name_len);
|
||||
if (*dname) {
|
||||
if (!StrCmp(name,dname)) {
|
||||
result=ISO1CDirFill(p,_result,isoptr);
|
||||
if (result &&
|
||||
!(fuf_flags&FUF_JUST_DIRS && !(_result->attr & _ATTR_DIR)) &&
|
||||
!(fuf_flags&FUF_JUST_FILES && _result->attr & _ATTR_DIR) )
|
||||
goto exit_this;
|
||||
else
|
||||
result=FALSE;
|
||||
}
|
||||
}
|
||||
i-=isoptr->len;
|
||||
isoptr(U8 *)+=isoptr->len;
|
||||
}
|
||||
}
|
||||
exit_this:
|
||||
Free(buf);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U8 *ISO1FileRead(CPrt *p,U8 *cur_dir,U8 *filename,I64 *_size,
|
||||
I64 *_attr,Bool raw,CArcCompress **_ac2)
|
||||
{
|
||||
U8 *buf=NULL;
|
||||
CDirEntry de;
|
||||
I64 c,blk_cnt,cur_dir_cluster;
|
||||
CArcCompress *ac;
|
||||
|
||||
PrtChk(p);
|
||||
if (_size) *_size=0;
|
||||
if (_ac2) *_ac2=NULL;
|
||||
if (_attr) *_attr=0;
|
||||
if (p->type!=PT_ISO9660)
|
||||
PutDefineErr("ST_NOT_ISO9660");
|
||||
else {
|
||||
try {
|
||||
PrtLock(p);
|
||||
cur_dir_cluster=Name2DirCluster(p,cur_dir);
|
||||
if (ISO1FileFind(p,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
|
||||
if (_attr) *_attr=de.attr;
|
||||
blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
|
||||
c=de.cluster;
|
||||
c=RClustersBlks(p,buf,c,blk_cnt);
|
||||
if (FileAttr(de.name)&_ATTR_COMPRESSED && !raw) {
|
||||
ac=buf;
|
||||
if (_attr) *_attr=FileAttr(de.name,*_attr);
|
||||
if (_size) *_size=ac->expanded_size;
|
||||
if (_ac2) {
|
||||
*_ac2=ac;
|
||||
buf=ExpandBuf(ac);
|
||||
} else {
|
||||
buf=ExpandBuf(ac);
|
||||
Free(ac);
|
||||
}
|
||||
} else {
|
||||
buf[de.size]=0; //Terminate
|
||||
if (_size) *_size=de.size;
|
||||
}
|
||||
if (_attr) *_attr=FileAttr(de.name,*_attr);
|
||||
}
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
PrtUnlock(p);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
Bool ISO1Cd(U8 *name,I64 cur_dir_cluster)
|
||||
{
|
||||
CDirEntry de;
|
||||
if (Fs->cur_prt->type!=PT_ISO9660)
|
||||
PutDefineErr("ST_NOT_ISO9660");
|
||||
else {
|
||||
if (ISO1FileFind(Fs->cur_prt,cur_dir_cluster,name,&de,FUF_JUST_DIRS))
|
||||
return TRUE;
|
||||
else {
|
||||
"%s ",name;
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CDirEntry *ISO1FilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL)
|
||||
{
|
||||
CPrt *p=Fs->cur_prt;
|
||||
CISO1DirEntry *buf,*buf2,*isoptr;
|
||||
I64 i,cur_dir_cluster=Name2DirCluster(p,Fs->cur_dir);
|
||||
CDirEntry *result=NULL,*tempm;
|
||||
if (fuf_flags&~FUG_FILES_FIND)
|
||||
throw(EXCEPT_FUF,9);
|
||||
isoptr=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(Fs->cur_prt,isoptr,cur_dir_cluster,1);
|
||||
if (isoptr->name_len==1 && !isoptr->name) { //curdir
|
||||
i=(isoptr->size.little+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS;
|
||||
buf=MAlloc(p->spc<<BLK_SIZE_BITS*i);
|
||||
RClusters(Fs->cur_prt,buf,cur_dir_cluster,i);
|
||||
Free(isoptr);
|
||||
} else {
|
||||
buf=isoptr;
|
||||
i=1;
|
||||
}
|
||||
buf2=buf;
|
||||
i*=p->spc<<BLK_SIZE_BITS;
|
||||
while (i>0) {
|
||||
if (!buf->len) {
|
||||
buf(U8 *)++;
|
||||
i--;
|
||||
} else {
|
||||
tempm=MAlloc(sizeof(CDirEntry));
|
||||
if (ISO1CDirFill(Fs->cur_prt,tempm,buf)) {
|
||||
tempm->parent=parent;
|
||||
if (Bt(&fuf_flags,FUf_RECURSE) && tempm->attr&_ATTR_DIR && *tempm->name!='.') {
|
||||
tempm->next=result;
|
||||
result=tempm;
|
||||
tempm->full_name=DirNameAbs(tempm->name);
|
||||
if (Cd(tempm->name)) {
|
||||
tempm->sub=ISO1FilesFind(files_find_mask,fuf_flags,tempm);
|
||||
Cd("..");
|
||||
}
|
||||
} else if ((tempm->attr & _ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
|
||||
!(Bt(&fuf_flags,FUf_RECURSE) && *tempm->name=='.' && tempm->attr&_ATTR_DIR) &&
|
||||
FilesFindMatch(files_find_mask,tempm->name,fuf_flags)) {
|
||||
tempm->next=result;
|
||||
result=tempm;
|
||||
tempm->full_name=FileNameAbs(tempm->name);
|
||||
} else
|
||||
CDirEntryDel(tempm);
|
||||
} else
|
||||
CDirEntryDel(tempm);
|
||||
i-=buf->len;
|
||||
buf(U8 *)+=buf->len;
|
||||
}
|
||||
}
|
||||
Free(buf2);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,718 @@
|
||||
U0 NativeFSFreeFreeLst(CPrt *p)
|
||||
{
|
||||
CFreeLst *tempf,*tempf1;
|
||||
Bool unlock;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
|
||||
if (tempf=p->next_free) {
|
||||
while (tempf!=&p->next_free) {
|
||||
tempf1=tempf->next;
|
||||
Free(tempf);
|
||||
tempf=tempf1;
|
||||
}
|
||||
}
|
||||
p->next_free=NULL;
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
|
||||
U0 NativeFSFreeLstBuild(CPrt *p)
|
||||
{
|
||||
Bool unlock;
|
||||
CFreeLst *tempf;
|
||||
I64 i,first=0,
|
||||
max_cluster=(p->size+p->offset-p->data)/p->spc;
|
||||
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
if (p->next_free)
|
||||
NativeFSFreeFreeLst(p);
|
||||
p->next_free=&p->next_free;
|
||||
p->last_free=&p->next_free;
|
||||
while (first<max_cluster) {
|
||||
i=0; //count free clusters
|
||||
while (first+i<max_cluster) {
|
||||
SetNativeBuf(p,first+i);
|
||||
if (Bt(p->cur_map_blk,(first+i)&(BLK_SIZE<<3-1)))
|
||||
break;
|
||||
else
|
||||
i++;
|
||||
}
|
||||
if (i) {
|
||||
tempf=AMAlloc(sizeof(CFreeLst));
|
||||
tempf->size=i;
|
||||
tempf->start=first;
|
||||
QueIns(tempf,p->last_free);
|
||||
}
|
||||
first+=i+1;
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
|
||||
U0 NativeFSPrtInit(CPrt *p)
|
||||
{
|
||||
CBootStruct br;
|
||||
Bool unlock;
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
RBlks(p,&br,p->offset,1);
|
||||
if (br.signature!=MBR_PT_NATIVE ||
|
||||
br.signature2!=0xAA55)
|
||||
throw(EXCEPT_PRT,7);
|
||||
p->type=PT_NATIVE;
|
||||
NativeFSFreeFreeLst(p);
|
||||
p->spc=br.sects_per_cluster;
|
||||
p->size=br.sects;
|
||||
p->data=p->offset+1+br.bitmap_sects-p->spc;
|
||||
p->root_cluster=br.root_cluster;
|
||||
p->map1=p->offset+1;
|
||||
p->map2=p->offset+1;
|
||||
MapBufAlloc(p,1);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
|
||||
Bool NativeFSDrvValidate(U8 drv_let)
|
||||
{
|
||||
CPrt *p;
|
||||
CBootStruct br;
|
||||
Bool result=FALSE;
|
||||
try {
|
||||
p=Drv2Prt(drv_let);
|
||||
if (p->type==PT_NATIVE &&
|
||||
RBlks(p,&br,p->offset,1) &&
|
||||
br.signature==MBR_PT_NATIVE &&
|
||||
br.signature2==0xAA55 &&
|
||||
br.sects==p->size)
|
||||
result=TRUE;
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 NativeFSFmt(U8 drv_let,Bool quick=TRUE)
|
||||
{
|
||||
U8 *root_dir;
|
||||
CDirEntry *d_native;
|
||||
CBootStruct *br=CAlloc(BLK_SIZE);
|
||||
CPrt *p=Drv2Prt(drv_let);
|
||||
I64 i,n;
|
||||
try {
|
||||
PrtLock(p);
|
||||
// SetDrvType(drv_let,PT_NATIVE);
|
||||
SetDrvType(drv_let,PT_FAT32);
|
||||
p->type=PT_NATIVE;
|
||||
br->U8s_per_sect=BLK_SIZE;
|
||||
if (p->size<0x20000)
|
||||
br->sects_per_cluster=1;
|
||||
else if (p->size<0x200000)
|
||||
br->sects_per_cluster=2;
|
||||
else if (p->size<0x2000000)
|
||||
br->sects_per_cluster=4;
|
||||
else if (p->size<0x20000000)
|
||||
br->sects_per_cluster=8;
|
||||
else if (p->size<0x200000000)
|
||||
br->sects_per_cluster=16;
|
||||
else
|
||||
br->sects_per_cluster=32;
|
||||
|
||||
br->signature=MBR_PT_NATIVE;
|
||||
br->signature2=0xAA55;
|
||||
br->sects=p->size;
|
||||
n=br->sects_per_cluster*(BLK_SIZE<<3);
|
||||
n=(br->sects+n-1)/n;
|
||||
br->bitmap_sects=n;
|
||||
br->unique_id=GetTimeStamp>>4;
|
||||
br->root_cluster=0;
|
||||
|
||||
if (quick)
|
||||
i=n+1;
|
||||
else
|
||||
i=p->size;
|
||||
WZeroBlks(p,p->offset,i);
|
||||
|
||||
WBlks(p,br,p->offset,1);
|
||||
NativeFSPrtInit(p);
|
||||
ClusersAlloc(p,0,1,FALSE); //Alloc #1
|
||||
br->root_cluster=ClusersAlloc(p,0,1,FALSE);
|
||||
WBlks(p,br,p->offset,1);
|
||||
root_dir=CAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
|
||||
d_native=root_dir-offset(CDirEntry.start);
|
||||
|
||||
d_native->attr=_ATTR_DIR|_ATTR_CONTIGUOUS;
|
||||
*d_native->name='.';
|
||||
d_native->cluster=br->root_cluster;
|
||||
d_native->size=p->spc<<BLK_SIZE_BITS;
|
||||
d_native->expanded_size=d_native->size;
|
||||
d_native->datetime=GetCurTimeCDate;
|
||||
|
||||
d_native(U8 *)+=CDIR_SIZE;
|
||||
|
||||
*d_native->name='.';
|
||||
d_native->name[1]='.';
|
||||
d_native->attr=_ATTR_DIR|_ATTR_CONTIGUOUS;
|
||||
d_native->cluster=br->root_cluster;
|
||||
d_native->datetime=GetCurTimeCDate;
|
||||
|
||||
WBlks(p,root_dir,p->data+br->root_cluster*p->spc,p->spc);
|
||||
NativeFSPrtInit(p);
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
PrtUnlock(p);
|
||||
Free(br);
|
||||
Free(root_dir);
|
||||
}
|
||||
|
||||
Bool NativeFSFileFind(CPrt *p,I64 cur_dir_cluster,U8 *name,CDirEntry *_result,I64 fuf_flags=0)
|
||||
{ //$LK,"FUF_JUST_DIRS","MN:FUF_JUST_DIRS"$, $LK,"FUF_JUST_FILES","MN:FUF_JUST_FILES"$
|
||||
CDirEntry *buf,*buf2,*ptr;
|
||||
U8 dname[CDIR_FILENAME_LEN];
|
||||
I64 ch;
|
||||
Bool result=FALSE,unlock;
|
||||
if (fuf_flags&~FUG_FILE_FIND)
|
||||
throw(EXCEPT_FUF,10);
|
||||
MemSet(_result,0,sizeof(CDirEntry));
|
||||
PrtChk(p);
|
||||
if (p->type!=PT_NATIVE)
|
||||
PutDefineErr("ST_NOT_NATIVE");
|
||||
else if (!CFileNameTo(dname,name))
|
||||
PutDefineErr("ST_INVALID_FILENAME");
|
||||
else {
|
||||
try {
|
||||
unlock=PrtLock(p);
|
||||
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(p,buf2,cur_dir_cluster,1);
|
||||
|
||||
ptr=buf2(U8 *)-offset(CDirEntry.start);
|
||||
buf=MAlloc(ptr->size);
|
||||
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
|
||||
Free(buf2);
|
||||
|
||||
ptr=buf(U8 *)-offset(CDirEntry.start);
|
||||
*ptr->name='.';
|
||||
ptr->name[1]=0;
|
||||
while (TRUE) {
|
||||
if (!(ch=*ptr->name))
|
||||
break;
|
||||
else if (!(ptr->attr & _ATTR_DELETED) &&
|
||||
!(fuf_flags&FUF_JUST_DIRS && !(ptr->attr & _ATTR_DIR)) &&
|
||||
!(fuf_flags&FUF_JUST_FILES && ptr->attr & _ATTR_DIR) &&
|
||||
!StrCmp(dname,ptr->name)) {
|
||||
MemCpy(&_result->attr,&ptr->attr,CDIR_SIZE);
|
||||
result=TRUE;
|
||||
goto exit_this;
|
||||
}
|
||||
ptr(U8 *)+=CDIR_SIZE;
|
||||
}
|
||||
exit_this:
|
||||
Free(buf);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
U8 *NativeFSFileRead(CPrt *p,U8 *cur_dir,U8 *filename,I64 *_size,
|
||||
I64 *_attr,Bool raw,CArcCompress **_ac2)
|
||||
{
|
||||
U8 *buf=NULL;
|
||||
CDirEntry de;
|
||||
I64 c,blk_cnt,cur_dir_cluster;
|
||||
CArcCompress *ac;
|
||||
|
||||
PrtChk(p);
|
||||
if (_size) *_size=0;
|
||||
if (_ac2) *_ac2=NULL;
|
||||
if (_attr) *_attr=0;
|
||||
if (p->type!=PT_NATIVE)
|
||||
PutDefineErr("ST_NOT_NATIVE");
|
||||
else {
|
||||
try {
|
||||
PrtLock(p);
|
||||
cur_dir_cluster=Name2DirCluster(p,cur_dir);
|
||||
if (NativeFSFileFind(p,cur_dir_cluster,filename,&de,FUF_JUST_FILES)) {
|
||||
if (_attr) *_attr=de.attr;
|
||||
blk_cnt=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
buf=MAlloc(blk_cnt<<BLK_SIZE_BITS+1);
|
||||
c=de.cluster;
|
||||
c=RClustersBlks(p,buf,c,blk_cnt);
|
||||
if (de.xsum) {
|
||||
if (de.xsum^ArcXSum(buf,de.size) !=NATIVE_XSUM)
|
||||
throw(EXCEPT_ARC_XSUM);
|
||||
}
|
||||
if (FileAttr(de.name) & _ATTR_COMPRESSED && !raw) {
|
||||
ac=buf;
|
||||
if (_attr) *_attr=FileAttr(de.name,*_attr);
|
||||
if (_size) *_size=ac->expanded_size;
|
||||
if (_ac2) {
|
||||
*_ac2=ac;
|
||||
buf=ExpandBuf(ac);
|
||||
} else {
|
||||
buf=ExpandBuf(ac);
|
||||
Free(ac);
|
||||
}
|
||||
} else {
|
||||
buf[de.size]=0; //Terminate
|
||||
if (_size) *_size=de.size;
|
||||
}
|
||||
if (_attr) *_attr=FileAttr(de.name,*_attr);
|
||||
}
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
PrtUnlock(p);
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
Bool NativeFSCd(U8 *name,I64 cur_dir_cluster)
|
||||
{
|
||||
CDirEntry de;
|
||||
if (Fs->cur_prt->type!=PT_NATIVE)
|
||||
PutDefineErr("ST_NOT_NATIVE");
|
||||
else {
|
||||
if (NativeFSFileFind(Fs->cur_prt,cur_dir_cluster,
|
||||
name,&de,FUF_JUST_DIRS))
|
||||
return TRUE;
|
||||
else {
|
||||
"%s ",name;
|
||||
PutDefineErr("ST_FILE_NOT_FOUND");
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 NativeFSFreeClusters(CPrt *p,I64 c,I64 cnt)
|
||||
{
|
||||
CFreeLst *tempf;
|
||||
Bool found=FALSE,unlock,unlock_break;
|
||||
PrtChk(p);
|
||||
if (!c) return;
|
||||
if (p->type!=PT_NATIVE)
|
||||
PutDefineErr("ST_NOT_NATIVE");
|
||||
else {
|
||||
try {
|
||||
unlock_break=BreakLock;
|
||||
unlock=PrtLock(p);
|
||||
if (!p->next_free)
|
||||
NativeFSFreeLstBuild(p);
|
||||
tempf=p->next_free;
|
||||
while (!found && tempf!=&p->next_free) {
|
||||
if (tempf->start+tempf->size==c) {
|
||||
tempf->size+=cnt;
|
||||
found=TRUE;
|
||||
} else if (c+cnt==tempf->start) {
|
||||
tempf->size+=cnt;
|
||||
tempf->start=c;
|
||||
found=TRUE;
|
||||
}
|
||||
tempf=tempf->next;
|
||||
}
|
||||
if (!found) {
|
||||
tempf=AMAlloc(sizeof(CFreeLst));
|
||||
tempf->size=cnt;
|
||||
tempf->start=c;
|
||||
QueIns(tempf,p->last_free);
|
||||
}
|
||||
while (cnt-->0) {
|
||||
SetNativeBuf(p,c);
|
||||
LBtr(p->cur_map_blk,c&(BLK_SIZE<<3-1));
|
||||
LBts(p->buffered_map_dirty_bits,0);
|
||||
c++;
|
||||
}
|
||||
CleanMAPBuf(p);
|
||||
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
} catch {
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
I64 NativeFSAllocClusters(CPrt *p,I64 cnt)
|
||||
{
|
||||
CFreeLst *tempf,*best_free=NULL;
|
||||
I64 i,first,best_size=MAX_I64;
|
||||
Bool unlock,unlock_break;
|
||||
if (cnt<=0)
|
||||
Dbg;
|
||||
try {
|
||||
unlock_break=BreakLock;
|
||||
unlock=PrtLock(p);
|
||||
if (!p->next_free)
|
||||
NativeFSFreeLstBuild(p);
|
||||
tempf=p->next_free;
|
||||
while (tempf!=&p->next_free) {
|
||||
if (tempf->size>=cnt && tempf->size<best_size) {
|
||||
best_free=tempf;
|
||||
best_size=tempf->size;
|
||||
if (tempf->size==cnt)
|
||||
break;
|
||||
}
|
||||
tempf=tempf->next;
|
||||
}
|
||||
if (!best_free)
|
||||
Dbg;
|
||||
first=best_free->start;
|
||||
for (i=0;i<cnt;i++) {
|
||||
SetNativeBuf(p,first+i);
|
||||
LBts(p->cur_map_blk,(first+i)&(BLK_SIZE<<3-1));
|
||||
LBts(p->buffered_map_dirty_bits,0);
|
||||
}
|
||||
CleanMAPBuf(p);
|
||||
if (best_free->size-=cnt)
|
||||
best_free->start+=cnt;
|
||||
else {
|
||||
QueRem(best_free);
|
||||
Free(best_free);
|
||||
}
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
} catch {
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
Bool NativeFSDirNew(CPrt *p,U8 *cur_dir,CDirEntry *de,Bool free_old_chain)
|
||||
{
|
||||
CDirEntry *buf,*buf2,*ptr,de2;
|
||||
CBootStruct *br;
|
||||
I64 c,ch,i=1,j=0,n=BLK_SIZE/CDIR_SIZE,dir_size,cur_dir_cluster;
|
||||
Bool written=FALSE,unlock,unlock_break;
|
||||
U8 *temp,*parent_dir;
|
||||
try {
|
||||
unlock_break=BreakLock;
|
||||
de->attr|=_ATTR_CONTIGUOUS;
|
||||
unlock=PrtLock(p);
|
||||
cur_dir_cluster=Name2DirCluster(p,cur_dir);
|
||||
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(p,buf2,cur_dir_cluster,1);
|
||||
|
||||
ptr=buf2(U8 *)-offset(CDirEntry.start);
|
||||
buf=MAlloc(ptr->size);
|
||||
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
|
||||
|
||||
dir_size=ptr->size;
|
||||
ptr=buf(U8 *)-offset(CDirEntry.start)+CDIR_SIZE;
|
||||
Free(buf2);
|
||||
while (TRUE) {
|
||||
if (!(ch=*ptr->name)) {
|
||||
if (!written)
|
||||
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
|
||||
if ((i+1)*CDIR_SIZE+j<<BLK_SIZE_BITS<dir_size)
|
||||
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,
|
||||
p->data+cur_dir_cluster*p->spc+j,1);
|
||||
else {
|
||||
buf2=CAlloc(dir_size+p->spc<<BLK_SIZE_BITS);
|
||||
MemCpy(buf2,buf,dir_size);
|
||||
NativeFSFreeClusters(p,cur_dir_cluster,
|
||||
(dir_size>>BLK_SIZE_BITS+p->spc-1)/p->spc);
|
||||
dir_size+=p->spc<<BLK_SIZE_BITS;
|
||||
c=ClusersAlloc(p,0,(dir_size>>BLK_SIZE_BITS+p->spc-1)/p->spc,TRUE);
|
||||
Free(buf);
|
||||
buf=buf2;
|
||||
ptr=buf(U8 *)-offset(CDirEntry.start);
|
||||
ptr->size=dir_size;
|
||||
ptr->expanded_size=dir_size;
|
||||
ptr->cluster=c;
|
||||
WClustersBlks(p,buf,c,dir_size>>BLK_SIZE_BITS);
|
||||
if (cur_dir_cluster==p->root_cluster) {
|
||||
br=CAlloc(BLK_SIZE);
|
||||
RBlks(p,br,p->offset,1);
|
||||
br->root_cluster=c;
|
||||
WBlks(p,br,p->offset,1);
|
||||
Free(br);
|
||||
p->root_cluster=c;
|
||||
} else {
|
||||
temp=StrNew(cur_dir);
|
||||
parent_dir=StrNew(cur_dir);
|
||||
StrLastRem(parent_dir,"/",temp);
|
||||
if (!*parent_dir) {
|
||||
Free(parent_dir);
|
||||
parent_dir=StrNew("/");
|
||||
}
|
||||
if (NativeFSFileFind(p,Name2DirCluster(p,parent_dir),
|
||||
temp,&de2,FUF_JUST_DIRS)) {
|
||||
de2.cluster=c;
|
||||
de2.size=dir_size;
|
||||
de2.expanded_size=dir_size;
|
||||
NativeFSDirNew(p,parent_dir,&de2,FALSE);
|
||||
} else
|
||||
Dbg;
|
||||
Free(temp);
|
||||
Free(parent_dir);
|
||||
}
|
||||
}
|
||||
break;
|
||||
} else if (ptr->attr & _ATTR_DELETED) {
|
||||
if (!written) {
|
||||
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
|
||||
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,
|
||||
p->data+cur_dir_cluster*p->spc+j,1);
|
||||
written=TRUE;
|
||||
}
|
||||
} else {
|
||||
if (!StrCmp(de->name,ptr->name)) {
|
||||
if (free_old_chain)
|
||||
NativeFSFreeClusters(p,ptr->cluster,
|
||||
(ptr->size+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS);
|
||||
if (!written)
|
||||
MemCpy(&ptr->start,&de->start,CDIR_SIZE);
|
||||
else
|
||||
ptr->attr|=_ATTR_DELETED;
|
||||
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,
|
||||
p->data+cur_dir_cluster*p->spc+j,1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr(U8 *)+=CDIR_SIZE;
|
||||
if (++i>=n) {
|
||||
j++;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
} catch {
|
||||
if (unlock)
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
I64 NativeFSFilesDel(CPrt *p,U8 *cur_dir,U8 *files_find_mask,I64 fuf_flags,
|
||||
Bool del_dir,Bool print_msg)
|
||||
{
|
||||
CDirEntry *buf,*buf2,*ptr;
|
||||
I64 i=0,result=0,ch,j=0,n=BLK_SIZE/CDIR_SIZE,cur_dir_cluster;
|
||||
Bool unlock_break;
|
||||
try {
|
||||
unlock_break=BreakLock;
|
||||
PrtLock(p);
|
||||
cur_dir_cluster=Name2DirCluster(p,cur_dir);
|
||||
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(p,buf2,cur_dir_cluster,1);
|
||||
|
||||
ptr=buf2(U8 *)-offset(CDirEntry.start);
|
||||
buf=MAlloc(ptr->size);
|
||||
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
|
||||
Free(buf2);
|
||||
|
||||
ptr=buf(U8 *)-offset(CDirEntry.start);
|
||||
*ptr->name='.';
|
||||
ptr->name[1]=0;
|
||||
while (TRUE) {
|
||||
if (!(ch=*ptr->name))
|
||||
break;
|
||||
else if (!(ptr->attr & _ATTR_DELETED) && ch!='.' && (del_dir ||
|
||||
!(ptr->attr & _ATTR_DIR)) &&
|
||||
FilesFindMatch(files_find_mask,ptr->name,fuf_flags)) {
|
||||
if (!(ptr->attr & _ATTR_DIR)) result++;
|
||||
if (print_msg) {
|
||||
PutDefine("ST_DELETE");
|
||||
"" ptr->name;
|
||||
NewLine;
|
||||
}
|
||||
ptr->attr|=_ATTR_DELETED;
|
||||
WBlks(p,buf(U8 *)+j<<BLK_SIZE_BITS,
|
||||
p->data+cur_dir_cluster*p->spc+j,1);
|
||||
NativeFSFreeClusters(p,ptr->cluster,
|
||||
(ptr->size+p->spc<<BLK_SIZE_BITS-1)/p->spc<<BLK_SIZE_BITS);
|
||||
}
|
||||
ptr(U8 *)+=CDIR_SIZE;
|
||||
if (++i>=n) {
|
||||
j++;
|
||||
i=0;
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
} catch {
|
||||
PrtUnlock(p);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 NativeFSFileWrite(CPrt *p,U8 *cur_dir,U8 *name,U8 *buf,I64 size,
|
||||
CDate spdt,I64 attr,Bool raw,
|
||||
CArcCompress **_ac2)
|
||||
{
|
||||
CDirEntry de;
|
||||
I64 c=0,flags=0,blk_cnt;
|
||||
CArcCompress *ac=NULL;
|
||||
Bool contiguous;
|
||||
MemSet(&de,0,sizeof(CDirEntry));
|
||||
if (_ac2) *_ac2=NULL;
|
||||
if (size<0) size=0;
|
||||
if (!spdt)
|
||||
spdt=GetCurTimeCDate;
|
||||
|
||||
if (p->type!=PT_NATIVE)
|
||||
PutDefineErr("ST_NOT_NATIVE");
|
||||
else if (!CFileNameTo(de.name,name))
|
||||
PutDefineErr("ST_INVALID_FILENAME");
|
||||
else {
|
||||
NativeFSFilesDel(p,cur_dir,de.name,0,FALSE,FALSE);
|
||||
attr=FileAttr(name,attr);
|
||||
attr|=_ATTR_CONTIGUOUS;
|
||||
contiguous=TRUE;
|
||||
de.expanded_size=size;
|
||||
if (attr&_ATTR_COMPRESSED && !raw) {
|
||||
ac=CompressBuf(buf,size,flags);
|
||||
size=ac->compressed_size;
|
||||
buf=ac;
|
||||
}
|
||||
de.size=size;
|
||||
de.xsum=ArcXSum(buf,size)^NATIVE_XSUM;
|
||||
if (blk_cnt=(size+BLK_SIZE-1)>>BLK_SIZE_BITS)
|
||||
c=ClusersAlloc(p,0,(blk_cnt+p->spc-1)/p->spc,contiguous);
|
||||
else
|
||||
c=INVALID_CLUSTER;
|
||||
de.cluster=c;
|
||||
de.attr=attr;
|
||||
de.datetime=spdt;
|
||||
if (blk_cnt)
|
||||
WClustersBlks(p,buf,c,blk_cnt);
|
||||
NativeFSDirNew(p,cur_dir,&de,TRUE);
|
||||
if (_ac2)
|
||||
*_ac2=ac;
|
||||
else
|
||||
Free(ac);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
CDirEntry *NativeFSFilesFind(U8 *files_find_mask,I64 fuf_flags,CDirEntry *parent=NULL)
|
||||
{
|
||||
CPrt *p=Fs->cur_prt;
|
||||
CDirEntry *buf,*buf2,*ptr,*result=NULL,*tempm;
|
||||
I64 ch,cur_dir_cluster;
|
||||
if (fuf_flags&~FUG_FILES_FIND)
|
||||
throw(EXCEPT_FUF,11);
|
||||
try {
|
||||
PrtLock(p);
|
||||
cur_dir_cluster=Name2DirCluster(p,Fs->cur_dir);
|
||||
buf2=MAlloc(p->spc<<BLK_SIZE_BITS);
|
||||
RClusters(p,buf2,cur_dir_cluster,1);
|
||||
|
||||
ptr=buf2(U8 *)-offset(CDirEntry.start);
|
||||
buf=MAlloc(ptr->size);
|
||||
RClustersBlks(p,buf,cur_dir_cluster,ptr->size>>BLK_SIZE_BITS);
|
||||
Free(buf2);
|
||||
|
||||
ptr=buf(U8 *)-offset(CDirEntry.start);
|
||||
*ptr->name='.';
|
||||
ptr->name[1]=0;
|
||||
ptr(U8 *)+=CDIR_SIZE;
|
||||
ptr->cluster=Name2ParentDirCluster(p,Fs->cur_dir);
|
||||
ptr(U8 *)-=CDIR_SIZE;
|
||||
while (TRUE) {
|
||||
if (!(ch=*ptr->name))
|
||||
break;
|
||||
else if (!(ptr->attr & _ATTR_DELETED)) {
|
||||
tempm=CAlloc(sizeof(CDirEntry));
|
||||
MemCpy(&tempm->start,&ptr->start,CDIR_SIZE);
|
||||
tempm->parent=parent;
|
||||
if (Bt(&fuf_flags,FUf_RECURSE) && tempm->attr&_ATTR_DIR && *tempm->name!='.') {
|
||||
tempm->next=result;
|
||||
result=tempm;
|
||||
tempm->full_name=DirNameAbs(tempm->name);
|
||||
PrtUnlock(p);
|
||||
if (Cd(tempm->name)) {
|
||||
tempm->sub=NativeFSFilesFind(files_find_mask,fuf_flags,tempm);
|
||||
Cd("..");
|
||||
}
|
||||
PrtLock(p);
|
||||
} else if ((tempm->attr&_ATTR_DIR || !Bt(&fuf_flags,FUf_JUST_DIRS)) &&
|
||||
!(Bt(&fuf_flags,FUf_RECURSE) && *tempm->name=='.' && tempm->attr&_ATTR_DIR) &&
|
||||
FilesFindMatch(files_find_mask,tempm->name,fuf_flags)) {
|
||||
tempm->next=result;
|
||||
result=tempm;
|
||||
tempm->full_name=FileNameAbs(tempm->name);
|
||||
} else
|
||||
CDirEntryDel(tempm);
|
||||
}
|
||||
ptr(U8 *)+=CDIR_SIZE;
|
||||
}
|
||||
Free(buf);
|
||||
PrtUnlock(p);
|
||||
} catch
|
||||
PrtUnlock(p);
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool NativeFSMkDir(CPrt *p,U8 *cur_dir,U8 *name)
|
||||
{
|
||||
I64 size=p->spc<<BLK_SIZE_BITS,c,
|
||||
cur_dir_cluster=Name2DirCluster(p,cur_dir);
|
||||
U8 *buf=CAlloc(size);
|
||||
CDirEntry *d_native=buf-offset(CDirEntry.start);
|
||||
Bool unlock_break;
|
||||
|
||||
try {
|
||||
unlock_break=BreakLock;
|
||||
c=FileWrite(name,buf,size,0,_ATTR_DIR,FALSE);
|
||||
d_native->attr=_ATTR_DIR|_ATTR_CONTIGUOUS;
|
||||
StrCpy(d_native->name,name);
|
||||
d_native->cluster=c;
|
||||
d_native->size=size;
|
||||
d_native->expanded_size=size;
|
||||
d_native->datetime=GetCurTimeCDate;
|
||||
d_native(U8 *)+=CDIR_SIZE;
|
||||
|
||||
d_native->attr=_ATTR_DIR|_ATTR_CONTIGUOUS;
|
||||
*d_native->name='.';
|
||||
d_native->name[1]='.';
|
||||
d_native->name[2]=0;
|
||||
d_native->cluster=cur_dir_cluster;
|
||||
d_native->size=0;
|
||||
d_native->expanded_size=0;
|
||||
d_native->datetime=GetCurTimeCDate;
|
||||
WClusters(p,buf,c,1);
|
||||
Free(buf);
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
} catch
|
||||
if (unlock_break)
|
||||
BreakUnlock;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
class CLine
|
||||
{
|
||||
CLine *next,*last;
|
||||
U8 *line;
|
||||
};
|
||||
|
||||
U0 EdLiteUpdate(CLine *root,CLine *cur_line,I64 cur_col,I64 line_start_col)
|
||||
{
|
||||
I64 ch,i,j,k,k2,cursor_col,cursor_row=-1;
|
||||
U8 *st;
|
||||
CLine *templ=cur_line;
|
||||
Bool done_eof=FALSE;
|
||||
sys_raw_dc_col=0;
|
||||
for (i=0;i<text_rows/2;i++)
|
||||
if (templ->last!=root)
|
||||
templ=templ->last;
|
||||
for (i=0;i<text_rows;i++) {
|
||||
if (cursor_row<0 && templ==cur_line) {
|
||||
k=0;
|
||||
for (j=0;j<cur_col;j++)
|
||||
if (templ->line[j]=='\t')
|
||||
k=(k+8)&~7;
|
||||
else
|
||||
k++;
|
||||
cursor_col=k;
|
||||
cursor_row=i;
|
||||
}
|
||||
if (templ!=root) {
|
||||
st=templ->line;
|
||||
k=0;
|
||||
j=0;
|
||||
while (ch=*st++) {
|
||||
if (ch=='\t')
|
||||
k2=(k+8)&~7;
|
||||
else
|
||||
k2=k+1;
|
||||
if (line_start_col<=k<line_start_col+text_cols) {
|
||||
'' ch;
|
||||
j=k2-line_start_col;
|
||||
}
|
||||
k=k2;
|
||||
}
|
||||
if (j<text_cols)
|
||||
NewLine;
|
||||
templ=templ->next;
|
||||
} else {
|
||||
if (!done_eof) {
|
||||
"<EOF>";
|
||||
done_eof=TRUE;
|
||||
}
|
||||
NewLine;
|
||||
}
|
||||
}
|
||||
sys_raw_dc_col=text_cols*cursor_row+cursor_col-line_start_col;
|
||||
RawPutChar(0x7F);
|
||||
}
|
||||
|
||||
|
||||
U0 EdLite(U8 *filename,I64 num=1)
|
||||
{
|
||||
//Light weight text editor for debugging
|
||||
U8 *src,*src2,*src3,*dst,*buf,*bin_data=NULL;
|
||||
I64 i,cnt=0,ch,sc,size,bin_size=0,line_start_col=0,cur_col=0,
|
||||
old_dc_flags=sys_raw_dc_flags;
|
||||
CLine root,*templ,*templ1,*cur_line;
|
||||
Bool old_raw=Raw(ON),
|
||||
old_debug=InDbg(ON),
|
||||
old_single=SingleUser(ON);
|
||||
|
||||
if (!filename) filename=sys_temp_filename;
|
||||
buf=FileRead(filename,&size);
|
||||
|
||||
PushFD;
|
||||
Cli;
|
||||
sys_raw_dc_flags=sys_raw_dc_flags&~RDCF_SCROLL|RDCF_SHOW_DOLLAR;
|
||||
sys_cur_scan_code=0;
|
||||
QueInit(&root);
|
||||
root.line=StrNew("");
|
||||
|
||||
if (buf) {
|
||||
src=buf;
|
||||
while (*src) {
|
||||
src2=src;
|
||||
while ((ch=*src++) && ch!=CH_CARRIAGE_RETURN && ch!='\n');
|
||||
src--;
|
||||
*src++=0;
|
||||
if (!ch)
|
||||
src--;
|
||||
while (ch==CH_CARRIAGE_RETURN && *src=='\n' || *src==CH_CURSOR)
|
||||
src++;
|
||||
dst=src3=src2;
|
||||
while (ch=*src3++)
|
||||
if (ch!='\n' && ch!=CH_CURSOR)
|
||||
*dst++=ch;
|
||||
*dst=0;
|
||||
|
||||
templ=MAlloc(sizeof(CLine));
|
||||
templ->line=StrNew(src2);
|
||||
QueIns(templ,root.last);
|
||||
cnt++;
|
||||
}
|
||||
|
||||
if (src+1-buf<size) {
|
||||
bin_data=MAlloc(bin_size=size-(src-buf));
|
||||
MemCpy(bin_data,src,bin_size);
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
cur_line=root.next;
|
||||
if (0<--num) {
|
||||
if (num<cnt)
|
||||
while (num--)
|
||||
cur_line=cur_line->next;
|
||||
else
|
||||
cur_line=&root;
|
||||
}
|
||||
do {
|
||||
if (cur_line==&root)
|
||||
cur_col=0;
|
||||
while (cur_col-line_start_col<0)
|
||||
line_start_col-=8;
|
||||
while (cur_col-line_start_col>=text_cols)
|
||||
line_start_col+=8;
|
||||
EdLiteUpdate(&root,cur_line,cur_col,line_start_col);
|
||||
switch (ch=GetKey(&sc,FALSE,TRUE)) {
|
||||
case 0:
|
||||
switch (sc.u8[0]) {
|
||||
case SC_CURSOR_UP:
|
||||
if (cur_line->last!=&root)
|
||||
cur_line=cur_line->last;
|
||||
if (cur_col>StrLen(cur_line->line))
|
||||
cur_col=StrLen(cur_line->line);
|
||||
break;
|
||||
case SC_CURSOR_DOWN:
|
||||
if (cur_line!=&root)
|
||||
cur_line=cur_line->next;
|
||||
if (cur_col>StrLen(cur_line->line))
|
||||
cur_col=StrLen(cur_line->line);
|
||||
break;
|
||||
case SC_CURSOR_RIGHT:
|
||||
cur_col++;
|
||||
if (cur_col>StrLen(cur_line->line)) {
|
||||
templ=cur_line->next;
|
||||
if (templ!=&root) {
|
||||
cur_col=0;
|
||||
cur_line=templ;
|
||||
} else
|
||||
cur_col=StrLen(cur_line->line);
|
||||
}
|
||||
break;
|
||||
case SC_CURSOR_LEFT:
|
||||
if (cur_col)
|
||||
cur_col--;
|
||||
else {
|
||||
templ=cur_line->last;
|
||||
if (templ!=&root) {
|
||||
cur_line=templ;
|
||||
cur_col=StrLen(templ->line);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_PAGE_UP:
|
||||
for (i=1;i<text_rows;i++) {
|
||||
if (cur_line->last!=&root)
|
||||
cur_line=cur_line->last;
|
||||
if (cur_col>StrLen(cur_line->line))
|
||||
cur_col=StrLen(cur_line->line);
|
||||
}
|
||||
break;
|
||||
case SC_PAGE_DOWN:
|
||||
for (i=1;i<text_rows;i++) {
|
||||
if (cur_line!=&root)
|
||||
cur_line=cur_line->next;
|
||||
if (cur_col>StrLen(cur_line->line))
|
||||
cur_col=StrLen(cur_line->line);
|
||||
}
|
||||
break;
|
||||
case SC_DELETE:
|
||||
if (cur_col==StrLen(cur_line->line)) {
|
||||
templ=cur_line->next;
|
||||
if (cur_line!=&root && templ!=&root) {
|
||||
src=MAlloc(StrLen(cur_line->line)+StrLen(templ->line)+1);
|
||||
StrCpy(src,cur_line->line);
|
||||
StrCat(src,templ->line);
|
||||
Free(cur_line->line);
|
||||
Free(templ->line);
|
||||
cur_line->line=src;
|
||||
QueRem(templ);
|
||||
Free(templ);
|
||||
}
|
||||
} else
|
||||
StrCpy(cur_line->line+cur_col,cur_line->line+cur_col+1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
case CH_CARRIAGE_RETURN:
|
||||
templ=MAlloc(sizeof(CLine));
|
||||
templ->line=StrNew(cur_line->line+cur_col);
|
||||
cur_line->line[cur_col]=0;
|
||||
QueIns(templ,cur_line);
|
||||
cur_line=templ;
|
||||
cur_col=0;
|
||||
break;
|
||||
case CH_BACKSPACE:
|
||||
if (cur_col) {
|
||||
StrCpy(cur_line->line+cur_col-1,cur_line->line+cur_col);
|
||||
cur_col--;
|
||||
} else if (cur_line!=&root && cur_line->last!=&root) {
|
||||
templ=cur_line->last;
|
||||
src=MAlloc(StrLen(cur_line->line)+StrLen(templ->line)+1);
|
||||
StrCpy(src,templ->line);
|
||||
StrCat(src,cur_line->line);
|
||||
cur_col=StrLen(templ->line);
|
||||
Free(cur_line->line);
|
||||
Free(templ->line);
|
||||
templ->line=src;
|
||||
QueRem(cur_line);
|
||||
Free(cur_line);
|
||||
cur_line=templ;
|
||||
}
|
||||
break;
|
||||
case CH_CTRLY:
|
||||
if (cur_line!=&root) {
|
||||
templ=cur_line;
|
||||
cur_line=cur_line->next;
|
||||
QueRem(templ);
|
||||
Free(templ->line);
|
||||
Free(templ);
|
||||
cur_col=0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (Bt(getkey_chars_bitmap,ch)) {
|
||||
if (cur_line==&root) {
|
||||
cur_line=MAlloc(sizeof(CLine));
|
||||
cur_line->line=StrNew("");
|
||||
QueIns(cur_line,root.last);
|
||||
}
|
||||
src=MAlloc(StrLen(cur_line->line)+2);
|
||||
MemCpy(src,cur_line->line,cur_col);
|
||||
src[cur_col]=ch;
|
||||
if (cur_col<StrLen(cur_line->line))
|
||||
StrCpy(src+cur_col+1,cur_line->line+cur_col);
|
||||
else
|
||||
src[cur_col+1]=0;
|
||||
Free(cur_line->line);
|
||||
cur_line->line=src;
|
||||
cur_col++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (ch!=CH_SHIFT_ESC && ch!=CH_ESC);
|
||||
|
||||
if (ch==CH_ESC) {
|
||||
size=bin_size;
|
||||
|
||||
templ=root.next;
|
||||
while (templ!=&root) {
|
||||
size+=StrLen(templ->line)+1;
|
||||
templ=templ->next;
|
||||
}
|
||||
|
||||
buf=dst=MAlloc(size);
|
||||
templ=root.next;
|
||||
while (templ!=&root) {
|
||||
i=StrLen(templ->line);
|
||||
MemCpy(dst,templ->line,i);
|
||||
dst+=i;
|
||||
*dst++='\n';
|
||||
templ=templ->next;
|
||||
}
|
||||
if (bin_data)
|
||||
MemCpy(dst,bin_data,bin_size);
|
||||
FileWrite(filename,buf,size);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
templ=root.next;
|
||||
while (templ!=&root) {
|
||||
templ1=templ->next;
|
||||
QueRem(templ);
|
||||
Free(templ->line);
|
||||
Free(templ);
|
||||
templ=templ1;
|
||||
}
|
||||
Free(root.line);
|
||||
Free(bin_data);
|
||||
Raw(old_raw);
|
||||
InDbg(old_debug);
|
||||
SingleUser(old_single);
|
||||
sys_raw_dc_flags=sys_raw_dc_flags&~RDCF_SHOW_DOLLAR|old_dc_flags&RDCF_SHOW_DOLLAR;
|
||||
PopFD;
|
||||
}
|
||||
|
||||
U0 EdLiteFileLine(U8 *_fl_file_line)
|
||||
{
|
||||
U8 *st,*fl_file_line=StrNew(_fl_file_line);
|
||||
I64 linenum;
|
||||
StrFirstRem(fl_file_line,":");
|
||||
st=StrNew(fl_file_line);
|
||||
StrLastRem(fl_file_line,",",st);
|
||||
linenum=A2I(st);
|
||||
Free(st);
|
||||
EdLite(fl_file_line,linenum);
|
||||
Free(fl_file_line);
|
||||
}
|
||||
|
||||
U0 SetFix(U8 *filename,I64 line)
|
||||
{
|
||||
U8 *st=MSPrintF("FL:%s,%d",filename,line);
|
||||
while (LBts(&sys_semas[SYS_SEMA_FIX],0))
|
||||
Yield;
|
||||
Free(sys_fix_file_line);
|
||||
sys_fix_file_line=AStrNew(st);
|
||||
LBtr(&sys_semas[SYS_SEMA_FIX],0);
|
||||
}
|
||||
|
||||
U0 Fix()
|
||||
{//Fix last compile err
|
||||
U8 *st;
|
||||
|
||||
while (LBts(&sys_semas[SYS_SEMA_FIX],0))
|
||||
Yield;
|
||||
st=StrNew(sys_fix_file_line);
|
||||
LBtr(&sys_semas[SYS_SEMA_FIX],0);
|
||||
|
||||
if (st) {
|
||||
if (IsRaw)
|
||||
EdLiteFileLine(st);
|
||||
else
|
||||
Ed(st);
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
I64 ExceptDepth(CTask *task=NULL)
|
||||
{
|
||||
CExcept *tempt;
|
||||
I64 result=0;
|
||||
if (!task) task=Fs;
|
||||
tempt=task->next_except;
|
||||
while (tempt!=&task->next_except) {
|
||||
result++;
|
||||
tempt=tempt->next;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
asm {
|
||||
USE64
|
||||
#assert !((CREG_NON_PTR_MASK|CREG_VARS_MASK)&~0xFCC0)
|
||||
_TEST_EXCEPT::
|
||||
XOR RAX,RAX
|
||||
MOV RAX,FS:U64 CTask.last_except[RAX]
|
||||
MOV RBP,U64 CExcept.rbp[RAX]
|
||||
MOV RSI,U64 CExcept.rsi[RAX]
|
||||
MOV RDI,U64 CExcept.rdi[RAX]
|
||||
MOV R10,U64 CExcept.r10[RAX]
|
||||
MOV R11,U64 CExcept.r11[RAX]
|
||||
MOV R12,U64 CExcept.r12[RAX]
|
||||
MOV R13,U64 CExcept.r13[RAX]
|
||||
MOV R14,U64 CExcept.r14[RAX]
|
||||
MOV R15,U64 CExcept.r15[RAX]
|
||||
PUSH U64 CExcept.rflags[RAX]
|
||||
POPFD
|
||||
JMP U64 CExcept.handler_catch[RAX]
|
||||
|
||||
_TAKE_EXCEPT::
|
||||
XOR RAX,RAX
|
||||
MOV RAX,FS:U64 CTask.last_except[RAX]
|
||||
MOV RSP,U64 CExcept.rsp[RAX]
|
||||
JMP U64 CExcept.handler_untry[RAX]
|
||||
|
||||
_SAVE_EXCEPT_REGS::
|
||||
ENTER 0
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
MOV U64 CExcept.rsi[RAX],RSI
|
||||
MOV U64 CExcept.rdi[RAX],RDI
|
||||
MOV U64 CExcept.r10[RAX],R10
|
||||
MOV U64 CExcept.r11[RAX],R11
|
||||
MOV U64 CExcept.r12[RAX],R12
|
||||
MOV U64 CExcept.r13[RAX],R13
|
||||
MOV U64 CExcept.r14[RAX],R14
|
||||
MOV U64 CExcept.r15[RAX],R15
|
||||
LEAVE
|
||||
RET1 8
|
||||
}
|
||||
|
||||
_extern _TEST_EXCEPT U0 TestExcept();
|
||||
_extern _TAKE_EXCEPT U0 TakeExcept();
|
||||
_extern _SAVE_EXCEPT_REGS U0 SaveExceptRegs(CExcept *t);
|
||||
|
||||
#exe {OptOn(OPTf_NO_REG_VAR);};
|
||||
|
||||
class CTryStk
|
||||
{
|
||||
I64 rbp;
|
||||
I64 ret_rip;
|
||||
I64 arg1;
|
||||
I64 arg2;
|
||||
};
|
||||
|
||||
U0 SysTry(U8 *catch_start,U8 *untry_start)
|
||||
{
|
||||
I64 *rbp=GetBasePtr,old_flags=GetFlags;
|
||||
CExcept *tempt=MAlloc(sizeof(CExcept));
|
||||
tempt->handler_catch=catch_start;
|
||||
tempt->handler_untry=untry_start;
|
||||
tempt->rsp=rbp(U8 *)+sizeof(CTryStk);
|
||||
tempt->rbp=*rbp;
|
||||
tempt->rflags=old_flags;
|
||||
SaveExceptRegs(tempt);
|
||||
Cli;
|
||||
QueIns(tempt,Fs->last_except);
|
||||
SetFlags(old_flags);
|
||||
}
|
||||
|
||||
U0 SysUntry()
|
||||
{
|
||||
CExcept *tempt=Fs->last_except;
|
||||
PushFD;
|
||||
//The adam task sometimes probes except depth,
|
||||
//so we lock it out. A probe from a multicore
|
||||
//would fail, but who'd want to do that?
|
||||
Cli;
|
||||
QueRem(tempt);
|
||||
PopFD;
|
||||
Free(tempt);
|
||||
}
|
||||
|
||||
U0 AdamLogExcept(I64 argc,I64 *argv)
|
||||
{
|
||||
I64 i;
|
||||
if (!Gs->num) { //TODO: Other cores
|
||||
AdamLog("Depth:%02X Task:%08X throw(",
|
||||
ExceptDepth(Fs),Fs);
|
||||
for (i=0;i<argc;i++) {
|
||||
AdamLog("%X",argv[i]);
|
||||
if (i<argc-1)
|
||||
AdamLog(",");
|
||||
}
|
||||
AdamLog(");\n");
|
||||
}
|
||||
}
|
||||
|
||||
U0 PutExcept()
|
||||
{
|
||||
I64 i;
|
||||
if (Fs->except_argc>0) {
|
||||
if (Fs->except_argv[0]<DefineSubCnt("ST_EXCEPT_TYPES")) {
|
||||
"Exception Type :%Z\n",Fs->except_argv[0],"ST_EXCEPT_TYPES";
|
||||
if (Fs->except_argv[0]==EXCEPT_UNDEF_DEFINE)
|
||||
"Name:'%s'\n",Fs->except_argv[1];
|
||||
else if (Fs->except_argv[0]==EXCEPT_DIVIDE_BY_ZERO)
|
||||
"Addr:%P\n",Fs->except_argv[1];
|
||||
else {
|
||||
for (i=1;i<Fs->except_argc;i++)
|
||||
"%016X ",Fs->except_argv[i];
|
||||
NewLine;
|
||||
}
|
||||
} else {
|
||||
"Exception:";
|
||||
for (i=0;i<Fs->except_argc;i++)
|
||||
"%016X ",Fs->except_argv[i];
|
||||
NewLine;
|
||||
}
|
||||
} else
|
||||
"Generic Exception\n";
|
||||
}
|
||||
|
||||
U0 throw_join(I64 argc,I64 *argv)
|
||||
{
|
||||
CExcept *tempt=Fs->last_except;
|
||||
Bool was_raw;
|
||||
|
||||
Fs->except_argc=argc;
|
||||
Fs->except_argv=argv;
|
||||
Fs->except_rbp=GetBasePtr;
|
||||
Fs->catch_except=FALSE;
|
||||
while (Fs->next_except!=&Fs->next_except) {
|
||||
TestExcept;
|
||||
if (Fs->catch_except)
|
||||
TakeExcept;
|
||||
SetBasePtr(Fs->except_rbp);
|
||||
tempt=Fs->last_except;
|
||||
QueRem(tempt);
|
||||
Free(tempt);
|
||||
}
|
||||
was_raw=Raw(ON);
|
||||
PutExcept;
|
||||
Dbg("Unhandled Exception");
|
||||
Raw(was_raw);
|
||||
}
|
||||
|
||||
U0 throw_no_log(...)
|
||||
{
|
||||
throw_join(argc,argv);
|
||||
}
|
||||
|
||||
U0 throw(...)
|
||||
{
|
||||
AdamLogExcept(argc,argv);
|
||||
throw_join(argc,argv);
|
||||
}
|
||||
|
||||
#exe {OptOff(OPTf_NO_REG_VAR);};
|
||||
|
||||
U0 SysThrowBreak()
|
||||
{
|
||||
if (Bt(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC))
|
||||
Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0x20100000201);
|
||||
else { //TODO: Might want lock
|
||||
Fs->wake_jiffy=0;
|
||||
TaskRstAwaitingMsg;
|
||||
PrtsRelease();
|
||||
BlkDevsRelease();
|
||||
FlushMsgs;
|
||||
throw(EXCEPT_BREAK);
|
||||
}
|
||||
}
|
||||
|
||||
//This can be used to exit an app, but not a task.
|
||||
U0 ThrowBreak(CTask *task=NULL)
|
||||
{
|
||||
if (task && task!=Fs) {
|
||||
if (!TaskValidate(task)) return;
|
||||
//TODO: Might want lock
|
||||
sys_focus_task=task;
|
||||
LBts(sys_ctrl_alt_flags,SYSf_CTRL_ALT_C);
|
||||
} else
|
||||
SysThrowBreak;
|
||||
}
|
||||
|
||||
Bool BreakLock(CTask *task=NULL)
|
||||
{
|
||||
if (!task) task=Fs;
|
||||
return !LBts(&task->task_flags,TASKf_BREAK_LOCKED);
|
||||
}
|
||||
|
||||
Bool BreakUnlock(CTask *task=NULL)
|
||||
{
|
||||
Bool result;
|
||||
if (!task) task=Fs;
|
||||
result=LBtr(&task->task_flags,TASKf_BREAK_LOCKED);
|
||||
if (LBtr(&task->task_flags,TASKf_PENDING_BREAK)) {
|
||||
if (task==Fs)
|
||||
ThrowBreak;
|
||||
else
|
||||
task->rip=&ThrowBreak;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 CatchAll()
|
||||
{
|
||||
PutExcept;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
CFifoU8 *FifoU8New(I64 size,CTask *mem_task=NULL)
|
||||
{
|
||||
CFifoU8 *f;
|
||||
if (!mem_task) mem_task=Fs;
|
||||
f=MAlloc(sizeof(CFifoU8),mem_task);
|
||||
f->buf=MAlloc(size,mem_task);
|
||||
f->mask=size-1;
|
||||
f->in_ptr=0;
|
||||
f->out_ptr=0;
|
||||
return f;
|
||||
}
|
||||
|
||||
U0 FifoU8Del(CFifoU8 *f)
|
||||
{
|
||||
Free(f->buf);
|
||||
Free(f);
|
||||
}
|
||||
|
||||
Bool FifoU8Ins(CFifoU8 *f,U8 b)
|
||||
{
|
||||
I64 new_in_ptr;
|
||||
PushFD;
|
||||
Cli;
|
||||
new_in_ptr=(f->in_ptr+1)&f->mask;
|
||||
if (new_in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
f->buf[f->in_ptr]=b;
|
||||
f->in_ptr=new_in_ptr;
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool FifoU8Rem(CFifoU8 *f,U8 *_b)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
*_b=f->buf[f->out_ptr];
|
||||
f->out_ptr=(f->out_ptr+1)&f->mask;
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool FifoU8Peek(CFifoU8 *f,U8 *_b)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
*_b=f->buf[f->out_ptr];
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 FifoU8Flush(CFifoU8 *f)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
f->out_ptr=f->in_ptr;
|
||||
PopFD;
|
||||
}
|
||||
|
||||
I64 FifoU8Cnt(CFifoU8 *f)
|
||||
{
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->out_ptr>f->in_ptr)
|
||||
result=f->mask+1-(f->out_ptr-f->in_ptr);
|
||||
else
|
||||
result=f->in_ptr-f->out_ptr;
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
|
||||
CFifoI64 *FifoI64New(I64 size,CTask *mem_task=NULL)
|
||||
{
|
||||
CFifoI64 *f;
|
||||
if (!mem_task) mem_task=Fs;
|
||||
f=MAlloc(sizeof(CFifoI64),mem_task);
|
||||
f->buf=MAlloc(size*sizeof(I64),mem_task);
|
||||
f->mask=size-1;
|
||||
f->in_ptr=0;
|
||||
f->out_ptr=0;
|
||||
return f;
|
||||
}
|
||||
|
||||
U0 FifoI64Del(CFifoI64 *f)
|
||||
{
|
||||
Free(f->buf);
|
||||
Free(f);
|
||||
}
|
||||
|
||||
Bool FifoI64Ins(CFifoI64 *f,I64 q)
|
||||
{
|
||||
I64 new_in_ptr;
|
||||
PushFD;
|
||||
Cli;
|
||||
new_in_ptr=(f->in_ptr+1)&f->mask;
|
||||
if (new_in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
f->buf[f->in_ptr]=q;
|
||||
f->in_ptr=new_in_ptr;
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool FifoI64Rem(CFifoI64 *f,I64 *_q)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
*_q=f->buf[f->out_ptr];
|
||||
f->out_ptr=(f->out_ptr+1)&f->mask;
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
Bool FifoI64Peek(CFifoI64 *f,I64 *_q)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->in_ptr==f->out_ptr) {
|
||||
PopFD;
|
||||
return FALSE;
|
||||
} else {
|
||||
*_q=f->buf[f->out_ptr];
|
||||
PopFD;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
U0 FifoI64Flush(CFifoI64 *f)
|
||||
{
|
||||
PushFD;
|
||||
Cli;
|
||||
f->out_ptr=f->in_ptr;
|
||||
PopFD;
|
||||
}
|
||||
|
||||
I64 FifoI64Cnt(CFifoI64 *f)
|
||||
{
|
||||
I64 result;
|
||||
PushFD;
|
||||
Cli;
|
||||
if (f->out_ptr>f->in_ptr)
|
||||
result=f->mask+1-(f->out_ptr-f->in_ptr);
|
||||
else
|
||||
result=f->in_ptr-f->out_ptr;
|
||||
PopFD;
|
||||
return result;
|
||||
}
|
||||
@@ -0,0 +1,261 @@
|
||||
//See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (1).
|
||||
|
||||
U8 sys_font_8x8[256*8]= {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x18,0x3C,0x3C,0x18,0x18,0x00,0x18,0x00,
|
||||
0x36,0x36,0x36,0x00,0x00,0x00,0x00,0x00,
|
||||
0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00,
|
||||
0x30,0xFC,0x16,0x7C,0xD0,0x7E,0x18,0x00,
|
||||
0x06,0x66,0x30,0x18,0x0C,0x66,0x60,0x00,
|
||||
0x1C,0x36,0x36,0x1C,0xB6,0x66,0xDC,0x00,
|
||||
0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
|
||||
0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00,
|
||||
0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00,
|
||||
0x00,0x18,0x7E,0x3C,0x7E,0x18,0x00,0x00,
|
||||
0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x0C,
|
||||
0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,
|
||||
0x00,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,
|
||||
0x3C,0x66,0x76,0x7E,0x6E,0x66,0x3C,0x00,
|
||||
0x18,0x1C,0x18,0x18,0x18,0x18,0x7E,0x00,
|
||||
0x3C,0x66,0x60,0x30,0x18,0x0C,0x7E,0x00,
|
||||
0x3C,0x66,0x60,0x38,0x60,0x66,0x3C,0x00,
|
||||
0x30,0x38,0x3C,0x36,0x7E,0x30,0x30,0x00,
|
||||
0x7E,0x06,0x3E,0x60,0x60,0x66,0x3C,0x00,
|
||||
0x38,0x0C,0x06,0x3E,0x66,0x66,0x3C,0x00,
|
||||
0x7E,0x60,0x30,0x18,0x0C,0x0C,0x0C,0x00,
|
||||
0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00,
|
||||
0x3C,0x66,0x66,0x7C,0x60,0x30,0x1C,0x00,
|
||||
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x00,
|
||||
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x0C,
|
||||
0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,
|
||||
0x00,0x00,0x7E,0x00,0x7E,0x00,0x00,0x00,
|
||||
0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,
|
||||
0x3C,0x66,0x30,0x18,0x18,0x00,0x18,0x00,
|
||||
0x3C,0x66,0x76,0x56,0x76,0x06,0x3C,0x00,
|
||||
0x3C,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,
|
||||
0x3E,0x66,0x66,0x3E,0x66,0x66,0x3E,0x00,
|
||||
0x3C,0x66,0x06,0x06,0x06,0x66,0x3C,0x00,
|
||||
0x1E,0x36,0x66,0x66,0x66,0x36,0x1E,0x00,
|
||||
0x7E,0x06,0x06,0x3E,0x06,0x06,0x7E,0x00,
|
||||
0x7E,0x06,0x06,0x3E,0x06,0x06,0x06,0x00,
|
||||
0x3C,0x66,0x06,0x76,0x66,0x66,0x3C,0x00,
|
||||
0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00,
|
||||
0x7E,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,
|
||||
0x7C,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,
|
||||
0x66,0x36,0x1E,0x0E,0x1E,0x36,0x66,0x00,
|
||||
0x06,0x06,0x06,0x06,0x06,0x06,0x7E,0x00,
|
||||
0xC6,0xEE,0xFE,0xD6,0xD6,0xC6,0xC6,0x00,
|
||||
0x66,0x66,0x6E,0x7E,0x76,0x66,0x66,0x00,
|
||||
0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,
|
||||
0x3E,0x66,0x66,0x3E,0x06,0x06,0x06,0x00,
|
||||
0x3C,0x66,0x66,0x66,0x56,0x36,0x6C,0x00,
|
||||
0x3E,0x66,0x66,0x3E,0x36,0x66,0x66,0x00,
|
||||
0x3C,0x66,0x06,0x3C,0x60,0x66,0x3C,0x00,
|
||||
0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x00,
|
||||
0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,
|
||||
0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,
|
||||
0xC6,0xC6,0xD6,0xD6,0xFE,0xEE,0xC6,0x00,
|
||||
0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,
|
||||
0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x00,
|
||||
0x7E,0x60,0x30,0x18,0x0C,0x06,0x7E,0x00,
|
||||
0x3E,0x06,0x06,0x06,0x06,0x06,0x3E,0x00,
|
||||
0x00,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,
|
||||
0x7C,0x60,0x60,0x60,0x60,0x60,0x7C,0x00,
|
||||
0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,
|
||||
0x0C,0x18,0x30,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x3C,0x60,0x7C,0x66,0x7C,0x00,
|
||||
0x06,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00,
|
||||
0x00,0x00,0x3C,0x66,0x06,0x66,0x3C,0x00,
|
||||
0x60,0x60,0x7C,0x66,0x66,0x66,0x7C,0x00,
|
||||
0x00,0x00,0x3C,0x66,0x7E,0x06,0x3C,0x00,
|
||||
0x38,0x0C,0x0C,0x3E,0x0C,0x0C,0x0C,0x00,
|
||||
0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0x3C,
|
||||
0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x00,
|
||||
0x18,0x00,0x1C,0x18,0x18,0x18,0x3C,0x00,
|
||||
0x18,0x00,0x1C,0x18,0x18,0x18,0x18,0x0E,
|
||||
0x06,0x06,0x66,0x36,0x1E,0x36,0x66,0x00,
|
||||
0x1C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,
|
||||
0x00,0x00,0x6C,0xFE,0xD6,0xD6,0xC6,0x00,
|
||||
0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x00,
|
||||
0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00,
|
||||
0x00,0x00,0x3E,0x66,0x66,0x3E,0x06,0x06,
|
||||
0x00,0x00,0x7C,0x66,0x66,0x7C,0x60,0xE0,
|
||||
0x00,0x00,0x36,0x6E,0x06,0x06,0x06,0x00,
|
||||
0x00,0x00,0x7C,0x06,0x3C,0x60,0x3E,0x00,
|
||||
0x0C,0x0C,0x3E,0x0C,0x0C,0x0C,0x38,0x00,
|
||||
0x00,0x00,0x66,0x66,0x66,0x66,0x7C,0x00,
|
||||
0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00,
|
||||
0x00,0x00,0xC6,0xD6,0xD6,0xFE,0x6C,0x00,
|
||||
0x00,0x00,0x66,0x3C,0x18,0x3C,0x66,0x00,
|
||||
0x00,0x00,0x66,0x66,0x66,0x7C,0x60,0x3C,
|
||||
0x00,0x00,0x7E,0x30,0x18,0x0C,0x7E,0x00,
|
||||
0x30,0x18,0x18,0x0E,0x18,0x18,0x30,0x00,
|
||||
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,
|
||||
0x0C,0x18,0x18,0x70,0x18,0x18,0x0C,0x00,
|
||||
0x8C,0xD6,0x62,0x00,0x00,0x00,0x00,0x00,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
|
||||
0x1E,0x33,0x03,0x33,0x1E,0x18,0x30,0x1E,
|
||||
0x00,0x33,0x00,0x33,0x33,0x33,0x7E,0x00,
|
||||
0x38,0x00,0x1E,0x33,0x3F,0x03,0x1E,0x00,
|
||||
0x7E,0xC3,0x3C,0x60,0x7C,0x66,0xFC,0x00,
|
||||
0x33,0x00,0x1E,0x30,0x3E,0x33,0x7E,0x00,
|
||||
0x07,0x00,0x1E,0x30,0x3E,0x33,0x7E,0x00,
|
||||
0x0C,0x0C,0x1E,0x30,0x3E,0x33,0x7E,0x00,
|
||||
0x00,0x00,0x3E,0x03,0x03,0x3E,0x60,0x3C,
|
||||
0x7E,0xC3,0x3C,0x66,0x7E,0x06,0x3C,0x00,
|
||||
0x33,0x00,0x1E,0x33,0x3F,0x03,0x1E,0x00,
|
||||
0x07,0x00,0x1E,0x33,0x3F,0x03,0x1E,0x00,
|
||||
0x33,0x00,0x0E,0x0C,0x0C,0x0C,0x1E,0x00,
|
||||
0x3E,0x63,0x1C,0x18,0x18,0x18,0x3C,0x00,
|
||||
0x07,0x00,0x0E,0x0C,0x0C,0x0C,0x1E,0x00,
|
||||
0x33,0x0C,0x1E,0x33,0x33,0x3F,0x33,0x00,
|
||||
0x0C,0x0C,0x00,0x1E,0x33,0x3F,0x33,0x00,
|
||||
0x38,0x00,0x3F,0x06,0x1E,0x06,0x3F,0x00,
|
||||
0x00,0x00,0xFE,0x30,0xFE,0x33,0xFE,0x00,
|
||||
0x7C,0x36,0x33,0x7F,0x33,0x33,0x73,0x00,
|
||||
0x1E,0x33,0x00,0x1E,0x33,0x33,0x1E,0x00,
|
||||
0x00,0x33,0x00,0x1E,0x33,0x33,0x1E,0x00,
|
||||
0x00,0x07,0x00,0x1E,0x33,0x33,0x1E,0x00,
|
||||
0x1E,0x33,0x00,0x33,0x33,0x33,0x7E,0x00,
|
||||
0x00,0x07,0x00,0x33,0x33,0x33,0x7E,0x00,
|
||||
0x00,0x33,0x00,0x33,0x33,0x3F,0x30,0x1F,
|
||||
0x63,0x1C,0x3E,0x63,0x63,0x3E,0x1C,0x00,
|
||||
0x33,0x00,0x33,0x33,0x33,0x33,0x1E,0x00,
|
||||
0x18,0x18,0x7E,0x03,0x03,0x7E,0x18,0x18,
|
||||
0x1C,0x36,0x26,0x0F,0x06,0x67,0x3F,0x00,
|
||||
0x33,0x33,0x1E,0x3F,0x0C,0x3F,0x0C,0x00,
|
||||
0x0F,0x1B,0x1B,0x2F,0x33,0x7B,0x33,0x70,
|
||||
0x70,0xD8,0x18,0x7E,0x18,0x18,0x1B,0x0E,
|
||||
0x38,0x00,0x1E,0x30,0x3E,0x33,0x7E,0x00,
|
||||
0x1C,0x00,0x0E,0x0C,0x0C,0x0C,0x1E,0x00,
|
||||
0x00,0x38,0x00,0x1E,0x33,0x33,0x1E,0x00,
|
||||
0x00,0x38,0x00,0x33,0x33,0x33,0x7E,0x00,
|
||||
0x00,0x1F,0x00,0x1F,0x33,0x33,0x33,0x00,
|
||||
0x3F,0x00,0x33,0x37,0x3F,0x3B,0x33,0x00,
|
||||
0x3C,0x36,0x36,0x7C,0x00,0x7E,0x00,0x00,
|
||||
0x3C,0x66,0x66,0x3C,0x00,0x7E,0x00,0x00,
|
||||
0x0C,0x00,0x0C,0x06,0x03,0x33,0x1E,0x00,
|
||||
0x00,0x00,0x00,0x3F,0x03,0x03,0x00,0x00,
|
||||
0x00,0x00,0x00,0x3F,0x30,0x30,0x00,0x00,
|
||||
0x63,0x33,0x1B,0x7C,0xC6,0x73,0x19,0xF8,
|
||||
0x63,0x33,0x1B,0xCF,0xE6,0xF3,0xF9,0xC0,
|
||||
0x00,0x18,0x00,0x18,0x18,0x3C,0x3C,0x18,
|
||||
0x00,0xCC,0x66,0x33,0x66,0xCC,0x00,0x00,
|
||||
0x00,0x33,0x66,0xCC,0x66,0x33,0x00,0x00,
|
||||
0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,
|
||||
0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,
|
||||
0xBB,0xEE,0xBB,0xEE,0xBB,0xEE,0xBB,0xEE,
|
||||
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
|
||||
0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,
|
||||
0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,
|
||||
0x6C,0x6C,0x6C,0x6C,0x6F,0x6C,0x6C,0x6C,
|
||||
0x00,0x00,0x00,0x00,0x7F,0x6C,0x6C,0x6C,
|
||||
0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,
|
||||
0x6C,0x6C,0x6F,0x60,0x6F,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,
|
||||
0x00,0x00,0x7F,0x60,0x6F,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0x6F,0x60,0x7F,0x00,0x00,0x00,
|
||||
0x6C,0x6C,0x6C,0x6C,0x7F,0x00,0x00,0x00,
|
||||
0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,
|
||||
0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,
|
||||
0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,
|
||||
0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,
|
||||
0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
|
||||
0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,
|
||||
0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,
|
||||
0x6C,0x6C,0x6C,0x6C,0xEC,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0xEC,0x0C,0xFC,0x00,0x00,0x00,
|
||||
0x00,0x00,0xFC,0x0C,0xEC,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0xEF,0x00,0xFF,0x00,0x00,0x00,
|
||||
0x00,0x00,0xFF,0x00,0xEF,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0xEC,0x0C,0xEC,0x6C,0x6C,0x6C,
|
||||
0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,
|
||||
0x6C,0x6C,0xEF,0x00,0xEF,0x6C,0x6C,0x6C,
|
||||
0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,
|
||||
0x6C,0x6C,0x6C,0x6C,0xFF,0x00,0x00,0x00,
|
||||
0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,
|
||||
0x00,0x00,0x00,0x00,0xFF,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0x6C,0x6C,0xFC,0x00,0x00,0x00,
|
||||
0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,
|
||||
0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,
|
||||
0x00,0x00,0x00,0x00,0xFC,0x6C,0x6C,0x6C,
|
||||
0x6C,0x6C,0x6C,0x6C,0xEF,0x6C,0x6C,0x6C,
|
||||
0x18,0x18,0xFF,0x00,0xFF,0x18,0x18,0x18,
|
||||
0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,
|
||||
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
||||
0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,
|
||||
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
|
||||
0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
|
||||
0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x6E,0x3B,0x13,0x3B,0x6E,0x00,
|
||||
0x00,0x1E,0x33,0x1F,0x33,0x1F,0x03,0x03,
|
||||
0x00,0x7F,0x63,0x03,0x03,0x03,0x03,0x00,
|
||||
0x00,0x7F,0x36,0x36,0x36,0x36,0x36,0x00,
|
||||
0x7F,0x66,0x0C,0x18,0x0C,0x66,0x7F,0x00,
|
||||
0x00,0x00,0x7E,0x33,0x33,0x33,0x1E,0x00,
|
||||
0x00,0x66,0x66,0x66,0x66,0x3E,0x06,0x03,
|
||||
0x00,0x6E,0x3B,0x18,0x18,0x18,0x18,0x00,
|
||||
0x3F,0x0C,0x1E,0x33,0x33,0x1E,0x0C,0x3F,
|
||||
0x1C,0x36,0x63,0x7F,0x63,0x36,0x1C,0x00,
|
||||
0x1C,0x36,0x63,0x63,0x36,0x36,0x77,0x00,
|
||||
0x38,0x0C,0x18,0x3E,0x33,0x33,0x1E,0x00,
|
||||
0x00,0x00,0x7E,0xDB,0xDB,0x7E,0x00,0x00,
|
||||
0x60,0x30,0x7E,0xDB,0xDB,0x7E,0x06,0x03,
|
||||
0x3C,0x06,0x03,0x3F,0x03,0x06,0x3C,0x00,
|
||||
0x1E,0x33,0x33,0x33,0x33,0x33,0x33,0x00,
|
||||
0x00,0x3F,0x00,0x3F,0x00,0x3F,0x00,0x00,
|
||||
0x0C,0x0C,0x3F,0x0C,0x0C,0x00,0x3F,0x00,
|
||||
0x06,0x0C,0x18,0x0C,0x06,0x00,0x3F,0x00,
|
||||
0x18,0x0C,0x06,0x0C,0x18,0x00,0x3F,0x00,
|
||||
0x70,0xD8,0xD8,0x18,0x18,0x18,0x18,0x18,
|
||||
0x18,0x18,0x18,0x18,0x18,0x1B,0x1B,0x0E,
|
||||
0x0C,0x0C,0x00,0x3F,0x00,0x0C,0x0C,0x00,
|
||||
0x00,0x4E,0x39,0x00,0x4E,0x39,0x00,0x00,
|
||||
0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,
|
||||
0xF0,0x30,0x30,0x30,0x37,0x36,0x3C,0x38,
|
||||
0x1E,0x36,0x36,0x36,0x36,0x00,0x00,0x00,
|
||||
0x1E,0x30,0x1C,0x06,0x3E,0x00,0x00,0x00,
|
||||
0x00,0x00,0x3C,0x3C,0x3C,0x3C,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
@@ -0,0 +1,811 @@
|
||||
/****
|
||||
$SP,"<1>",1$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Tasks have symbol tables. If symbol not found, parent task's table
|
||||
is searched. Adam task has system-wide symbols.
|
||||
|
||||
SYMBOL LOOK-UP (Especially, used by JIT compiler and Loader)
|
||||
1) Symbol text name is hashed -- Adding the ASCII values of all
|
||||
chars with shifts.
|
||||
2) Hash body array is indexed.
|
||||
3) Linked-lst is traversed until match of text and type-of-entry
|
||||
4) If not found, next hash table is searched.
|
||||
|
||||
Duplicate entries are allowed--they overshadow old entries.
|
||||
|
||||
|
||||
ADDRESS-TO-SYMBOL LOOK-UP (Slow because not important--could add tree)
|
||||
1)PSect Cache is scanned.
|
||||
2)"next_added,last_added" que links are traversed. This speeds look-up
|
||||
instead of scanning hash table because hash table is so sparce.
|
||||
|
||||
See $LK,"PSectFind","MN:PSectFind"$().
|
||||
|
||||
****/
|
||||
|
||||
asm {
|
||||
USE64
|
||||
// ************************************
|
||||
// IN: RSI=Addr of string
|
||||
// OUT: RAX
|
||||
SYS_HASH_STR::
|
||||
XOR RAX,RAX
|
||||
OR RSI,RSI
|
||||
JZ @@15
|
||||
|
||||
PUSH RSI
|
||||
PUSH RBX
|
||||
XOR RBX,RBX
|
||||
JMP @@10
|
||||
|
||||
@@05: SHL1 RBX
|
||||
ADC RBX,RAX
|
||||
@@10: LODSB
|
||||
OR AL,AL
|
||||
JNZ @@05
|
||||
|
||||
MOV RAX,RBX
|
||||
SHR RBX,16
|
||||
ADC RAX,RBX
|
||||
POP RBX
|
||||
POP RSI
|
||||
|
||||
@@15: RET
|
||||
// ************************************
|
||||
// IN: RAX=HASHED_STRING
|
||||
// RSI=STR
|
||||
// RBX=TYPE MASK
|
||||
// RDI=TABLE
|
||||
// RCX=INSTANCE, NOT ZERO
|
||||
// OUT: RAX=ENTRY OR ZERO NOT FOUND
|
||||
// RDX=POINTER TO POINTER TO ENTRY
|
||||
// RCX IF NOT FOUND ENOUGH, DECREMENTED BY NUM MATCHES
|
||||
// ZERO FLAG SET NOT FOUND
|
||||
SYS_HASH_SINGLE_TABLE_FIND1::
|
||||
MOV RCX,1
|
||||
SYS_HASH_SINGLE_TABLE_FIND::
|
||||
OR RCX,RCX
|
||||
JNZ @@05
|
||||
XOR RAX,RAX
|
||||
RET
|
||||
@@05: AND RAX,U64 CHashTable.mask[RDI]
|
||||
MOV RDX,U64 CHashTable.body[RDI]
|
||||
LEA RDX,U64 [RDX+RAX*8]
|
||||
@@10: MOV RAX,U64 [RDX]
|
||||
OR RAX,RAX
|
||||
JNZ @@15
|
||||
RET
|
||||
|
||||
@@15: TEST U32 CHash.type[RAX],EBX
|
||||
JZ @@30
|
||||
PUSH RAX
|
||||
PUSH RDI
|
||||
PUSH RSI
|
||||
MOV RDI,U64 CHash.str[RAX]
|
||||
@@20: LODSB
|
||||
CMP U8 [RDI],AL
|
||||
JNE @@25
|
||||
INC RDI
|
||||
OR AL,AL
|
||||
JNZ @@20
|
||||
POP RSI
|
||||
POP RDI
|
||||
POP RAX
|
||||
LOOP @@30
|
||||
INC U32 CHash.use_cnt[RAX]
|
||||
OR RAX,RAX
|
||||
RET
|
||||
|
||||
@@25: POP RSI
|
||||
POP RDI
|
||||
POP RAX
|
||||
|
||||
@@30: LEA RDX,U64 CHash.next[RAX]
|
||||
JMP @@10
|
||||
// ************************************
|
||||
// IN: RSI=STR
|
||||
// RBX=TYPE MASK
|
||||
// RDI=TABLE
|
||||
// RCX=INSTANCE NUM
|
||||
// OUT: RAX=ENTRY OR ZERO NOT FOUND
|
||||
// ZERO FLAG SET NOT FOUND
|
||||
SYS_HASH_FIND1::
|
||||
MOV RCX,1
|
||||
SYS_HASH_FIND::
|
||||
PUSH RDI
|
||||
CALL SYS_HASH_STR
|
||||
|
||||
@@05: PUSH RAX
|
||||
CALL SYS_HASH_SINGLE_TABLE_FIND
|
||||
JNZ @@15
|
||||
POP RAX
|
||||
@@10: MOV RDI,U64 CHashTable.next[RDI]
|
||||
OR RDI,RDI
|
||||
JNZ @@05
|
||||
POP RDI
|
||||
XOR RAX,RAX
|
||||
RET
|
||||
|
||||
@@15: ADD RSP,8
|
||||
POP RDI
|
||||
OR RAX,RAX
|
||||
RET
|
||||
// ************************************
|
||||
// IN: RSI=STR
|
||||
// RDI=TABLE
|
||||
// OUT: RAX=BUCKET
|
||||
SYS_HASH_BUCKET_FIND::
|
||||
PUSH RDX
|
||||
CALL SYS_HASH_STR
|
||||
AND RAX,U64 CHashTable.mask[RDI]
|
||||
MOV RDX,U64 CHashTable.body[RDI]
|
||||
LEA RAX,U64 [RDX+RAX*8]
|
||||
POP RDX
|
||||
RET
|
||||
// ************************************
|
||||
//IN: RSI
|
||||
// RCX=INSTANCE
|
||||
//OUT: RAX
|
||||
// ZERO FLAG SET NOT FOUND
|
||||
SYS_EXT_FIND1::
|
||||
MOV RCX,1
|
||||
SYS_EXT_FIND::
|
||||
PUSH RDI
|
||||
PUSH RBX
|
||||
XOR RAX,RAX
|
||||
MOV RDI,U64 FS:CTask.hash_table[RAX]
|
||||
MOV RBX,HTT_FUN|HTT_EXPORT_SYS_SYM
|
||||
CALL SYS_HASH_FIND
|
||||
JZ @@15
|
||||
@@05: TEST U32 CHash.type[RAX],HTT_FUN
|
||||
JZ @@10
|
||||
MOV RAX,U64 CHashFun.executable_addr[RAX]
|
||||
JMP @@15
|
||||
@@10: MOV RAX,U64 CHashExport.val[RAX]
|
||||
@@15: POP RBX
|
||||
POP RDI
|
||||
OR RAX,RAX
|
||||
RET
|
||||
_EXT_FIND::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
XOR RAX,RAX
|
||||
MOV RDI,U64 FS:CTask.hash_table[RAX]
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
MOV RCX,U64 SF_ARG2[RBP]
|
||||
MOV RBX,HTT_FUN|HTT_EXPORT_SYS_SYM
|
||||
CALL SYS_HASH_FIND
|
||||
JZ @@15
|
||||
@@05: TEST U32 CHash.type[RAX],HTT_FUN
|
||||
JZ @@10
|
||||
MOV RAX,U64 CHashFun.executable_addr[RAX]
|
||||
JMP @@15
|
||||
@@10: MOV RAX,U64 CHashExport.val[RAX]
|
||||
@@15: POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 16
|
||||
// ************************************
|
||||
_HASH_STR::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
CALL SYS_HASH_STR
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 8
|
||||
// ************************************
|
||||
_HASH_FIND::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
MOV RBX,U64 SF_ARG3[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
CALL SYS_HASH_FIND
|
||||
POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 32
|
||||
// ************************************
|
||||
_HASH_SINGLE_TABLE_FIND::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
MOV RBX,U64 SF_ARG3[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
CALL SYS_HASH_STR
|
||||
CALL SYS_HASH_SINGLE_TABLE_FIND
|
||||
POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 32
|
||||
// ************************************
|
||||
_HASH_BUCKET_FIND::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RSI,U64 SF_ARG1[RBP]
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
CALL SYS_HASH_BUCKET_FIND
|
||||
POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 16
|
||||
// ************************************
|
||||
_HASH_ADD::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
MOV RSI,U64 CHash.str[RCX]
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
CALL SYS_HASH_BUCKET_FIND
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
PUSHFD
|
||||
CLI
|
||||
MOV RBX,U64 [RAX]
|
||||
MOV U64 CHash.next[RCX],RBX
|
||||
MOV U64 [RAX],RCX
|
||||
|
||||
//Queins
|
||||
MOV RBX,U64 CHashTable.last_added[RDI]
|
||||
MOV U64 CHash.last_added[RCX],RBX
|
||||
MOV U64 CHash.next_added[RBX],RCX
|
||||
MOV U64 CHashTable.last_added[RDI],RCX
|
||||
MOV U64 CHash.next_added[RCX],RDI
|
||||
|
||||
POPFD
|
||||
POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 16
|
||||
// ************************************
|
||||
_HASH_ADD_AFTER::
|
||||
ENTER 0
|
||||
PUSH RDI
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
MOV RDI,U64 SF_ARG3[RBP]
|
||||
PUSHFD
|
||||
CLI
|
||||
MOV RAX,SF_ARG2[RBP]
|
||||
MOV RBX,U64 [RAX]
|
||||
MOV U64 CHash.next[RCX],RBX
|
||||
MOV U64 [RAX],RCX
|
||||
|
||||
//QueIns
|
||||
MOV RBX,U64 CHashTable.last_added[RDI]
|
||||
MOV U64 CHash.last_added[RCX],RBX
|
||||
MOV U64 CHash.next_added[RBX],RCX
|
||||
MOV U64 CHashTable.last_added[RDI],RCX
|
||||
MOV U64 CHash.next_added[RCX],RDI
|
||||
|
||||
POPFD
|
||||
POP RDI
|
||||
LEAVE
|
||||
RET1 24
|
||||
// ************************************
|
||||
_HASH_REPLACE::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
OR RCX,RCX
|
||||
JZ @@15
|
||||
MOV RSI,U64 CHash.str[RCX]
|
||||
XOR RBX,RBX
|
||||
MOV EBX,U32 CHash.type[RCX]
|
||||
AND EBX,~HTF_FLAGS_MASK&0xFFFFFFFF
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
MOV RCX,U64 SF_ARG3[RBP]
|
||||
CALL SYS_HASH_STR
|
||||
|
||||
PUSHFD
|
||||
CLI
|
||||
CALL SYS_HASH_SINGLE_TABLE_FIND
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
JZ @@05 //Z set by find
|
||||
|
||||
//QueRem/QueIns
|
||||
MOV RBX,U64 CHash.next_added[RAX]
|
||||
MOV U64 CHash.next_added[RCX],RBX
|
||||
MOV U64 CHash.last_added[RBX],RCX
|
||||
MOV RBX,U64 CHash.last_added[RAX]
|
||||
MOV U64 CHash.last_added[RCX],RBX
|
||||
MOV U64 CHash.next_added[RBX],RCX
|
||||
|
||||
MOV RBX,U64 CHash.next[RAX]
|
||||
JMP @@10
|
||||
|
||||
//QueIns
|
||||
@@05: MOV RBX,U64 CHashTable.last_added[RDI]
|
||||
MOV U64 CHash.last_added[RCX],RBX
|
||||
MOV U64 CHash.next_added[RBX],RCX
|
||||
MOV U64 CHashTable.last_added[RDI],RCX
|
||||
MOV U64 CHash.next_added[RCX],RDI
|
||||
|
||||
MOV RBX,RAX
|
||||
|
||||
@@10: MOV U64 CHash.next[RCX],RBX
|
||||
MOV U64 [RDX],RCX
|
||||
POPFD
|
||||
|
||||
OR RAX,RAX
|
||||
JZ @@15
|
||||
PUSH_C_REGS
|
||||
PUSH RAX
|
||||
CALL &HashDel
|
||||
POP_C_REGS
|
||||
|
||||
@@15: POP RDI
|
||||
POP RSI
|
||||
LEAVE
|
||||
RET1 24
|
||||
// ************************************
|
||||
_HASH_REM_DEL::
|
||||
ENTER 0
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
OR RCX,RCX
|
||||
JZ @@10
|
||||
MOV RSI,U64 CHash.str[RCX]
|
||||
XOR RBX,RBX
|
||||
MOV EBX,U32 CHash.type[RCX]
|
||||
AND EBX,~HTF_FLAGS_MASK&0xFFFFFFFF
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
MOV RCX,U64 SF_ARG3[RBP]
|
||||
CALL SYS_HASH_STR
|
||||
|
||||
PUSHFD
|
||||
CLI
|
||||
CALL SYS_HASH_SINGLE_TABLE_FIND
|
||||
JZ @@05
|
||||
CMP RAX,U64 SF_ARG1[RBP]
|
||||
JNE @@05
|
||||
|
||||
MOV RBX,U64 CHash.next[RAX]
|
||||
MOV U64 [RDX],RBX
|
||||
|
||||
//QueRem
|
||||
MOV RBX,U64 CHash.next_added[RAX]
|
||||
MOV RDX,U64 CHash.last_added[RAX]
|
||||
MOV U64 CHash.next_added[RDX],RBX
|
||||
MOV U64 CHash.last_added[RBX],RDX
|
||||
|
||||
POPFD
|
||||
|
||||
PUSH_C_REGS
|
||||
PUSH RAX
|
||||
CALL &HashDel
|
||||
POP_C_REGS
|
||||
|
||||
POP RDI
|
||||
POP RSI
|
||||
MOV RAX,1
|
||||
LEAVE
|
||||
RET1 24
|
||||
|
||||
@@05: POPFD
|
||||
@@10: POP RDI
|
||||
POP RSI
|
||||
XOR RAX,RAX
|
||||
LEAVE
|
||||
RET1 24
|
||||
}
|
||||
|
||||
_extern _HASH_STR I64 HashStr(U8 *st);
|
||||
_extern _HASH_FIND CHash *
|
||||
HashFind(U8 *st,CHashTable *table,I64 mask,I64 instance=1);
|
||||
_extern _HASH_SINGLE_TABLE_FIND CHash *
|
||||
HashSingleTableFind(U8 *st,CHashTable *table,I64 mask,I64 instance=1);
|
||||
_extern _HASH_BUCKET_FIND CHash **
|
||||
HashBucketFind(U8 *st,CHashTable *table);
|
||||
_extern _HASH_ADD U0 HashAdd(CHash *temph,CHashTable *table);
|
||||
_extern _HASH_REPLACE U0 HashReplace(CHash *temph,CHashTable *table,
|
||||
I64 instance=1);//instance must match temph's
|
||||
_extern _HASH_REM_DEL Bool HashRemDel(CHash *temph,CHashTable *table,
|
||||
I64 instance=1);//instance must match temph's
|
||||
|
||||
I64 HashTypeNum(CHash *temph)
|
||||
{
|
||||
if (temph)
|
||||
return Bsf(temph->type&HTT_TYPE_MASK);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
CHashTable *HashTableNew(I64 size,CTask *mem_task=NULL)
|
||||
{
|
||||
CHashTable *tempht;
|
||||
tempht=CAlloc(sizeof(CHashTable),mem_task);
|
||||
tempht->body=CAlloc(size<<3,mem_task);
|
||||
tempht->mask=size-1;
|
||||
tempht->next_added=tempht->last_added=tempht;
|
||||
return tempht;
|
||||
}
|
||||
|
||||
U0 HashDel(CHashSrcSym *temph)
|
||||
{
|
||||
if (!temph) return;
|
||||
if (!(temph->type&HTT_DICT_WORD))
|
||||
Free(temph->str);
|
||||
if (temph->type & HTG_SRC_SYM) {
|
||||
Free(temph->src_link);
|
||||
Free(temph->index);
|
||||
Free(temph->import_name);
|
||||
LinkedLstDel(temph->ie_lst);
|
||||
if (temph->type & (HTT_FUN | HTT_EXPORT_SYS_SYM)) {
|
||||
Free(temph->debug);
|
||||
Free(temph->indent);
|
||||
}
|
||||
if (temph->type & (HTT_FUN | HTT_CLASS))
|
||||
//Assumes code not on heap, so doesn't Free.
|
||||
//$LK,"MemberLstDel","MN:MemberLstDel"$() is an import to the Kernel module
|
||||
MemberLstDel(temph);
|
||||
else if (temph->type&HTT_DEFINE_STR)
|
||||
Free(temph(CHashDefineStr *)->data);
|
||||
else if (temph->type & HTT_GLBL_VAR) {
|
||||
if (!(temph(CHashGlblVar *)->flags&GVAF_ALIAS))
|
||||
Free(temph(CHashGlblVar *)->data_addr);
|
||||
LinkedLstDel(temph(CHashGlblVar *)->dim.next);
|
||||
if (temph(CHashGlblVar *)->fun_ptr)
|
||||
HashDel(temph(CHashGlblVar *)->fun_ptr-temph(CHashGlblVar *)->fun_ptr->ptr_cnt);
|
||||
}
|
||||
} else if (temph->type & HTT_FILE)
|
||||
Free(temph(CHashGeneric *)->user_data0);
|
||||
Free(temph);
|
||||
}
|
||||
|
||||
U0 HashTableDel(CHashTable *tempht)
|
||||
{
|
||||
CHashSrcSym *temph,*temph1;
|
||||
if (!tempht) return;
|
||||
temph=tempht->next_added;
|
||||
while (temph!=tempht) {
|
||||
temph1=temph->next_added;
|
||||
HashDel(temph);
|
||||
temph=temph1;
|
||||
}
|
||||
Free(tempht->body);
|
||||
Free(tempht);
|
||||
}
|
||||
|
||||
CHashGeneric *HashGenericAdd(U8 *name,I64 type,I64 u0=0,I64 u1=0,I64 u2=0,CTask *task=NULL)
|
||||
{
|
||||
if (!task) task=Fs;
|
||||
CHashGeneric *result=CAlloc(sizeof(CHashGeneric),task);
|
||||
result->type=type;
|
||||
result->user_data0=u0;
|
||||
result->user_data1=u1;
|
||||
result->user_data2=u2;
|
||||
result->str=StrNew(name,task);
|
||||
HashAdd(result,task->hash_table);
|
||||
return result;
|
||||
}
|
||||
|
||||
I64 NamedFramePtr(U8 *name,CTask *task=NULL)
|
||||
{
|
||||
CHashGeneric *temph;
|
||||
if (!task) task=Fs;
|
||||
if (temph=HashFind(name,task->hash_table,HTT_NAMED_FRAME_PTR))
|
||||
return temph->user_data0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHashGeneric *NamedFramePtrAdd(U8 *name,I64 val,CTask *task=NULL)
|
||||
{
|
||||
return HashGenericAdd(name,HTT_NAMED_FRAME_PTR,val,0,0,task);
|
||||
}
|
||||
|
||||
I64 NamedFramePtrSet(U8 *name,I64 val,CTask *task=NULL)
|
||||
{
|
||||
CHashGeneric *temph;
|
||||
if (!task) task=Fs;
|
||||
if (temph=HashFind(name,task->hash_table,HTT_NAMED_FRAME_PTR))
|
||||
return LXchgU64(&temph->user_data0,val);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
I64 NamedFramePtrDel(U8 *name,CTask *task=NULL)
|
||||
{
|
||||
CHashGeneric *temph;
|
||||
I64 result=0;
|
||||
if (!task) task=Fs;
|
||||
if (temph=HashFind(name,task->hash_table,HTT_NAMED_FRAME_PTR)) {
|
||||
result=temph->user_data0;
|
||||
HashRemDel(temph,task->hash_table);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
U0 LoadOneImport(U8 **_src,U8 *module_base,I64 ld_flags)
|
||||
{
|
||||
U8 *src=*_src,*ptr2,*st_ptr;
|
||||
I64 i,etype;
|
||||
CHashExport *tempess=NULL;
|
||||
CHashImport *tempiss;
|
||||
Bool first=TRUE;
|
||||
CHashFun *tempf;
|
||||
CHashGlblVar *tempg;
|
||||
|
||||
while (etype=*src++) {
|
||||
i=*src(U32 *)++;
|
||||
st_ptr=src;
|
||||
src+=StrLen(st_ptr)+1;
|
||||
if (*st_ptr) {
|
||||
if (!first) {
|
||||
*_src=st_ptr-5;
|
||||
return;
|
||||
} else {
|
||||
first=FALSE;
|
||||
if (!(tempess=HashFind(st_ptr,Fs->hash_table,HTG_ALL-HTT_IMPORT_SYS_SYM))) {
|
||||
if (!(ld_flags & LDF_SILENT)) {
|
||||
PutDefine("ST_UNRESOLVED_REFERENCE");
|
||||
"" st_ptr;
|
||||
NewLine;
|
||||
}
|
||||
tempiss=CAlloc(sizeof(CHashImport));
|
||||
tempiss->str=StrNew(st_ptr);
|
||||
tempiss->type=HTT_IMPORT_SYS_SYM;
|
||||
tempiss->module_header_entry=st_ptr-5;
|
||||
tempiss->module_base=module_base;
|
||||
HashAdd(tempiss,Fs->hash_table);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tempess) {
|
||||
ptr2=module_base+i;
|
||||
if (tempess->type & HTT_FUN) {
|
||||
tempf=tempess;
|
||||
if (etype & 1)
|
||||
i=tempf->executable_addr;
|
||||
else
|
||||
i=tempf->executable_addr-module_base;
|
||||
} else if (tempess->type & HTT_GLBL_VAR) {
|
||||
tempg=tempess;
|
||||
if (etype & 1)
|
||||
i=tempg->data_addr;
|
||||
else
|
||||
i=tempg->data_addr-module_base;
|
||||
} else {
|
||||
if (etype & 1)
|
||||
i=tempess->val;
|
||||
else
|
||||
i=tempess->val(U8 *)-module_base;
|
||||
}
|
||||
if (etype<=EIE_LIT_U8)
|
||||
*ptr2(U8 *)+=i;
|
||||
else if (etype<=EIE_LIT_U16)
|
||||
*ptr2(U16 *)+=i;
|
||||
else if (etype<=EIE_LIT_U32)
|
||||
*ptr2(U32 *)+=i;
|
||||
else if (etype<=EIE_LIT_U64)
|
||||
*ptr2(I64 *)+=i;
|
||||
}
|
||||
}
|
||||
*_src=src-1;
|
||||
}
|
||||
|
||||
U0 SysSymImportsResolve(U8 *st_ptr,I64 ld_flags)
|
||||
{
|
||||
CHashImport *tempiss;
|
||||
U8 *ptr;
|
||||
while (tempiss=HashSingleTableFind(st_ptr,Fs->hash_table,HTT_IMPORT_SYS_SYM)) {
|
||||
ptr=tempiss->module_header_entry;
|
||||
LoadOneImport(&ptr,tempiss->module_base,ld_flags);
|
||||
tempiss->type=HTT_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
U0 LoadPass1(U8 *src,U8 *module_base,I64 ld_flags)
|
||||
{
|
||||
U8 *ptr2,*ptr3,*st_ptr;
|
||||
I64 i,j,cnt,etype;
|
||||
CHashExport *tempess=NULL;
|
||||
while (etype=*src++) {
|
||||
i=*src(U32 *)++;
|
||||
st_ptr=src;
|
||||
src+=StrLen(st_ptr)+1;
|
||||
switch (etype) {
|
||||
case EIE_REL_EXPORT:
|
||||
case EIE_LIT_EXPORT:
|
||||
tempess=CAlloc(sizeof(CHashExport));
|
||||
tempess->str=StrNew(st_ptr);
|
||||
tempess->type=HTT_EXPORT_SYS_SYM|HTF_LIT;
|
||||
if (etype==EIE_LIT_EXPORT)
|
||||
tempess->val=i;
|
||||
else
|
||||
tempess->val=i+module_base;
|
||||
HashAdd(tempess,Fs->hash_table);
|
||||
SysSymImportsResolve(st_ptr,ld_flags);
|
||||
break;
|
||||
case EIE_REL_U8...EIE_LIT_U64:
|
||||
src=st_ptr-5;
|
||||
LoadOneImport(&src,module_base,ld_flags);
|
||||
break;
|
||||
case EIE_ABS_ADDR:
|
||||
if (ld_flags & LDF_NO_ABSS)
|
||||
src+=i*sizeof(U32);
|
||||
else {
|
||||
cnt=i;
|
||||
for (j=0;j<cnt;j++) {
|
||||
ptr2=module_base+*src(U32 *)++;
|
||||
*ptr2(U32 *)+=module_base;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case EIE_HEAP_GLBL:
|
||||
ptr3=MAlloc(*src(I64 *)++);
|
||||
|
||||
if (*st_ptr) {
|
||||
tempess=CAlloc(sizeof(CHashExport));
|
||||
tempess->str=StrNew(st_ptr);
|
||||
tempess->type=HTT_EXPORT_SYS_SYM|HTF_LIT;
|
||||
tempess->val=ptr3;
|
||||
HashAdd(tempess,Fs->hash_table);
|
||||
}
|
||||
|
||||
cnt=i;
|
||||
for (j=0;j<cnt;j++) {
|
||||
ptr2=module_base+*src(U32 *)++;
|
||||
*ptr2(I64 *)+=ptr3;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
U0 LoadPass2(U8 *src,U8 *module_base,I64)
|
||||
{
|
||||
U8 *st_ptr;
|
||||
I64 i,etype;
|
||||
while (etype=*src++) {
|
||||
i=*src(U32 *)++;
|
||||
st_ptr=src;
|
||||
src+=StrLen(st_ptr)+1;
|
||||
switch (etype) {
|
||||
case EIE_MAIN:
|
||||
Call(i+module_base);
|
||||
break;
|
||||
case EIE_ABS_ADDR:
|
||||
src+=sizeof(U32)*i;
|
||||
break;
|
||||
case EIE_HEAP_GLBL:
|
||||
src+=8+sizeof(U32)*i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U8 *Load(U8 *filename,I64 ld_flags=0,CBinFile *bfh_addr=INVALID_PTR)
|
||||
{ //See $LK,"BinRep","MN:BinRep"$().
|
||||
//bfh_addr==INVALID_PTR means don't care what load addr.
|
||||
U8 *fbuf,*module_base,*absname;
|
||||
I64 size,module_alignment,module_org;
|
||||
CBinFile *bfh2;
|
||||
CBinFilePatchTableWithOrg *bfpt;
|
||||
fbuf=DftExt(filename,"BIN.Z");
|
||||
if (!(bfh2=FileRead(fbuf,&size))) {
|
||||
Free(fbuf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//See $LK,"Loader Patch Table Generation","FF:::/TempleOS/Compiler/CmpMain.CPP,EIE_MODULE_ALIGNMENT"$
|
||||
bfpt=bfh2(U8 *)+bfh2->loader_patch_table_offset;
|
||||
module_alignment=bfpt->module_alignment;
|
||||
if (bfpt->eie_module_org==EIE_MODULE_ORG)
|
||||
module_org=bfpt->module_org;
|
||||
else
|
||||
module_org=INVALID_PTR;
|
||||
|
||||
if (!module_alignment || Bsf(module_alignment)!=Bsr(module_alignment))
|
||||
throw(EXCEPT_BIN_MODULE);
|
||||
|
||||
#assert sizeof(CBinFile)==16
|
||||
|
||||
if (bfh_addr==INVALID_PTR) {
|
||||
if (module_org==INVALID_PTR) {
|
||||
if (Fs->code_heap!=Fs->data_heap) {
|
||||
if (module_alignment<16)
|
||||
module_alignment=16;
|
||||
bfh_addr=MAllocAligned(size,module_alignment,Fs->code_heap,module_alignment-sizeof(CBinFile));
|
||||
} else if (module_alignment>8)
|
||||
bfh_addr=MAllocAligned(size,module_alignment,NULL,module_alignment-sizeof(CBinFile));
|
||||
else { //Less than 2Gig system memory
|
||||
bfh_addr=bfh2;
|
||||
goto lo_skip; //File is already in code heap area, don't copy.
|
||||
}
|
||||
} else
|
||||
bfh_addr=module_org;
|
||||
}
|
||||
MemCpy(bfh_addr,bfh2,size);
|
||||
Free(bfh2);
|
||||
|
||||
lo_skip:
|
||||
module_base=bfh_addr(U8 *)+sizeof(CBinFile);
|
||||
|
||||
if (ArcXSum(bfh_addr,bfh_addr->file_size)!=NATIVE_XSUM)
|
||||
throw(EXCEPT_ARC_XSUM);
|
||||
|
||||
absname=FileNameAbs(fbuf);
|
||||
Free(fbuf);
|
||||
fbuf=StrNew(absname);
|
||||
FileExtRem(fbuf);
|
||||
if (fbuf[1]==':' && StrLen(fbuf)>2)
|
||||
HashGenericAdd(fbuf+2,HTT_MODULE|HTF_PUBLIC,bfh_addr);
|
||||
Free(fbuf);
|
||||
|
||||
LoadPass1(bfh_addr(U8 *)+bfh_addr->loader_patch_table_offset,module_base,ld_flags);
|
||||
if (!(ld_flags&LDF_JUST_LOAD))
|
||||
LoadPass2(bfh_addr(U8 *)+bfh_addr->loader_patch_table_offset,module_base,ld_flags);
|
||||
Free(absname);
|
||||
return bfh_addr;
|
||||
}
|
||||
|
||||
U0 LoadKernel()
|
||||
{
|
||||
HashGenericAdd(KERNEL_MODULE_NAME,HTT_MODULE|HTF_PUBLIC,sys_boot_base-sizeof(CBinFile));
|
||||
|
||||
//Abs patches done here $LK,"CBinFilePatchTableWithoutOrg","FF:D:/TempleOS/Kernel/KStart.CPP,CBinFilePatchTableWithoutOrg"$.
|
||||
LoadPass1(sys_boot_patch_table_base,sys_boot_base,LDF_NO_ABSS|LDF_SILENT);
|
||||
|
||||
//No main routines
|
||||
// LoadPass2(sys_boot_patch_table_base,sys_boot_base,0);
|
||||
}
|
||||
| ||||