words[]: type FD = { } ; const bool yes = 1 , no = 0 ; const bool true = 1 , false = 0 ; extern { uint8 msbit ( uint16 ) ; uint8 msbit ( uint32 ) ; int sign ( int16 ) ; int sign ( int32 ) ; uint16 abs ( int16 ) ; uint32 abs ( int32 ) ; uint16 swap_bytes ( uint16 ) ; uint32 revert_bytes ( uint32 ) ; uint32 swap_words ( uint32 ) ; uint16 random ( ) ; uint32 mul_wwl ( uint16 , uint16 ) ; void flip ( int8 [ to ] ) = opcode flip ; void rol ( int8 [ to ] ) = opcode rol ; void ror ( int8 [ to ] ) = opcode ror ; void sort ( int8 [ to ] ) = opcode sort ; void rsort ( int8 [ to ] ) = opcode rsort ; void shuffle ( int8 [ to ] ) = opcode shuffle ; void revert ( int8 [ to ] ) = opcode revert ; int8 [ ] join ( int8 [ ] [ ] ¢ , int8 ) = opcode join ; int8 [ ] join ( int8 [ ] [ ] ¢ , int8 [ ] ¢ ) = opcode join ; int8 [ ] [ ] split ( int8 [ ] ¢ , int8 ) = opcode split ; int8 [ ] [ ] split ( int8 [ ] ¢ , int8 [ ] ¢ ) = opcode split ; int8 min ( int8 , int8 ) ; int8 min ( int8 , int8 , int8 ) ; int8 min ( int8 [ to ] ) ; int8 max ( int8 , int8 ) ; int8 max ( int8 , int8 , int8 ) ; int8 max ( int8 [ to ] ) ; uint find ( int8 [ to ] , int8 ) = opcode find ; uint find ( int8 [ to ] , int8 [ ] ¢ ) = opcode find ; uint rfind ( int8 [ to ] , int8 ) = opcode rfind ; uint rfind ( int8 [ to ] , int8 [ ] ¢ ) = opcode rfind ; void shrinktofit ( int8 [ ] & ) ; int8 [ to ] substr ( int8 [ ] ¢ , uint a , uint e ) ; int8 [ to ] midstr ( int8 [ ] ¢ , uint i , uint n ) ; int8 [ to ] leftstr ( int8 [ ] ¢ , uint n ) ; int8 [ to ] rightstr ( int8 [ ] ¢ , uint n ) ; int8 numval ( utf8str ¢ ) ; int8 numval ( ucs1str ¢ ) ; int8 numval ( ucs2str ¢ ) ; void flip ( uint8 [ to ] ) = opcode flip ; void rol ( uint8 [ to ] ) = opcode rol ; void ror ( uint8 [ to ] ) = opcode ror ; void sort ( uint8 [ to ] ) = opcode sort ; void rsort ( uint8 [ to ] ) = opcode rsort ; void shuffle ( uint8 [ to ] ) = opcode shuffle ; void revert ( uint8 [ to ] ) = opcode revert ; uint8 [ ] join ( uint8 [ ] [ ] ¢ , uint8 ) = opcode join ; uint8 [ ] join ( uint8 [ ] [ ] ¢ , uint8 [ ] ¢ ) = opcode join ; uint8 [ ] [ ] split ( uint8 [ ] ¢ , uint8 ) = opcode split ; uint8 [ ] [ ] split ( uint8 [ ] ¢ , uint8 [ ] ¢ ) = opcode split ; uint8 min ( uint8 , uint8 ) ; uint8 min ( uint8 , uint8 , uint8 ) ; uint8 min ( uint8 [ to ] ) ; uint8 max ( uint8 , uint8 ) ; uint8 max ( uint8 , uint8 , uint8 ) ; uint8 max ( uint8 [ to ] ) ; uint find ( uint8 [ to ] , uint8 ) = opcode find ; uint find ( uint8 [ to ] , uint8 [ ] ¢ ) = opcode find ; uint rfind ( uint8 [ to ] , uint8 ) = opcode rfind ; uint rfind ( uint8 [ to ] , uint8 [ ] ¢ ) = opcode rfind ; void shrinktofit ( uint8 [ ] & ) ; uint8 [ to ] substr ( uint8 [ ] ¢ , uint a , uint e ) ; uint8 [ to ] midstr ( uint8 [ ] ¢ , uint i , uint n ) ; uint8 [ to ] leftstr ( uint8 [ ] ¢ , uint n ) ; uint8 [ to ] rightstr ( uint8 [ ] ¢ , uint n ) ; uint8 numval ( utf8str ¢ ) ; uint8 numval ( ucs1str ¢ ) ; uint8 numval ( ucs2str ¢ ) ; void flip ( int16 [ to ] ) = opcode flip ; void rol ( int16 [ to ] ) = opcode rol ; void ror ( int16 [ to ] ) = opcode ror ; void sort ( int16 [ to ] ) = opcode sort ; void rsort ( int16 [ to ] ) = opcode rsort ; void shuffle ( int16 [ to ] ) = opcode shuffle ; void revert ( int16 [ to ] ) = opcode revert ; int16 [ ] join ( int16 [ ] [ ] ¢ , int16 ) = opcode join ; int16 [ ] join ( int16 [ ] [ ] ¢ , int16 [ ] ¢ ) = opcode join ; int16 [ ] [ ] split ( int16 [ ] ¢ , int16 ) = opcode split ; int16 [ ] [ ] split ( int16 [ ] ¢ , int16 [ ] ¢ ) = opcode split ; int16 min ( int16 , int16 ) ; int16 min ( int16 , int16 , int16 ) ; int16 min ( int16 [ to ] ) ; int16 max ( int16 , int16 ) ; int16 max ( int16 , int16 , int16 ) ; int16 max ( int16 [ to ] ) ; uint find ( int16 [ to ] , int16 ) = opcode find ; uint find ( int16 [ to ] , int16 [ ] ¢ ) = opcode find ; uint rfind ( int16 [ to ] , int16 ) = opcode rfind ; uint rfind ( int16 [ to ] , int16 [ ] ¢ ) = opcode rfind ; void shrinktofit ( int16 [ ] & ) ; int16 [ to ] substr ( int16 [ ] ¢ , uint a , uint e ) ; int16 [ to ] midstr ( int16 [ ] ¢ , uint i , uint n ) ; int16 [ to ] leftstr ( int16 [ ] ¢ , uint n ) ; int16 [ to ] rightstr ( int16 [ ] ¢ , uint n ) ; int16 numval ( utf8str ¢ ) ; int16 numval ( ucs1str ¢ ) ; int16 numval ( ucs2str ¢ ) ; void flip ( uint16 [ to ] ) = opcode flip ; void rol ( uint16 [ to ] ) = opcode rol ; void ror ( uint16 [ to ] ) = opcode ror ; void sort ( uint16 [ to ] ) = opcode sort ; void rsort ( uint16 [ to ] ) = opcode rsort ; void shuffle ( uint16 [ to ] ) = opcode shuffle ; void revert ( uint16 [ to ] ) = opcode revert ; uint16 [ ] join ( uint16 [ ] [ ] ¢ , uint16 ) = opcode join ; uint16 [ ] join ( uint16 [ ] [ ] ¢ , uint16 [ ] ¢ ) = opcode join ; uint16 [ ] [ ] split ( uint16 [ ] ¢ , uint16 ) = opcode split ; uint16 [ ] [ ] split ( uint16 [ ] ¢ , uint16 [ ] ¢ ) = opcode split ; uint16 min ( uint16 , uint16 ) ; uint16 min ( uint16 , uint16 , uint16 ) ; uint16 min ( uint16 [ to ] ) ; uint16 max ( uint16 , uint16 ) ; uint16 max ( uint16 , uint16 , uint16 ) ; uint16 max ( uint16 [ to ] ) ; uint find ( uint16 [ to ] , uint16 ) = opcode find ; uint find ( uint16 [ to ] , uint16 [ ] ¢ ) = opcode find ; uint rfind ( uint16 [ to ] , uint16 ) = opcode rfind ; uint rfind ( uint16 [ to ] , uint16 [ ] ¢ ) = opcode rfind ; void shrinktofit ( uint16 [ ] & ) ; uint16 [ to ] substr ( uint16 [ ] ¢ , uint a , uint e ) ; uint16 [ to ] midstr ( uint16 [ ] ¢ , uint i , uint n ) ; uint16 [ to ] leftstr ( uint16 [ ] ¢ , uint n ) ; uint16 [ to ] rightstr ( uint16 [ ] ¢ , uint n ) ; uint16 numval ( utf8str ¢ ) ; uint16 numval ( ucs1str ¢ ) ; uint16 numval ( ucs2str ¢ ) ; void flip ( int32 [ to ] ) = opcode flip ; void rol ( int32 [ to ] ) = opcode rol ; void ror ( int32 [ to ] ) = opcode ror ; void sort ( int32 [ to ] ) = opcode sort ; void rsort ( int32 [ to ] ) = opcode rsort ; void shuffle ( int32 [ to ] ) = opcode shuffle ; void revert ( int32 [ to ] ) = opcode revert ; int32 [ ] join ( int32 [ ] [ ] ¢ , int32 ) = opcode join ; int32 [ ] join ( int32 [ ] [ ] ¢ , int32 [ ] ¢ ) = opcode join ; int32 [ ] [ ] split ( int32 [ ] ¢ , int32 ) = opcode split ; int32 [ ] [ ] split ( int32 [ ] ¢ , int32 [ ] ¢ ) = opcode split ; int32 min ( int32 , int32 ) ; int32 min ( int32 , int32 , int32 ) ; int32 min ( int32 [ to ] ) ; int32 max ( int32 , int32 ) ; int32 max ( int32 , int32 , int32 ) ; int32 max ( int32 [ to ] ) ; uint find ( int32 [ to ] , int32 ) = opcode find ; uint find ( int32 [ to ] , int32 [ ] ¢ ) = opcode find ; uint rfind ( int32 [ to ] , int32 ) = opcode rfind ; uint rfind ( int32 [ to ] , int32 [ ] ¢ ) = opcode rfind ; void shrinktofit ( int32 [ ] & ) ; int32 [ to ] substr ( int32 [ ] ¢ , uint a , uint e ) ; int32 [ to ] midstr ( int32 [ ] ¢ , uint i , uint n ) ; int32 [ to ] leftstr ( int32 [ ] ¢ , uint n ) ; int32 [ to ] rightstr ( int32 [ ] ¢ , uint n ) ; int32 numval ( utf8str ¢ ) ; int32 numval ( ucs1str ¢ ) ; int32 numval ( ucs2str ¢ ) ; void flip ( uint32 [ to ] ) = opcode flip ; void rol ( uint32 [ to ] ) = opcode rol ; void ror ( uint32 [ to ] ) = opcode ror ; void sort ( uint32 [ to ] ) = opcode sort ; void rsort ( uint32 [ to ] ) = opcode rsort ; void shuffle ( uint32 [ to ] ) = opcode shuffle ; void revert ( uint32 [ to ] ) = opcode revert ; uint32 [ ] join ( uint32 [ ] [ ] ¢ , uint32 ) = opcode join ; uint32 [ ] join ( uint32 [ ] [ ] ¢ , uint32 [ ] ¢ ) = opcode join ; uint32 [ ] [ ] split ( uint32 [ ] ¢ , uint32 ) = opcode split ; uint32 [ ] [ ] split ( uint32 [ ] ¢ , uint32 [ ] ¢ ) = opcode split ; uint32 min ( uint32 , uint32 ) ; uint32 min ( uint32 , uint32 , uint32 ) ; uint32 min ( uint32 [ to ] ) ; uint32 max ( uint32 , uint32 ) ; uint32 max ( uint32 , uint32 , uint32 ) ; uint32 max ( uint32 [ to ] ) ; uint find ( uint32 [ to ] , uint32 ) = opcode find ; uint find ( uint32 [ to ] , uint32 [ ] ¢ ) = opcode find ; uint rfind ( uint32 [ to ] , uint32 ) = opcode rfind ; uint rfind ( uint32 [ to ] , uint32 [ ] ¢ ) = opcode rfind ; void shrinktofit ( uint32 [ ] & ) ; uint32 [ to ] substr ( uint32 [ ] ¢ , uint a , uint e ) ; uint32 [ to ] midstr ( uint32 [ ] ¢ , uint i , uint n ) ; uint32 [ to ] leftstr ( uint32 [ ] ¢ , uint n ) ; uint32 [ to ] rightstr ( uint32 [ ] ¢ , uint n ) ; uint32 numval ( utf8str ¢ ) ; uint32 numval ( ucs1str ¢ ) ; uint32 numval ( ucs2str ¢ ) ; void flip ( utf8char [ to ] ) = opcode flip ; void rol ( utf8char [ to ] ) = opcode rol ; void ror ( utf8char [ to ] ) = opcode ror ; void sort ( utf8char [ to ] ) = opcode sort ; void rsort ( utf8char [ to ] ) = opcode rsort ; void shuffle ( utf8char [ to ] ) = opcode shuffle ; void revert ( utf8char [ to ] ) = opcode revert ; utf8char [ ] join ( utf8char [ ] [ ] ¢ , utf8char ) = opcode join ; utf8char [ ] join ( utf8char [ ] [ ] ¢ , utf8char [ ] ¢ ) = opcode join ; utf8char [ ] [ ] split ( utf8char [ ] ¢ , utf8char ) = opcode split ; utf8char [ ] [ ] split ( utf8char [ ] ¢ , utf8char [ ] ¢ ) = opcode split ; utf8char min ( utf8char , utf8char ) ; utf8char min ( utf8char , utf8char , utf8char ) ; utf8char min ( utf8char [ to ] ) ; utf8char max ( utf8char , utf8char ) ; utf8char max ( utf8char , utf8char , utf8char ) ; utf8char max ( utf8char [ to ] ) ; uint find ( utf8char [ to ] , utf8char ) = opcode find ; uint find ( utf8char [ to ] , utf8char [ ] ¢ ) = opcode find ; uint rfind ( utf8char [ to ] , utf8char ) = opcode rfind ; uint rfind ( utf8char [ to ] , utf8char [ ] ¢ ) = opcode rfind ; void shrinktofit ( utf8char [ ] & ) ; utf8char [ to ] substr ( utf8char [ ] ¢ , uint a , uint e ) ; utf8char [ to ] midstr ( utf8char [ ] ¢ , uint i , uint n ) ; utf8char [ to ] leftstr ( utf8char [ ] ¢ , uint n ) ; utf8char [ to ] rightstr ( utf8char [ ] ¢ , uint n ) ; utf8char numval ( utf8str ¢ ) ; utf8char numval ( ucs1str ¢ ) ; utf8char numval ( ucs2str ¢ ) ; void flip ( ucs1char [ to ] ) = opcode flip ; void rol ( ucs1char [ to ] ) = opcode rol ; void ror ( ucs1char [ to ] ) = opcode ror ; void sort ( ucs1char [ to ] ) = opcode sort ; void rsort ( ucs1char [ to ] ) = opcode rsort ; void shuffle ( ucs1char [ to ] ) = opcode shuffle ; void revert ( ucs1char [ to ] ) = opcode revert ; ucs1char [ ] join ( ucs1char [ ] [ ] ¢ , ucs1char ) = opcode join ; ucs1char [ ] join ( ucs1char [ ] [ ] ¢ , ucs1char [ ] ¢ ) = opcode join ; ucs1char [ ] [ ] split ( ucs1char [ ] ¢ , ucs1char ) = opcode split ; ucs1char [ ] [ ] split ( ucs1char [ ] ¢ , ucs1char [ ] ¢ ) = opcode split ; ucs1char min ( ucs1char , ucs1char ) ; ucs1char min ( ucs1char , ucs1char , ucs1char ) ; ucs1char min ( ucs1char [ to ] ) ; ucs1char max ( ucs1char , ucs1char ) ; ucs1char max ( ucs1char , ucs1char , ucs1char ) ; ucs1char max ( ucs1char [ to ] ) ; uint find ( ucs1char [ to ] , ucs1char ) = opcode find ; uint find ( ucs1char [ to ] , ucs1char [ ] ¢ ) = opcode find ; uint rfind ( ucs1char [ to ] , ucs1char ) = opcode rfind ; uint rfind ( ucs1char [ to ] , ucs1char [ ] ¢ ) = opcode rfind ; void shrinktofit ( ucs1char [ ] & ) ; ucs1char [ to ] substr ( ucs1char [ ] ¢ , uint a , uint e ) ; ucs1char [ to ] midstr ( ucs1char [ ] ¢ , uint i , uint n ) ; ucs1char [ to ] leftstr ( ucs1char [ ] ¢ , uint n ) ; ucs1char [ to ] rightstr ( ucs1char [ ] ¢ , uint n ) ; ucs1char numval ( utf8str ¢ ) ; ucs1char numval ( ucs1str ¢ ) ; ucs1char numval ( ucs2str ¢ ) ; void flip ( ucs2char [ to ] ) = opcode flip ; void rol ( ucs2char [ to ] ) = opcode rol ; void ror ( ucs2char [ to ] ) = opcode ror ; void sort ( ucs2char [ to ] ) = opcode sort ; void rsort ( ucs2char [ to ] ) = opcode rsort ; void shuffle ( ucs2char [ to ] ) = opcode shuffle ; void revert ( ucs2char [ to ] ) = opcode revert ; ucs2char [ ] join ( ucs2char [ ] [ ] ¢ , ucs2char ) = opcode join ; ucs2char [ ] join ( ucs2char [ ] [ ] ¢ , ucs2char [ ] ¢ ) = opcode join ; ucs2char [ ] [ ] split ( ucs2char [ ] ¢ , ucs2char ) = opcode split ; ucs2char [ ] [ ] split ( ucs2char [ ] ¢ , ucs2char [ ] ¢ ) = opcode split ; ucs2char min ( ucs2char , ucs2char ) ; ucs2char min ( ucs2char , ucs2char , ucs2char ) ; ucs2char min ( ucs2char [ to ] ) ; ucs2char max ( ucs2char , ucs2char ) ; ucs2char max ( ucs2char , ucs2char , ucs2char ) ; ucs2char max ( ucs2char [ to ] ) ; uint find ( ucs2char [ to ] , ucs2char ) = opcode find ; uint find ( ucs2char [ to ] , ucs2char [ ] ¢ ) = opcode find ; uint rfind ( ucs2char [ to ] , ucs2char ) = opcode rfind ; uint rfind ( ucs2char [ to ] , ucs2char [ ] ¢ ) = opcode rfind ; void shrinktofit ( ucs2char [ ] & ) ; ucs2char [ to ] substr ( ucs2char [ ] ¢ , uint a , uint e ) ; ucs2char [ to ] midstr ( ucs2char [ ] ¢ , uint i , uint n ) ; ucs2char [ to ] leftstr ( ucs2char [ ] ¢ , uint n ) ; ucs2char [ to ] rightstr ( ucs2char [ ] ¢ , uint n ) ; ucs2char numval ( utf8str ¢ ) ; ucs2char numval ( ucs1str ¢ ) ; ucs2char numval ( ucs2str ¢ ) ; bool is_letter ( char ) ; bool is_bin_digit ( char ) ; bool is_dec_digit ( char ) ; bool is_hex_digit ( char ) ; uint digit_value ( char ) ; } ; float64 round ( float64 ) ; float64 floor ( float64 ) ; float64 ceil ( float64 ) ; float64 integ ( float64 ) ; float64 fract ( float64 ) ; int sign ( float64 ) ; float64 abs ( float64 ) ; float64 min ( float64 , float64 ) ; float64 max ( float64 , float64 ) ; float64 min ( float64 , float64 , float64 ) ; float64 max ( float64 , float64 , float64 ) ; float64 random ( ) ; float64 random ( float64 ) ; float64 sin ( float64 ) ; float64 cos ( float64 ) ; float64 tan ( float64 ) ; float64 asin ( float64 ) ; float64 acos ( float64 ) ; float64 atan ( float64 ) ; float64 sinh ( float64 ) ; float64 cosh ( float64 ) ; float64 tanh ( float64 ) ; float64 exp10 ( float64 ) ; float64 log10 ( float64 ) ; float64 exp2 ( float64 ) ; float64 log2 ( float64 ) ; float64 expe ( float64 ) ; float64 loge ( float64 ) ; float64 exp ( float64 , float64 ) ; float64 log ( float64 , float64 ) ; float64 pow ( float64 , int ) ; float64 sqrt ( float64 ) ; str numstr ( float64 ) ; float64 numval ( str ¢ ) ; float64 min ( float64 [ ] ¢ ) ; float64 min ( float64 [ to ] ) ; float64 max ( float64 [ ] ¢ ) ; float64 max ( float64 [ to ] ) ; scope ucs2str { ucs2char [ ] spacestr ( uint ) ucs2char [ ] spacestr ( uint , ucs2char ) ucs2char [ ] charstr ( uint ) ucs2char hexchar ( uint ) ucs2char [ ] hexstr ( uint8 ) ucs2char [ ] hexstr ( uint16 ) ucs2char [ ] hexstr ( uint32 ) ucs2char [ ] hexstr ( uint , uint digits ) ucs2char [ ] hexstr ( ulong , uint digits ) ucs2char [ ] binstr ( uint8 ) ucs2char [ ] binstr ( uint16 ) ucs2char [ ] binstr ( uint32 ) ucs2char [ ] binstr ( uint , uint digits ) ucs2char [ ] binstr ( ulong , uint digits ) ucs2char [ ] binstr ( uint , ucs2char [ ] ¢ o , ucs2char [ ] ¢ l ) ucs2char [ ] binstr ( ulong , ucs2char [ ] ¢ o , ucs2char [ ] ¢ l ) ucs2char [ ] numstr ( int ) ucs2char [ ] numstr ( uint ) ucs2char [ ] numstr ( long ) ucs2char [ ] numstr ( ulong ) ucs2char [ ] toupper ( ucs2char [ ] ¢ ) ucs2char [ ] tolower ( ucs2char [ ] ¢ ) ucs2char [ ] escape ( ucs2char [ ] ¢ , ucs2char leftquote ) ucs2char [ ] unescape ( ucs2char [ ] ¢ ) ucs2char [ ] urlencode ( ucs2char [ ] ¢ ) ucs2char [ ] urldecode ( ucs2char [ ] ¢ ) ucs2char [ ] entab ( ucs2char [ ] ¢ , uint tabwidth ) ucs2char [ ] detab ( ucs2char [ ] ¢ , uint tabwidth ) ucs2char [ ] toupper ( ucs2char [ to ] ) ucs2char [ ] tolower ( ucs2char [ to ] ) ucs2char [ ] escape ( ucs2char [ to ] , ucs2char leftquote ) ucs2char [ ] unescape ( ucs2char [ to ] ) ucs2char [ ] urlencode ( ucs2char [ to ] ) ucs2char [ ] urldecode ( ucs2char [ to ] ) ucs2char [ ] entab ( ucs2char [ to ] , uint tabwidth ) ucs2char [ ] detab ( ucs2char [ to ] , uint tabwidth ) ucs1str toucs1 ( ucs2char [ ] ¢ ) ucs2str toucs2 ( ucs2char [ ] ¢ ) utf8str toutf8 ( ucs2char [ ] ¢ ) ucs1str toucs1 ( ucs2char [ to ] ) ucs2str toucs2 ( ucs2char [ to ] ) utf8str toutf8 ( ucs2char [ to ] ) ucs2char [ ] min ( ucs2char [ ] , ucs2char [ ] ) ucs2char [ ] min ( ucs2char [ ] , ucs2char [ ] ¢ ) ucs2char [ ] min ( ucs2char [ ] ¢ , ucs2char [ ] ) ucs2char [ ] ¢ min ( ucs2char [ ] ¢ , ucs2char [ ] ¢ ) ucs2char [ ] ¢ min ( ucs2char [ ] [ ] ¢ ) ucs2char [ ] ¢ min ( ucs2char [ ] [ to ] ) ucs2char [ ] max ( ucs2char [ ] , ucs2char [ ] ) ucs2char [ ] max ( ucs2char [ ] , ucs2char [ ] ¢ ) ucs2char [ ] max ( ucs2char [ ] ¢ , ucs2char [ ] ) ucs2char [ ] ¢ max ( ucs2char [ ] ¢ , ucs2char [ ] ¢ ) ucs2char [ ] ¢ max ( ucs2char [ ] [ ] ¢ ) ucs2char [ ] ¢ max ( ucs2char [ ] [ to ] ) void flip ( ucs2char [ ] [ to ] ) void rol ( ucs2char [ ] [ to ] ) void ror ( ucs2char [ ] [ to ] ) void sort ( ucs2char [ ] [ to ] ) void rsort ( ucs2char [ ] [ to ] ) void shuffle ( ucs2char [ ] [ to ] ) void revert ( ucs2char [ ] [ to ] ) } scope ucs1str { ucs1char [ ] spacestr ( uint ) ucs1char [ ] spacestr ( uint , ucs1char ) ucs1char [ ] charstr ( uint ) ucs1char hexchar ( uint ) ucs1char [ ] hexstr ( uint8 ) ucs1char [ ] hexstr ( uint16 ) ucs1char [ ] hexstr ( uint32 ) ucs1char [ ] hexstr ( uint , uint digits ) ucs1char [ ] hexstr ( ulong , uint digits ) ucs1char [ ] binstr ( uint8 ) ucs1char [ ] binstr ( uint16 ) ucs1char [ ] binstr ( uint32 ) ucs1char [ ] binstr ( uint , uint digits ) ucs1char [ ] binstr ( ulong , uint digits ) ucs1char [ ] binstr ( uint , ucs1char [ ] ¢ o , ucs1char [ ] ¢ l ) ucs1char [ ] binstr ( ulong , ucs1char [ ] ¢ o , ucs1char [ ] ¢ l ) ucs1char [ ] numstr ( int ) ucs1char [ ] numstr ( uint ) ucs1char [ ] numstr ( long ) ucs1char [ ] numstr ( ulong ) ucs1char [ ] toupper ( ucs1char [ ] ¢ ) ucs1char [ ] tolower ( ucs1char [ ] ¢ ) ucs1char [ ] escape ( ucs1char [ ] ¢ , ucs1char leftquote ) ucs1char [ ] unescape ( ucs1char [ ] ¢ ) ucs1char [ ] urlencode ( ucs1char [ ] ¢ ) ucs1char [ ] urldecode ( ucs1char [ ] ¢ ) ucs1char [ ] entab ( ucs1char [ ] ¢ , uint tabwidth ) ucs1char [ ] detab ( ucs1char [ ] ¢ , uint tabwidth ) ucs1char [ ] toupper ( ucs1char [ to ] ) ucs1char [ ] tolower ( ucs1char [ to ] ) ucs1char [ ] escape ( ucs1char [ to ] , ucs1char leftquote ) ucs1char [ ] unescape ( ucs1char [ to ] ) ucs1char [ ] urlencode ( ucs1char [ to ] ) ucs1char [ ] urldecode ( ucs1char [ to ] ) ucs1char [ ] entab ( ucs1char [ to ] , uint tabwidth ) ucs1char [ ] detab ( ucs1char [ to ] , uint tabwidth ) ucs1str toucs1 ( ucs1char [ ] ¢ ) ucs2str toucs2 ( ucs1char [ ] ¢ ) utf8str toutf8 ( ucs1char [ ] ¢ ) ucs1str toucs1 ( ucs1char [ to ] ) ucs2str toucs2 ( ucs1char [ to ] ) utf8str toutf8 ( ucs1char [ to ] ) ucs1char [ ] min ( ucs1char [ ] , ucs1char [ ] ) ucs1char [ ] min ( ucs1char [ ] , ucs1char [ ] ¢ ) ucs1char [ ] min ( ucs1char [ ] ¢ , ucs1char [ ] ) ucs1char [ ] ¢ min ( ucs1char [ ] ¢ , ucs1char [ ] ¢ ) ucs1char [ ] ¢ min ( ucs1char [ ] [ ] ¢ ) ucs1char [ ] ¢ min ( ucs1char [ ] [ to ] ) ucs1char [ ] max ( ucs1char [ ] , ucs1char [ ] ) ucs1char [ ] max ( ucs1char [ ] , ucs1char [ ] ¢ ) ucs1char [ ] max ( ucs1char [ ] ¢ , ucs1char [ ] ) ucs1char [ ] ¢ max ( ucs1char [ ] ¢ , ucs1char [ ] ¢ ) ucs1char [ ] ¢ max ( ucs1char [ ] [ ] ¢ ) ucs1char [ ] ¢ max ( ucs1char [ ] [ to ] ) void flip ( ucs1char [ ] [ to ] ) void rol ( ucs1char [ ] [ to ] ) void ror ( ucs1char [ ] [ to ] ) void sort ( ucs1char [ ] [ to ] ) void rsort ( ucs1char [ ] [ to ] ) void shuffle ( ucs1char [ ] [ to ] ) void revert ( ucs1char [ ] [ to ] ) } scope utf8str { utf8char [ ] spacestr ( uint ) utf8char [ ] spacestr ( uint , utf8char ) utf8char [ ] charstr ( uint ) char hexchar ( uint ) utf8char [ ] hexstr ( uint8 ) utf8char [ ] hexstr ( uint16 ) utf8char [ ] hexstr ( uint32 ) utf8char [ ] hexstr ( uint , uint digits ) utf8char [ ] hexstr ( ulong , uint digits ) utf8char [ ] binstr ( uint8 ) utf8char [ ] binstr ( uint16 ) utf8char [ ] binstr ( uint32 ) utf8char [ ] binstr ( uint , uint digits ) utf8char [ ] binstr ( ulong , uint digits ) utf8char [ ] binstr ( uint , utf8char [ ] ¢ o , utf8char [ ] ¢ l ) utf8char [ ] binstr ( ulong , utf8char [ ] ¢ o , utf8char [ ] ¢ l ) utf8char [ ] numstr ( int ) utf8char [ ] numstr ( uint ) utf8char [ ] numstr ( long ) utf8char [ ] numstr ( ulong ) utf8char [ ] toupper ( utf8char [ ] ¢ ) utf8char [ ] tolower ( utf8char [ ] ¢ ) utf8char [ ] escape ( utf8char [ ] ¢ , char leftquote ) utf8char [ ] unescape ( utf8char [ ] ¢ ) utf8char [ ] urlencode ( utf8char [ ] ¢ ) utf8char [ ] urldecode ( utf8char [ ] ¢ ) utf8char [ ] entab ( utf8char [ ] ¢ , uint tabwidth ) utf8char [ ] detab ( utf8char [ ] ¢ , uint tabwidth ) utf8char [ ] toupper ( utf8char [ to ] ) utf8char [ ] tolower ( utf8char [ to ] ) utf8char [ ] escape ( utf8char [ to ] , char leftquote ) utf8char [ ] unescape ( utf8char [ to ] ) utf8char [ ] urlencode ( utf8char [ to ] ) utf8char [ ] urldecode ( utf8char [ to ] ) utf8char [ ] entab ( utf8char [ to ] , uint tabwidth ) utf8char [ ] detab ( utf8char [ to ] , uint tabwidth ) ucs1str toucs1 ( utf8char [ ] ¢ ) ucs2str toucs2 ( utf8char [ ] ¢ ) utf8str toutf8 ( utf8char [ ] ¢ ) ucs1str toucs1 ( utf8char [ to ] ) ucs2str toucs2 ( utf8char [ to ] ) utf8str toutf8 ( utf8char [ to ] ) utf8char [ ] min ( utf8char [ ] , utf8char [ ] ) utf8char [ ] min ( utf8char [ ] , utf8char [ ] ¢ ) utf8char [ ] min ( utf8char [ ] ¢ , utf8char [ ] ) utf8char [ ] ¢ min ( utf8char [ ] ¢ , utf8char [ ] ¢ ) utf8char [ ] ¢ min ( utf8char [ ] [ ] ¢ ) utf8char [ ] ¢ min ( utf8char [ ] [ to ] ) utf8char [ ] max ( utf8char [ ] , utf8char [ ] ) utf8char [ ] max ( utf8char [ ] , utf8char [ ] ¢ ) utf8char [ ] max ( utf8char [ ] ¢ , utf8char [ ] ) utf8char [ ] ¢ max ( utf8char [ ] ¢ , utf8char [ ] ¢ ) utf8char [ ] ¢ max ( utf8char [ ] [ ] ¢ ) utf8char [ ] ¢ max ( utf8char [ ] [ to ] ) void flip ( utf8char [ ] [ to ] ) void rol ( utf8char [ ] [ to ] ) void ror ( utf8char [ ] [ to ] ) void sort ( utf8char [ ] [ to ] ) void rsort ( utf8char [ ] [ to ] ) void shuffle ( utf8char [ ] [ to ] ) void revert ( utf8char [ ] [ to ] ) } ucs1char [ ] spacestr ( uint ) ucs1char [ ] spacestr ( uint , ucs1char ) ucs1char [ ] charstr ( uint ) ucs1char hexchar ( uint ) ucs1char [ ] hexstr ( uint8 ) ucs1char [ ] hexstr ( uint16 ) ucs1char [ ] hexstr ( uint32 ) ucs1char [ ] hexstr ( uint , uint digits ) ucs1char [ ] hexstr ( ulong , uint digits ) ucs1char [ ] binstr ( uint8 ) ucs1char [ ] binstr ( uint16 ) ucs1char [ ] binstr ( uint32 ) ucs1char [ ] binstr ( uint , uint digits ) ucs1char [ ] binstr ( ulong , uint digits ) ucs1char [ ] binstr ( uint , ucs1char [ ] ¢ o , ucs1char [ ] ¢ l ) ucs1char [ ] binstr ( ulong , ucs1char [ ] ¢ o , ucs1char [ ] ¢ l ) ucs1char [ ] numstr ( int ) ucs1char [ ] numstr ( uint ) ucs1char [ ] numstr ( long ) ucs1char [ ] numstr ( ulong ) ucs1char [ ] toupper ( ucs1char [ ] ¢ ) ucs1char [ ] tolower ( ucs1char [ ] ¢ ) ucs1char [ ] escape ( ucs1char [ ] ¢ , ucs1char leftquote ) ucs1char [ ] unescape ( ucs1char [ ] ¢ ) ucs1char [ ] urlencode ( ucs1char [ ] ¢ ) ucs1char [ ] urldecode ( ucs1char [ ] ¢ ) ucs1char [ ] entab ( ucs1char [ ] ¢ , uint tabwidth ) ucs1char [ ] detab ( ucs1char [ ] ¢ , uint tabwidth ) ucs1char [ ] toupper ( ucs1char [ to ] ) ucs1char [ ] tolower ( ucs1char [ to ] ) ucs1char [ ] escape ( ucs1char [ to ] , ucs1char leftquote ) ucs1char [ ] unescape ( ucs1char [ to ] ) ucs1char [ ] urlencode ( ucs1char [ to ] ) ucs1char [ ] urldecode ( ucs1char [ to ] ) ucs1char [ ] entab ( ucs1char [ to ] , uint tabwidth ) ucs1char [ ] detab ( ucs1char [ to ] , uint tabwidth ) ucs1str toucs1 ( ucs1char [ ] ¢ ) ucs2str toucs2 ( ucs1char [ ] ¢ ) utf8str toutf8 ( ucs1char [ ] ¢ ) ucs1str toucs1 ( ucs1char [ to ] ) ucs2str toucs2 ( ucs1char [ to ] ) utf8str toutf8 ( ucs1char [ to ] ) ucs1char [ ] min ( ucs1char [ ] , ucs1char [ ] ) ucs1char [ ] min ( ucs1char [ ] , ucs1char [ ] ¢ ) ucs1char [ ] min ( ucs1char [ ] ¢ , ucs1char [ ] ) ucs1char [ ] ¢ min ( ucs1char [ ] ¢ , ucs1char [ ] ¢ ) ucs1char [ ] ¢ min ( ucs1char [ ] [ ] ¢ ) ucs1char [ ] ¢ min ( ucs1char [ ] [ to ] ) ucs1char [ ] max ( ucs1char [ ] , ucs1char [ ] ) ucs1char [ ] max ( ucs1char [ ] , ucs1char [ ] ¢ ) ucs1char [ ] max ( ucs1char [ ] ¢ , ucs1char [ ] ) ucs1char [ ] ¢ max ( ucs1char [ ] ¢ , ucs1char [ ] ¢ ) ucs1char [ ] ¢ max ( ucs1char [ ] [ ] ¢ ) ucs1char [ ] ¢ max ( ucs1char [ ] [ to ] ) void flip ( ucs1char [ ] [ to ] ) void rol ( ucs1char [ ] [ to ] ) void ror ( ucs1char [ ] [ to ] ) void sort ( ucs1char [ ] [ to ] ) void rsort ( ucs1char [ ] [ to ] ) void shuffle ( ucs1char [ ] [ to ] ) void revert ( ucs1char [ ] [ to ] ) enum { tm_utc = 0 , tm_localtime = 1 , tm_time = 2 , tm_date = 4 , tm_timezone = 8 , tm_sec = 16 , tm_msec = 32 } extern { float now ( ) ; str timestr ( float seconds , uint flags ) ; float timeval ( str ¢ , uint flags ) ; } enum uint8 { c_reset = 0 , c_speed = 1 , c_hwhsk = 2 , c_swhsk = 3 , c_flushin = 4 , c_availin = 4 , c_flushout = 5 , c_availout = 5 , c_clk_hsk = 6 , c_log2blocksize = 7 , c_totalblocks_lo = 8 , c_totalblocks_hi = 9 , c_reserved2 = 10 } ; enum uint8 OSErr = { ok = 0 , parameter_error = 1 , function_not_supported = 1 , io_error = 2 , device_not_responding = 3 , file_error , filesystem_invalid , device_not_found , directory_not_found , file_not_found , not_a_directory , is_a_directory , file_already_open_for_writing , file_already_open , file_exists , file_not_writable , end_of_file , disk_full , directory_corrupted , filesystem_corrupted } ; extern { OSErr errno ; OSErr error ( ) ; void clear_error ( ) ; void set_error ( OSErr ) ; bool yes_with_error ( OSErr ) ; void * null_with_error ( OSErr ) ; } enum uint8 NodeType = { t_endmarker = 0 , t_file = 1 , t_dir = 2 , t_ser = 3 , t_block = 4 , m_erased = 128 } ; scope NodeType { NodeType operator | ( NodeType , NodeType ) = opcode operator | ; NodeType operator & ( NodeType , NodeType ) = opcode operator & ; } type FD_Handlers = { uint ( FD ¢ , uint8 fu ) getctl ; void ( FD ¢ , uint8 fu , uint ) setctl ; uint ( FD ¢ ) avail_in ; uint ( FD ¢ ) avail_out ; char ( FD ¢ ) getc ; void ( FD ¢ , char ) putc ; bool ( FD ¢ , uint8 [ to ] ) read ; bool ( FD ¢ , uint8 [ to ] ) write ; bool ( FD ¢ , uint32 , uint8 [ ] ¢ ) read_block ; bool ( FD ¢ , uint32 , uint8 [ ] ¢ ) write_block ; void ( FD ¢ ) kill ; ulong ( FD ¢ ) getfpos ; bool ( FD ¢ , ulong fpos ) setfpos ; } extern { uint no_avail_in ( FD ¢ ) uint no_avail_out ( FD ¢ ) = no_avail_in ; char no_getc ( FD ¢ ) = no_avail_in ; void no_putc ( FD ¢ , char ) ulong no_getfpos ( FD ¢ ) bool no_setfpos ( FD ¢ , ulong ) bool no_read ( FD ¢ , uint8 [ to ] ) bool no_write ( FD ¢ , uint8 [ to ] ) = no_read ; bool no_read_block ( FD ¢ , uint32 , uint8 [ ] ¢ ) bool no_write_block ( FD ¢ , uint32 , uint8 [ ] ¢ ) = no_read_block ; } type FD = { FD_Handlers ¢ handlers ; NodeType nodetype ; str name ; } extern { uint avail_in ( ) ; uint avail_out ( ) ; const uint delimiters = 1 << 0 + 1 << 4 + 1 << 10 + 1 << 12 + 1 << 13 ; char getc ( ) ; void putc ( char c ) ; str gets ( uint delimiters ) ; void puts ( str ¢ ) ; void puts ( str ) ; void putnum ( uint ) ; void putnum ( int ) ; bool read ( uint8 [ to ] ) ; bool write ( uint8 [ to ] ) ; } scope FD { extern { void init ( FD ¢ , NodeType , str ¢ name , FD_Handlers ¢ ) ; void kill ( FD ¢ ) ; FD kill ( FD ) ; uint getctl ( FD ¢ , uint8 fu ) void setctl ( FD ¢ , uint8 fu , uint n ) uint avail_in ( FD ¢ ) ; uint avail_out ( FD ¢ ) ; char getc ( FD ¢ ) ; void putc ( FD ¢ , char c ) ; str gets ( FD ¢ , uint delimiters ) ; void puts ( FD ¢ , str ¢ ) ; void puts ( FD ¢ , str ) ; void putnum ( FD ¢ , uint ) ; void putnum ( FD ¢ , int ) ; bool read ( FD ¢ , uint8 [ to ] ) bool write ( FD ¢ , uint8 [ to ] ) bool read_block ( FD ¢ , uint32 blk , uint8 [ ] ¢ ) ; bool write_block ( FD ¢ , uint32 blk , uint8 [ ] ¢ ) ; ulong getfpos ( FD ¢ ) bool setfpos ( FD ¢ , ulong fpos ) bool is_dir ( FD ¢ ) ; bool is_file ( FD ¢ ) ; } } extern const { bool option_a5 = true ; uint8 bSIO_SELECT = 1 ; uint8 bIDE_SELECT = 2 ; uint8 mSIO_SELECT = 255 - 1 << bSIO_SELECT ; uint8 mIDE_SELECT = 255 - 2 << bSIO_SELECT ; } ; type FD = { } ; type BlockDevice = { } ; type IdeBlockDevice = { } ; type I2cBlockDevice = { } ; type SerialDevice = { } ; type Range = { } ; type File = { } ; type FD_Handlers = { } ; extern { uint8 k1_irpt_mask ; uint8 sysflags ; uint32 systemtime ; uint16 period ; uint32 timestamp ; uint16 tsmsec ; char * romdate ; char * romtime ; FD [ ] devs ; File [ ] fds ; FD stdin ; FD stdout ; SerialDevice sio1A ; SerialDevice sio1B ; IdeBlockDevice ide2A ; IdeBlockDevice ide2B ; I2cBlockDevice sio1rom ; I2cBlockDevice ide2rom ; OSErr errno ; void di ( ) void ei ( ) ; void ei_all ( ) ; void select ( uint8 ) uint8 in ( uint8 ) void out ( uint8 , uint8 ) void wait ( ) void memcpy ( void * z , void * q , uint cnt ) void memset ( void * z , uint c , uint cnt ) void memclr ( void * z , uint cnt ) void set_red_led ( ) ; void set_yellow_led ( ) ; void set_both_leds ( ) ; void clear_both_leds ( ) ; OSErr lock_eeprom ( ) ; OSErr unlock_eeprom ( ) ; void write_eeprom ( void * q , void * z , uint16 cnt ) ; void download_firmware ( ) ; void abort ( ) = opcode abort ; void panic ( uint8 blinkcode ) ; void assert1 ( bool ) ; void assert0 ( bool ) ; uint mem_get_free ( ) ; uint mem_get_free_total ( ) ; void download_firmware ( ) ; uint8 fd_function_not_supported ( ) ; void sio_init_channel ( SerialDevice ¢ , str ¢ name , uint8 devselbit , uint8 ch ) ; void ide_init_blockdevice ( BlockDevice ¢ ) ; void i2c_init_blockdevice ( BlockDevice ¢ ) ; } ; type File = { } ; type BlockDevice = FD + { uint blocksize ; uint blockmask ; uint8 log2blocksize ; uint32 totalblocks ; bool wide ; File [ ] open_files ; } ; scope BlockDevice { extern void init ( BlockDevice ¢ , NodeType , str ¢ name , FD_Handlers ¢ , uint8 log2blksz , uint32 totalblocks ) ; extern void kill ( BlockDevice ¢ ) = void FD . kill ( FD ¢ ) ; extern uint getctl ( BlockDevice ¢ fd , uint8 fu ) ; extern void setctl ( BlockDevice ¢ fd , uint8 fu , uint n ) ; } ; type Range = { uint32 start ; uint32 count ; } ; extern Range new ( uint32 start , uint32 count ) ; scope Range { uint32 ende ( Range ¢ r ) ; } type Ranges = Range [ ] ; extern Ranges new ( Range ) ; extern Ranges new ( uint32 start , uint32 count ) ; scope Ranges { extern uint32 totalblocks ( Ranges ¢ ) ; extern Range pop ( Ranges ¢ ) ; } type FileType = NodeType ; type File = BlockDevice + { uint32 parent ; BlockDevice device ; uint32 fsize ; Range [ ] ranges ; bool writable ; bool file_dirty ; bool buffer_dirty ; bool buffer_valid ; uint8 [ ] buffer ; uint32 blkno ; uint32 fpos ; uint ri ; uint32 bi ; } ; scope File { File kill ( File ) = FD FD . kill ( FD ) ; void kill ( File ¢ ) ; extern { uint getctl ( File ¢ , uint8 fu ) ; void setctl ( File ¢ , uint8 fu , uint n ) ; uint bu_free ( File ¢ ) ; uint bu_avail ( File ¢ ) ; uint avail_in ( File ¢ ) = bu_avail ; uint avail_out ( File ¢ ) = bu_free ; uint32 getfpos ( File ¢ ) ; uint32 getfsize ( File ¢ ) ; uint32 getfavail ( File ¢ ) ; bool setfpos ( File ¢ , uint32 fpos ) ; bool rewind ( File ¢ ) ; bool seek_end ( File ¢ ) ; bool skip ( File ¢ , int32 offs ) ; bool truncate ( File ¢ ) ; bool readbyte ( File ¢ , uint8 & ) ; bool writebyte ( File ¢ , uint8 ) ; char getc ( File ¢ ) ; void putc ( File ¢ , char c ) ; void puts ( File ¢ , str ¢ s ) ; void puts ( File ¢ , str s ) ; bool write ( File ¢ , uint8 [ ] ¢ , uint a , uint e ) ; bool read ( File ¢ , uint8 [ ] ¢ , uint a , uint e ) ; bool write ( File ¢ , uint8 [ to ] ) = bool write ( File ¢ , uint8 [ ] ¢ , uint , uint ) ; bool read ( File ¢ , uint8 [ to ] ) = bool read ( File ¢ , uint8 [ ] ¢ , uint , uint ) ; bool write_block ( File ¢ , uint32 , uint8 [ ] ¢ ) ; bool read_block ( File ¢ , uint32 , uint8 [ ] ¢ ) ; bool copy_block ( File ¢ fd , uint32 z , uint32 q , uint32 n ) ; bool open_gap ( File ¢ fd , uint32 start , uint32 size ) ; bool close_gap ( File ¢ fd , uint32 start , uint32 size ) ; bool sync ( File ¢ ) ; bool purge_buffer ( File ¢ ) ; uint32 block0 ( File ¢ ) ; void _rewind ( File ¢ fd ) } } ; scope BlockDevice { extern Range allocate_blocks ( BlockDevice ¢ bdev , uint32 maxnum , uint32 bestpos ) ; } extern FD_Handlers file_handlers ; FD_Handlers file_handlers = ( FD_Handlers ) { getctl = File . getctl , setctl = File . setctl , avail_in = File . avail_in , avail_out = File . avail_out , getc = File . getc , putc = File . putc , read = bool File . read ( File ¢ , uint8 [ to ] ) , write = bool File . write ( File ¢ , uint8 [ to ] ) , getfpos = File . getfpos , setfpos = File . setfpos read_block = bool File . read_block ( File ¢ , uint32 blk , uint8 [ ] ¢ ) write_block = bool File . write_block ( File ¢ , uint32 blk , uint8 [ ] ¢ ) kill = void File . kill ( File ¢ ) } Range new ( uint32 start , uint32 count ) { Range this = alloc Range ( ) ; this . start = start ; this . count = count ; return this ; } Ranges new ( Range range ) { Ranges ranges = alloc Ranges ( 1 ) ; ranges [ 0 ] := range ; return ranges ; } Ranges new ( uint32 start , uint32 count ) { return new Ranges ( new Range ( start , count ) ) ; } scope Range { uint32 ende ( Range ¢ r ) { return r . start + r . count ; } } ; scope Ranges { uint32 totalblocks ( Ranges ¢ ranges ) { uint32 n = 0 ; uint i = ranges . count ( ) ; do { while i ; n += ranges [ -- i ] . count ; } return n ; } Range pop ( Ranges ¢ ranges ) = asm { ld a , d or e jr z , 1 $ ; ranges == null = > return null deref_handle_de ; de -> ranges . data ex hl , de ; hl -> ranges . data ld d , ( -- hl ) ld e , ( -- hl ) ; de = ranges . size , hl -> ranges . size ld a , d or e jr z , 1 $ ; size = count = 0 = > return null dec de dec de ; de = ranges . size - 2 == ( count - 1 ) * 2 ld ( hl ++ ) , e ld ( hl ++ ) , d ; ranges . size -= 2 , hl -> ranges . data add hl , de ; hl -> ranges . last . lo xor a ld e , ( hl ) ld ( hl ++ ) , a ld d , ( hl ) ; de = ranges . last ld ( hl ) , a ; new_next_block . size = 0 1 $ : jp next } } scope File { uint32 block0 ( File ¢ fd ) { return fd . ranges . count ( ) ? fd . ranges [ 0 ] . start : 0 ; } void _increment_ribi_for_fpos ( File ¢ fd ) { assert1 ( fd . fpos . lo & fd . blockmask == 0 ) ; fd . buffer_valid = no ; if ( ++ fd . bi >= fd . ranges [ fd . ri ] . count ) { fd . bi = 0 ; fd . ri ++ ; } } void _rewind ( File ¢ fd ) { fd . ri = 0 ; fd . bi = 0 ; fd . fpos = 0 ; } bool _copy_block ( File ¢ fd , uint32 z , uint32 q , uint16 n , uint8 [ ] ¢ bu ) { return n && ( fd . setfpos ( q ) || fd . read ( bu , 0 , n ) || fd . setfpos ( z ) || fd . write ( bu , 0 , n ) ) ; } uint32 diskblock_for_fileblock ( File ¢ fd , uint32 fblk ) { assert1 ( fblk < fd . totalblocks ) ; uint ri = 0 ; do { assert1 ( ri < fd . ranges . count ( ) ) ; Range ¢ range = fd . ranges [ ri ++ ] ; if ( fblk < range . count ) return range . start + fblk ; fblk -= range . count ; } return 0 ; } bool append_blocks ( File ¢ fd , uint32 num ) { assert1 ( num >= 1 ) ; if ( fd . ranges . count ( ) ) { Range ¢ last = fd . ranges [ fd . ranges . count ( ) - 1 ] ; uint32 best = last . ende ( ) ; Range r = fd . device . allocate_blocks ( num , best ) ; if ( ! r ) return yes ; fd . totalblocks += r . count ; if ( r . start == best ) { if ( fd . ri == fd . ranges . count ( ) ) { fd . ri -- ; fd . bi = last . count ; } last . count += r . count ; } else { fd . ranges += r ; } } else { Range r = fd . device . allocate_blocks ( num , 0 ) ; if ( ! r ) return yes ; fd . totalblocks += r . count ; fd . ranges = alloc Range [ ] ( 1 ) ; fd . ranges [ 0 ] := r ; } return no ; } bool write_buffer_to_disk ( File ¢ fd ) { assert1 ( fd . buffer_dirty ) ; assert1 ( !! fd . buffer ) ; if ( fd . device . handlers . write_block ( fd . device , fd . blkno , fd . buffer ) ) return yes ; fd . buffer_dirty = no ; fd . file_dirty = yes ; return no ; } bool set_buffer_to_fpos ( File ¢ fd ) { if ( fd . buffer_dirty && fd . write_buffer_to_disk ( ) ) return yes ; assert1 ( ! fd . buffer_dirty ) ; if ( fd . ri >= fd . ranges . count ( ) && fd . append_blocks ( 8 ) ) return yes ; assert1 ( fd . ri < fd . ranges . count ( ) ) ; assert1 ( fd . bi < fd . ranges [ fd . ri ] . count ) ; fd . blkno = fd . ranges [ fd . ri ] . start + fd . bi ; fd . buffer_valid = no ; return no ; } bool read_buffer_from_disk ( File ¢ fd ) { assert1 ( ! fd . buffer_valid || ! fd . buffer ) ; assert1 ( ! fd . buffer_valid || fd . ri >= fd . ranges . count ( ) ) ; assert1 ( ! fd . buffer_valid || fd . blkno != fd . ranges [ fd . ri ] . start + fd . bi ) ; if ( fd . buffer_valid ) return no ; if ( fd . set_buffer_to_fpos ( ) ) return yes ; if ( ! fd . buffer ) fd . buffer = alloc uint8 [ ] ( fd . blocksize ) ; if ( fd . device . handlers . read_block ( fd . device , fd . blkno , fd . buffer ) ) return yes ; fd . buffer_valid = yes ; return no ; } bool purge_buffer ( File ¢ fd ) { if ( fd . buffer_dirty && fd . write_buffer_to_disk ( ) ) return yes ; fd . buffer_valid = no ; fd . buffer_dirty = no ; fd . buffer = null ; return no ; } void kill ( File ¢ fd ) { ( void ) fd . sync ( ) ; fd . buffer . dispose ( ) ; fd . device . dispose ( ) ; fd . ranges . dispose ( ) ; FD . kill ( fd ) ; } uint getctl ( File ¢ fd , uint8 fu ) { switch ( fu ) { case c_availin : return fd . avail_in ( ) ; case c_availout : return fd . avail_out ( ) ; } return BlockDevice . getctl ( fd , fu ) ; } void setctl ( File ¢ this , uint8 fu , uint value ) { } uint bu_free ( File ¢ fd ) { return fd . blocksize - fd . fpos . lo & fd . blockmask ; } uint bu_avail ( File ¢ fd ) { uint32 favail = getfavail ( fd ) ; return favail . hi ? fd . bu_free ( ) : min ( favail . lo , fd . bu_free ( ) ) ; } uint32 getfpos ( File ¢ fd ) { return fd . fpos ; } uint32 getfsize ( File ¢ fd ) { return fd . fsize ; } uint32 getfavail ( File ¢ fd ) { return fd . fsize - fd . fpos ; } bool setfpos ( File ¢ fd , uint32 newfpos ) { if ( newfpos > fd . fsize ) { if ( fd . writable ) { uint32 n = ( newfpos - 1 ) >> fd . log2blocksize + 1 ; do { while fd . totalblocks < n ; if ( fd . append_blocks ( n - fd . totalblocks ) ) return yes ; } fd . fsize = newfpos ; } else return yes_with_error ( end_of_file ) ; } fd . fpos . lo ^= ( fd . fpos . lo ^ newfpos . lo ) & fd . blockmask ; if ( newfpos == fd . fpos ) return no ; if ( newfpos < fd . fpos ) _rewind ( fd ) ; fd . bi += ( newfpos - fd . fpos ) >> fd . log2blocksize ; do { while fd . ri < fd . ranges . count ( ) ; until fd . bi < fd . ranges [ fd . ri ] . count ; fd . bi -= fd . ranges [ fd . ri ++ ] . count ; } fd . buffer_valid = no ; fd . fpos = newfpos ; return no ; } bool rewind ( File ¢ fd ) { return setfpos ( fd , 0 ) ; } bool seek_end ( File ¢ fd ) { return setfpos ( fd , fd . fsize ) ; } bool skip ( File ¢ fd , int32 n ) { return setfpos ( fd , fd . fpos + n ) ; } bool truncate ( File ¢ fd ) { if ( ! fd . writable ) return yes_with_error ( file_not_writable ) ; fd . fsize = fd . fpos ; if ( fd . fpos . lo & fd . blockmask == 0 ) fd . buffer_dirty = no ; fd . file_dirty = yes ; return no ; } bool readbyte ( File ¢ fd , uint8 & n ) { if ( fd . fpos >= fd . fsize ) return yes_with_error ( end_of_file ) ; if ( ! fd . buffer_valid && fd . read_buffer_from_disk ( ) ) return yes ; n = fd . buffer [ ( fd . fpos ++ ) . lo & fd . blockmask ] ; if ( fd . fpos . lo & fd . blockmask == 0 ) fd . _increment_ribi_for_fpos ( ) ; return no ; } bool writebyte ( File ¢ fd , uint8 n ) { if ( ! fd . writable ) return yes_with_error ( file_not_writable ) ; if ( ! fd . buffer_valid && fd . read_buffer_from_disk ( ) ) return yes ; fd . buffer [ fd . fpos . lo & fd . blockmask ] = n ; fd . buffer_dirty = yes ; if ( ++ fd . fpos > fd . fsize ) fd . fsize = fd . fpos ; if ( fd . fpos . lo & fd . blockmask == 0 ) fd . _increment_ribi_for_fpos ( ) ; return no ; } char getc ( File ¢ fd ) = asm { ; char c ; ; ( void ) fd . readbyte ( c ) ; ; return c ; ; p_enter ; dw IVAL0 ; dw OVER ; dw LVAR2 ; dw File . readbyte__4FileC_5uint8P_4bool ; dw DROP ; dw NIP1RETURN ld hl , 0 push hl ; stack : c fd p_enter dw LVAR2 ; stack : c fd & c dw File . readbyte__4FileC_5uint8P_4bool dw DROP1RETURN } void putc ( File ¢ fd , char c ) = asm { ; ( void ) fd . writebyte ( c ) ; ; p_enter ; dw DUP32 ; dw File . writebyte__4FileC_5uint8_4bool ; dw DROP3RETURN p_enter dw File . writebyte__4FileC_5uint8_4bool dw DROP1RETURN } void puts ( File ¢ fd , str ¢ s ) = asm { ; ( void ) fd . write ( s ) ; ; p_enter ; dw DUP32 ; dw CASTbAE2r ; dw File . write__4FileC_5uint8AEC_6uint16_6uint16_4bool ; dw DROP3RETURN p_enter dw CASTbAE2r dw File . write__4FileC_5uint8AEC_6uint16_6uint16_4bool dw DROP1RETURN } void puts ( File ¢ fd , str s ) { ( void ) fd . write ( s ) ; } bool read ( File ¢ fd , uint8 [ ] ¢ bu , uint a , uint e ) { if ( fd . getfavail ( ) < e - a ) return fd . read ( bu , a , a + fd . getfavail ( ) ) || yes_with_error ( end_of_file ) ; do { if ( a >= e ) return no ; uint m = fd . bu_free ( ) ; uint n = min ( e - a , m ) ; until ! fd . buffer_valid && fd . read_buffer_from_disk ( ) ; memcpy ( & bu [ a ] , & fd . buffer [ fd . fpos . lo & fd . blockmask ] , n ) ; a += n ; fd . fpos += n ; if ( fd . fpos . lo & fd . blockmask == 0 ) fd . _increment_ribi_for_fpos ( ) ; } return yes ; } bool write ( File ¢ fd , uint8 [ ] ¢ bu , uint a , uint e ) { if ( ! fd . writable ) return yes_with_error ( file_not_writable ) ; do { if ( a >= e ) return no ; uint m = bu_free ( fd ) ; uint n = min ( e - a , m ) ; until ! fd . buffer_valid && fd . read_buffer_from_disk ( ) ; memcpy ( & fd . buffer [ fd . fpos . lo & fd . blockmask ] , & bu [ a ] , n ) ; fd . buffer_dirty = true ; a += n ; fd . fpos += n ; if ( fd . fpos . lo & fd . blockmask == 0 ) fd . _increment_ribi_for_fpos ( ) ; if ( fd . fpos > fd . fsize ) fd . fsize = fd . fpos ; } return yes ; } bool write_block ( File ¢ fd , uint32 fblk , uint8 [ ] ¢ bu ) { if ( ! fd . writable ) return yes_with_error ( file_not_writable ) ; if ( fblk >= fd . totalblocks ) return yes_with_error ( end_of_file ) ; if ( fd . buffer && fd . purge_buffer ( ) ) return yes ; return fd . device . handlers . write_block ( fd . device , fd . diskblock_for_fileblock ( fblk ) , bu ) ; } bool read_block ( File ¢ fd , uint32 fblk , uint8 [ ] ¢ bu ) { if ( fblk >= fd . totalblocks ) return yes_with_error ( end_of_file ) ; if ( fd . buffer && fd . purge_buffer ( ) ) return yes ; return fd . device . handlers . read_block ( fd . device , fd . diskblock_for_fileblock ( fblk ) , bu ) ; } bool open_gap ( File ¢ fd , uint32 start , uint32 size ) { assert1 ( start <= fd . fsize ) ; return fd . copy_block ( start + size , start , fd . fsize - start ) ; } bool close_gap ( File ¢ fd , uint32 start , uint32 size ) { assert1 ( start + size <= fd . fsize ) ; return fd . copy_block ( start , start + size , fd . fsize - ( start + size ) ) || fd . truncate ( ) ; } bool copy_block ( File ¢ fd , uint32 z , uint32 q , uint32 n ) { if ( ! fd . writable ) return yes_with_error ( file_not_writable ) ; if ( q == z ) return no ; uint blocksize = fd . blocksize ; uint8 [ ] bu = alloc uint8 [ ] ( blocksize ) ; if ( z > q ) { q += n ; z += n ; uint m = z . lo & fd . blockmask ; if ( m > n ) m = n . lo ; q -= m ; z -= m ; n -= m ; if ( fd . _copy_block ( z , q , m , bu ) ) return yes ; do { while n >= blocksize ; q -= blocksize ; z -= blocksize ; n -= blocksize ; if ( fd . setfpos ( q ) || fd . read ( bu ) || fd . setfpos ( z ) || fd . set_buffer_to_fpos ( ) ) return yes ; swap ( bu , fd . buffer ) ; fd . buffer_valid = yes ; fd . buffer_dirty = yes ; } q -= n . lo ; z -= n . lo ; } else { uint m = blocksize - z . lo & fd . blockmask ; if ( m > n ) m = n . lo ; if ( fd . _copy_block ( z , q , m , bu ) ) return yes ; q += m ; z += m ; n -= m ; do { while n >= blocksize ; if ( fd . setfpos ( q ) || fd . read ( bu ) || fd . setfpos ( z ) || fd . set_buffer_to_fpos ( ) ) return yes ; swap ( bu , fd . buffer ) ; fd . buffer_valid = yes ; fd . buffer_dirty = yes ; q += blocksize ; z += blocksize ; n -= blocksize ; } } return fd . _copy_block ( z , q , n . lo , bu ) ; } } ""